From 77d5ef2f6888079356222fec96fa9bd155f28f7e Mon Sep 17 00:00:00 2001 From: lilia Date: Wed, 19 Apr 2017 15:25:03 -0700 Subject: [PATCH] Add spellcheck As of Electron 1.6.5, this requires disabling the sandbox in order to get access to the `webFrame` api. // FREEBIE --- main.js | 2 +- package.json | 2 ++ preload.js | 56 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 59 insertions(+), 1 deletion(-) diff --git a/main.js b/main.js index 56d84e77d..e0e8ac403 100644 --- a/main.js +++ b/main.js @@ -73,7 +73,7 @@ function createWindow () { height: 610, webPreferences: { nodeIntegration: false, - sandbox: true, + //sandbox: true, preload: path.join(__dirname, 'preload.js') } }) diff --git a/package.json b/package.json index 8e013ff80..fc366d9f5 100644 --- a/package.json +++ b/package.json @@ -98,6 +98,8 @@ }, "dependencies": { "config": "^1.25.1", + "electron-editor-context-menu": "^1.1.1", + "electron-spell-check-provider": "^1.1.0", "electron-updater": "^1.11.2" } } diff --git a/preload.js b/preload.js index 2ba77f103..dc8b5baf1 100644 --- a/preload.js +++ b/preload.js @@ -8,4 +8,60 @@ const ipc = electron.ipcRenderer window.config.locale_json = ipc.sendSync('locale-data'); + /** + * Enables spell-checking and the right-click context menu in text editors. + * Electron (`webFrame.setSpellCheckProvider`) only underlines misspelled words; + * we must manage the menu ourselves. + * + * Run this in the renderer process. + */ + var remote = electron.remote; + var webFrame = electron.webFrame; + var SpellCheckProvider = require('electron-spell-check-provider'); + // `remote.require` since `Menu` is a main-process module. + var buildEditorContextMenu = remote.require('electron-editor-context-menu'); + + var selection; + function resetSelection() { + selection = { + isMisspelled: false, + spellingSuggestions: [] + }; + } + resetSelection(); + + // Reset the selection when clicking around, before the spell-checker runs and the context menu shows. + window.addEventListener('mousedown', resetSelection); + + // The spell-checker runs when the user clicks on text and before the 'contextmenu' event fires. + // Thus, we may retrieve spell-checking suggestions to put in the menu just before it shows. + webFrame.setSpellCheckProvider( + 'en-US', + // Not sure what this parameter (`autoCorrectWord`) does: https://github.com/atom/electron/issues/4371 + // The documentation for `webFrame.setSpellCheckProvider` passes `true` so we do too. + true, + new SpellCheckProvider('en-US').on('misspelling', function(suggestions) { + // Prime the context menu with spelling suggestions _if_ the user has selected text. Electron + // may sometimes re-run the spell-check provider for an outdated selection e.g. if the user + // right-clicks some misspelled text and then an image. + if (window.getSelection().toString()) { + selection.isMisspelled = true; + // Take the first three suggestions if any. + selection.spellingSuggestions = suggestions.slice(0, 3); + } + })); + + window.addEventListener('contextmenu', function(e) { + // Only show the context menu in text editors. + if (!e.target.closest('textarea, input, [contenteditable="true"]')) return; + + var menu = buildEditorContextMenu(selection); + + // The 'contextmenu' event is emitted after 'selectionchange' has fired but possibly before the + // visible selection has changed. Try to wait to show the menu until after that, otherwise the + // visible selection will update after the menu dismisses and look weird. + setTimeout(function() { + menu.popup(remote.getCurrentWindow()); + }, 30); + }); })();