diff --git a/atom/renderer/api/atom_api_spell_check_client.cc b/atom/renderer/api/atom_api_spell_check_client.cc index fc32e071bb..8b97af3cc6 100644 --- a/atom/renderer/api/atom_api_spell_check_client.cc +++ b/atom/renderer/api/atom_api_spell_check_client.cc @@ -7,15 +7,52 @@ #include #include "atom/common/native_mate_converters/string16_converter.h" +#include "base/logging.h" #include "native_mate/converter.h" +#include "native_mate/dictionary.h" +#include "third_party/icu/source/common/unicode/uscript.h" #include "third_party/WebKit/public/web/WebTextCheckingCompletion.h" +#include "third_party/WebKit/public/web/WebTextCheckingResult.h" #include "atom/common/node_includes.h" +namespace mate { + +template<> +struct Converter { + static bool FromV8(v8::Isolate* isolate, v8::Handle val, + blink::WebTextCheckingResult* out) { + mate::Dictionary dict; + if (!ConvertFromV8(isolate, val, &dict)) + return false; + return dict.Get("location", &(out->location)) && + dict.Get("length", &(out->length)); + } +}; + +} // namespace mate + namespace atom { namespace api { +namespace { + +bool HasWordCharacters(const base::string16& text, int index) { + const base::char16* data = text.data(); + int length = text.length(); + while (index < length) { + uint32 code = 0; + U16_NEXT(data, index, length, code); + UErrorCode error = U_ZERO_ERROR; + if (uscript_getScript(code, &error) != USCRIPT_COMMON) + return true; + } + return false; +} + +} // namespace + SpellCheckClient::SpellCheckClient(v8::Isolate* isolate, v8::Handle provider) : isolate_(isolate), provider_(isolate, provider) {} @@ -27,21 +64,25 @@ void SpellCheckClient::spellCheck( int& misspelledOffset, int& misspelledLength, blink::WebVector* optionalSuggestions) { - std::vector result; + blink::WebTextCheckingResult result; if (!CallProviderMethod("spellCheck", text, &result)) return; - if (result.size() != 2) - return; - - misspelledOffset = result[0]; - misspelledLength = result[1]; + misspelledOffset = result.location; + misspelledLength = result.length; } void SpellCheckClient::checkTextOfParagraph( const blink::WebString& text, blink::WebTextCheckingTypeMask mask, blink::WebVector* results) { + if (!results) + return; + + if (!(mask & blink::WebTextCheckingTypeSpelling)) + return; + + NOTREACHED() << "checkTextOfParagraph should never be called"; } void SpellCheckClient::requestCheckingOfText( @@ -49,8 +90,27 @@ void SpellCheckClient::requestCheckingOfText( const blink::WebVector& markersInText, const blink::WebVector& markerOffsets, blink::WebTextCheckingCompletion* completionCallback) { - if (completionCallback) + v8::HandleScope handle_scope(isolate_); + v8::Handle provider = provider_.NewHandle(); + if (!provider->Has(mate::StringToV8(isolate_, "requestCheckingOfText"))) { completionCallback->didCancelCheckingText(); + return; + } + + base::string16 text(textToCheck); + if (text.empty() || !HasWordCharacters(text, 0)) { + completionCallback->didCancelCheckingText(); + return; + } + + std::vector result; + if (!CallProviderMethod("requestCheckingOfText", textToCheck, &result)) { + completionCallback->didCancelCheckingText(); + return; + } + + completionCallback->didFinishCheckingText(result); + return; } blink::WebString SpellCheckClient::autoCorrectWord( diff --git a/atom/renderer/api/atom_api_spell_check_client.h b/atom/renderer/api/atom_api_spell_check_client.h index a6d05f8645..d6ec801734 100644 --- a/atom/renderer/api/atom_api_spell_check_client.h +++ b/atom/renderer/api/atom_api_spell_check_client.h @@ -41,8 +41,7 @@ class SpellCheckClient : public blink::WebSpellCheckClient { const blink::WebString& word) override; template - bool CallProviderMethod(const char* method, - const blink::WebString& text, + bool CallProviderMethod(const char* method, const blink::WebString& text, T* result); v8::Isolate* isolate_;