Bug 1402822 - Support multiple dictionaries in InlineSpellChecker; r=smaug,Gijs

Differential Revision: https://phabricator.services.mozilla.com/D140242
This commit is contained in:
Dan Minor 2022-03-23 13:53:38 +00:00
parent 0f00bde70a
commit 12a8486570
5 changed files with 47 additions and 41 deletions

View file

@ -1669,8 +1669,8 @@ nsresult mozInlineSpellChecker::ResumeCheck(
return NS_ERROR_FAILURE; return NS_ERROR_FAILURE;
} }
nsAutoCString currentDictionary; nsTArray<nsCString> currentDictionaries;
nsresult rv = mSpellCheck->GetCurrentDictionary(currentDictionary); nsresult rv = mSpellCheck->GetCurrentDictionaries(currentDictionaries);
if (NS_FAILED(rv)) { if (NS_FAILED(rv)) {
MOZ_LOG(sInlineSpellCheckerLog, LogLevel::Debug, MOZ_LOG(sInlineSpellCheckerLog, LogLevel::Debug,
("%s: no active dictionary.", __FUNCTION__)); ("%s: no active dictionary.", __FUNCTION__));

View file

@ -17,8 +17,8 @@ ChromeUtils.defineModuleGetter(
class InlineSpellCheckerChild extends JSWindowActorChild { class InlineSpellCheckerChild extends JSWindowActorChild {
receiveMessage(msg) { receiveMessage(msg) {
switch (msg.name) { switch (msg.name) {
case "InlineSpellChecker:selectDictionary": case "InlineSpellChecker:selectDictionaries":
InlineSpellCheckerContent.selectDictionary(msg.data.localeCode); InlineSpellCheckerContent.selectDictionaries(msg.data.localeCodes);
break; break;
case "InlineSpellChecker:replaceMisspelling": case "InlineSpellChecker:replaceMisspelling":

View file

@ -9,9 +9,9 @@
var EXPORTED_SYMBOLS = ["InlineSpellCheckerParent"]; var EXPORTED_SYMBOLS = ["InlineSpellCheckerParent"];
class InlineSpellCheckerParent extends JSWindowActorParent { class InlineSpellCheckerParent extends JSWindowActorParent {
selectDictionary({ localeCode }) { selectDictionaries({ localeCodes }) {
this.sendAsyncMessage("InlineSpellChecker:selectDictionary", { this.sendAsyncMessage("InlineSpellChecker:selectDictionaries", {
localeCode, localeCodes,
}); });
} }

View file

@ -242,20 +242,43 @@ InlineSpellChecker.prototype = {
} }
var list; var list;
var curlang = ""; var curlangs = new Set();
if (this.mRemote) { if (this.mRemote) {
list = this.mRemote.dictionaryList; list = this.mRemote.dictionaryList;
curlang = this.mRemote.currentDictionary; curlangs = new Set(this.mRemote.currentDictionaries);
} else if (this.mInlineSpellChecker) { } else if (this.mInlineSpellChecker) {
var spellchecker = this.mInlineSpellChecker.spellChecker; var spellchecker = this.mInlineSpellChecker.spellChecker;
list = spellchecker.GetDictionaryList(); list = spellchecker.GetDictionaryList();
try { try {
curlang = spellchecker.GetCurrentDictionary(); curlangs = new Set(spellchecker.getCurrentDictionaries());
} catch (e) {} } catch (e) {}
} }
var sortedList = this.sortDictionaryList(list); var sortedList = this.sortDictionaryList(list);
menu.addEventListener(
"command",
async evt => {
let localeCodes = new Set(curlangs);
let localeCode = evt.target.dataset.localeCode;
if (localeCodes.has(localeCode)) {
localeCodes.delete(localeCode);
} else {
localeCodes.add(localeCode);
}
let dictionaries = Array.from(localeCodes);
await this.selectDictionaries(dictionaries);
// Notify change of dictionary, especially for Thunderbird,
// which is otherwise not notified any more.
var view = menu.ownerGlobal;
var spellcheckChangeEvent = new view.CustomEvent("spellcheck-changed", {
detail: { dictionaries },
});
menu.ownerDocument.dispatchEvent(spellcheckChangeEvent);
},
true
);
for (var i = 0; i < sortedList.length; i++) { for (var i = 0; i < sortedList.length; i++) {
var item = menu.ownerDocument.createXULElement("menuitem"); var item = menu.ownerDocument.createXULElement("menuitem");
item.setAttribute( item.setAttribute(
@ -266,29 +289,12 @@ InlineSpellChecker.prototype = {
// inject regionNames/languageNames FTL and localize using // inject regionNames/languageNames FTL and localize using
// `l10n-id` here. // `l10n-id` here.
item.setAttribute("label", sortedList[i].displayName); item.setAttribute("label", sortedList[i].displayName);
item.setAttribute("type", "radio"); item.setAttribute("type", "checkbox");
item.setAttribute("selection-type", "multiple");
this.mDictionaryItems.push(item); this.mDictionaryItems.push(item);
if (curlang == sortedList[i].localeCode) { item.dataset.localeCode = sortedList[i].localeCode;
if (curlangs.has(sortedList[i].localeCode)) {
item.setAttribute("checked", "true"); item.setAttribute("checked", "true");
} else {
var callback = function(me, localeCode) {
return function(evt) {
me.selectDictionary(localeCode);
// Notify change of dictionary, especially for Thunderbird,
// which is otherwise not notified any more.
var view = menu.ownerGlobal;
var spellcheckChangeEvent = new view.CustomEvent(
"spellcheck-changed",
{ detail: { dictionary: localeCode } }
);
menu.ownerDocument.dispatchEvent(spellcheckChangeEvent);
};
};
item.addEventListener(
"command",
callback(this, sortedList[i].localeCode),
true
);
} }
if (insertBefore) { if (insertBefore) {
menu.insertBefore(item, insertBefore); menu.insertBefore(item, insertBefore);
@ -309,16 +315,16 @@ InlineSpellChecker.prototype = {
}, },
// callback for selecting a dictionary // callback for selecting a dictionary
selectDictionary(localeCode) { async selectDictionaries(localeCodes) {
if (this.mRemote) { if (this.mRemote) {
this.mRemote.selectDictionary(localeCode); this.mRemote.selectDictionaries(localeCodes);
return; return;
} }
if (!this.mInlineSpellChecker) { if (!this.mInlineSpellChecker) {
return; return;
} }
var spellchecker = this.mInlineSpellChecker.spellChecker; var spellchecker = this.mInlineSpellChecker.spellChecker;
spellchecker.SetCurrentDictionary(localeCode); await spellchecker.setCurrentDictionaries(localeCodes);
this.mInlineSpellChecker.spellCheckRange(null); // causes recheck this.mInlineSpellChecker.spellCheckRange(null); // causes recheck
}, },
@ -537,15 +543,15 @@ RemoteSpellChecker.prototype = {
return this._spellInfo.spellSuggestions; return this._spellInfo.spellSuggestions;
}, },
get currentDictionary() { get currentDictionaries() {
return this._spellInfo.currentDictionary; return this._spellInfo.currentDictionaries;
}, },
get dictionaryList() { get dictionaryList() {
return this._spellInfo.dictionaryList.slice(); return this._spellInfo.dictionaryList.slice();
}, },
selectDictionary(localeCode) { selectDictionaries(localeCodes) {
this._actor.selectDictionary({ localeCode }); this._actor.selectDictionaries({ localeCodes });
}, },
replaceMisspelling(suggestion) { replaceMisspelling(suggestion) {

View file

@ -71,7 +71,7 @@ var InlineSpellCheckerContent = {
overMisspelling: spellChecker.overMisspelling, overMisspelling: spellChecker.overMisspelling,
misspelling: spellChecker.mMisspelling, misspelling: spellChecker.mMisspelling,
spellSuggestions, spellSuggestions,
currentDictionary: spellChecker.mInlineSpellChecker.spellChecker.GetCurrentDictionary(), currentDictionaries: spellChecker.mInlineSpellChecker.spellChecker.getCurrentDictionaries(),
dictionaryList, dictionaryList,
}; };
}, },
@ -103,8 +103,8 @@ var InlineSpellCheckerContent = {
return suggestions; return suggestions;
}, },
selectDictionary(localeCode) { selectDictionaries(localeCodes) {
this._spellChecker.selectDictionary(localeCode); this._spellChecker.selectDictionaries(localeCodes);
}, },
replaceMisspelling(suggestion) { replaceMisspelling(suggestion) {