Bug 693555 - Update inline spellchecker underlining for multiprocess(e10s).r=ehsan, mrbkap

This commit is contained in:
Allison Naaktgeboren 2014-07-01 15:24:27 -07:00
Родитель 25b7f98ebb
Коммит cd7511f5cf
18 изменённых файлов: 292 добавлений и 11 удалений

Просмотреть файл

@ -376,7 +376,7 @@
label="&spellCheckToggle.label;"
type="checkbox"
accesskey="&spellCheckToggle.accesskey;"
oncommand="InlineSpellCheckerUI.toggleEnabled();"/>
oncommand="InlineSpellCheckerUI.toggleEnabled(window);"/>
<menuitem id="spell-add-dictionaries-main"
label="&spellAddDictionaries.label;"
accesskey="&spellAddDictionaries.accesskey;"

Просмотреть файл

@ -151,6 +151,7 @@
#include "mozilla/dom/telephony/PTelephonyChild.h"
#include "mozilla/dom/time/DateCacheCleaner.h"
#include "mozilla/net/NeckoMessageUtils.h"
#include "mozilla/RemoteSpellCheckEngineChild.h"
using namespace base;
using namespace mozilla;
@ -1052,6 +1053,20 @@ ContentChild::AllocPBlobChild(const BlobConstructorParams& aParams)
return nsIContentChild::AllocPBlobChild(aParams);
}
mozilla::PRemoteSpellcheckEngineChild *
ContentChild::AllocPRemoteSpellcheckEngineChild()
{
NS_NOTREACHED("Default Constructor for PRemoteSpellcheckEngineChilf should never be called");
return nullptr;
}
bool
ContentChild::DeallocPRemoteSpellcheckEngineChild(PRemoteSpellcheckEngineChild *child)
{
delete child;
return true;
}
bool
ContentChild::DeallocPBlobChild(PBlobChild* aActor)
{

Просмотреть файл

@ -26,6 +26,7 @@ struct ResourceMapping;
struct OverrideMapping;
namespace mozilla {
class RemoteSpellcheckEngineChild;
namespace ipc {
class OptionalURIParams;
@ -237,6 +238,8 @@ public:
virtual mozilla::jsipc::PJavaScriptChild* AllocPJavaScriptChild() MOZ_OVERRIDE;
virtual bool DeallocPJavaScriptChild(mozilla::jsipc::PJavaScriptChild*) MOZ_OVERRIDE;
virtual PRemoteSpellcheckEngineChild* AllocPRemoteSpellcheckEngineChild() MOZ_OVERRIDE;
virtual bool DeallocPRemoteSpellcheckEngineChild(PRemoteSpellcheckEngineChild*) MOZ_OVERRIDE;
virtual bool RecvSetOffline(const bool& offline) MOZ_OVERRIDE;

Просмотреть файл

@ -157,6 +157,8 @@ using namespace mozilla::system;
#include "JavaScriptParent.h"
#include "mozilla/RemoteSpellCheckEngineParent.h"
#ifdef MOZ_B2G_FM
#include "mozilla/dom/FMRadioParent.h"
#endif
@ -2693,6 +2695,20 @@ ContentParent::DeallocPBlobParent(PBlobParent* aActor)
return true;
}
mozilla::PRemoteSpellcheckEngineParent *
ContentParent::AllocPRemoteSpellcheckEngineParent()
{
mozilla::RemoteSpellcheckEngineParent *parent = new mozilla::RemoteSpellcheckEngineParent();
return parent;
}
bool
ContentParent::DeallocPRemoteSpellcheckEngineParent(PRemoteSpellcheckEngineParent *parent)
{
delete parent;
return true;
}
void
ContentParent::KillHard()
{

Просмотреть файл

@ -36,6 +36,7 @@ class nsIMemoryReporter;
class ParentIdleListener;
namespace mozilla {
class PRemoteSpellcheckEngineParent;
namespace ipc {
class OptionalURIParams;
@ -246,6 +247,7 @@ public:
RecvPJavaScriptConstructor(PJavaScriptParent* aActor) MOZ_OVERRIDE {
return PContentParent::RecvPJavaScriptConstructor(aActor);
}
virtual PRemoteSpellcheckEngineParent* AllocPRemoteSpellcheckEngineParent() MOZ_OVERRIDE;
virtual bool RecvRecordingDeviceEvents(const nsString& aRecordingStatus,
const nsString& aPageURL,
@ -389,6 +391,7 @@ private:
virtual bool DeallocPJavaScriptParent(mozilla::jsipc::PJavaScriptParent*) MOZ_OVERRIDE;
virtual bool DeallocPRemoteSpellcheckEngineParent(PRemoteSpellcheckEngineParent*) MOZ_OVERRIDE;
virtual PBrowserParent* AllocPBrowserParent(const IPCTabContext& aContext,
const uint32_t& aChromeFlags,
const uint64_t& aId,

Просмотреть файл

@ -30,6 +30,7 @@ include protocol PStorage;
include protocol PTelephony;
include protocol PTestShell;
include protocol PJavaScript;
include protocol PRemoteSpellcheckEngine;
include DOMTypes;
include JavaScriptTypes;
include InputStreamParams;
@ -309,6 +310,7 @@ intr protocol PContent
manages PTelephony;
manages PTestShell;
manages PJavaScript;
manages PRemoteSpellcheckEngine;
both:
// Depending on exactly how the new browser is being created, it might be
@ -462,6 +464,7 @@ parent:
async PJavaScript();
sync PRemoteSpellcheckEngine();
PDeviceStorageRequest(DeviceStorageParams params);
PFileSystemRequest(FileSystemParams params);

Просмотреть файл

@ -42,6 +42,7 @@
#include "nsString.h" // for nsAutoString, nsString, etc
#include "nsStringFwd.h" // for nsAFlatString
#include "nsStyleUtil.h" // for nsStyleUtil
#include "nsXULAppAPI.h" // for XRE_GetProcessType
using namespace mozilla;
@ -705,8 +706,16 @@ nsEditorSpellCheck::UpdateCurrentDictionary(nsIEditorSpellCheckCallback* aCallba
NS_ENSURE_STATE(doc);
doc->GetContentLanguage(fetcher->mRootDocContentLang);
rv = fetcher->Fetch(mEditor);
NS_ENSURE_SUCCESS(rv, rv);
if (XRE_GetProcessType() == GeckoProcessType_Content) {
// Content prefs don't work in E10S (Bug 1027898) pretend that we
// didn't have any & trigger the asynchrous completion.
nsCOMPtr<nsIRunnable> runnable =
NS_NewRunnableMethodWithArg<uint16_t>(fetcher, &DictionaryFetcher::HandleCompletion, 0);
NS_DispatchToMainThread(runnable);
} else {
rv = fetcher->Fetch(mEditor);
NS_ENSURE_SUCCESS(rv, rv);
}
return NS_OK;
}

Просмотреть файл

@ -0,0 +1,20 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
include protocol PContent;
namespace mozilla {
sync protocol PRemoteSpellcheckEngine {
manager PContent;
parent:
__delete__();
sync CheckForMisspelling(nsString aWord) returns (bool isMisspelled);
sync SetDictionary(nsString aDictionary) returns (bool success);
};
} // namespace mozilla

Просмотреть файл

@ -0,0 +1,21 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "RemoteSpellCheckEngineChild.h"
namespace mozilla {
RemoteSpellcheckEngineChild::RemoteSpellcheckEngineChild(mozSpellChecker *aOwner)
:mOwner(aOwner)
{
}
RemoteSpellcheckEngineChild::~RemoteSpellcheckEngineChild()
{
// null out the owner's SpellcheckEngineChild to prevent state corruption
// during shutdown
mOwner->DeleteRemoteEngine();
}
} //namespace mozilla

Просмотреть файл

@ -0,0 +1,26 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef RemoteSpellcheckEngineChild_h_
#define RemoteSpellcheckEngineChild_h_
#include "mozilla/PRemoteSpellcheckEngineChild.h"
#include "mozSpellChecker.h"
class mozSpellChecker;
namespace mozilla {
class RemoteSpellcheckEngineChild : public mozilla::PRemoteSpellcheckEngineChild
{
public:
RemoteSpellcheckEngineChild(mozSpellChecker *aOwner);
~RemoteSpellcheckEngineChild();
private:
mozSpellChecker *mOwner;
};
} //namespace mozilla
#endif // RemoteSpellcheckEngineChild_h_

Просмотреть файл

@ -0,0 +1,49 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "RemoteSpellCheckEngineParent.h"
#include "mozISpellCheckingEngine.h"
#include "nsServiceManagerUtils.h"
#define DEFAULT_SPELL_CHECKER "@mozilla.org/spellchecker/engine;1"
namespace mozilla {
RemoteSpellcheckEngineParent::RemoteSpellcheckEngineParent()
{
mEngine = do_GetService(DEFAULT_SPELL_CHECKER);
}
RemoteSpellcheckEngineParent::~RemoteSpellcheckEngineParent()
{
}
bool
RemoteSpellcheckEngineParent::RecvSetDictionary(
const nsString& aDictionary,
bool* success)
{
nsresult rv = mEngine->SetDictionary(aDictionary.get());
*success = NS_SUCCEEDED(rv);
return true;
}
bool
RemoteSpellcheckEngineParent::RecvCheckForMisspelling(
const nsString& aWord,
bool* isMisspelled)
{
bool isCorrect = false;
mEngine->Check(aWord.get(), &isCorrect);
*isMisspelled = !isCorrect;
return true;
}
void
RemoteSpellcheckEngineParent::ActorDestroy(ActorDestroyReason aWhy)
{
}
} // namespace mozilla

Просмотреть файл

@ -0,0 +1,31 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef RemoteSpellcheckEngineParent_h_
#define RemoteSpellcheckEngineParent_h_
#include "mozISpellCheckingEngine.h"
#include "mozilla/PRemoteSpellcheckEngineParent.h"
#include "nsCOMPtr.h"
namespace mozilla {
class RemoteSpellcheckEngineParent : public mozilla::PRemoteSpellcheckEngineParent {
public:
RemoteSpellcheckEngineParent();
~RemoteSpellcheckEngineParent();
virtual void ActorDestroy(ActorDestroyReason aWhy);
bool RecvSetDictionary(const nsString& aDictionary, bool* success);
bool RecvCheckForMisspelling( const nsString& aWord, bool* isMisspelled);
private:
nsCOMPtr<mozISpellCheckingEngine> mEngine;
};
}
#endif

Просмотреть файл

@ -4,9 +4,11 @@
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
UNIFIED_SOURCES += [
SOURCES += [
'mozHunspell.cpp',
'mozHunspellDirProvider.cpp',
'RemoteSpellCheckEngineChild.cpp',
'RemoteSpellCheckEngineParent.cpp',
]
if not CONFIG['MOZ_NATIVE_HUNSPELL']:
@ -40,3 +42,14 @@ LOCAL_INCLUDES += [
# Suppress warnings in third-party code.
if CONFIG['CLANG_CXX']:
CXXFLAGS += ['-Wno-unused-private-field']
include('/ipc/chromium/chromium-config.mozbuild')
IPDL_SOURCES = [
'PRemoteSpellcheckEngine.ipdl',
]
EXPORTS.mozilla += [
'RemoteSpellCheckEngineChild.h',
'RemoteSpellCheckEngineParent.h',
]

Просмотреть файл

@ -4,7 +4,8 @@
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
UNIFIED_SOURCES += [
include('/ipc/chromium/chromium-config.mozbuild')
SOURCES += [
'mozEnglishWordUtils.cpp',
'mozGenericWordUtils.cpp',
'mozInlineSpellChecker.cpp',
@ -24,5 +25,8 @@ LOCAL_INCLUDES += [
'/content/base/src',
'/editor/libeditor/base',
]
EXPORTS.mozilla += [
'mozSpellChecker.h',
]
FAIL_ON_WARNINGS = True

Просмотреть файл

@ -10,6 +10,13 @@
#include "nsICategoryManager.h"
#include "nsISupportsPrimitives.h"
#include "nsISimpleEnumerator.h"
#include "mozilla/PRemoteSpellcheckEngineChild.h"
#include "mozilla/dom/ContentChild.h"
#include "nsXULAppAPI.h"
using mozilla::dom::ContentChild;
using mozilla::PRemoteSpellcheckEngineChild;
using mozilla::RemoteSpellcheckEngineChild;
#define DEFAULT_SPELL_CHECKER "@mozilla.org/spellchecker/engine;1"
@ -38,6 +45,10 @@ mozSpellChecker::~mozSpellChecker()
}
mSpellCheckingEngine = nullptr;
mPersonalDictionary = nullptr;
if(XRE_GetProcessType() == GeckoProcessType_Content) {
mEngine->Send__delete__(mEngine);
}
}
nsresult
@ -46,6 +57,12 @@ mozSpellChecker::Init()
mPersonalDictionary = do_GetService("@mozilla.org/spellchecker/personaldictionary;1");
mSpellCheckingEngine = nullptr;
if (XRE_GetProcessType() == GeckoProcessType_Content) {
mozilla::dom::ContentChild* contentChild = mozilla::dom::ContentChild::GetSingleton();
MOZ_ASSERT(contentChild);
mEngine = new RemoteSpellcheckEngineChild(this);
contentChild->SendPRemoteSpellcheckEngineConstructor(mEngine);
}
return NS_OK;
}
@ -108,9 +125,16 @@ mozSpellChecker::CheckWord(const nsAString &aWord, bool *aIsMisspelled, nsTArray
{
nsresult result;
bool correct;
if(!mSpellCheckingEngine)
return NS_ERROR_NULL_POINTER;
if (XRE_GetProcessType() == GeckoProcessType_Content) {
nsString wordwrapped = nsString(aWord);
bool rv = mEngine->SendCheckForMisspelling(wordwrapped, aIsMisspelled);
return rv ? NS_OK : NS_ERROR_NOT_AVAILABLE;
}
if(!mSpellCheckingEngine) {
return NS_ERROR_NULL_POINTER;
}
*aIsMisspelled = false;
result = mSpellCheckingEngine->Check(PromiseFlatString(aWord).get(), &correct);
NS_ENSURE_SUCCESS(result, result);
@ -332,6 +356,13 @@ mozSpellChecker::GetCurrentDictionary(nsAString &aDictionary)
NS_IMETHODIMP
mozSpellChecker::SetCurrentDictionary(const nsAString &aDictionary)
{
if (XRE_GetProcessType() == GeckoProcessType_Content) {
nsString wrappedDict = nsString(aDictionary);
bool isSuccess;
mEngine->SendSetDictionary(wrappedDict, &isSuccess);
return isSuccess ? NS_OK : NS_ERROR_NOT_AVAILABLE;
}
// Calls to mozISpellCheckingEngine::SetDictionary might destroy us
nsRefPtr<mozSpellChecker> kungFuDeathGrip = this;
@ -528,3 +559,7 @@ mozSpellChecker::GetEngineList(nsCOMArray<mozISpellCheckingEngine>* aSpellChecki
return NS_OK;
}
void mozSpellChecker::DeleteRemoteEngine() {
mEngine = nullptr;
}

Просмотреть файл

@ -17,6 +17,12 @@
#include "nsTArray.h"
#include "mozISpellI18NUtil.h"
#include "nsCycleCollectionParticipant.h"
#include "RemoteSpellCheckEngineChild.h"
namespace mozilla {
class PRemoteSpellcheckEngineChild;
class RemoteSpellcheckEngineChild;
}
class mozSpellChecker : public nsISpellChecker
{
@ -43,6 +49,7 @@ public:
NS_IMETHOD GetCurrentDictionary(nsAString &aDictionary);
NS_IMETHOD SetCurrentDictionary(const nsAString &aDictionary);
NS_IMETHOD CheckCurrentDictionary();
void DeleteRemoteEngine();
protected:
virtual ~mozSpellChecker();
@ -59,5 +66,7 @@ protected:
nsresult GetCurrentBlockIndex(nsITextServicesDocument *aDoc, int32_t *outBlockIndex);
nsresult GetEngineList(nsCOMArray<mozISpellCheckingEngine> *aDictionaryList);
mozilla::PRemoteSpellcheckEngineChild *mEngine;
};
#endif // mozSpellChecker_h__

Просмотреть файл

@ -541,7 +541,7 @@
<xul:menuitem label="&selectAllCmd.label;" accesskey="&selectAllCmd.accesskey;" cmd="cmd_selectAll"/>
<xul:menuseparator anonid="spell-check-separator"/>
<xul:menuitem label="&spellCheckToggle.label;" type="checkbox" accesskey="&spellCheckToggle.accesskey;" anonid="spell-check-enabled"
oncommand="this.parentNode.parentNode.spellCheckerUI.toggleEnabled();"/>
oncommand="this.parentNode.parentNode.spellCheckerUI.toggleEnabled(window);"/>
<xul:menu label="&spellDictionaries.label;" accesskey="&spellDictionaries.accesskey;" anonid="spell-dictionaries">
<xul:menupopup anonid="spell-dictionaries-menu"
onpopupshowing="event.stopPropagation();"

Просмотреть файл

@ -191,7 +191,7 @@ InlineSpellChecker.prototype = {
if (curlang == sortedList[i].id) {
item.setAttribute("checked", "true");
} else {
var callback = function(me, val) { return function(evt) { me.selectDictionary(val); } };
var callback = function(me, val) { return function(evt) { me.selectDictionary(val, me.menu.ownerDocument.defaultView); } };
item.addEventListener("command", callback(this, i), true);
}
if (insertBefore)
@ -272,8 +272,20 @@ InlineSpellChecker.prototype = {
},
// callback for selecting a dictionary
selectDictionary: function(index)
selectDictionary: function(index, aWindow)
{
// Avoid a crash in multiprocess until Bug 1030451 lands
// Remove aWindow parameter at that time
const Ci = Components.interfaces;
let chromeFlags = aWindow.QueryInterface(Ci.nsIInterfaceRequestor).
getInterface(Ci.nsIWebNavigation).
QueryInterface(Ci.nsIDocShellTreeItem).treeOwner.
QueryInterface(Ci.nsIInterfaceRequestor).
getInterface(Ci.nsIXULWindow).chromeFlags;
let chromeRemoteWindow = Ci.nsIWebBrowserChrome.CHROME_REMOTE_WINDOW;
if (chromeFlags & chromeRemoteWindow) {
return;
}
if (! this.mInlineSpellChecker || index < 0 || index >= this.mDictionaryNames.length)
return;
var spellchecker = this.mInlineSpellChecker.spellChecker;
@ -293,8 +305,20 @@ InlineSpellChecker.prototype = {
},
// callback for enabling or disabling spellchecking
toggleEnabled: function()
toggleEnabled: function(aWindow)
{
// Avoid a crash in multiprocess until Bug 1030451 lands
// Remove aWindow parameter at that time
const Ci = Components.interfaces;
let chromeFlags = aWindow.QueryInterface(Ci.nsIInterfaceRequestor).
getInterface(Ci.nsIWebNavigation).
QueryInterface(Ci.nsIDocShellTreeItem).treeOwner.
QueryInterface(Ci.nsIInterfaceRequestor).
getInterface(Ci.nsIXULWindow).chromeFlags;
let chromeRemoteWindow = Ci.nsIWebBrowserChrome.CHROME_REMOTE_WINDOW;
if (chromeFlags & chromeRemoteWindow) {
return;
}
this.mEditor.setSpellcheckUserOverride(!this.mInlineSpellChecker.enableRealTimeSpell);
},