Skip to content

Commit

Permalink
Support rich text for Cut, Copy, and Paste items
Browse files Browse the repository at this point in the history
Fixes #92
  • Loading branch information
sindresorhus committed Feb 1, 2020
1 parent 1410532 commit 296ae9c
Show file tree
Hide file tree
Showing 5 changed files with 32 additions and 13 deletions.
3 changes: 3 additions & 0 deletions fixture.html
Expand Up @@ -26,5 +26,8 @@ <h1>Fixture</h1>
<br>
<a href="https://github.com">Link</a>
<webview id="webview" src="http://example.org">
<br>
<br>
<b>Copy <span style="color: hotPink">rich</span> text</b>
</body>
</html>
2 changes: 2 additions & 0 deletions index.d.ts
Expand Up @@ -72,6 +72,8 @@ declare namespace contextMenu {
interface ActionOptions {
/**
Apply a transformation to the content of the action.
If you use this on `cut`, `copy`, or `paste`, they will convert rich text to plain text.
*/
readonly transform?: (content: string) => string;
}
Expand Down
33 changes: 25 additions & 8 deletions index.js
Expand Up @@ -57,9 +57,14 @@ const create = (win, options) => {
enabled: can('Cut'),
visible: props.isEditable,
click(menuItem) {
props.selectionText = menuItem.transform ? menuItem.transform(props.selectionText) : props.selectionText;
electron.clipboard.writeText(props.selectionText);
webContents(win).delete();
const target = webContents(win);

if (!menuItem.transform && target) {
target.cut();
} else {
props.selectionText = menuItem.transform ? menuItem.transform(props.selectionText) : props.selectionText;
electron.clipboard.writeText(props.selectionText);
}
}
}),
copy: decorateMenuItem({
Expand All @@ -68,8 +73,14 @@ const create = (win, options) => {
enabled: can('Copy'),
visible: props.isEditable || hasText,
click(menuItem) {
props.selectionText = menuItem.transform ? menuItem.transform(props.selectionText) : props.selectionText;
electron.clipboard.writeText(props.selectionText);
const target = webContents(win);

if (!menuItem.transform && target) {
target.copy();
} else {
props.selectionText = menuItem.transform ? menuItem.transform(props.selectionText) : props.selectionText;
electron.clipboard.writeText(props.selectionText);
}
}
}),
paste: decorateMenuItem({
Expand All @@ -78,9 +89,15 @@ const create = (win, options) => {
enabled: editFlags.canPaste,
visible: props.isEditable,
click(menuItem) {
let clipboardContent = electron.clipboard.readText(props.selectionText);
clipboardContent = menuItem.transform ? menuItem.transform(clipboardContent) : clipboardContent;
webContents(win).insertText(clipboardContent);
const target = webContents(win);

if (menuItem.transform) {
let clipboardContent = electron.clipboard.readText(props.selectionText);
clipboardContent = menuItem.transform ? menuItem.transform(clipboardContent) : clipboardContent;
target.insertText(clipboardContent);
} else {
target.paste();
}
}
}),
saveImage: decorateMenuItem({
Expand Down
1 change: 1 addition & 0 deletions package.json
Expand Up @@ -4,6 +4,7 @@
"description": "Context menu for your Electron app",
"license": "MIT",
"repository": "sindresorhus/electron-context-menu",
"funding": "https://github.com/sponsors/sindresorhus",
"author": {
"name": "Sindre Sorhus",
"email": "sindresorhus@gmail.com",
Expand Down
6 changes: 1 addition & 5 deletions readme.md
Expand Up @@ -8,7 +8,6 @@ Electron doesn't have a built-in context menu. You're supposed to handle that yo

You can use this module directly in both the main and renderer process.


## Install

```
Expand All @@ -17,7 +16,6 @@ $ npm install electron-context-menu

*Requires Electron 4 or later.*


## Usage

```js
Expand Down Expand Up @@ -49,7 +47,6 @@ let mainWindow;
})();
```


## API

### contextMenu(options?)
Expand Down Expand Up @@ -174,7 +171,7 @@ Type: `Function`

This option lets you manually pick what menu items to include. It's meant for advanced needs. The default menu with the other options should be enough for most use-cases, and it ensures correct behavior, for example, correct order of menu items. So prefer the `append` and `prepend` option instead of `menu` whenever possible.

The function passed to this option is expected to return [`MenuItem[]`](https://electronjs.org/docs/api/menu-item/). The first argument the function receives is an array of default actions that can be used. These actions are functions that can take an object with a transform property (except for `separator` and `inspect`). The transform function will be passed the content of the action and can modify it if needed.
The function passed to this option is expected to return [`MenuItem[]`](https://electronjs.org/docs/api/menu-item/). The first argument the function receives is an array of default actions that can be used. These actions are functions that can take an object with a transform property (except for `separator` and `inspect`). The transform function will be passed the content of the action and can modify it if needed. If you use `transform` on `cut`, `copy`, or `paste`, they will convert rich text to plain text.

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.

Expand Down Expand Up @@ -231,7 +228,6 @@ Example:
}
```


## Related

- [electron-util](https://github.com/sindresorhus/electron-util) - Useful utilities for developing Electron apps and modules
Expand Down

0 comments on commit 296ae9c

Please sign in to comment.