1a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#ifndef CHROME_BROWSER_RENDERER_CONTEXT_MENU_SPELLING_MENU_OBSERVER_H_ 6a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#define CHROME_BROWSER_RENDERER_CONTEXT_MENU_SPELLING_MENU_OBSERVER_H_ 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <vector> 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/compiler_specific.h" 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/scoped_ptr.h" 122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/prefs/pref_member.h" 13868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/string16.h" 14eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "base/timer/timer.h" 15a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "chrome/browser/renderer_context_menu/render_view_context_menu_observer.h" 162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/spellchecker/spelling_service_client.h" 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class RenderViewContextMenuProxy; 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct SpellCheckResult; 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// An observer that listens to events from the RenderViewContextMenu class and 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// shows suggestions from the Spelling ("do you mean") service to a context menu 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// while we show it. This class implements two interfaces: 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// * RenderViewContextMenuObserver 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This interface is used for adding a menu item and update it while showing. 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// * net::URLFetcherDelegate 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This interface is used for sending a JSON_RPC request to the Spelling 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// service and retrieving its response. 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// These interfaces allow this class to make a JSON-RPC call to the Spelling 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// service in the background and update the context menu while showing. The 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// following snippet describes how to add this class to the observer list of the 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// RenderViewContextMenu class. 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// void RenderViewContextMenu::InitMenu() { 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// spelling_menu_observer_.reset(new SpellingMenuObserver(this)); 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// if (spelling_menu_observer_.get()) 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// observers_.AddObserver(spelling_menu_observer.get()); 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// } 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class SpellingMenuObserver : public RenderViewContextMenuObserver { 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) explicit SpellingMenuObserver(RenderViewContextMenuProxy* proxy); 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual ~SpellingMenuObserver(); 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // RenderViewContextMenuObserver implementation. 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void InitMenu(const content::ContextMenuParams& params) OVERRIDE; 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual bool IsCommandIdSupported(int command_id) OVERRIDE; 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual bool IsCommandIdChecked(int command_id) OVERRIDE; 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual bool IsCommandIdEnabled(int command_id) OVERRIDE; 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void ExecuteCommand(int command_id) OVERRIDE; 5190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) virtual void OnMenuCancel() OVERRIDE; 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // A callback function called when the Spelling service finishes checking a 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // misspelled word. 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void OnTextCheckComplete( 562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SpellingServiceClient::ServiceType type, 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool success, 58a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) const base::string16& text, 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::vector<SpellCheckResult>& results); 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The callback function for base::RepeatingTimer<SpellingMenuClient>. This 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // function updates the "loading..." animation in the context-menu item. 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void OnAnimationTimerExpired(); 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The interface to add a context-menu item and update it. This class uses 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // this interface to avoid accesing context-menu items directly. 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RenderViewContextMenuProxy* proxy_; 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Suggested words from the local spellchecker. If the spelling service 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // returns a word in this list, we hide the context-menu item to prevent 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // showing the same word twice. 735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) std::vector<base::string16> suggestions_; 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The string used for animation until we receive a response from the Spelling 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // service. The current animation just adds periods at the end of this string: 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 'Loading' -> 'Loading.' -> 'Loading..' -> 'Loading...' (-> 'Loading') 78a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) base::string16 loading_message_; 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t loading_frame_; 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // A flag represending whether a JSON-RPC call to the Spelling service 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // finished successfully and its response had a suggestion not included in the 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // ones provided by the local spellchecker. When this flag is true, we enable 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the context-menu item so users can choose it. 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool succeeded_; 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The misspelled word. When we choose the "Add to dictionary" item, we add 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // this word to the custom-word dictionary. 89a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) base::string16 misspelled_word_; 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // The hash identifier for the misspelled word. Used for collecting user 9290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // feedback to spellcheck suggestions. 9390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) uint32 misspelling_hash_; 9490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The string representing the result of this call. This string is a 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // suggestion when this call finished successfully. Otherwise it is error 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // text. Until we receive a response from the Spelling service, this string 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // stores the input string. (Since the Spelling service sends only misspelled 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // words, we replace these misspelled words in the input text with the 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // suggested words to create suggestion text. 101a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) base::string16 result_; 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The URLFetcher object used for sending a JSON-RPC request. 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<SpellingServiceClient> client_; 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // A timer used for loading animation. 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::RepeatingTimer<SpellingMenuObserver> animation_timer_; 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Flag indicating whether online spelling correction service is enabled. When 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // this variable is true and we right-click a misspelled word, we send a 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // JSON-RPC request to the service and retrieve suggestions. 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BooleanPrefMember integrate_spelling_service_; 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Flag indicating whether automatic spelling correction is enabled. 1152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) BooleanPrefMember autocorrect_spelling_; 1162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(SpellingMenuObserver); 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 120a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#endif // CHROME_BROWSER_RENDERER_CONTEXT_MENU_SPELLING_MENU_OBSERVER_H_ 121