diff --git a/package.json b/package.json index 5b9ffe7..d5474df 100644 --- a/package.json +++ b/package.json @@ -63,7 +63,7 @@ }, "build": { "appId": "im.riot.app", - "electronVersion": "7.1.3", + "electronVersion": "8.0.1", "files": [ "package.json", { diff --git a/src/electron-main.js b/src/electron-main.js index 35276ef..7350592 100644 --- a/src/electron-main.js +++ b/src/electron-main.js @@ -285,6 +285,35 @@ ipcMain.on('ipcCall', async function(ev, payload) { case 'getConfig': ret = vectorConfig; break; + case 'setLanguage': { + // work around `setSpellCheckerLanguages` being case-sensitive by converting to expected case + const caseMap = {}; + const availableLanguages = mainWindow.webContents.session.availableSpellCheckerLanguages; + availableLanguages.forEach(lang => { + caseMap[lang.toLowerCase()] = lang; + }); + + const languages = args[0].map(lang => { + const lcLang = lang.toLowerCase(); + if (caseMap[lcLang]) { + return caseMap[lcLang]; + } + + // as a fallback if the language is unknown check if the language group is known, e.g en for en-AU + const langGroup = lcLang.substr(0, lcLang.indexOf("-")); + if (caseMap[langGroup]) { + return caseMap[langGroup]; + } + + // as a further fallback, pick another variant from the same language group + return availableLanguages.find(availableLang => availableLang.startsWith(langGroup)); + }).filter(Boolean); + + if (languages.length) { + mainWindow.webContents.session.setSpellCheckerLanguages(languages); + } + break; + } default: mainWindow.webContents.send('ipcReply', { @@ -614,6 +643,7 @@ app.on('ready', async () => { // main page from the background script. contextIsolation: false, webgl: false, + spellcheck: true, }, }); mainWindow.loadURL('vector://vector/webapp/'); diff --git a/src/webcontents-handler.js b/src/webcontents-handler.js index c958690..a749e0a 100644 --- a/src/webcontents-handler.js +++ b/src/webcontents-handler.js @@ -126,7 +126,30 @@ function onLinkContextMenu(ev, params) { } function _CutCopyPasteSelectContextMenus(params) { - return [{ + const options = []; + + if (params.misspelledWord) { + params.dictionarySuggestions.forEach(word => { + options.push({ + label: word, + click: (menuItem, browserWindow) => { + browserWindow.webContents.replaceMisspelling(word); + }, + }); + }); + options.push({ + type: 'separator', + }, { + label: 'Add to dictionary', + click: (menuItem, browserWindow) => { + browserWindow.webContents.session.addWordToSpellCheckerDictionary(params.misspelledWord); + }, + }, { + type: 'separator', + }); + } + + options.push({ role: 'cut', label: 'Cu&t', enabled: params.editFlags.canCut, @@ -145,7 +168,8 @@ function _CutCopyPasteSelectContextMenus(params) { role: 'selectall', label: "Select &All", enabled: params.editFlags.canSelectAll, - }]; + }); + return options; } function onSelectedContextMenu(ev, params) {