Context-Menu COPY is not working in vscode webview, BUT ctrl+c is working fine

Viewed 294

We are developing an vscode extension with webview. In the webview, we are performing below steps

  1. Select the text
  2. Right Click
  3. Cut+Copy+Paste context menu appears
  4. Click on Copy

Webview Default Context-Menu Screenshot

  • Expected Result: Text should be copied to clipboard
  • Actual Result: Text is not getting copied.

Note: Instead of using Context Menu, if we just press Ctrl+C, the text is actually getting copied.

Debug Result

We have debugged further and found the one difference between Ctrl+C key-press and clicking COPY from context-menu in editorExtensions.ts file.

For, Ctrl+C, webview implementation is returning TRUE

Ctrl+C implementation object Screenshot

for COPY, generic-dom implementation is returning TRUE

Context Menu COPY implementation object Screenshot

    public runCommand(accessor: ServicesAccessor, args: any): void | Promise<void> {
        const logService = accessor.get(ILogService);
        logService.trace(`Executing Command '${this.id}' which has ${this._implementations.length} bound.`);
        for (const impl of this._implementations) {
            const result = impl.implementation(accessor, args);
            if (result) {
                logService.trace(`Command '${this.id}' was handled by '${impl.name}'.`);
                if (typeof result === 'boolean') {
                    return;
                }
                return result;
            }
        }
        logService.trace(`The Command '${this.id}' was not handled by any implementation.`);
    }

So, we need help to

  • Find the reason why COPY context menu is not working and how to make it work
  • How to make CUT/PASTE context menu disabled/grey-out
1 Answers

Visual Studio Code 1.70 should offer fully custom context menus according to its release note that's hard to fully copy from its webview due to this issue.

Webview context menus

The new webview context menu proposal makes it easy for advanced webviews to customize the context menus that shows when a user right-clicks inside a webview. This new contribution point uses VS Code's normal context menus, so custom menus fit right in with the rest of the editor. Webviews can also show custom context menus for different sections of the webview.

To try out this new API, you need to enable the contribWebviewContext proposal.

"enabledApiProposals": [
  "contribWebviewContext"
]

To add a new context menu item to your webview, add a new entry in menus under the new webview/context section. Each contribution takes a command (which is also where the title comes from) and a when clause. The when clause should include webview == 'YOUR_WEBVIEW_VIEW_TYPE' to make sure the context menus only apply to your extension's webviews:

"contributes": {
  "menus": {
    "webview/context": [
      {
        "command": "catCoding.yarn",
        "when": "webview == 'catCoding'"
      },
      {
        "command": "catCoding.insertLion",
        "when": "webview == 'catCoding' && webviewSection == 'editor'"
      }
    ]
  },
  "commands": [
    {
      "command": "catCoding.yarn",
      "title": "Yarn ",
      "category": "Cat Coding"
    },
    {
      "command": "catCoding.insertLion",
      "title": "Insert ",
      "category": "Cat Coding"
    },
    ...
  ]
}

Inside of the webview, you can also set the contexts for specific areas of the HTML using the data-vscode-context data attribute (or in JavaScript with dataset.vscodeContext). The data-vscode-context value is a JSON object that specifies the contexts to set when the user right-clicks on the element. The final context is determined by going from the document root to the element that was clicked.

Consider this HTML for example:

<div class="main" data-vscode-context='{"webviewSection": "main", "mouseCount": 4}'>
  <h1>Cat Coding</h1>

  <textarea data-vscode-context='{"webviewSection": "editor", "preventDefaultContextMenuItems": true}'></textarea>
</div>

If the users right-clicks on the textarea, the following contexts will be set:

  • webviewSection == 'editor' — This overrides webviewSection from the parent element.
  • mouseCount == 4 — This is inherited from the parent element.
  • preventDefaultContextMenuItems == true — This is a special context that hides the copy and paste entries that VS Code normally adds to webview context menus.

If the user right-clicks inside of the <textarea>, they will see:

Custom context menus showing in a webview

Commands editor.action.clipboardCopyAction and editor.action.clipboardCutAction should work. Perhaps unbound cut and default:cut are currently broken, but I don't see their copy versions in Keyboard Shortcuts, which do still work in the webview.

Related