diff --git a/index.d.ts b/index.d.ts index 9bb66d6..f7252d1 100644 --- a/index.d.ts +++ b/index.d.ts @@ -10,6 +10,13 @@ import { declare namespace contextMenu { interface Labels { + /** + The placeholder `{selection}` will be replaced by the currently selected text. + + @default 'Look Up “{selection}”' + */ + readonly lookUpSelection?: string; + /** @default 'Cut' */ @@ -65,15 +72,15 @@ declare namespace contextMenu { interface Actions { readonly separator: () => MenuItem; - readonly inspect: () => MenuItem; - readonly services: () => MenuItem; + readonly lookUpSelection: (options: ActionOptions) => MenuItem; readonly cut: (options: ActionOptions) => MenuItem; readonly copy: (options: ActionOptions) => MenuItem; readonly paste: (options: ActionOptions) => MenuItem; readonly saveImage: (options: ActionOptions) => MenuItem; readonly saveImageAs: (options: ActionOptions) => MenuItem; readonly copyImageAddress: (options: ActionOptions) => MenuItem; - readonly lookUpSelection: (options: ActionOptions) => MenuItem; + readonly inspect: () => MenuItem; + readonly services: () => MenuItem; } interface Options { @@ -101,6 +108,13 @@ declare namespace contextMenu { browserWindow: BrowserWindow | WebviewTag ) => MenuItem[]; + /** + Show the `Look Up {selection}` menu item when right-clicking text on macOS. + + @default true + */ + readonly showLookUpSelection?: boolean; + /** Show the `Copy Image Address` menu item when right-clicking on an image. @@ -129,13 +143,6 @@ declare namespace contextMenu { */ readonly showServices?: boolean; - /** - Show the `Look Up [selection]` menu item when right-clicking text on macOS. - - @default true - */ - readonly showLookUpSelection?: boolean; - /** Overwrite labels for the default menu items. Useful for i18n. diff --git a/index.js b/index.js index 6d408e7..add9ad5 100644 --- a/index.js +++ b/index.js @@ -39,6 +39,17 @@ const create = (win, options) => { const can = type => editFlags[`can${type}`] && hasText; const defaultActions = { + separator: () => ({type: 'separator'}), + lookUpSelection: decorateMenuItem({ + id: 'lookUpSelection', + label: 'Look Up “{selection}”', + visible: process.platform === 'darwin' && hasText, + click() { + if (process.platform === 'darwin') { + webContents(win).showDefinitionForSelection(); + } + } + }), cut: decorateMenuItem({ id: 'cut', label: 'Cut', @@ -71,25 +82,6 @@ const create = (win, options) => { webContents(win).insertText(clipboardContent); } }), - inspect: () => ({ - id: 'inspect', - label: 'Inspect Element', - enabled: isDev, - click() { - win.inspectElement(props.x, props.y); - - if (webContents(win).isDevToolsOpened()) { - webContents(win).devToolsWebContents.focus(); - } - } - }), - services: () => ({ - id: 'services', - label: 'Services', - role: 'services', - visible: process.platform === 'darwin' && (props.isEditable || hasText) - }), - separator: () => ({type: 'separator'}), saveImage: decorateMenuItem({ id: 'save', label: 'Save Image', @@ -134,15 +126,23 @@ const create = (win, options) => { }); } }), - lookUpSelection: decorateMenuItem({ - id: 'lookUpSelection', - label: `Look Up “${cliTruncate(props.selectionText.trim(), 25)}”`, - visible: process.platform === 'darwin' && hasText, + inspect: () => ({ + id: 'inspect', + label: 'Inspect Element', + enabled: isDev, click() { - if (process.platform === 'darwin') { - webContents(win).showDefinitionForSelection(); + win.inspectElement(props.x, props.y); + + if (webContents(win).isDevToolsOpened()) { + webContents(win).devToolsWebContents.focus(); } } + }), + services: () => ({ + id: 'services', + label: 'Services', + role: 'services', + visible: process.platform === 'darwin' && (props.isEditable || hasText) }) }; @@ -189,12 +189,16 @@ const create = (win, options) => { // TODO: https://github.com/electron/electron/issues/5869 menuTemplate = removeUnusedMenuItems(menuTemplate); - // Apply custom labels for default menu items - if (options.labels) { - for (const menuItem of menuTemplate) { - if (options.labels[menuItem.id]) { - menuItem.label = options.labels[menuItem.id]; - } + for (const menuItem of menuTemplate) { + // Apply custom labels for default menu items + if (options.labels && options.labels[menuItem.id]) { + menuItem.label = options.labels[menuItem.id]; + } + + // Replace placeholders in menu item labels + if (typeof menuItem.label === 'string' && menuItem.label.indexOf('{selection}') !== -1) { + const selectionString = typeof props.selectionText === 'string' ? props.selectionText.trim() : ''; + menuItem.label = menuItem.label.replace('{selection}', cliTruncate(selectionString, 25)); } } diff --git a/readme.md b/readme.md index 8123573..de40767 100644 --- a/readme.md +++ b/readme.md @@ -25,11 +25,21 @@ const {app, BrowserWindow} = require('electron'); const contextMenu = require('electron-context-menu'); contextMenu({ - prepend: (defaultActions, params, browserWindow) => [{ - label: 'Rainbow', - // Only show it when right-clicking images - visible: params.mediaType === 'image' - }] + prepend: (defaultActions, params, browserWindow) => [ + { + label: 'Rainbow', + // Only show it when right-clicking images + visible: params.mediaType === 'image' + }, + { + label: 'Search Google for “{selection}”', + // Only show it when right-clicking text + visible: (params.selectionText.trim().length > 0), + click: () => { + shell.openExternal(`https://www.google.com/search?q=${encodeURIComponent(params.selectionText)}`); + } + } + ] }); let mainWindow; @@ -64,6 +74,8 @@ Should return an array of [MenuItem](https://electronjs.org/docs/api/menu-item/) The first argument is an array of default actions that can be used. The second argument is [this `params` object](https://electronjs.org/docs/api/web-contents/#event-context-menu). The third argument is the [BrowserWindow](https://electronjs.org/docs/api/browser-window/) the context menu was requested for. +`MenuItem` labels may contain the the placeholder `{selection}` which will be replaced by the currently selected text as described in [`options.labels`](#labels). + #### append Type: `Function` @@ -72,6 +84,15 @@ Should return an array of [MenuItem](https://electronjs.org/docs/api/menu-item/) The first argument is an array of default actions that can be used. The second argument is [this `params` object](https://electronjs.org/docs/api/web-contents/#event-context-menu). The third argument is the [BrowserWindow](https://electronjs.org/docs/api/browser-window/) the context menu was requested for. +`MenuItem` labels may contain the the placeholder `{selection}` which will be replaced by the currently selected text as described in [`options.labels`](#labels). + +#### showLookUpSelection + +Type: `boolean`
+Default: `true` + +Show the `Look Up {selection}` menu item when right-clicking text on macOS. + #### showCopyImageAddress Type: `boolean`
@@ -102,27 +123,26 @@ Show the system `Services` submenu when right-clicking text on macOS. Note: Due to [a bug in the Electron implementation](https://github.com/electron/electron/issues/18476), this menu is not identical to the "Services" submenu in the context menus of native apps. Instead, it looks the same as the "Services" menu in the main App Menu. For this reason, it is currently disabled by default. -#### showLookUpSelection - -Type: `boolean`
-Default: `true` - -Show the `Look Up [selection]` menu item when right-clicking text on macOS. - #### labels Type: `Object`
Default: `{}` -Overwrite labels for the default menu items. Useful for i18n. +Override labels for the default menu items. Useful for i18n. + +The placeholder `{selection}` may be used in any label, and will be replaced by the currently selected text, trimmed to a maximum of 25 characters length. +This is useful when localizing the `Look Up “{selection}”` menu item, but can also be used in custom menu items – for example, to implement a `Search Google for “{selection}”` menu item. + +If there is no selection, the `{selection}` placeholder will be replaced by an empty string. Normally this placeholder is only useful for menu items which will only be shown when there is text selected. This can be checked using `visible: (params.selectionText.trim().length > 0)` when implementing a custom menu item, as shown in the usage example above. Format: ```js { labels: { - copy: 'Configured Copy', - saveImageAs: 'Configured Save Image As…' + copy: 'Copiar', + saveImageAs: 'Guardar imagen como…', + lookUpSelection: 'Consultar “{selection}”' } } ``` @@ -154,6 +174,8 @@ The function passed to this option is expected to return [`MenuItem[]`](https:// Even though you include an action, it will still only be shown/enabled when appropriate. For example, the `saveImage` action is only shown when right-clicking an image. +`MenuItem` labels may contain the the placeholder `{selection}` which will be replaced by the currently selected text as described in [`options.labels`](#labels). + The following options are ignored when `menu` is used: - `showLookUpSelection`