TextCheckerGtk.cpp [plain text]
#include "config.h"
#include "TextChecker.h"
#include "TextBreakIterator.h"
#include "TextCheckerState.h"
#include "WebProcessPool.h"
#include "WebTextChecker.h"
#include <WebCore/NotImplemented.h>
#include <WebCore/TextCheckerEnchant.h>
#include <wtf/NeverDestroyed.h>
using namespace WebCore;
namespace WebKit {
static WebCore::TextCheckerEnchant& enchantTextChecker()
{
static NeverDestroyed<WebCore::TextCheckerEnchant> checker;
return checker;
}
TextCheckerState& checkerState()
{
static TextCheckerState textCheckerState;
static std::once_flag onceFlag;
std::call_once(onceFlag, [] {
textCheckerState.isContinuousSpellCheckingEnabled = false;
textCheckerState.isGrammarCheckingEnabled = false;
});
return textCheckerState;
}
const TextCheckerState& TextChecker::state()
{
return checkerState();
}
static void updateStateForAllProcessPools()
{
for (const auto& processPool : WebProcessPool::allProcessPools())
processPool->textCheckerStateChanged();
}
bool TextChecker::isContinuousSpellCheckingAllowed()
{
return true;
}
void TextChecker::setContinuousSpellCheckingEnabled(bool isContinuousSpellCheckingEnabled)
{
if (checkerState().isContinuousSpellCheckingEnabled == isContinuousSpellCheckingEnabled)
return;
checkerState().isContinuousSpellCheckingEnabled = isContinuousSpellCheckingEnabled;
updateStateForAllProcessPools();
}
void TextChecker::setGrammarCheckingEnabled(bool isGrammarCheckingEnabled)
{
if (checkerState().isGrammarCheckingEnabled == isGrammarCheckingEnabled)
return;
checkerState().isGrammarCheckingEnabled = isGrammarCheckingEnabled;
updateStateForAllProcessPools();
}
void TextChecker::continuousSpellCheckingEnabledStateChanged(bool enabled)
{
checkerState().isContinuousSpellCheckingEnabled = enabled;
}
void TextChecker::grammarCheckingEnabledStateChanged(bool enabled)
{
checkerState().isGrammarCheckingEnabled = enabled;
}
int64_t TextChecker::uniqueSpellDocumentTag(WebPageProxy*)
{
return 0;
}
void TextChecker::closeSpellDocumentWithTag(int64_t )
{
}
void TextChecker::checkSpellingOfString(int64_t , StringView text, int32_t& misspellingLocation, int32_t& misspellingLength)
{
misspellingLocation = -1;
misspellingLength = 0;
enchantTextChecker().checkSpellingOfString(text.toStringWithoutCopying(), misspellingLocation, misspellingLength);
}
void TextChecker::checkGrammarOfString(int64_t , StringView , Vector<WebCore::GrammarDetail>& , int32_t& , int32_t& )
{
}
bool TextChecker::spellingUIIsShowing()
{
return false;
}
void TextChecker::toggleSpellingUIIsShowing()
{
}
void TextChecker::updateSpellingUIWithMisspelledWord(int64_t , const String& )
{
}
void TextChecker::updateSpellingUIWithGrammarString(int64_t , const String& , const GrammarDetail& )
{
}
void TextChecker::getGuessesForWord(int64_t , const String& word, const String& , Vector<String>& guesses)
{
guesses = enchantTextChecker().getGuessesForWord(word);
}
void TextChecker::learnWord(int64_t , const String& word)
{
enchantTextChecker().learnWord(word);
}
void TextChecker::ignoreWord(int64_t , const String& word)
{
enchantTextChecker().ignoreWord(word);
}
void TextChecker::requestCheckingOfString(PassRefPtr<TextCheckerCompletion> completion)
{
if (!completion)
return;
TextCheckingRequestData request = completion->textCheckingRequestData();
ASSERT(request.sequence() != unrequestedTextCheckingSequence);
ASSERT(request.mask() != TextCheckingTypeNone);
completion->didFinishCheckingText(checkTextOfParagraph(completion->spellDocumentTag(), request.text(), request.mask()));
}
#if USE(UNIFIED_TEXT_CHECKING)
static unsigned nextWordOffset(StringView text, unsigned currentOffset)
{
TextBreakIterator* textIterator = wordBreakIterator(text);
if (!textIterator)
return currentOffset;
unsigned wordOffset = currentOffset;
while (wordOffset < text.length() && isTextBreak(textIterator, wordOffset))
++wordOffset;
if (!currentOffset && wordOffset == 1)
return currentOffset;
if ((wordOffset - currentOffset) > 1)
--wordOffset;
return wordOffset;
}
Vector<TextCheckingResult> TextChecker::checkTextOfParagraph(int64_t spellDocumentTag, StringView text, uint64_t checkingTypes)
{
if (!(checkingTypes & TextCheckingTypeSpelling))
return Vector<TextCheckingResult>();
TextBreakIterator* textIterator = wordBreakIterator(text);
if (!textIterator)
return Vector<TextCheckingResult>();
unsigned offset = nextWordOffset(text, 0);
unsigned lengthStrip = text.length();
while (lengthStrip > 0 && isTextBreak(textIterator, lengthStrip - 1))
--lengthStrip;
Vector<TextCheckingResult> paragraphCheckingResult;
while (offset < lengthStrip) {
int32_t misspellingLocation = -1;
int32_t misspellingLength = 0;
checkSpellingOfString(spellDocumentTag, text.substring(offset, lengthStrip - offset), misspellingLocation, misspellingLength);
if (!misspellingLength)
break;
TextCheckingResult misspellingResult;
misspellingResult.type = TextCheckingTypeSpelling;
misspellingResult.location = offset + misspellingLocation;
misspellingResult.length = misspellingLength;
paragraphCheckingResult.append(misspellingResult);
offset += misspellingLocation + misspellingLength;
offset = nextWordOffset(text.substring(0, lengthStrip), offset);
}
return paragraphCheckingResult;
}
#endif
void TextChecker::setSpellCheckingLanguages(const Vector<String>& languages)
{
enchantTextChecker().updateSpellCheckingLanguages(languages);
}
Vector<String> TextChecker::loadedSpellCheckingLanguages()
{
return enchantTextChecker().loadedSpellCheckingLanguages();
}
}