Modified: trunk/Source/WebCore/platform/text/enchant/TextCheckerEnchant.cpp (230197 => 230198)
--- trunk/Source/WebCore/platform/text/enchant/TextCheckerEnchant.cpp 2018-04-03 07:11:04 UTC (rev 230197)
+++ trunk/Source/WebCore/platform/text/enchant/TextCheckerEnchant.cpp 2018-04-03 07:16:45 UTC (rev 230198)
@@ -22,46 +22,43 @@
#if ENABLE(SPELLCHECK)
-#include <glib.h>
#include <unicode/ubrk.h>
#include <wtf/Language.h>
+#include <wtf/NeverDestroyed.h>
+#include <wtf/text/CString.h>
#include <wtf/text/TextBreakIterator.h>
+#include <wtf/text/WTFString.h>
namespace WebCore {
-static const size_t maximumNumberOfSuggestions = 10;
+TextCheckerEnchant& TextCheckerEnchant::singleton()
+{
+ static NeverDestroyed<TextCheckerEnchant> textChecker;
+ return textChecker;
+}
-static void enchantDictDescribeCallback(const char* const languageTag, const char* const, const char* const, const char* const, void* data)
+void TextCheckerEnchant::EnchantDictDeleter::operator()(EnchantDict* dictionary) const
{
- Vector<CString>* dictionaries = static_cast<Vector<CString>*>(data);
- dictionaries->append(languageTag);
+ enchant_broker_free_dict(TextCheckerEnchant::singleton().m_broker, dictionary);
}
TextCheckerEnchant::TextCheckerEnchant()
: m_broker(enchant_broker_init())
- , m_enchantDictionaries(0)
{
}
-TextCheckerEnchant::~TextCheckerEnchant()
-{
- if (!m_broker)
- return;
-
- freeEnchantBrokerDictionaries();
- enchant_broker_free(m_broker);
-}
-
void TextCheckerEnchant::ignoreWord(const String& word)
{
+ auto utf8Word = word.utf8();
for (auto& dictionary : m_enchantDictionaries)
- enchant_dict_add_to_session(dictionary, word.utf8().data(), -1);
+ enchant_dict_add_to_session(dictionary.get(), utf8Word.data(), utf8Word.length());
}
void TextCheckerEnchant::learnWord(const String& word)
{
+ auto utf8Word = word.utf8();
for (auto& dictionary : m_enchantDictionaries)
- enchant_dict_add(dictionary, word.utf8().data(), -1);
+ enchant_dict_add(dictionary.get(), utf8Word.data(), utf8Word.length());
}
void TextCheckerEnchant::checkSpellingOfWord(const String& word, int start, int end, int& misspellingLocation, int& misspellingLength)
@@ -69,7 +66,7 @@
CString string = word.substring(start, end - start).utf8();
for (auto& dictionary : m_enchantDictionaries) {
- if (!enchant_dict_check(dictionary, string.data(), string.length())) {
+ if (!enchant_dict_check(dictionary.get(), string.data(), string.length())) {
// Stop checking, this word is ok in at least one dict.
misspellingLocation = -1;
misspellingLength = 0;
@@ -108,15 +105,18 @@
Vector<String> TextCheckerEnchant::getGuessesForWord(const String& word)
{
- Vector<String> guesses;
if (!hasDictionary())
- return guesses;
+ return { };
+ static const size_t maximumNumberOfSuggestions = 10;
+
+ Vector<String> guesses;
+ auto utf8Word = word.utf8();
for (auto& dictionary : m_enchantDictionaries) {
size_t numberOfSuggestions;
size_t i;
- char** suggestions = enchant_dict_suggest(dictionary, word.utf8().data(), -1, &numberOfSuggestions);
+ char** suggestions = enchant_dict_suggest(dictionary.get(), utf8Word.data(), utf8Word.length(), &numberOfSuggestions);
if (numberOfSuggestions <= 0)
continue;
@@ -126,7 +126,7 @@
for (i = 0; i < numberOfSuggestions; i++)
guesses.append(String::fromUTF8(suggestions[i]));
- enchant_dict_free_string_list(dictionary, suggestions);
+ enchant_dict_free_string_list(dictionary.get(), suggestions);
}
return guesses;
@@ -134,8 +134,7 @@
void TextCheckerEnchant::updateSpellCheckingLanguages(const Vector<String>& languages)
{
- Vector<EnchantDict*> spellDictionaries;
-
+ Vector<UniqueEnchantDict> spellDictionaries;
if (!languages.isEmpty()) {
for (auto& language : languages) {
CString currentLanguage = language.utf8();
@@ -146,60 +145,52 @@
}
} else {
// Languages are not specified by user, try to get default language.
- CString utf8Language = defaultLanguage().utf8();
- const char* language = utf8Language.data();
- if (enchant_broker_dict_exists(m_broker, language)) {
- if (auto* dict = enchant_broker_request_dict(m_broker, language))
+ CString language = defaultLanguage().utf8();
+ if (enchant_broker_dict_exists(m_broker, language.data())) {
+ if (auto* dict = enchant_broker_request_dict(m_broker, language.data()))
spellDictionaries.append(dict);
} else {
// No dictionaries selected, we get the first one from the list.
- Vector<CString> allDictionaries;
- enchant_broker_list_dicts(m_broker, enchantDictDescribeCallback, &allDictionaries);
- if (!allDictionaries.isEmpty()) {
- if (auto* dict = enchant_broker_request_dict(m_broker, allDictionaries.first().data()))
+ CString dictLanguage;
+ enchant_broker_list_dicts(m_broker, [](const char* const languageTag, const char* const, const char* const, const char* const, void* data) {
+ auto* dictLanguage = static_cast<CString*>(data);
+ if (dictLanguage->isNull())
+ *dictLanguage = languageTag;
+ }, &dictLanguage);
+ if (!dictLanguage.isNull()) {
+ if (auto* dict = enchant_broker_request_dict(m_broker, dictLanguage.data()))
spellDictionaries.append(dict);
}
}
}
- freeEnchantBrokerDictionaries();
- m_enchantDictionaries = spellDictionaries;
+ m_enchantDictionaries = WTFMove(spellDictionaries);
}
Vector<String> TextCheckerEnchant::loadedSpellCheckingLanguages() const
{
- Vector<String> languages;
if (!hasDictionary())
- return languages;
+ return { };
- // Get a Vector<CString> with the list of languages in use.
- Vector<CString> currentDictionaries;
- for (auto& dictionary : m_enchantDictionaries)
- enchant_dict_describe(dictionary, enchantDictDescribeCallback, ¤tDictionaries);
-
- for (auto& dictionary : currentDictionaries)
- languages.append(String::fromUTF8(dictionary.data()));
-
+ Vector<String> languages;
+ for (auto& dictionary : m_enchantDictionaries) {
+ enchant_dict_describe(dictionary.get(), [](const char* const languageTag, const char* const, const char* const, const char* const, void* data) {
+ auto* languages = static_cast<Vector<String>*>(data);
+ languages->append(String::fromUTF8(languageTag));
+ }, &languages);
+ }
return languages;
}
Vector<String> TextCheckerEnchant::availableSpellCheckingLanguages() const
{
- Vector<CString> allDictionaries;
- enchant_broker_list_dicts(m_broker, enchantDictDescribeCallback, &allDictionaries);
-
Vector<String> languages;
- for (auto& dictionary : allDictionaries)
- languages.append(String::fromUTF8(dictionary.data()));
-
+ enchant_broker_list_dicts(m_broker, [](const char* const languageTag, const char* const, const char* const, const char* const, void* data) {
+ auto* languages = static_cast<Vector<String>*>(data);
+ languages->append(String::fromUTF8(languageTag));
+ }, &languages);
return languages;
}
-void TextCheckerEnchant::freeEnchantBrokerDictionaries()
-{
- for (auto& dictionary : m_enchantDictionaries)
- enchant_broker_free_dict(m_broker, dictionary);
-}
-
} // namespace WebCore
#endif // ENABLE(SPELLCHECK)
Modified: trunk/Source/WebCore/platform/text/enchant/TextCheckerEnchant.h (230197 => 230198)
--- trunk/Source/WebCore/platform/text/enchant/TextCheckerEnchant.h 2018-04-03 07:11:04 UTC (rev 230197)
+++ trunk/Source/WebCore/platform/text/enchant/TextCheckerEnchant.h 2018-04-03 07:16:45 UTC (rev 230198)
@@ -17,25 +17,21 @@
* Boston, MA 02110-1301, USA.
*/
-#ifndef TextCheckerEnchant_h
-#define TextCheckerEnchant_h
+#pragma once
#if ENABLE(SPELLCHECK)
#include <enchant.h>
-#include <wtf/FastMalloc.h>
+#include <wtf/Forward.h>
#include <wtf/Vector.h>
-#include <wtf/text/CString.h>
-#include <wtf/text/WTFString.h>
namespace WebCore {
class TextCheckerEnchant {
- WTF_MAKE_FAST_ALLOCATED;
-
+ WTF_MAKE_NONCOPYABLE(TextCheckerEnchant); WTF_MAKE_FAST_ALLOCATED;
+ friend class WTF::NeverDestroyed<TextCheckerEnchant>;
public:
- TextCheckerEnchant();
- virtual ~TextCheckerEnchant();
+ static TextCheckerEnchant& singleton();
void ignoreWord(const String&);
void learnWord(const String&);
@@ -47,15 +43,21 @@
Vector<String> availableSpellCheckingLanguages() const;
private:
- void freeEnchantBrokerDictionaries();
+ TextCheckerEnchant();
+ ~TextCheckerEnchant() = delete;
+
void checkSpellingOfWord(const String&, int start, int end, int& misspellingLocation, int& misspellingLength);
+ struct EnchantDictDeleter {
+ void operator()(EnchantDict*) const;
+ };
+
+ using UniqueEnchantDict = std::unique_ptr<EnchantDict, EnchantDictDeleter>;
+
EnchantBroker* m_broker;
- Vector<EnchantDict*> m_enchantDictionaries;
+ Vector<UniqueEnchantDict> m_enchantDictionaries;
};
} // namespace WebCore
#endif // ENABLE(SPELLCHECK)
-
-#endif
Modified: trunk/Source/WebKit/UIProcess/gtk/TextCheckerGtk.cpp (230197 => 230198)
--- trunk/Source/WebKit/UIProcess/gtk/TextCheckerGtk.cpp 2018-04-03 07:11:04 UTC (rev 230197)
+++ trunk/Source/WebKit/UIProcess/gtk/TextCheckerGtk.cpp 2018-04-03 07:16:45 UTC (rev 230198)
@@ -39,14 +39,6 @@
namespace WebKit {
using namespace WebCore;
-#if ENABLE(SPELLCHECK)
-static WebCore::TextCheckerEnchant& enchantTextChecker()
-{
- static NeverDestroyed<WebCore::TextCheckerEnchant> checker;
- return checker;
-}
-#endif
-
TextCheckerState& checkerState()
{
static TextCheckerState textCheckerState;
@@ -149,7 +141,7 @@
#if ENABLE(SPELLCHECK)
misspellingLocation = -1;
misspellingLength = 0;
- enchantTextChecker().checkSpellingOfString(text.toStringWithoutCopying(), misspellingLocation, misspellingLength);
+ TextCheckerEnchant::singleton().checkSpellingOfString(text.toStringWithoutCopying(), misspellingLocation, misspellingLength);
#else
UNUSED_PARAM(text);
UNUSED_PARAM(misspellingLocation);
@@ -181,7 +173,7 @@
void TextChecker::getGuessesForWord(int64_t /* spellDocumentTag */, const String& word, const String& /* context */, int32_t /* insertionPoint */, Vector<String>& guesses, bool)
{
#if ENABLE(SPELLCHECK)
- guesses = enchantTextChecker().getGuessesForWord(word);
+ guesses = TextCheckerEnchant::singleton().getGuessesForWord(word);
#else
UNUSED_PARAM(word);
UNUSED_PARAM(guesses);
@@ -191,7 +183,7 @@
void TextChecker::learnWord(int64_t /* spellDocumentTag */, const String& word)
{
#if ENABLE(SPELLCHECK)
- enchantTextChecker().learnWord(word);
+ TextCheckerEnchant::singleton().learnWord(word);
#else
UNUSED_PARAM(word);
#endif
@@ -200,7 +192,7 @@
void TextChecker::ignoreWord(int64_t /* spellDocumentTag */, const String& word)
{
#if ENABLE(SPELLCHECK)
- enchantTextChecker().ignoreWord(word);
+ TextCheckerEnchant::singleton().ignoreWord(word);
#else
UNUSED_PARAM(word);
#endif
@@ -296,7 +288,7 @@
void TextChecker::setSpellCheckingLanguages(const Vector<String>& languages)
{
#if ENABLE(SPELLCHECK)
- enchantTextChecker().updateSpellCheckingLanguages(languages);
+ TextCheckerEnchant::singleton().updateSpellCheckingLanguages(languages);
#else
UNUSED_PARAM(languages);
#endif
@@ -305,7 +297,7 @@
Vector<String> TextChecker::loadedSpellCheckingLanguages()
{
#if ENABLE(SPELLCHECK)
- return enchantTextChecker().loadedSpellCheckingLanguages();
+ return TextCheckerEnchant::singleton().loadedSpellCheckingLanguages();
#else
return Vector<String>();
#endif