15f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved. 25f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// found in the LICENSE file. 45f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 55f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "content/shell/renderer/test_runner/spell_check_client.h" 65f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 75f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "content/shell/renderer/test_runner/mock_grammar_check.h" 81320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "content/shell/renderer/test_runner/web_test_delegate.h" 95f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "content/shell/renderer/test_runner/web_test_proxy.h" 105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "third_party/WebKit/public/web/WebTextCheckingCompletion.h" 115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "third_party/WebKit/public/web/WebTextCheckingResult.h" 125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)namespace content { 145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)namespace { 165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)class HostMethodTask : public WebMethodTask<SpellCheckClient> { 185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) public: 195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) typedef void (SpellCheckClient::*CallbackMethodType)(); 205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) HostMethodTask(SpellCheckClient* object, CallbackMethodType callback) 215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) : WebMethodTask<SpellCheckClient>(object), callback_(callback) {} 225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) virtual ~HostMethodTask() {} 245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 251320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci virtual void RunIfValid() OVERRIDE { (object_->*callback_)(); } 265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) private: 285f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) CallbackMethodType callback_; 295f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 305f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(HostMethodTask); 315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}; 325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)} // namespace 345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)SpellCheckClient::SpellCheckClient(WebTestProxyBase* web_test_proxy) 365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) : last_requested_text_checking_completion_(0), 375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) web_test_proxy_(web_test_proxy) { 385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)} 395f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 405f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)SpellCheckClient::~SpellCheckClient() { 415f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)} 425f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void SpellCheckClient::SetDelegate(WebTestDelegate* delegate) { 445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) delegate_ = delegate; 455f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)} 465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// blink::WebSpellCheckClient 485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void SpellCheckClient::spellCheck( 495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) const blink::WebString& text, 505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) int& misspelled_offset, 515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) int& misspelled_length, 525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) blink::WebVector<blink::WebString>* optional_suggestions) { 535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // Check the spelling of the given text. 545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) spell_check_.SpellCheckWord(text, &misspelled_offset, &misspelled_length); 555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)} 565f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void SpellCheckClient::checkTextOfParagraph( 585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) const blink::WebString& text, 595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) blink::WebTextCheckingTypeMask mask, 605f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) blink::WebVector<blink::WebTextCheckingResult>* web_results) { 615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) std::vector<blink::WebTextCheckingResult> results; 625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (mask & blink::WebTextCheckingTypeSpelling) { 635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) size_t offset = 0; 645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) base::string16 data = text; 655f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) while (offset < data.length()) { 665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) int misspelled_position = 0; 675f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) int misspelled_length = 0; 685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) spell_check_.SpellCheckWord( 695f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) data.substr(offset), &misspelled_position, &misspelled_length); 705f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (!misspelled_length) 715f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) break; 725f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) blink::WebTextCheckingResult result; 735f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) result.decoration = blink::WebTextDecorationTypeSpelling; 745f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) result.location = offset + misspelled_position; 755f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) result.length = misspelled_length; 765f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) results.push_back(result); 775f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) offset += misspelled_position + misspelled_length; 785f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 795f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 805f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (mask & blink::WebTextCheckingTypeGrammar) 815f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) MockGrammarCheck::CheckGrammarOfString(text, &results); 825f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) web_results->assign(results); 835f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)} 845f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 855f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void SpellCheckClient::requestCheckingOfText( 865f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) const blink::WebString& text, 875f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) const blink::WebVector<uint32_t>& markers, 885f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) const blink::WebVector<unsigned>& marker_offsets, 895f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) blink::WebTextCheckingCompletion* completion) { 905f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (text.isEmpty()) { 915f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (completion) 925f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) completion->didCancelCheckingText(); 935f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return; 945f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 955f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 965f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (last_requested_text_checking_completion_) 975f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) last_requested_text_checking_completion_->didCancelCheckingText(); 985f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 995f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) last_requested_text_checking_completion_ = completion; 1005f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) last_requested_text_check_string_ = text; 1015f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (spell_check_.HasInCache(text)) 1025f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) FinishLastTextCheck(); 1035f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) else 1041320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci delegate_->PostDelayedTask( 1055f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) new HostMethodTask(this, &SpellCheckClient::FinishLastTextCheck), 0); 1065f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)} 1075f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 1085f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void SpellCheckClient::FinishLastTextCheck() { 1095f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (!last_requested_text_checking_completion_) 1105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return; 1115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) std::vector<blink::WebTextCheckingResult> results; 1125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) int offset = 0; 1135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) base::string16 text = last_requested_text_check_string_; 1145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (!spell_check_.IsMultiWordMisspelling(blink::WebString(text), &results)) { 1155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) while (text.length()) { 1165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) int misspelled_position = 0; 1175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) int misspelled_length = 0; 1185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) spell_check_.SpellCheckWord( 1195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) blink::WebString(text), &misspelled_position, &misspelled_length); 1205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (!misspelled_length) 1215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) break; 1225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) blink::WebVector<blink::WebString> suggestions; 1235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) spell_check_.FillSuggestionList( 1245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) blink::WebString(text.substr(misspelled_position, misspelled_length)), 1255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) &suggestions); 1265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) results.push_back(blink::WebTextCheckingResult( 1275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) blink::WebTextDecorationTypeSpelling, 1285f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) offset + misspelled_position, 1295f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) misspelled_length, 1305f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) suggestions.isEmpty() ? blink::WebString() : suggestions[0])); 1315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) text = text.substr(misspelled_position + misspelled_length); 1325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) offset += misspelled_position + misspelled_length; 1335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 1345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) MockGrammarCheck::CheckGrammarOfString(last_requested_text_check_string_, 1355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) &results); 1365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 1375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) last_requested_text_checking_completion_->didFinishCheckingText(results); 1385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) last_requested_text_checking_completion_ = 0; 1395f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 1405f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) web_test_proxy_->PostSpellCheckEvent(blink::WebString("FinishLastTextCheck")); 1415f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)} 1425f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 1435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)blink::WebString SpellCheckClient::autoCorrectWord( 1445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) const blink::WebString& word) { 1455f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // Returns an empty string as Mac WebKit ('WebKitSupport/WebEditorClient.mm') 1465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // does. (If this function returns a non-empty string, WebKit replaces the 1475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // given misspelled string with the result one. This process executes some 1485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // editor commands and causes layout-test failures.) 1495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return blink::WebString(); 1505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)} 1515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 1525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)} // namespace content 153