Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(28)

Unified Diff: chrome/browser/tab_contents/spelling_menu_observer.cc

Issue 178193005: Move render_view_context_menu.* related files out of tab_contents. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: context_menu->renderer_context_menu for disambiguation Created 6 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: chrome/browser/tab_contents/spelling_menu_observer.cc
diff --git a/chrome/browser/tab_contents/spelling_menu_observer.cc b/chrome/browser/tab_contents/spelling_menu_observer.cc
deleted file mode 100644
index c1eb6cfff926eb53c67dfba102aa72e6f0ab979a..0000000000000000000000000000000000000000
--- a/chrome/browser/tab_contents/spelling_menu_observer.cc
+++ /dev/null
@@ -1,420 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "chrome/browser/tab_contents/spelling_menu_observer.h"
-
-#include "base/bind.h"
-#include "base/command_line.h"
-#include "base/i18n/case_conversion.h"
-#include "base/prefs/pref_service.h"
-#include "base/strings/utf_string_conversions.h"
-#include "chrome/app/chrome_command_ids.h"
-#include "chrome/browser/profiles/profile.h"
-#include "chrome/browser/spellchecker/spellcheck_factory.h"
-#include "chrome/browser/spellchecker/spellcheck_host_metrics.h"
-#include "chrome/browser/spellchecker/spellcheck_platform_mac.h"
-#include "chrome/browser/spellchecker/spellcheck_service.h"
-#include "chrome/browser/spellchecker/spelling_service_client.h"
-#include "chrome/browser/tab_contents/render_view_context_menu.h"
-#include "chrome/browser/tab_contents/spelling_bubble_model.h"
-#include "chrome/browser/ui/confirm_bubble.h"
-#include "chrome/common/chrome_switches.h"
-#include "chrome/common/pref_names.h"
-#include "chrome/common/spellcheck_result.h"
-#include "content/public/browser/render_view_host.h"
-#include "content/public/browser/render_widget_host_view.h"
-#include "content/public/browser/web_contents.h"
-#include "content/public/browser/web_contents_view.h"
-#include "content/public/common/context_menu_params.h"
-#include "extensions/browser/view_type_utils.h"
-#include "grit/generated_resources.h"
-#include "ui/base/l10n/l10n_util.h"
-#include "ui/gfx/rect.h"
-
-using content::BrowserThread;
-
-SpellingMenuObserver::SpellingMenuObserver(RenderViewContextMenuProxy* proxy)
- : proxy_(proxy),
- loading_frame_(0),
- succeeded_(false),
- misspelling_hash_(0),
- client_(new SpellingServiceClient) {
- if (proxy && proxy->GetProfile()) {
- integrate_spelling_service_.Init(prefs::kSpellCheckUseSpellingService,
- proxy->GetProfile()->GetPrefs());
- autocorrect_spelling_.Init(prefs::kEnableAutoSpellCorrect,
- proxy->GetProfile()->GetPrefs());
- }
-}
-
-SpellingMenuObserver::~SpellingMenuObserver() {
-}
-
-void SpellingMenuObserver::InitMenu(const content::ContextMenuParams& params) {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
- DCHECK(!params.misspelled_word.empty() ||
- params.dictionary_suggestions.empty());
-
- // Exit if we are not in an editable element because we add a menu item only
- // for editable elements.
- Profile* profile = proxy_->GetProfile();
- if (!params.is_editable || !profile)
- return;
-
- // Exit if there is no misspelled word.
- if (params.misspelled_word.empty())
- return;
-
- suggestions_ = params.dictionary_suggestions;
- misspelled_word_ = params.misspelled_word;
- misspelling_hash_ = params.misspelling_hash;
-
- bool use_suggestions = SpellingServiceClient::IsAvailable(
- profile, SpellingServiceClient::SUGGEST);
-
- if (!suggestions_.empty() || use_suggestions)
- proxy_->AddSeparator();
-
- // Append Dictionary spell check suggestions.
- for (size_t i = 0; i < params.dictionary_suggestions.size() &&
- IDC_SPELLCHECK_SUGGESTION_0 + i <= IDC_SPELLCHECK_SUGGESTION_LAST;
- ++i) {
- proxy_->AddMenuItem(IDC_SPELLCHECK_SUGGESTION_0 + static_cast<int>(i),
- params.dictionary_suggestions[i]);
- }
-
- // The service types |SpellingServiceClient::SPELLCHECK| and
- // |SpellingServiceClient::SUGGEST| are mutually exclusive. Only one is
- // available at at time.
- //
- // When |SpellingServiceClient::SPELLCHECK| is available, the contextual
- // suggestions from |SpellingServiceClient| are already stored in
- // |params.dictionary_suggestions|. |SpellingMenuObserver| places these
- // suggestions in the slots |IDC_SPELLCHECK_SUGGESTION_[0-LAST]|. If
- // |SpellingMenuObserver| queried |SpellingServiceClient| again, then quality
- // of suggestions would be reduced by lack of context around the misspelled
- // word.
- //
- // When |SpellingServiceClient::SUGGEST| is available,
- // |params.dictionary_suggestions| contains suggestions only from Hunspell
- // dictionary. |SpellingMenuObserver| queries |SpellingServiceClient| with the
- // misspelled word without the surrounding context. Spellcheck suggestions
- // from |SpellingServiceClient::SUGGEST| are not available until
- // |SpellingServiceClient| responds to the query. While |SpellingMenuObserver|
- // waits for |SpellingServiceClient|, it shows a placeholder text "Loading
- // suggestion..." in the |IDC_CONTENT_CONTEXT_SPELLING_SUGGESTION| slot. After
- // |SpellingServiceClient| responds to the query, |SpellingMenuObserver|
- // replaces the placeholder text with either the spelling suggestion or the
- // message "No more suggestions from Google." The "No more suggestions"
- // message is there when |SpellingServiceClient| returned the same suggestion
- // as Hunspell.
- if (use_suggestions) {
- // Append a placeholder item for the suggestion from the Spelling service
- // and send a request to the service if we can retrieve suggestions from it.
- // Also, see if we can use the spelling service to get an ideal suggestion.
- // Otherwise, we'll fall back to the set of suggestions. Initialize
- // variables used in OnTextCheckComplete(). We copy the input text to the
- // result text so we can replace its misspelled regions with suggestions.
- succeeded_ = false;
- result_ = params.misspelled_word;
-
- // Add a placeholder item. This item will be updated when we receive a
- // response from the Spelling service. (We do not have to disable this
- // item now since Chrome will call IsCommandIdEnabled() and disable it.)
- loading_message_ =
- l10n_util::GetStringUTF16(IDS_CONTENT_CONTEXT_SPELLING_CHECKING);
- proxy_->AddMenuItem(IDC_CONTENT_CONTEXT_SPELLING_SUGGESTION,
- loading_message_);
- // Invoke a JSON-RPC call to the Spelling service in the background so we
- // can update the placeholder item when we receive its response. It also
- // starts the animation timer so we can show animation until we receive
- // it.
- bool result = client_->RequestTextCheck(
- profile, SpellingServiceClient::SUGGEST, params.misspelled_word,
- base::Bind(&SpellingMenuObserver::OnTextCheckComplete,
- base::Unretained(this), SpellingServiceClient::SUGGEST));
- if (result) {
- loading_frame_ = 0;
- animation_timer_.Start(FROM_HERE, base::TimeDelta::FromSeconds(1),
- this, &SpellingMenuObserver::OnAnimationTimerExpired);
- }
- }
-
- if (params.dictionary_suggestions.empty()) {
- proxy_->AddMenuItem(
- IDC_CONTENT_CONTEXT_NO_SPELLING_SUGGESTIONS,
- l10n_util::GetStringUTF16(IDS_CONTENT_CONTEXT_NO_SPELLING_SUGGESTIONS));
- bool use_spelling_service = SpellingServiceClient::IsAvailable(
- profile, SpellingServiceClient::SPELLCHECK);
- if (use_suggestions || use_spelling_service)
- proxy_->AddSeparator();
- } else {
- proxy_->AddSeparator();
-
- // |spellcheck_service| can be null when the suggested word is
- // provided by Web SpellCheck API.
- SpellcheckService* spellcheck_service =
- SpellcheckServiceFactory::GetForContext(profile);
- if (spellcheck_service && spellcheck_service->GetMetrics())
- spellcheck_service->GetMetrics()->RecordSuggestionStats(1);
- }
-
- // If word is misspelled, give option for "Add to dictionary" and a check item
- // "Ask Google for suggestions".
- proxy_->AddMenuItem(IDC_SPELLCHECK_ADD_TO_DICTIONARY,
- l10n_util::GetStringUTF16(IDS_CONTENT_CONTEXT_ADD_TO_DICTIONARY));
-
-#if defined(TOOLKIT_GTK)
- extensions::ViewType view_type =
- extensions::GetViewType(proxy_->GetWebContents());
- if (view_type != extensions::VIEW_TYPE_PANEL) {
-#endif
- proxy_->AddCheckItem(IDC_CONTENT_CONTEXT_SPELLING_TOGGLE,
- l10n_util::GetStringUTF16(IDS_CONTENT_CONTEXT_SPELLING_ASK_GOOGLE));
-#if defined(TOOLKIT_GTK)
- }
-#endif
-
- const CommandLine* command_line = CommandLine::ForCurrentProcess();
- if (command_line->HasSwitch(switches::kEnableSpellingAutoCorrect)) {
- proxy_->AddCheckItem(IDC_CONTENT_CONTEXT_AUTOCORRECT_SPELLING_TOGGLE,
- l10n_util::GetStringUTF16(IDS_CONTENT_CONTEXT_SPELLING_AUTOCORRECT));
- }
-
- proxy_->AddSeparator();
-}
-
-bool SpellingMenuObserver::IsCommandIdSupported(int command_id) {
- if (command_id >= IDC_SPELLCHECK_SUGGESTION_0 &&
- command_id <= IDC_SPELLCHECK_SUGGESTION_LAST)
- return true;
-
- switch (command_id) {
- case IDC_SPELLCHECK_ADD_TO_DICTIONARY:
- case IDC_CONTENT_CONTEXT_NO_SPELLING_SUGGESTIONS:
- case IDC_CONTENT_CONTEXT_SPELLING_SUGGESTION:
- case IDC_CONTENT_CONTEXT_SPELLING_TOGGLE:
- case IDC_CONTENT_CONTEXT_AUTOCORRECT_SPELLING_TOGGLE:
- return true;
-
- default:
- return false;
- }
- return false;
-}
-
-bool SpellingMenuObserver::IsCommandIdChecked(int command_id) {
- DCHECK(IsCommandIdSupported(command_id));
-
- if (command_id == IDC_CONTENT_CONTEXT_SPELLING_TOGGLE)
- return integrate_spelling_service_.GetValue() &&
- !proxy_->GetProfile()->IsOffTheRecord();
- else if (command_id == IDC_CONTENT_CONTEXT_AUTOCORRECT_SPELLING_TOGGLE)
- return autocorrect_spelling_.GetValue() &&
- !proxy_->GetProfile()->IsOffTheRecord();
- return false;
-}
-
-bool SpellingMenuObserver::IsCommandIdEnabled(int command_id) {
- DCHECK(IsCommandIdSupported(command_id));
-
- if (command_id >= IDC_SPELLCHECK_SUGGESTION_0 &&
- command_id <= IDC_SPELLCHECK_SUGGESTION_LAST)
- return true;
-
- switch (command_id) {
- case IDC_SPELLCHECK_ADD_TO_DICTIONARY:
- return !misspelled_word_.empty();
-
- case IDC_CONTENT_CONTEXT_NO_SPELLING_SUGGESTIONS:
- return false;
-
- case IDC_CONTENT_CONTEXT_SPELLING_SUGGESTION:
- return succeeded_;
-
- case IDC_CONTENT_CONTEXT_SPELLING_TOGGLE:
- return integrate_spelling_service_.IsUserModifiable() &&
- !proxy_->GetProfile()->IsOffTheRecord();
-
- case IDC_CONTENT_CONTEXT_AUTOCORRECT_SPELLING_TOGGLE:
- return integrate_spelling_service_.IsUserModifiable() &&
- !proxy_->GetProfile()->IsOffTheRecord();
-
- default:
- return false;
- }
- return false;
-}
-
-void SpellingMenuObserver::ExecuteCommand(int command_id) {
- DCHECK(IsCommandIdSupported(command_id));
-
- if (command_id >= IDC_SPELLCHECK_SUGGESTION_0 &&
- command_id <= IDC_SPELLCHECK_SUGGESTION_LAST) {
- int suggestion_index = command_id - IDC_SPELLCHECK_SUGGESTION_0;
- proxy_->GetRenderViewHost()->ReplaceMisspelling(
- suggestions_[suggestion_index]);
- // GetSpellCheckHost() can return null when the suggested word is provided
- // by Web SpellCheck API.
- Profile* profile = proxy_->GetProfile();
- if (profile) {
- SpellcheckService* spellcheck =
- SpellcheckServiceFactory::GetForContext(profile);
- if (spellcheck) {
- if (spellcheck->GetMetrics())
- spellcheck->GetMetrics()->RecordReplacedWordStats(1);
- spellcheck->GetFeedbackSender()->SelectedSuggestion(
- misspelling_hash_, suggestion_index);
- }
- }
- return;
- }
-
- // When we choose the suggestion sent from the Spelling service, we replace
- // the misspelled word with the suggestion and add it to our custom-word
- // dictionary so this word is not marked as misspelled any longer.
- if (command_id == IDC_CONTENT_CONTEXT_SPELLING_SUGGESTION) {
- proxy_->GetRenderViewHost()->ReplaceMisspelling(result_);
- misspelled_word_ = result_;
- }
-
- if (command_id == IDC_CONTENT_CONTEXT_SPELLING_SUGGESTION ||
- command_id == IDC_SPELLCHECK_ADD_TO_DICTIONARY) {
- // GetHostForProfile() can return null when the suggested word is provided
- // by Web SpellCheck API.
- Profile* profile = proxy_->GetProfile();
- if (profile) {
- SpellcheckService* spellcheck =
- SpellcheckServiceFactory::GetForContext(profile);
- if (spellcheck) {
- spellcheck->GetCustomDictionary()->AddWord(base::UTF16ToUTF8(
- misspelled_word_));
- spellcheck->GetFeedbackSender()->AddedToDictionary(misspelling_hash_);
- }
- }
-#if defined(OS_MACOSX)
- spellcheck_mac::AddWord(misspelled_word_);
-#endif
- }
-
- // The spelling service can be toggled by the user only if it is not managed.
- if (command_id == IDC_CONTENT_CONTEXT_SPELLING_TOGGLE &&
- integrate_spelling_service_.IsUserModifiable()) {
- // When a user enables the "Ask Google for spelling suggestions" item, we
- // show a bubble to confirm it. On the other hand, when a user disables this
- // item, we directly update/ the profile and stop integrating the spelling
- // service immediately.
- if (!integrate_spelling_service_.GetValue()) {
- content::RenderViewHost* rvh = proxy_->GetRenderViewHost();
- gfx::Rect rect = rvh->GetView()->GetViewBounds();
- chrome::ShowConfirmBubble(
-#if defined(TOOLKIT_VIEWS)
- proxy_->GetWebContents()->GetView()->GetTopLevelNativeWindow(),
-#else
- rvh->GetView()->GetNativeView(),
-#endif
- gfx::Point(rect.CenterPoint().x(), rect.y()),
- new SpellingBubbleModel(proxy_->GetProfile(),
- proxy_->GetWebContents(),
- false));
- } else {
- Profile* profile = proxy_->GetProfile();
- if (profile)
- profile->GetPrefs()->SetBoolean(prefs::kSpellCheckUseSpellingService,
- false);
- profile->GetPrefs()->SetBoolean(prefs::kEnableAutoSpellCorrect,
- false);
- }
- }
- // Autocorrect requires use of the spelling service and the spelling service
- // can be toggled by the user only if it is not managed.
- if (command_id == IDC_CONTENT_CONTEXT_AUTOCORRECT_SPELLING_TOGGLE &&
- integrate_spelling_service_.IsUserModifiable()) {
- // When the user enables autocorrect, we'll need to make sure that we can
- // ask Google for suggestions since that service is required. So we show
- // the bubble and just make sure to enable autocorrect as well.
- if (!integrate_spelling_service_.GetValue()) {
- content::RenderViewHost* rvh = proxy_->GetRenderViewHost();
- gfx::Rect rect = rvh->GetView()->GetViewBounds();
- chrome::ShowConfirmBubble(rvh->GetView()->GetNativeView(),
- gfx::Point(rect.CenterPoint().x(), rect.y()),
- new SpellingBubbleModel(
- proxy_->GetProfile(),
- proxy_->GetWebContents(),
- true));
- } else {
- Profile* profile = proxy_->GetProfile();
- if (profile) {
- bool current_value = autocorrect_spelling_.GetValue();
- profile->GetPrefs()->SetBoolean(prefs::kEnableAutoSpellCorrect,
- !current_value);
- }
- }
- }
-}
-
-void SpellingMenuObserver::OnMenuCancel() {
- Profile* profile = proxy_->GetProfile();
- if (!profile)
- return;
- SpellcheckService* spellcheck =
- SpellcheckServiceFactory::GetForContext(profile);
- if (!spellcheck)
- return;
- spellcheck->GetFeedbackSender()->IgnoredSuggestions(misspelling_hash_);
-}
-
-void SpellingMenuObserver::OnTextCheckComplete(
- SpellingServiceClient::ServiceType type,
- bool success,
- const base::string16& text,
- const std::vector<SpellCheckResult>& results) {
- animation_timer_.Stop();
-
- // Scan the text-check results and replace the misspelled regions with
- // suggested words. If the replaced text is included in the suggestion list
- // provided by the local spellchecker, we show a "No suggestions from Google"
- // message.
- succeeded_ = success;
- if (results.empty()) {
- succeeded_ = false;
- } else {
- typedef std::vector<SpellCheckResult> SpellCheckResults;
- for (SpellCheckResults::const_iterator it = results.begin();
- it != results.end(); ++it) {
- result_.replace(it->location, it->length, it->replacement);
- }
- base::string16 result = base::i18n::ToLower(result_);
- for (std::vector<base::string16>::const_iterator it = suggestions_.begin();
- it != suggestions_.end(); ++it) {
- if (result == base::i18n::ToLower(*it)) {
- succeeded_ = false;
- break;
- }
- }
- }
- if (type != SpellingServiceClient::SPELLCHECK) {
- if (!succeeded_) {
- result_ = l10n_util::GetStringUTF16(
- IDS_CONTENT_CONTEXT_SPELLING_NO_SUGGESTIONS_FROM_GOOGLE);
- }
-
- // Update the menu item with the result text. We disable this item and hide
- // it when the spelling service does not provide valid suggestions.
- proxy_->UpdateMenuItem(IDC_CONTENT_CONTEXT_SPELLING_SUGGESTION, succeeded_,
- false, result_);
- }
-}
-
-void SpellingMenuObserver::OnAnimationTimerExpired() {
- // Append '.' characters to the end of "Checking".
- loading_frame_ = (loading_frame_ + 1) & 3;
- base::string16 loading_message =
- loading_message_ + base::string16(loading_frame_,'.');
-
- // Update the menu item with the text. We disable this item to prevent users
- // from selecting it.
- proxy_->UpdateMenuItem(IDC_CONTENT_CONTEXT_SPELLING_SUGGESTION, false, false,
- loading_message);
-}

Powered by Google App Engine
This is Rietveld 408576698