зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1719110 - Don't use sync IPC to show suggestion by spellchecker. r=Gijs
CheckCurrentWord on content process causes sync IPC, so I would like to remove this call on content process. New nsIEditorSpellChecker.suggest method can avoid it. Differential Revision: https://phabricator.services.mozilla.com/D119937
This commit is contained in:
Родитель
a6944a1428
Коммит
49cc605308
|
@ -507,7 +507,7 @@ class ContextMenuChild extends JSWindowActorChild {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
handleEvent(aEvent) {
|
async handleEvent(aEvent) {
|
||||||
contextMenus.set(this.browsingContext, this);
|
contextMenus.set(this.browsingContext, this);
|
||||||
|
|
||||||
let defaultPrevented = aEvent.defaultPrevented;
|
let defaultPrevented = aEvent.defaultPrevented;
|
||||||
|
@ -645,7 +645,6 @@ class ContextMenuChild extends JSWindowActorChild {
|
||||||
referrerInfo,
|
referrerInfo,
|
||||||
editFlags,
|
editFlags,
|
||||||
principal,
|
principal,
|
||||||
spellInfo,
|
|
||||||
contentType,
|
contentType,
|
||||||
docLocation,
|
docLocation,
|
||||||
loginFillInfo,
|
loginFillInfo,
|
||||||
|
@ -692,6 +691,15 @@ class ContextMenuChild extends JSWindowActorChild {
|
||||||
// instead.
|
// instead.
|
||||||
aEvent.stopPropagation();
|
aEvent.stopPropagation();
|
||||||
|
|
||||||
|
data.spellInfo = null;
|
||||||
|
if (!spellInfo) {
|
||||||
|
this.sendAsyncMessage("contextmenu", data);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
data.spellInfo = await spellInfo;
|
||||||
|
} catch (ex) {}
|
||||||
this.sendAsyncMessage("contextmenu", data);
|
this.sendAsyncMessage("contextmenu", data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -284,6 +284,10 @@ class nsContextMenu {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (this.contentData.spellInfo) {
|
||||||
|
this.spellSuggesions = this.contentData.spellInfo.spellSuggestions;
|
||||||
|
}
|
||||||
|
|
||||||
if (context.shouldInitInlineSpellCheckerUIWithChildren) {
|
if (context.shouldInitInlineSpellCheckerUIWithChildren) {
|
||||||
InlineSpellCheckerUI.initFromRemote(
|
InlineSpellCheckerUI.initFromRemote(
|
||||||
this.contentData.spellInfo,
|
this.contentData.spellInfo,
|
||||||
|
@ -769,7 +773,7 @@ class nsContextMenu {
|
||||||
var numsug = InlineSpellCheckerUI.addSuggestionsToMenu(
|
var numsug = InlineSpellCheckerUI.addSuggestionsToMenu(
|
||||||
suggestionsSeparator.parentNode,
|
suggestionsSeparator.parentNode,
|
||||||
suggestionsSeparator,
|
suggestionsSeparator,
|
||||||
5
|
this.spellSuggesions
|
||||||
);
|
);
|
||||||
this.showItem("spell-no-suggestions", numsug == 0);
|
this.showItem("spell-no-suggestions", numsug == 0);
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -35,13 +35,22 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=1272623
|
||||||
// Perform the spelling correction
|
// Perform the spelling correction
|
||||||
let mm = SpecialPowers.loadChromeScript(function() {
|
let mm = SpecialPowers.loadChromeScript(function() {
|
||||||
const {Services} = ChromeUtils.import("resource://gre/modules/Services.jsm");
|
const {Services} = ChromeUtils.import("resource://gre/modules/Services.jsm");
|
||||||
|
const {BrowserTestUtils} = ChromeUtils.import("resource://testing-common/BrowserTestUtils.jsm");
|
||||||
|
|
||||||
// Chrome scripts are run with synchronous messages, so make sure we're completely
|
// Chrome scripts are run with synchronous messages, so make sure we're completely
|
||||||
// decoupled from the content process before doing this work.
|
// decoupled from the content process before doing this work.
|
||||||
Cu.dispatch(function() {
|
Cu.dispatch(async function() {
|
||||||
let chromeWin = Services.ww.activeWindow;
|
let chromeWin = Services.ww.activeWindow;
|
||||||
let contextMenu = chromeWin.document.getElementById("contentAreaContextMenu");
|
let contextMenu = chromeWin.document.getElementById("contentAreaContextMenu");
|
||||||
let suggestion = contextMenu.querySelector(".spell-suggestion");
|
let suggestion = contextMenu.querySelector(".spell-suggestion");
|
||||||
|
if (!suggestion) {
|
||||||
|
await BrowserTestUtils.waitForMutationCondition(
|
||||||
|
contextMenu,
|
||||||
|
{ childList: true },
|
||||||
|
() => contextMenu.querySelector(".spell-suggestion")
|
||||||
|
);
|
||||||
|
suggestion = contextMenu.querySelector(".spell-suggestion");
|
||||||
|
}
|
||||||
suggestion.doCommand();
|
suggestion.doCommand();
|
||||||
contextMenu.hidePopup();
|
contextMenu.hidePopup();
|
||||||
sendAsyncMessage("spellingCorrected");
|
sendAsyncMessage("spellingCorrected");
|
||||||
|
|
|
@ -22,7 +22,7 @@ class InlineSpellCheckerChild extends JSWindowActorChild {
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case "InlineSpellChecker:replaceMisspelling":
|
case "InlineSpellChecker:replaceMisspelling":
|
||||||
InlineSpellCheckerContent.replaceMisspelling(msg.data.index);
|
InlineSpellCheckerContent.replaceMisspelling(msg.data.suggestion);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case "InlineSpellChecker:toggleEnabled":
|
case "InlineSpellChecker:toggleEnabled":
|
||||||
|
|
|
@ -15,8 +15,10 @@ class InlineSpellCheckerParent extends JSWindowActorParent {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
replaceMisspelling({ index }) {
|
replaceMisspelling({ suggestion }) {
|
||||||
this.sendAsyncMessage("InlineSpellChecker:replaceMisspelling", { index });
|
this.sendAsyncMessage("InlineSpellChecker:replaceMisspelling", {
|
||||||
|
suggestion,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
toggleEnabled() {
|
toggleEnabled() {
|
||||||
|
|
|
@ -144,7 +144,7 @@
|
||||||
|
|
||||||
// suggestion list
|
// suggestion list
|
||||||
var suggestionsSeparator = this.getMenuItem("spell-no-suggestions");
|
var suggestionsSeparator = this.getMenuItem("spell-no-suggestions");
|
||||||
var numsug = spellui.addSuggestionsToMenu(
|
var numsug = spellui.addSuggestionsToMenuOnParent(
|
||||||
event.target,
|
event.target,
|
||||||
suggestionsSeparator,
|
suggestionsSeparator,
|
||||||
5
|
5
|
||||||
|
|
|
@ -62,7 +62,6 @@ InlineSpellChecker.prototype = {
|
||||||
this.mOverMisspelling = false;
|
this.mOverMisspelling = false;
|
||||||
this.mMisspelling = "";
|
this.mMisspelling = "";
|
||||||
this.mMenu = null;
|
this.mMenu = null;
|
||||||
this.mSpellSuggestions = [];
|
|
||||||
this.mSuggestionItems = [];
|
this.mSuggestionItems = [];
|
||||||
this.mDictionaryMenu = null;
|
this.mDictionaryMenu = null;
|
||||||
this.mDictionaryItems = [];
|
this.mDictionaryItems = [];
|
||||||
|
@ -144,7 +143,40 @@ InlineSpellChecker.prototype = {
|
||||||
|
|
||||||
// this prepends up to "maxNumber" suggestions at the given menu position
|
// this prepends up to "maxNumber" suggestions at the given menu position
|
||||||
// for the word under the cursor. Returns the number of suggestions inserted.
|
// for the word under the cursor. Returns the number of suggestions inserted.
|
||||||
addSuggestionsToMenu(menu, insertBefore, maxNumber) {
|
addSuggestionsToMenuOnParent(menu, insertBefore, maxNumber) {
|
||||||
|
if (this.mRemote) {
|
||||||
|
// This is used on parent process only.
|
||||||
|
// If you want to add suggestions to context menu, get suggestions then
|
||||||
|
// use addSuggestionsToMenu instead.
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (!this.mInlineSpellChecker || !this.mOverMisspelling) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
let spellchecker = this.mInlineSpellChecker.spellChecker;
|
||||||
|
let spellSuggestions = [];
|
||||||
|
|
||||||
|
try {
|
||||||
|
if (!spellchecker.CheckCurrentWord(this.mMisspelling)) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (let i = 0; i < maxNumber; i++) {
|
||||||
|
let suggestion = spellchecker.GetSuggestedWord();
|
||||||
|
if (!suggestion.length) {
|
||||||
|
// no more data
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
spellSuggestions.push(suggestion);
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return this._addSuggestionsToMenu(menu, insertBefore, spellSuggestions);
|
||||||
|
},
|
||||||
|
|
||||||
|
addSuggestionsToMenu(menu, insertBefore, spellSuggestions) {
|
||||||
if (
|
if (
|
||||||
!this.mRemote &&
|
!this.mRemote &&
|
||||||
(!this.mInlineSpellChecker || !this.mOverMisspelling)
|
(!this.mInlineSpellChecker || !this.mOverMisspelling)
|
||||||
|
@ -152,41 +184,31 @@ InlineSpellChecker.prototype = {
|
||||||
return 0;
|
return 0;
|
||||||
} // nothing to do
|
} // nothing to do
|
||||||
|
|
||||||
var spellchecker = this.mRemote || this.mInlineSpellChecker.spellChecker;
|
if (!spellSuggestions?.length) {
|
||||||
try {
|
|
||||||
if (!this.mRemote && !spellchecker.CheckCurrentWord(this.mMisspelling)) {
|
|
||||||
return 0;
|
|
||||||
} // word seems not misspelled after all (?)
|
|
||||||
} catch (e) {
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return this._addSuggestionsToMenu(menu, insertBefore, spellSuggestions);
|
||||||
|
},
|
||||||
|
|
||||||
|
_addSuggestionsToMenu(menu, insertBefore, spellSuggestions) {
|
||||||
this.mMenu = menu;
|
this.mMenu = menu;
|
||||||
this.mSpellSuggestions = [];
|
|
||||||
this.mSuggestionItems = [];
|
this.mSuggestionItems = [];
|
||||||
for (var i = 0; i < maxNumber; i++) {
|
|
||||||
var suggestion = spellchecker.GetSuggestedWord();
|
|
||||||
if (!suggestion.length) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
this.mSpellSuggestions.push(suggestion);
|
|
||||||
|
|
||||||
|
for (let suggestion of spellSuggestions) {
|
||||||
var item = menu.ownerDocument.createXULElement("menuitem");
|
var item = menu.ownerDocument.createXULElement("menuitem");
|
||||||
this.mSuggestionItems.push(item);
|
this.mSuggestionItems.push(item);
|
||||||
item.setAttribute("label", suggestion);
|
item.setAttribute("label", suggestion);
|
||||||
item.setAttribute("value", suggestion);
|
item.setAttribute("value", suggestion);
|
||||||
// this function thing is necessary to generate a callback with the
|
item.addEventListener(
|
||||||
// correct binding of "val" (the index in this loop).
|
"command",
|
||||||
var callback = function(me, val) {
|
this.replaceMisspelling.bind(this, suggestion),
|
||||||
return function(evt) {
|
true
|
||||||
me.replaceMisspelling(val);
|
);
|
||||||
};
|
|
||||||
};
|
|
||||||
item.addEventListener("command", callback(this, i), true);
|
|
||||||
item.setAttribute("class", "spell-suggestion");
|
item.setAttribute("class", "spell-suggestion");
|
||||||
menu.insertBefore(item, insertBefore);
|
menu.insertBefore(item, insertBefore);
|
||||||
}
|
}
|
||||||
return this.mSpellSuggestions.length;
|
return spellSuggestions.length;
|
||||||
},
|
},
|
||||||
|
|
||||||
// undoes the work of addSuggestionsToMenu for the same menu
|
// undoes the work of addSuggestionsToMenu for the same menu
|
||||||
|
@ -301,21 +323,18 @@ InlineSpellChecker.prototype = {
|
||||||
},
|
},
|
||||||
|
|
||||||
// callback for selecting a suggested replacement
|
// callback for selecting a suggested replacement
|
||||||
replaceMisspelling(index) {
|
replaceMisspelling(suggestion) {
|
||||||
if (this.mRemote) {
|
if (this.mRemote) {
|
||||||
this.mRemote.replaceMisspelling(index);
|
this.mRemote.replaceMisspelling(suggestion);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!this.mInlineSpellChecker || !this.mOverMisspelling) {
|
if (!this.mInlineSpellChecker || !this.mOverMisspelling) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (index < 0 || index >= this.mSpellSuggestions.length) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
this.mInlineSpellChecker.replaceWord(
|
this.mInlineSpellChecker.replaceWord(
|
||||||
this.mWordNode,
|
this.mWordNode,
|
||||||
this.mWordOffset,
|
this.mWordOffset,
|
||||||
this.mSpellSuggestions[index]
|
suggestion
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -514,22 +533,8 @@ RemoteSpellChecker.prototype = {
|
||||||
get enableRealTimeSpell() {
|
get enableRealTimeSpell() {
|
||||||
return this._spellInfo.enableRealTimeSpell;
|
return this._spellInfo.enableRealTimeSpell;
|
||||||
},
|
},
|
||||||
|
get suggestions() {
|
||||||
GetSuggestedWord() {
|
return this._spellInfo.spellSuggestions;
|
||||||
if (!this._suggestionGenerator) {
|
|
||||||
this._suggestionGenerator = (function*(spellInfo) {
|
|
||||||
for (let i of spellInfo.spellSuggestions) {
|
|
||||||
yield i;
|
|
||||||
}
|
|
||||||
})(this._spellInfo);
|
|
||||||
}
|
|
||||||
|
|
||||||
let next = this._suggestionGenerator.next();
|
|
||||||
if (next.done) {
|
|
||||||
this._suggestionGenerator = null;
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
return next.value;
|
|
||||||
},
|
},
|
||||||
|
|
||||||
get currentDictionary() {
|
get currentDictionary() {
|
||||||
|
@ -543,8 +548,8 @@ RemoteSpellChecker.prototype = {
|
||||||
this._actor.selectDictionary({ localeCode });
|
this._actor.selectDictionary({ localeCode });
|
||||||
},
|
},
|
||||||
|
|
||||||
replaceMisspelling(index) {
|
replaceMisspelling(suggestion) {
|
||||||
this._actor.replaceMisspelling({ index });
|
this._actor.replaceMisspelling({ suggestion });
|
||||||
},
|
},
|
||||||
|
|
||||||
toggleEnabled() {
|
toggleEnabled() {
|
||||||
|
|
|
@ -15,7 +15,7 @@ var InlineSpellCheckerContent = {
|
||||||
_spellChecker: null,
|
_spellChecker: null,
|
||||||
_actor: null,
|
_actor: null,
|
||||||
|
|
||||||
initContextMenu(event, editFlags, actor) {
|
async initContextMenu(event, editFlags, actor) {
|
||||||
this._actor = actor;
|
this._actor = actor;
|
||||||
this._actor.registerDestructionObserver(this);
|
this._actor.registerDestructionObserver(this);
|
||||||
|
|
||||||
|
@ -62,6 +62,7 @@ var InlineSpellCheckerContent = {
|
||||||
|
|
||||||
let realSpellChecker = spellChecker.mInlineSpellChecker.spellChecker;
|
let realSpellChecker = spellChecker.mInlineSpellChecker.spellChecker;
|
||||||
let dictionaryList = realSpellChecker.GetDictionaryList();
|
let dictionaryList = realSpellChecker.GetDictionaryList();
|
||||||
|
let spellSuggestions = await this._generateSpellSuggestions();
|
||||||
|
|
||||||
return {
|
return {
|
||||||
canSpellCheck: spellChecker.canSpellCheck,
|
canSpellCheck: spellChecker.canSpellCheck,
|
||||||
|
@ -69,7 +70,7 @@ var InlineSpellCheckerContent = {
|
||||||
enableRealTimeSpell: spellChecker.enabled,
|
enableRealTimeSpell: spellChecker.enabled,
|
||||||
overMisspelling: spellChecker.overMisspelling,
|
overMisspelling: spellChecker.overMisspelling,
|
||||||
misspelling: spellChecker.mMisspelling,
|
misspelling: spellChecker.mMisspelling,
|
||||||
spellSuggestions: this._generateSpellSuggestions(),
|
spellSuggestions,
|
||||||
currentDictionary: spellChecker.mInlineSpellChecker.spellChecker.GetCurrentDictionary(),
|
currentDictionary: spellChecker.mInlineSpellChecker.spellChecker.GetCurrentDictionary(),
|
||||||
dictionaryList,
|
dictionaryList,
|
||||||
};
|
};
|
||||||
|
@ -87,24 +88,18 @@ var InlineSpellCheckerContent = {
|
||||||
this.uninitContextMenu();
|
this.uninitContextMenu();
|
||||||
},
|
},
|
||||||
|
|
||||||
_generateSpellSuggestions() {
|
async _generateSpellSuggestions() {
|
||||||
let spellChecker = this._spellChecker.mInlineSpellChecker.spellChecker;
|
let spellChecker = this._spellChecker.mInlineSpellChecker.spellChecker;
|
||||||
|
let suggestions = null;
|
||||||
try {
|
try {
|
||||||
spellChecker.CheckCurrentWord(this._spellChecker.mMisspelling);
|
suggestions = await spellChecker.suggest(
|
||||||
|
this._spellChecker.mMisspelling,
|
||||||
|
5
|
||||||
|
);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
|
|
||||||
let suggestions = new Array(5);
|
|
||||||
for (let i = 0; i < 5; ++i) {
|
|
||||||
suggestions[i] = spellChecker.GetSuggestedWord();
|
|
||||||
if (suggestions[i].length === 0) {
|
|
||||||
suggestions.length = i;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
this._spellChecker.mSpellSuggestions = suggestions;
|
|
||||||
return suggestions;
|
return suggestions;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -112,8 +107,8 @@ var InlineSpellCheckerContent = {
|
||||||
this._spellChecker.selectDictionary(localeCode);
|
this._spellChecker.selectDictionary(localeCode);
|
||||||
},
|
},
|
||||||
|
|
||||||
replaceMisspelling(index) {
|
replaceMisspelling(suggestion) {
|
||||||
this._spellChecker.replaceMisspelling(index);
|
this._spellChecker.replaceMisspelling(suggestion);
|
||||||
},
|
},
|
||||||
|
|
||||||
toggleEnabled() {
|
toggleEnabled() {
|
||||||
|
|
Загрузка…
Ссылка в новой задаче