diff --git a/cef.gyp b/cef.gyp index cd36980b8..7be2baaec 100644 --- a/cef.gyp +++ b/cef.gyp @@ -849,10 +849,14 @@ '<(DEPTH)/cc/blink/cc_blink.gyp:cc_blink', '<(DEPTH)/cc/cc.gyp:cc', '<(DEPTH)/components/components.gyp:crash_component', + '<(DEPTH)/components/components.gyp:keyed_service_content', + '<(DEPTH)/components/components.gyp:keyed_service_core', '<(DEPTH)/components/components.gyp:navigation_interception', '<(DEPTH)/components/components.gyp:pdf_browser', '<(DEPTH)/components/components.gyp:pdf_common', '<(DEPTH)/components/components.gyp:pdf_renderer', + '<(DEPTH)/components/components.gyp:pref_registry', + '<(DEPTH)/components/components.gyp:user_prefs', '<(DEPTH)/components/components.gyp:web_cache_renderer', '<(DEPTH)/content/content.gyp:content_app_both', '<(DEPTH)/content/content.gyp:content_browser', @@ -872,6 +876,8 @@ '<(DEPTH)/pdf/pdf.gyp:pdf', '<(DEPTH)/skia/skia.gyp:skia', '<(DEPTH)/storage/storage_browser.gyp:storage', + '<(DEPTH)/sync/sync.gyp:sync', + '<(DEPTH)/third_party/hunspell/hunspell.gyp:hunspell', '<(DEPTH)/third_party/libxml/libxml.gyp:libxml', '<(DEPTH)/third_party/re2/re2.gyp:re2', '<(DEPTH)/third_party/WebKit/public/blink.gyp:blink', @@ -1126,6 +1132,50 @@ # determine the current locale. '<(DEPTH)/chrome/browser/browser_process.cc', '<(DEPTH)/chrome/browser/browser_process.h', + # Include sources for spell checking support. + '<(DEPTH)/chrome/browser/spellchecker/feedback.cc', + '<(DEPTH)/chrome/browser/spellchecker/feedback.h', + '<(DEPTH)/chrome/browser/spellchecker/feedback_sender.cc', + '<(DEPTH)/chrome/browser/spellchecker/feedback_sender.h', + '<(DEPTH)/chrome/browser/spellchecker/misspelling.cc', + '<(DEPTH)/chrome/browser/spellchecker/misspelling.h', + '<(DEPTH)/chrome/browser/spellchecker/spellcheck_action.cc', + '<(DEPTH)/chrome/browser/spellchecker/spellcheck_action.h', + '<(DEPTH)/chrome/browser/spellchecker/spellcheck_custom_dictionary.cc', + '<(DEPTH)/chrome/browser/spellchecker/spellcheck_custom_dictionary.h', + '<(DEPTH)/chrome/browser/spellchecker/spellcheck_factory.cc', + '<(DEPTH)/chrome/browser/spellchecker/spellcheck_factory.h', + '<(DEPTH)/chrome/browser/spellchecker/spellcheck_host_metrics.cc', + '<(DEPTH)/chrome/browser/spellchecker/spellcheck_host_metrics.h', + '<(DEPTH)/chrome/browser/spellchecker/spellcheck_hunspell_dictionary.cc', + '<(DEPTH)/chrome/browser/spellchecker/spellcheck_hunspell_dictionary.h', + '<(DEPTH)/chrome/browser/spellchecker/spellcheck_message_filter.cc', + '<(DEPTH)/chrome/browser/spellchecker/spellcheck_message_filter.h', + '<(DEPTH)/chrome/browser/spellchecker/spellcheck_service.cc', + '<(DEPTH)/chrome/browser/spellchecker/spellcheck_service.h', + '<(DEPTH)/chrome/browser/spellchecker/spelling_service_client.cc', + '<(DEPTH)/chrome/browser/spellchecker/spelling_service_client.h', + '<(DEPTH)/chrome/browser/spellchecker/word_trimmer.cc', + '<(DEPTH)/chrome/browser/spellchecker/word_trimmer.h', + '<(DEPTH)/chrome/common/chrome_constants.cc', + '<(DEPTH)/chrome/common/spellcheck_common.cc', + '<(DEPTH)/chrome/common/spellcheck_common.h', + '<(DEPTH)/chrome/common/spellcheck_marker.h', + '<(DEPTH)/chrome/common/spellcheck_messages.h', + '<(DEPTH)/chrome/common/spellcheck_result.h', + '<(DEPTH)/chrome/renderer/spellchecker/custom_dictionary_engine.cc', + '<(DEPTH)/chrome/renderer/spellchecker/custom_dictionary_engine.h', + '<(DEPTH)/chrome/renderer/spellchecker/hunspell_engine.cc', + '<(DEPTH)/chrome/renderer/spellchecker/hunspell_engine.h', + '<(DEPTH)/chrome/renderer/spellchecker/spellcheck.cc', + '<(DEPTH)/chrome/renderer/spellchecker/spellcheck.h', + '<(DEPTH)/chrome/renderer/spellchecker/spellcheck_language.cc', + '<(DEPTH)/chrome/renderer/spellchecker/spellcheck_language.h', + '<(DEPTH)/chrome/renderer/spellchecker/spellcheck_provider.cc', + '<(DEPTH)/chrome/renderer/spellchecker/spellcheck_provider.h', + '<(DEPTH)/chrome/renderer/spellchecker/spellcheck_worditerator.cc', + '<(DEPTH)/chrome/renderer/spellchecker/spellcheck_worditerator.h', + '<(DEPTH)/chrome/renderer/spellchecker/spelling_engine.h', ], 'conditions': [ ['OS=="win"', { @@ -1162,6 +1212,13 @@ # Include sources for CoreAnimation support. '<(DEPTH)/chrome/browser/ui/cocoa/nsview_additions.h', '<(DEPTH)/chrome/browser/ui/cocoa/nsview_additions.mm', + # Include sources for spell checking support. + '<(DEPTH)/chrome/browser/spellchecker/spellcheck_message_filter_mac.cc', + '<(DEPTH)/chrome/browser/spellchecker/spellcheck_message_filter_mac.h', + '<(DEPTH)/chrome/browser/spellchecker/spellcheck_platform_mac.h', + '<(DEPTH)/chrome/browser/spellchecker/spellcheck_platform_mac.mm', + '<(DEPTH)/chrome/renderer/spellchecker/cocoa_spelling_engine_mac.cc', + '<(DEPTH)/chrome/renderer/spellchecker/cocoa_spelling_engine_mac.h', ], }], [ 'OS=="linux" or OS=="freebsd" or OS=="openbsd"', { diff --git a/include/capi/cef_browser_capi.h b/include/capi/cef_browser_capi.h index 23274630b..6ecc0cdea 100644 --- a/include/capi/cef_browser_capi.h +++ b/include/capi/cef_browser_capi.h @@ -358,6 +358,13 @@ typedef struct _cef_browser_host_t { int (CEF_CALLBACK *is_mouse_cursor_change_disabled)( struct _cef_browser_host_t* self); + /// + // If a misspelled word is currently selected in an editable node calling this + // function will replace it with the specified |word|. + /// + void (CEF_CALLBACK *replace_misspelling)(struct _cef_browser_host_t* self, + const cef_string_t* word); + /// // Returns true (1) if window rendering is disabled. /// diff --git a/include/capi/cef_context_menu_handler_capi.h b/include/capi/cef_context_menu_handler_capi.h index 115d291b8..598295aad 100644 --- a/include/capi/cef_context_menu_handler_capi.h +++ b/include/capi/cef_context_menu_handler_capi.h @@ -198,11 +198,41 @@ typedef struct _cef_context_menu_params_t { cef_string_userfree_t (CEF_CALLBACK *get_selection_text)( struct _cef_context_menu_params_t* self); + /// + // Returns the text of the misspelled word, if any, that the context menu was + // invoked on. + /// + // The resulting string must be freed by calling cef_string_userfree_free(). + cef_string_userfree_t (CEF_CALLBACK *get_misspelled_word)( + struct _cef_context_menu_params_t* self); + + /// + // Returns the hash of the misspelled word, if any, that the context menu was + // invoked on. + /// + int (CEF_CALLBACK *get_misspelling_hash)( + struct _cef_context_menu_params_t* self); + + /// + // Returns true (1) if suggestions exist, false (0) otherwise. Fills in + // |suggestions| from the spell check service for the misspelled word if there + // is one. + /// + int (CEF_CALLBACK *get_dictionary_suggestions)( + struct _cef_context_menu_params_t* self, cef_string_list_t suggestions); + /// // Returns true (1) if the context menu was invoked on an editable node. /// int (CEF_CALLBACK *is_editable)(struct _cef_context_menu_params_t* self); + /// + // Returns true (1) if the context menu was invoked on an editable node where + // spell-check is enabled. + /// + int (CEF_CALLBACK *is_spell_check_enabled)( + struct _cef_context_menu_params_t* self); + /// // Returns flags representing the actions supported by the editable node, if // any, that the context menu was invoked on. diff --git a/include/cef_browser.h b/include/cef_browser.h index a067afe43..b16cce8be 100644 --- a/include/cef_browser.h +++ b/include/cef_browser.h @@ -404,6 +404,13 @@ class CefBrowserHost : public virtual CefBase { /*--cef()--*/ virtual bool IsMouseCursorChangeDisabled() =0; + /// + // If a misspelled word is currently selected in an editable node calling + // this method will replace it with the specified |word|. + /// + /*--cef()--*/ + virtual void ReplaceMisspelling(const CefString& word) =0; + /// // Returns true if window rendering is disabled. /// diff --git a/include/cef_context_menu_handler.h b/include/cef_context_menu_handler.h index 048a2bcc5..f841722de 100644 --- a/include/cef_context_menu_handler.h +++ b/include/cef_context_menu_handler.h @@ -193,12 +193,40 @@ class CefContextMenuParams : public virtual CefBase { /*--cef()--*/ virtual CefString GetSelectionText() =0; + /// + // Returns the text of the misspelled word, if any, that the context menu was + // invoked on. + /// + /*--cef()--*/ + virtual CefString GetMisspelledWord() =0; + + /// + // Returns the hash of the misspelled word, if any, that the context menu was + // invoked on. + /// + /*--cef()--*/ + virtual int GetMisspellingHash() =0; + + /// + // Returns true if suggestions exist, false otherwise. Fills in |suggestions| + // from the spell check service for the misspelled word if there is one. + /// + /*--cef()--*/ + virtual bool GetDictionarySuggestions(std::vector& suggestions) =0; + /// // Returns true if the context menu was invoked on an editable node. /// /*--cef()--*/ virtual bool IsEditable() =0; + /// + // Returns true if the context menu was invoked on an editable node where + // spell-check is enabled. + /// + /*--cef()--*/ + virtual bool IsSpellCheckEnabled() =0; + /// // Returns flags representing the actions supported by the editable node, if // any, that the context menu was invoked on. diff --git a/include/internal/cef_types.h b/include/internal/cef_types.h index fea83a079..cd0c11291 100644 --- a/include/internal/cef_types.h +++ b/include/internal/cef_types.h @@ -1292,6 +1292,15 @@ typedef enum { MENU_ID_PRINT = 131, MENU_ID_VIEW_SOURCE = 132, + // Spell checking word correction suggestions. + MENU_ID_SPELLCHECK_SUGGESTION_0 = 200, + MENU_ID_SPELLCHECK_SUGGESTION_1 = 201, + MENU_ID_SPELLCHECK_SUGGESTION_2 = 202, + MENU_ID_SPELLCHECK_SUGGESTION_3 = 203, + MENU_ID_SPELLCHECK_SUGGESTION_4 = 204, + MENU_ID_SPELLCHECK_SUGGESTION_LAST = 204, + MENU_ID_NO_SPELLING_SUGGESTIONS = 205, + // All user-defined menu IDs should come between MENU_ID_USER_FIRST and // MENU_ID_USER_LAST to avoid overlapping the Chromium and CEF ID ranges // defined in the tools/gritsettings/resource_ids file. diff --git a/libcef/browser/browser_context_impl.cc b/libcef/browser/browser_context_impl.cc index 32176e749..e65f51460 100644 --- a/libcef/browser/browser_context_impl.cc +++ b/libcef/browser/browser_context_impl.cc @@ -15,6 +15,7 @@ #include "base/bind.h" #include "base/logging.h" #include "base/threading/thread.h" +#include "components/keyed_service/content/browser_context_dependency_manager.h" #include "content/public/browser/download_manager.h" #include "content/public/browser/browser_thread.h" #include "content/public/browser/resource_context.h" @@ -61,6 +62,10 @@ CefBrowserContextImpl::~CefBrowserContextImpl() { BrowserThread::DeleteSoon( BrowserThread::IO, FROM_HERE, resource_context_.release()); } + + // Remove any BrowserContextKeyedServiceFactory associations. + BrowserContextDependencyManager::GetInstance()->DestroyBrowserContextServices( + this); } base::FilePath CefBrowserContextImpl::GetPath() const { diff --git a/libcef/browser/browser_context_proxy.cc b/libcef/browser/browser_context_proxy.cc index 501a315e6..aa4a837e3 100644 --- a/libcef/browser/browser_context_proxy.cc +++ b/libcef/browser/browser_context_proxy.cc @@ -13,6 +13,7 @@ #include "base/bind.h" #include "base/logging.h" #include "base/threading/thread.h" +#include "components/keyed_service/content/browser_context_dependency_manager.h" #include "content/public/browser/browser_thread.h" #include "content/public/browser/resource_context.h" #include "content/public/browser/storage_partition.h" @@ -59,6 +60,10 @@ CefBrowserContextProxy::~CefBrowserContextProxy() { BrowserThread::DeleteSoon( BrowserThread::IO, FROM_HERE, resource_context_.release()); } + + // Remove any BrowserContextKeyedServiceFactory associations. + BrowserContextDependencyManager::GetInstance()->DestroyBrowserContextServices( + this); } base::FilePath CefBrowserContextProxy::GetPath() const { diff --git a/libcef/browser/browser_host_impl.cc b/libcef/browser/browser_host_impl.cc index b74b1148a..70811e86b 100644 --- a/libcef/browser/browser_host_impl.cc +++ b/libcef/browser/browser_host_impl.cc @@ -860,6 +860,17 @@ bool CefBrowserHostImpl::IsWindowRenderingDisabled() { return IsWindowless(); } +void CefBrowserHostImpl::ReplaceMisspelling(const CefString& word) { + if (!CEF_CURRENTLY_ON_UIT()) { + CEF_POST_TASK(CEF_UIT, + base::Bind(&CefBrowserHostImpl::ReplaceMisspelling, this, word)); + return; + } + + if(web_contents()) + web_contents()->ReplaceMisspelling(word); +} + void CefBrowserHostImpl::WasResized() { if (!IsWindowless()) { NOTREACHED() << "Window rendering is not disabled"; diff --git a/libcef/browser/browser_host_impl.h b/libcef/browser/browser_host_impl.h index 129de5f5c..1ab569d60 100644 --- a/libcef/browser/browser_host_impl.h +++ b/libcef/browser/browser_host_impl.h @@ -158,6 +158,7 @@ class CefBrowserHostImpl : public CefBrowserHost, virtual void SetMouseCursorChangeDisabled(bool disabled) OVERRIDE; virtual bool IsMouseCursorChangeDisabled() OVERRIDE; virtual bool IsWindowRenderingDisabled() OVERRIDE; + virtual void ReplaceMisspelling(const CefString& word) OVERRIDE; virtual void WasResized() OVERRIDE; virtual void WasHidden(bool hidden) OVERRIDE; virtual void NotifyScreenInfoChanged() OVERRIDE; diff --git a/libcef/browser/browser_main.cc b/libcef/browser/browser_main.cc index df5a7efef..a92060822 100644 --- a/libcef/browser/browser_main.cc +++ b/libcef/browser/browser_main.cc @@ -17,6 +17,7 @@ #include "base/message_loop/message_loop.h" #include "base/strings/string_number_conversions.h" #include "chrome/browser/net/proxy_service_factory.h" +#include "components/user_prefs/user_prefs.h" #include "content/browser/webui/content_web_ui_controller_factory.h" #include "content/public/browser/gpu_data_manager.h" #include "content/public/browser/web_ui_controller_factory.h" @@ -149,6 +150,8 @@ void CefBrowserMainParts::PreMainMessageLoopRun() { LOG(WARNING) << "Invalid http debugger port number " << port; } } + + user_prefs::UserPrefs::Set(browser_context(), pref_service()); } void CefBrowserMainParts::PostMainMessageLoopRun() { diff --git a/libcef/browser/browser_pref_store.cc b/libcef/browser/browser_pref_store.cc index 7e575e44d..3a5834fe7 100644 --- a/libcef/browser/browser_pref_store.cc +++ b/libcef/browser/browser_pref_store.cc @@ -3,25 +3,83 @@ // be found in the LICENSE file. #include "libcef/browser/browser_pref_store.h" + #include "libcef/browser/media_capture_devices_dispatcher.h" +#include "libcef/common/cef_switches.h" #include "base/command_line.h" #include "base/prefs/pref_service.h" #include "base/prefs/pref_service_factory.h" #include "base/prefs/pref_registry_simple.h" +#include "base/strings/string_number_conversions.h" #include "base/values.h" #include "chrome/browser/net/pref_proxy_config_tracker_impl.h" #include "chrome/browser/prefs/command_line_pref_store.h" #include "chrome/browser/prefs/proxy_config_dictionary.h" +#include "chrome/common/chrome_switches.h" #include "chrome/common/pref_names.h" +#include "grit/cef_strings.h" +#include "ui/base/l10n/l10n_util.h" + +namespace { + +// A helper function for registering localized values. +// Based on CreateLocaleDefaultValue from +// components/pref_registry/pref_registry_syncable.cc. +void RegisterLocalizedValue(PrefRegistrySimple* registry, + const char* path, + base::Value::Type type, + int message_id) { + const std::string resource_string = l10n_util::GetStringUTF8(message_id); + DCHECK(!resource_string.empty()); + switch (type) { + case base::Value::TYPE_BOOLEAN: { + if ("true" == resource_string) + registry->RegisterBooleanPref(path, true); + else if ("false" == resource_string) + registry->RegisterBooleanPref(path, false); + return; + } + + case base::Value::TYPE_INTEGER: { + int val; + base::StringToInt(resource_string, &val); + registry->RegisterIntegerPref(path, val); + return; + } + + case base::Value::TYPE_DOUBLE: { + double val; + base::StringToDouble(resource_string, &val); + registry->RegisterDoublePref(path, val); + return; + } + + case base::Value::TYPE_STRING: { + registry->RegisterStringPref(path, resource_string); + return; + } + + default: { + NOTREACHED() << + "list and dictionary types cannot have default locale values"; + } + } + NOTREACHED(); +} + +} // namespace CefBrowserPrefStore::CefBrowserPrefStore() { } scoped_ptr CefBrowserPrefStore::CreateService() { + const base::CommandLine* command_line = + base::CommandLine::ForCurrentProcess(); + base::PrefServiceFactory factory; factory.set_command_line_prefs( - new CommandLinePrefStore(CommandLine::ForCurrentProcess())); + new CommandLinePrefStore(command_line)); factory.set_user_prefs(this); scoped_refptr registry(new PrefRegistrySimple()); @@ -30,8 +88,28 @@ scoped_ptr CefBrowserPrefStore::CreateService() { CefMediaCaptureDevicesDispatcher::RegisterPrefs(registry.get()); PrefProxyConfigTrackerImpl::RegisterPrefs(registry.get()); + // Print settings. registry->RegisterBooleanPref(prefs::kPrintingEnabled, true); + // Spell checking settings. + std::string spellcheck_lang = + command_line->GetSwitchValueASCII(switches::kOverrideSpellCheckLang); + if (!spellcheck_lang.empty()) { + registry->RegisterStringPref(prefs::kSpellCheckDictionary, spellcheck_lang); + } else { + RegisterLocalizedValue(registry.get(), + prefs::kSpellCheckDictionary, + base::Value::TYPE_STRING, + IDS_SPELLCHECK_DICTIONARY); + } + registry->RegisterBooleanPref(prefs::kSpellCheckUseSpellingService, + command_line->HasSwitch(switches::kEnableSpellingService)); + registry->RegisterBooleanPref(prefs::kEnableContinuousSpellcheck, true); + // The kEnableSpellingAutoCorrect command-line value is also checked in + // SpellCheckProvider::autoCorrectWord. + registry->RegisterBooleanPref(prefs::kEnableAutoSpellCorrect, + command_line->HasSwitch(switches::kEnableSpellingAutoCorrect)); + return factory.Create(registry.get()); } diff --git a/libcef/browser/content_browser_client.cc b/libcef/browser/content_browser_client.cc index 35b5f87bf..57f011764 100644 --- a/libcef/browser/content_browser_client.cc +++ b/libcef/browser/content_browser_client.cc @@ -31,6 +31,7 @@ #include "base/command_line.h" #include "base/files/file_path.h" #include "base/path_service.h" +#include "chrome/browser/spellchecker/spellcheck_message_filter.h" #include "chrome/common/chrome_switches.h" #include "content/browser/plugin_service_impl.h" #include "content/public/browser/access_token_store.h" @@ -47,6 +48,10 @@ #include "ui/base/ui_base_switches.h" #include "url/gurl.h" +#if defined(OS_MACOSX) +#include "chrome/browser/spellchecker/spellcheck_message_filter_mac.h" +#endif + #if defined(OS_POSIX) && !defined(OS_MACOSX) #include "base/debug/leak_annotations.h" #include "components/crash/app/breakpad_linux.h" @@ -357,7 +362,7 @@ void TranslatePopupFeatures(const blink::WebWindowFeatures& webKitFeatures, breakpad::CrashHandlerHostLinux* CreateCrashHandlerHost( const std::string& process_type) { base::FilePath dumps_path = - CommandLine::ForCurrentProcess()->GetSwitchValuePath( + base::CommandLine::ForCurrentProcess()->GetSwitchValuePath( switches::kCrashDumpsDir); { ANNOTATE_SCOPED_MEMORY_LEAK; @@ -369,7 +374,7 @@ breakpad::CrashHandlerHostLinux* CreateCrashHandlerHost( } } -int GetCrashSignalFD(const CommandLine& command_line) { +int GetCrashSignalFD(const base::CommandLine& command_line) { if (!breakpad::IsCrashReporterEnabled()) return -1; @@ -606,8 +611,19 @@ content::BrowserMainParts* CefContentBrowserClient::CreateBrowserMainParts( void CefContentBrowserClient::RenderProcessWillLaunch( content::RenderProcessHost* host) { + const base::CommandLine* command_line = + base::CommandLine::ForCurrentProcess(); + const int id = host->GetID(); + host->GetChannel()->AddFilter(new CefBrowserMessageFilter(host)); - host->AddFilter(new printing::PrintingMessageFilter(host->GetID())); + host->AddFilter(new printing::PrintingMessageFilter(id)); + + if (!command_line->HasSwitch(switches::kDisableSpellChecking)) { + host->AddFilter(new SpellCheckMessageFilter(id)); +#if defined(OS_MACOSX) + host->AddFilter(new SpellCheckMessageFilterMac(id)); +#endif + } AddBrowserContextReference( static_cast(host->GetBrowserContext())); @@ -653,8 +669,9 @@ bool CefContentBrowserClient::IsHandledURL(const GURL& url) { } void CefContentBrowserClient::AppendExtraCommandLineSwitches( - CommandLine* command_line, int child_process_id) { - const CommandLine& browser_cmd = *CommandLine::ForCurrentProcess(); + base::CommandLine* command_line, int child_process_id) { + const base::CommandLine& browser_cmd = + *base::CommandLine::ForCurrentProcess(); { // Propagate the following switches to all command lines (along with any @@ -683,8 +700,10 @@ void CefContentBrowserClient::AppendExtraCommandLineSwitches( // any associated values) if present in the browser command line. static const char* const kSwitchNames[] = { switches::kContextSafetyImplementation, + switches::kDisableSpellChecking, switches::kEnableMediaStream, switches::kEnableSpeechInput, + switches::kEnableSpellingAutoCorrect, switches::kUncaughtExceptionStackSize, }; command_line->CopySwitchesFrom(browser_cmd, kSwitchNames, @@ -726,8 +745,9 @@ content::MediaObserver* CefContentBrowserClient::GetMediaObserver() { content::SpeechRecognitionManagerDelegate* CefContentBrowserClient::GetSpeechRecognitionManagerDelegate() { - const CommandLine& command_line = *CommandLine::ForCurrentProcess(); - if (command_line.HasSwitch(switches::kEnableSpeechInput)) + const base::CommandLine* command_line = + base::CommandLine::ForCurrentProcess(); + if (command_line->HasSwitch(switches::kEnableSpeechInput)) return new CefSpeechRecognitionManagerDelegate(); return NULL; @@ -933,6 +953,9 @@ void CefContentBrowserClient::OverrideWebkitPrefs( content::RenderViewHost* rvh, const GURL& url, content::WebPreferences* prefs) { + const base::CommandLine* command_line = + base::CommandLine::ForCurrentProcess(); + CefRefPtr browser = CefBrowserHostImpl::GetBrowserForHost(rvh); DCHECK(browser.get()); @@ -941,6 +964,11 @@ void CefContentBrowserClient::OverrideWebkitPrefs( BrowserToWebSettings(browser->settings(), *prefs); prefs->base_background_color = GetBaseBackgroundColor(rvh); + + prefs->asynchronous_spell_checking_enabled = true; + // Auto-correct does not work in combination with the unified text checker. + prefs->unified_textchecker_enabled = + !command_line->HasSwitch(switches::kEnableSpellingAutoCorrect); } SkColor CefContentBrowserClient::GetBaseBackgroundColor( diff --git a/libcef/browser/context_menu_params_impl.cc b/libcef/browser/context_menu_params_impl.cc index 4883db273..57f8cf2ef 100644 --- a/libcef/browser/context_menu_params_impl.cc +++ b/libcef/browser/context_menu_params_impl.cc @@ -95,11 +95,44 @@ CefString CefContextMenuParamsImpl::GetSelectionText() { return const_value().selection_text; } +CefString CefContextMenuParamsImpl::GetMisspelledWord() { + CEF_VALUE_VERIFY_RETURN(false, CefString()); + return const_value().misspelled_word; +} + +int CefContextMenuParamsImpl::GetMisspellingHash() { + CEF_VALUE_VERIFY_RETURN(false, 0); + return const_value().misspelling_hash; +} + +bool CefContextMenuParamsImpl::GetDictionarySuggestions( + std::vector& suggestions) { + CEF_VALUE_VERIFY_RETURN(false, false); + + if (!suggestions.empty()) + suggestions.clear(); + + if(const_value().dictionary_suggestions.empty()) + return false; + + std::vector::const_iterator it = + const_value().dictionary_suggestions.begin(); + for (; it != const_value().dictionary_suggestions.end(); ++it) + suggestions.push_back(*it); + + return true; +} + bool CefContextMenuParamsImpl::IsEditable() { CEF_VALUE_VERIFY_RETURN(false, false); return const_value().is_editable; } +bool CefContextMenuParamsImpl::IsSpellCheckEnabled() { + CEF_VALUE_VERIFY_RETURN(false, false); + return const_value().spellcheck_enabled; +} + CefContextMenuParamsImpl::EditStateFlags CefContextMenuParamsImpl::GetEditStateFlags() { CEF_VALUE_VERIFY_RETURN(false, CM_EDITFLAG_NONE); diff --git a/libcef/browser/context_menu_params_impl.h b/libcef/browser/context_menu_params_impl.h index 0877db2ab..d53dbfa6d 100644 --- a/libcef/browser/context_menu_params_impl.h +++ b/libcef/browser/context_menu_params_impl.h @@ -31,7 +31,12 @@ class CefContextMenuParamsImpl virtual MediaType GetMediaType() OVERRIDE; virtual MediaStateFlags GetMediaStateFlags() OVERRIDE; virtual CefString GetSelectionText() OVERRIDE; + virtual CefString GetMisspelledWord() OVERRIDE; + virtual int GetMisspellingHash() OVERRIDE; + virtual bool GetDictionarySuggestions( + std::vector& suggestions) OVERRIDE; virtual bool IsEditable() OVERRIDE; + virtual bool IsSpellCheckEnabled() OVERRIDE; virtual EditStateFlags GetEditStateFlags() OVERRIDE; DISALLOW_COPY_AND_ASSIGN(CefContextMenuParamsImpl); diff --git a/libcef/browser/menu_creator.cc b/libcef/browser/menu_creator.cc index 80291ec23..76980a249 100644 --- a/libcef/browser/menu_creator.cc +++ b/libcef/browser/menu_creator.cc @@ -231,6 +231,26 @@ void CefMenuCreator::CreateDefaultModel() { model_->SetEnabled(MENU_ID_DELETE, false); if (!(params_.edit_flags & CM_EDITFLAG_CAN_SELECT_ALL)) model_->SetEnabled(MENU_ID_SELECT_ALL, false); + + if(!params_.misspelled_word.empty()) { + if (!params_.dictionary_suggestions.empty()) + model_->AddSeparator(); + + for (size_t i = 0; + i < params_.dictionary_suggestions.size() && + MENU_ID_SPELLCHECK_SUGGESTION_0 + i <= + MENU_ID_SPELLCHECK_SUGGESTION_LAST; + ++i) { + model_->AddItem(MENU_ID_SPELLCHECK_SUGGESTION_0 + static_cast(i), + params_.dictionary_suggestions[i].c_str()); + } + + if (params_.dictionary_suggestions.empty()) { + model_->AddItem( + MENU_ID_NO_SPELLING_SUGGESTIONS, + GetLabel(IDS_MENU_NO_SPELLING_SUGGESTIONS)); + } + } } else if (!params_.selection_text.empty()) { // Something is selected. model_->AddItem(MENU_ID_COPY, GetLabel(IDS_MENU_COPY)); @@ -251,6 +271,18 @@ void CefMenuCreator::CreateDefaultModel() { } void CefMenuCreator::ExecuteDefaultCommand(int command_id) { + // If the user chose a replacement word for a misspelling, replace it here. + if (command_id >= MENU_ID_SPELLCHECK_SUGGESTION_0 && + command_id <= MENU_ID_SPELLCHECK_SUGGESTION_LAST) { + const size_t suggestion_index = + static_cast(command_id) - MENU_ID_SPELLCHECK_SUGGESTION_0; + if (suggestion_index < params_.dictionary_suggestions.size()) { + browser_->ReplaceMisspelling( + params_.dictionary_suggestions[suggestion_index]); + } + return; + } + switch (command_id) { // Navigation. case MENU_ID_BACK: diff --git a/libcef/browser/proxy_stubs.cc b/libcef/browser/proxy_stubs.cc index 98ba2d75a..135c6af64 100644 --- a/libcef/browser/proxy_stubs.cc +++ b/libcef/browser/proxy_stubs.cc @@ -3,16 +3,22 @@ // found in the LICENSE file. #include "base/logging.h" -#include "components/pref_registry/pref_registry_syncable.h" +#include "content/public/browser/browser_context.h" -namespace user_prefs { +// Used by chrome/browser/spellchecker/spellcheck_factory.cc. +namespace chrome { -// Required by PrefProxyConfigTrackerImpl::RegisterUserPrefs. -void PrefRegistrySyncable::RegisterDictionaryPref( - const char* path, - base::DictionaryValue* default_value, - PrefSyncStatus sync_status) { - NOTREACHED(); +// Returns the original browser context even for Incognito contexts. +content::BrowserContext* GetBrowserContextRedirectedInIncognito( + content::BrowserContext* context) { + return context; } -} // namespace user_prefs +// Returns non-NULL even for Incognito contexts so that a separate +// instance of a service is created for the Incognito context. +content::BrowserContext* GetBrowserContextOwnInstanceInIncognito( + content::BrowserContext* context) { + return context; +} + +} // namespace chrome diff --git a/libcef/common/cef_messages.h b/libcef/common/cef_messages.h index fe3f7766e..3aa85d1b8 100644 --- a/libcef/common/cef_messages.h +++ b/libcef/common/cef_messages.h @@ -215,6 +215,7 @@ struct ParamTraits > { #include "chrome/common/prerender_messages.h" #include "chrome/common/print_messages.h" +#include "chrome/common/spellcheck_messages.h" #if defined(OS_WIN) #include "chrome/common/chrome_utility_printing_messages.h" diff --git a/libcef/common/cef_switches.cc b/libcef/common/cef_switches.cc index 6084bc1bb..898696537 100644 --- a/libcef/common/cef_switches.cc +++ b/libcef/common/cef_switches.cc @@ -85,4 +85,13 @@ const char kEnableProfanityFilter[] = "enable-profanity-filter"; // The directory breakpad should store minidumps in. const char kCrashDumpsDir[] = "crash-dumps-dir"; +// Disable spell checking. +const char kDisableSpellChecking[] = "disable-spell-checking"; + +// Enable the remote spelling service. +const char kEnableSpellingService[] = "enable-spelling-service"; + +// Override the default spellchecking language which comes from locales.pak. +const char kOverrideSpellCheckLang[] = "override-spell-check-lang"; + } // namespace switches diff --git a/libcef/common/cef_switches.h b/libcef/common/cef_switches.h index f3bdf9bfd..ddd96bde3 100644 --- a/libcef/common/cef_switches.h +++ b/libcef/common/cef_switches.h @@ -38,6 +38,9 @@ extern const char kEnableMediaStream[]; extern const char kEnableSpeechInput[]; extern const char kEnableProfanityFilter[]; extern const char kCrashDumpsDir[]; +extern const char kDisableSpellChecking[]; +extern const char kEnableSpellingService[]; +extern const char kOverrideSpellCheckLang[]; } // namespace switches diff --git a/libcef/common/main_delegate.cc b/libcef/common/main_delegate.cc index dee191402..396caa42f 100644 --- a/libcef/common/main_delegate.cc +++ b/libcef/common/main_delegate.cc @@ -409,13 +409,25 @@ void CefMainDelegate::PreSandboxStartup() { #endif } -#if defined(OS_MACOSX) if (!command_line.HasSwitch(switches::kProcessType)) { - // Only override the child process path when executing the main process. + // Only these paths when executing the main process. +#if defined(OS_MACOSX) OverrideChildProcessPath(); - } #endif + // Paths used to locate spell checking dictionary files. + // TODO(cef): It may be better to use a persistent location for + // DIR_USER_DATA. See the implementation of GetDefaultUserDataDirectory in + // chrome/common/chrome_paths_*. + const base::FilePath& cache_path = CefContext::Get()->cache_path(); + PathService::Override(chrome::DIR_USER_DATA, cache_path); + PathService::OverrideAndCreateIfNeeded( + chrome::DIR_APP_DICTIONARIES, + cache_path.AppendASCII("Dictionaries"), + false, // May not be an absolute path. + true); // Create if necessary. + } + OverridePdfPluginPath(); if (command_line.HasSwitch(switches::kDisablePackLoading)) diff --git a/libcef/renderer/content_renderer_client.cc b/libcef/renderer/content_renderer_client.cc index c69935da5..2ab476ee6 100644 --- a/libcef/renderer/content_renderer_client.cc +++ b/libcef/renderer/content_renderer_client.cc @@ -39,6 +39,8 @@ MSVC_POP_WARNING(); #include "chrome/renderer/loadtimes_extension_bindings.h" #include "chrome/renderer/pepper/chrome_pdf_print_client.h" #include "chrome/renderer/printing/print_web_view_helper.h" +#include "chrome/renderer/spellchecker/spellcheck.h" +#include "chrome/renderer/spellchecker/spellcheck_provider.h" #include "components/pdf/renderer/ppb_pdf_impl.h" #include "components/web_cache/renderer/web_cache_render_process_observer.h" #include "content/child/child_thread.h" @@ -50,6 +52,7 @@ MSVC_POP_WARNING(); #include "content/public/common/content_paths.h" #include "content/public/renderer/render_thread.h" #include "content/public/renderer/render_view.h" +#include "content/public/renderer/render_view_visitor.h" #include "content/renderer/render_frame_impl.h" #include "ipc/ipc_sync_channel.h" #include "media/base/media.h" @@ -439,6 +442,9 @@ void CefContentRendererClient::RunSingleProcessCleanup() { } void CefContentRendererClient::RenderThreadStarted() { + const base::CommandLine* command_line = + base::CommandLine::ForCurrentProcess(); + render_task_runner_ = base::MessageLoopProxy::current(); observer_.reset(new CefRenderProcessObserver()); web_cache_observer_.reset(new web_cache::WebCacheRenderProcessObserver()); @@ -449,6 +455,11 @@ void CefContentRendererClient::RenderThreadStarted() { thread->GetChannel()->AddFilter(new CefRenderMessageFilter); thread->RegisterExtension(extensions_v8::LoadTimesExtension::Get()); + if (!command_line->HasSwitch(switches::kDisableSpellChecking)) { + spellcheck_.reset(new SpellCheck()); + thread->AddObserver(spellcheck_.get()); + } + if (content::RenderProcessHost::run_renderer_in_process()) { // When running in single-process mode register as a destruction observer // on the render thread's MessageLoop. @@ -721,6 +732,9 @@ void CefContentRendererClient::WillDestroyCurrentMessageLoop() { void CefContentRendererClient::BrowserCreated( content::RenderView* render_view, content::RenderFrame* render_frame) { + const base::CommandLine* command_line = + base::CommandLine::ForCurrentProcess(); + // Retrieve the browser information synchronously. This will also register // the routing ids with the browser info object in the browser process. CefProcessHostMsg_GetNewBrowserInfo_Params params; @@ -752,6 +766,9 @@ void CefContentRendererClient::BrowserCreated( new CefPrerendererClient(render_view); new printing::PrintWebViewHelper(render_view); + if (!command_line->HasSwitch(switches::kDisableSpellChecking)) + new SpellCheckProvider(render_view, spellcheck_.get()); + // Notify the render process handler. CefRefPtr application = CefContentClient::Get()->application(); if (application.get()) { diff --git a/libcef/renderer/content_renderer_client.h b/libcef/renderer/content_renderer_client.h index 4c8af794e..ee387219a 100644 --- a/libcef/renderer/content_renderer_client.h +++ b/libcef/renderer/content_renderer_client.h @@ -27,6 +27,7 @@ class WebCacheRenderProcessObserver; class CefRenderProcessObserver; struct Cef_CrossOriginWhiteListEntry_Params; class ChromePDFPrintClient; +class SpellCheck; class CefContentRendererClient : public content::ContentRendererClient, public base::MessageLoop::DestructionObserver { @@ -118,6 +119,7 @@ class CefContentRendererClient : public content::ContentRendererClient, scoped_refptr render_task_runner_; scoped_ptr observer_; scoped_ptr web_cache_observer_; + scoped_ptr spellcheck_; // Map of RenderView pointers to CefBrowserImpl references. typedef std::map > BrowserMap; diff --git a/libcef/resources/cef_strings.grd b/libcef/resources/cef_strings.grd index e72d539ce..506d14964 100644 --- a/libcef/resources/cef_strings.grd +++ b/libcef/resources/cef_strings.grd @@ -11,9 +11,7 @@ need to be translated for each locale.--> - - + @@ -79,7 +77,9 @@ need to be translated for each locale.--> - + + + @@ -107,74 +107,51 @@ need to be translated for each locale.--> - - - + - - - + - - - + - - - + - - - + - - - + - - - + - - - + - - - - + + - - - + - - - - + + - + @@ -191,13 +168,64 @@ need to be translated for each locale.--> - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -277,6 +305,15 @@ need to be translated for each locale.--> The selected printer is not available or not installed correctly. Check your printer or try selecting another printer. + + + + + en-US + + + &No spelling suggestions + diff --git a/libcef/resources/grit_stub/chrome/grit/locale_settings.h b/libcef/resources/grit_stub/chrome/grit/locale_settings.h new file mode 100644 index 000000000..0d2c14a96 --- /dev/null +++ b/libcef/resources/grit_stub/chrome/grit/locale_settings.h @@ -0,0 +1,2 @@ +#include +#include diff --git a/libcef_dll/cpptoc/browser_host_cpptoc.cc b/libcef_dll/cpptoc/browser_host_cpptoc.cc index 3577dc80e..f897e5233 100644 --- a/libcef_dll/cpptoc/browser_host_cpptoc.cc +++ b/libcef_dll/cpptoc/browser_host_cpptoc.cc @@ -411,6 +411,23 @@ int CEF_CALLBACK browser_host_is_mouse_cursor_change_disabled( return _retval; } +void CEF_CALLBACK browser_host_replace_misspelling( + struct _cef_browser_host_t* self, const cef_string_t* word) { + // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING + + DCHECK(self); + if (!self) + return; + // Verify param: word; type: string_byref_const + DCHECK(word); + if (!word) + return; + + // Execute + CefBrowserHostCppToC::Get(self)->ReplaceMisspelling( + CefString(word)); +} + int CEF_CALLBACK browser_host_is_window_rendering_disabled( struct _cef_browser_host_t* self) { // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING @@ -782,6 +799,7 @@ CefBrowserHostCppToC::CefBrowserHostCppToC(CefBrowserHost* cls) browser_host_set_mouse_cursor_change_disabled; struct_.struct_.is_mouse_cursor_change_disabled = browser_host_is_mouse_cursor_change_disabled; + struct_.struct_.replace_misspelling = browser_host_replace_misspelling; struct_.struct_.is_window_rendering_disabled = browser_host_is_window_rendering_disabled; struct_.struct_.was_resized = browser_host_was_resized; diff --git a/libcef_dll/cpptoc/context_menu_params_cpptoc.cc b/libcef_dll/cpptoc/context_menu_params_cpptoc.cc index 017dfafd1..103cabe1d 100644 --- a/libcef_dll/cpptoc/context_menu_params_cpptoc.cc +++ b/libcef_dll/cpptoc/context_menu_params_cpptoc.cc @@ -11,6 +11,7 @@ // #include "libcef_dll/cpptoc/context_menu_params_cpptoc.h" +#include "libcef_dll/transfer_util.h" // MEMBER FUNCTIONS - Body may be edited by hand. @@ -214,6 +215,66 @@ cef_string_userfree_t CEF_CALLBACK context_menu_params_get_selection_text( return _retval.DetachToUserFree(); } +cef_string_userfree_t CEF_CALLBACK context_menu_params_get_misspelled_word( + struct _cef_context_menu_params_t* self) { + // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING + + DCHECK(self); + if (!self) + return NULL; + + // Execute + CefString _retval = CefContextMenuParamsCppToC::Get(self)->GetMisspelledWord( + ); + + // Return type: string + return _retval.DetachToUserFree(); +} + +int CEF_CALLBACK context_menu_params_get_misspelling_hash( + struct _cef_context_menu_params_t* self) { + // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING + + DCHECK(self); + if (!self) + return 0; + + // Execute + int _retval = CefContextMenuParamsCppToC::Get(self)->GetMisspellingHash(); + + // Return type: simple + return _retval; +} + +int CEF_CALLBACK context_menu_params_get_dictionary_suggestions( + struct _cef_context_menu_params_t* self, cef_string_list_t suggestions) { + // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING + + DCHECK(self); + if (!self) + return 0; + // Verify param: suggestions; type: string_vec_byref + DCHECK(suggestions); + if (!suggestions) + return 0; + + // Translate param: suggestions; type: string_vec_byref + std::vector suggestionsList; + transfer_string_list_contents(suggestions, suggestionsList); + + // Execute + bool _retval = CefContextMenuParamsCppToC::Get( + self)->GetDictionarySuggestions( + suggestionsList); + + // Restore param: suggestions; type: string_vec_byref + cef_string_list_clear(suggestions); + transfer_string_list_contents(suggestionsList, suggestions); + + // Return type: bool + return _retval; +} + int CEF_CALLBACK context_menu_params_is_editable( struct _cef_context_menu_params_t* self) { // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING @@ -229,6 +290,21 @@ int CEF_CALLBACK context_menu_params_is_editable( return _retval; } +int CEF_CALLBACK context_menu_params_is_spell_check_enabled( + struct _cef_context_menu_params_t* self) { + // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING + + DCHECK(self); + if (!self) + return 0; + + // Execute + bool _retval = CefContextMenuParamsCppToC::Get(self)->IsSpellCheckEnabled(); + + // Return type: bool + return _retval; +} + cef_context_menu_edit_state_flags_t CEF_CALLBACK context_menu_params_get_edit_state_flags( struct _cef_context_menu_params_t* self) { // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING @@ -267,7 +343,14 @@ CefContextMenuParamsCppToC::CefContextMenuParamsCppToC( struct_.struct_.get_media_state_flags = context_menu_params_get_media_state_flags; struct_.struct_.get_selection_text = context_menu_params_get_selection_text; + struct_.struct_.get_misspelled_word = context_menu_params_get_misspelled_word; + struct_.struct_.get_misspelling_hash = + context_menu_params_get_misspelling_hash; + struct_.struct_.get_dictionary_suggestions = + context_menu_params_get_dictionary_suggestions; struct_.struct_.is_editable = context_menu_params_is_editable; + struct_.struct_.is_spell_check_enabled = + context_menu_params_is_spell_check_enabled; struct_.struct_.get_edit_state_flags = context_menu_params_get_edit_state_flags; } diff --git a/libcef_dll/cpptoc/render_handler_cpptoc.cc b/libcef_dll/cpptoc/render_handler_cpptoc.cc index 602aa6a0f..203322453 100644 --- a/libcef_dll/cpptoc/render_handler_cpptoc.cc +++ b/libcef_dll/cpptoc/render_handler_cpptoc.cc @@ -315,6 +315,23 @@ void CEF_CALLBACK render_handler_update_drag_cursor( operation); } +void CEF_CALLBACK render_handler_on_scroll_offset_changed( + struct _cef_render_handler_t* self, cef_browser_t* browser) { + // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING + + DCHECK(self); + if (!self) + return; + // Verify param: browser; type: refptr_diff + DCHECK(browser); + if (!browser) + return; + + // Execute + CefRenderHandlerCppToC::Get(self)->OnScrollOffsetChanged( + CefBrowserCToCpp::Wrap(browser)); +} + // CONSTRUCTOR - Do not edit by hand. @@ -331,6 +348,8 @@ CefRenderHandlerCppToC::CefRenderHandlerCppToC(CefRenderHandler* cls) struct_.struct_.on_cursor_change = render_handler_on_cursor_change; struct_.struct_.start_dragging = render_handler_start_dragging; struct_.struct_.update_drag_cursor = render_handler_update_drag_cursor; + struct_.struct_.on_scroll_offset_changed = + render_handler_on_scroll_offset_changed; } #ifndef NDEBUG diff --git a/libcef_dll/ctocpp/browser_host_ctocpp.cc b/libcef_dll/ctocpp/browser_host_ctocpp.cc index 55ddc87dc..56737dbce 100644 --- a/libcef_dll/ctocpp/browser_host_ctocpp.cc +++ b/libcef_dll/ctocpp/browser_host_ctocpp.cc @@ -331,6 +331,22 @@ bool CefBrowserHostCToCpp::IsMouseCursorChangeDisabled() { return _retval?true:false; } +void CefBrowserHostCToCpp::ReplaceMisspelling(const CefString& word) { + if (CEF_MEMBER_MISSING(struct_, replace_misspelling)) + return; + + // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING + + // Verify param: word; type: string_byref_const + DCHECK(!word.empty()); + if (word.empty()) + return; + + // Execute + struct_->replace_misspelling(struct_, + word.GetStruct()); +} + bool CefBrowserHostCToCpp::IsWindowRenderingDisabled() { if (CEF_MEMBER_MISSING(struct_, is_window_rendering_disabled)) return false; diff --git a/libcef_dll/ctocpp/browser_host_ctocpp.h b/libcef_dll/ctocpp/browser_host_ctocpp.h index 901296336..c4857cc59 100644 --- a/libcef_dll/ctocpp/browser_host_ctocpp.h +++ b/libcef_dll/ctocpp/browser_host_ctocpp.h @@ -62,6 +62,7 @@ class CefBrowserHostCToCpp virtual void CloseDevTools() OVERRIDE; virtual void SetMouseCursorChangeDisabled(bool disabled) OVERRIDE; virtual bool IsMouseCursorChangeDisabled() OVERRIDE; + virtual void ReplaceMisspelling(const CefString& word) OVERRIDE; virtual bool IsWindowRenderingDisabled() OVERRIDE; virtual void WasResized() OVERRIDE; virtual void WasHidden(bool hidden) OVERRIDE; diff --git a/libcef_dll/ctocpp/context_menu_params_ctocpp.cc b/libcef_dll/ctocpp/context_menu_params_ctocpp.cc index 8748c3641..950869bcd 100644 --- a/libcef_dll/ctocpp/context_menu_params_ctocpp.cc +++ b/libcef_dll/ctocpp/context_menu_params_ctocpp.cc @@ -11,6 +11,7 @@ // #include "libcef_dll/ctocpp/context_menu_params_ctocpp.h" +#include "libcef_dll/transfer_util.h" // VIRTUAL METHODS - Body may be edited by hand. @@ -200,6 +201,62 @@ CefString CefContextMenuParamsCToCpp::GetSelectionText() { return _retvalStr; } +CefString CefContextMenuParamsCToCpp::GetMisspelledWord() { + if (CEF_MEMBER_MISSING(struct_, get_misspelled_word)) + return CefString(); + + // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING + + // Execute + cef_string_userfree_t _retval = struct_->get_misspelled_word(struct_); + + // Return type: string + CefString _retvalStr; + _retvalStr.AttachToUserFree(_retval); + return _retvalStr; +} + +int CefContextMenuParamsCToCpp::GetMisspellingHash() { + if (CEF_MEMBER_MISSING(struct_, get_misspelling_hash)) + return 0; + + // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING + + // Execute + int _retval = struct_->get_misspelling_hash(struct_); + + // Return type: simple + return _retval; +} + +bool CefContextMenuParamsCToCpp::GetDictionarySuggestions( + std::vector& suggestions) { + if (CEF_MEMBER_MISSING(struct_, get_dictionary_suggestions)) + return false; + + // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING + + // Translate param: suggestions; type: string_vec_byref + cef_string_list_t suggestionsList = cef_string_list_alloc(); + DCHECK(suggestionsList); + if (suggestionsList) + transfer_string_list_contents(suggestions, suggestionsList); + + // Execute + int _retval = struct_->get_dictionary_suggestions(struct_, + suggestionsList); + + // Restore param:suggestions; type: string_vec_byref + if (suggestionsList) { + suggestions.clear(); + transfer_string_list_contents(suggestionsList, suggestions); + cef_string_list_free(suggestionsList); + } + + // Return type: bool + return _retval?true:false; +} + bool CefContextMenuParamsCToCpp::IsEditable() { if (CEF_MEMBER_MISSING(struct_, is_editable)) return false; @@ -213,6 +270,19 @@ bool CefContextMenuParamsCToCpp::IsEditable() { return _retval?true:false; } +bool CefContextMenuParamsCToCpp::IsSpellCheckEnabled() { + if (CEF_MEMBER_MISSING(struct_, is_spell_check_enabled)) + return false; + + // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING + + // Execute + int _retval = struct_->is_spell_check_enabled(struct_); + + // Return type: bool + return _retval?true:false; +} + CefContextMenuParams::EditStateFlags CefContextMenuParamsCToCpp::GetEditStateFlags( ) { if (CEF_MEMBER_MISSING(struct_, get_edit_state_flags)) diff --git a/libcef_dll/ctocpp/context_menu_params_ctocpp.h b/libcef_dll/ctocpp/context_menu_params_ctocpp.h index e23ff501b..33b6481f6 100644 --- a/libcef_dll/ctocpp/context_menu_params_ctocpp.h +++ b/libcef_dll/ctocpp/context_menu_params_ctocpp.h @@ -18,6 +18,7 @@ #pragma message("Warning: "__FILE__" may be accessed wrapper-side only") #else // USING_CEF_SHARED +#include #include "include/cef_context_menu_handler.h" #include "include/capi/cef_context_menu_handler_capi.h" #include "libcef_dll/ctocpp/ctocpp.h" @@ -47,7 +48,12 @@ class CefContextMenuParamsCToCpp virtual MediaType GetMediaType() OVERRIDE; virtual MediaStateFlags GetMediaStateFlags() OVERRIDE; virtual CefString GetSelectionText() OVERRIDE; + virtual CefString GetMisspelledWord() OVERRIDE; + virtual int GetMisspellingHash() OVERRIDE; + virtual bool GetDictionarySuggestions( + std::vector& suggestions) OVERRIDE; virtual bool IsEditable() OVERRIDE; + virtual bool IsSpellCheckEnabled() OVERRIDE; virtual EditStateFlags GetEditStateFlags() OVERRIDE; }; diff --git a/libcef_dll/ctocpp/render_handler_ctocpp.cc b/libcef_dll/ctocpp/render_handler_ctocpp.cc index cf5290537..3b46f9d14 100644 --- a/libcef_dll/ctocpp/render_handler_ctocpp.cc +++ b/libcef_dll/ctocpp/render_handler_ctocpp.cc @@ -250,6 +250,23 @@ void CefRenderHandlerCToCpp::UpdateDragCursor(CefRefPtr browser, operation); } +void CefRenderHandlerCToCpp::OnScrollOffsetChanged( + CefRefPtr browser) { + if (CEF_MEMBER_MISSING(struct_, on_scroll_offset_changed)) + return; + + // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING + + // Verify param: browser; type: refptr_diff + DCHECK(browser.get()); + if (!browser.get()) + return; + + // Execute + struct_->on_scroll_offset_changed(struct_, + CefBrowserCppToC::Wrap(browser)); +} + #ifndef NDEBUG template<> base::AtomicRefCount CefCToCpp browser, DragOperation operation) OVERRIDE; + virtual void OnScrollOffsetChanged(CefRefPtr browser) OVERRIDE; }; #endif // BUILDING_CEF_SHARED diff --git a/patch/patch.cfg b/patch/patch.cfg index 9d2a95e0a..53fe0d406 100644 --- a/patch/patch.cfg +++ b/patch/patch.cfg @@ -117,6 +117,13 @@ patches = [ 'name': 'renderer_415478', 'path': '../content/renderer/', }, + { + # Fix AtExitManager assertion on SpellcheckServiceFactory destruction during + # Windows multi-threaded message loop shutdown. + # https://code.google.com/p/chromiumembedded/issues/detail?id=137 + 'name': 'spellcheck_137', + 'path': '../chrome/browser/spellchecker/', + }, { # Disable scollbar bounce and overlay on OS X. # http://code.google.com/p/chromiumembedded/issues/detail?id=364 diff --git a/patch/patches/spellcheck_137.patch b/patch/patches/spellcheck_137.patch new file mode 100644 index 000000000..07949c069 --- /dev/null +++ b/patch/patches/spellcheck_137.patch @@ -0,0 +1,49 @@ +diff --git spellcheck_factory.cc spellcheck_factory.cc +index 8df78f4..33e4201e 100644 +--- spellcheck_factory.cc ++++ spellcheck_factory.cc +@@ -14,6 +14,13 @@ + #include "components/user_prefs/user_prefs.h" + #include "content/public/browser/render_process_host.h" + ++namespace { ++ ++static base::LazyInstance::Leaky ++ g_spellcheck_service_factory = LAZY_INSTANCE_INITIALIZER; ++ ++} // namespace ++ + // static + SpellcheckService* SpellcheckServiceFactory::GetForContext( + content::BrowserContext* context) { +@@ -36,7 +43,7 @@ SpellcheckService* SpellcheckServiceFactory::GetForRenderProcessId( + + // static + SpellcheckServiceFactory* SpellcheckServiceFactory::GetInstance() { +- return Singleton::get(); ++ return g_spellcheck_service_factory.Pointer(); + } + + SpellcheckServiceFactory::SpellcheckServiceFactory() +diff --git spellcheck_factory.h spellcheck_factory.h +index d2f4679..c1a790c 100644 +--- spellcheck_factory.h ++++ spellcheck_factory.h +@@ -7,7 +7,7 @@ + + #include "base/basictypes.h" + #include "base/gtest_prod_util.h" +-#include "base/memory/singleton.h" ++#include "base/lazy_instance.h" + #include "components/keyed_service/content/browser_context_keyed_service_factory.h" + + class SpellcheckService; +@@ -26,7 +26,7 @@ class SpellcheckServiceFactory : public BrowserContextKeyedServiceFactory { + static SpellcheckServiceFactory* GetInstance(); + + private: +- friend struct DefaultSingletonTraits; ++ friend struct base::DefaultLazyInstanceTraits; + + SpellcheckServiceFactory(); + virtual ~SpellcheckServiceFactory();