microsoft / vscode

Visual Studio Code
https://code.visualstudio.com
MIT License
163.32k stars 28.9k forks source link

Some drag-and-drop interactions fail within iframe in extension's webview #147148

Closed protozoo closed 1 year ago

protozoo commented 2 years ago

Does this issue occur when all extensions are disabled?: Yes/No

Steps to Reproduce:

  1. Create a new vscode extension (or use one that you already have)
  2. Create a Webview that contains an HTML document with an iframe loading the GrapesJS demo (see example code below)
  3. Run the extension and webview to load the GrapesJS demo
  4. Try to drag a Grapes Block in the canvas

Further information

I am coding a vscode extension for enabling visual building of HTML pages, using GrapesJS framework. Grapesjs allows you, as a user, to compose web pages by dragging components ("blocks") from a library into your page, then editing properties, moving them around, arrangin layouts, etc... All of this works flawlesly in a web browser (have a quick look at their demo).

I am trying to use this inside a webview in a vscode extension, using an iframe. Most interactions work as expected, including dragging existing elements in the page to change their position. However, there's one particular (an important) interaction that fails when the application is used within the extension webview: dragging blocks from the right-side panel (the "library") to the web page. Looks like some drag events are being blocked.

I already opened an issue at GrapesJS repo but after investing quite many hours trying to debug the problem source, I strongly believe I need to look at the vscode side of my setup. My understanding is that HTML/JS content loaded in a webview's iframe is expected to behave as it would in a regular web browser (and, indeed, that's what happens with all other interactions in my app. They just work fine within the extension). But apparently vscode is blocking some events, or changing some other piece of the system, causing this problem to occur.

GrapesJS makes use of an iframe itself to host the content being edited, which means that my extension is dealing in this case with 2 levels of nested iframes. The first level is the iframe created directly in the webview, containing the GrapesJS instance. And then this GrapesJS instance contains itself another iframe for the edited contents. The failing interaction happens when dragging elements from the first-level iframe into the second one.

Here's a video showing the problem: https://www.protozoo.com/tests/grapesjs/vscode_extension_grapes.mov And here's a simplified code example (an actual vscode extension) to try it out: http://www.protozoo.com/tests/grapesjs/visualEditor_vscode_extension.zip

As a quick reference, here's how I'm creating the webview:

const vscode = require('vscode');

/**
 * @param {vscode.ExtensionContext} context
 */
function activate(context) {
    console.log('Congratulations, your extension "visualEditor" is now active!');
    let disposable = vscode.commands.registerCommand('visualeditor.openVisualEditor', function () {
        const panel = vscode.window.createWebviewPanel(
            'visualEditor',
            'Visual Editor',
            vscode.ViewColumn.One,
            {   enableScripts: true }
          );

          panel.webview.html = `<!DOCTYPE html>
          <html lang="en">
          <head>
              <meta charset="UTF-8">
              <meta name="viewport" content="width=device-width, initial-scale=1.0">
              <title>Visual Editor</title>
          </head>
          <body style="padding: 0 0px;">
              <iframe src="https://grapesjs.com/demo.html" style="position: fixed; width: 100%; height: 100%;">
            </iframe>
          </body>
          </html>`
    });

    context.subscriptions.push(disposable);
}

function deactivate() {}

module.exports = {
    activate,
    deactivate
}

Any solution or even just a hint on possible causes for this would be greatly appreciated. I.e. Is there any known caveat on using nested iframes within an extension's webview?

Many thanks.

mjbvz commented 2 years ago

Thanks for the sample

Have you tried seeing if this also happens outside of VS Code. Try creating a normal webpage with same html content and then see if you the see the same issue when testing it on Chrome

protozoo commented 2 years ago

Hi @mjbvz , thanks for the reply.

Yes, I tried outside VS Code with the same code and the error did not happen. It only happens in VS Code, using a webView. Here's the test running in case you want to try yourself: https://www.protozoo.com/tests/grapesjs/grapes_iframe.html

I opened this issue/discussion at the GrapesJS repo, where they indicated that the problem probably comes from VS Code capturing or blocking the iFrame's native drag and drop functionality. I checked the VS Code documentation but couldn't find anything relevant.

Does this give you any hint about where the problem may be happening and how to solve it?

Thanks!

mjbvz commented 2 years ago

Thanks for testing. A good starting point would be to create a minimal extension that demonstrates the issue. There are too many factors at play right now

You can build on the https://github.com/microsoft/vscode-extension-samples/tree/main/webview-sample for this

Try adding a minimal iframe inside the webview which demonstrates drag not working as expected

protozoo commented 2 years ago

Hi @mjbvz , thanks for the reply.

I think you missed the part in my initial post above where I mentioned I did actually build this "minimal extension" demonstrating the issue. The relevant part of the code is quoted there, and the complete code for the minimal extension can be found here.

Thanks again

protozoo commented 2 years ago

Hi again @mjbvz .

Did you have a chance to review the example code I provided?

Thanks!

mjbvz commented 2 years ago

Thanks for the example code. TBH I likely won't have time to investigate this myself but have marked it as help wanted

protozoo commented 2 years ago

Ok thanks

protozoo commented 2 years ago

Hello, is there any update on this? Last time I asked I was able to get my case working with a workaround (basically disabling the native draggable property of my element) but I am now in a different situation where this workaround won't work. Do you have any news about this issue? Thanks

vscodenpa commented 1 year ago

We closed this issue because we don't plan to address it in the foreseeable future. If you disagree and feel that this issue is crucial: we are happy to listen and to reconsider.

If you wonder what we are up to, please see our roadmap and issue reporting guidelines.

Thanks for your understanding, and happy coding!

protozoo commented 1 year ago

@mjbvz Honestly surprised this has been closed after 8 months since I posed the question/issue and, apparently, nobody looked into it despite me providing code examples and an elaborated description of the problem so it's easy to reproduce. I would appreciate someone having a look and giving some response, even if it doesn't include a solution but points to workarounds or suggestions on how to handle it. Thanks.

mjbvz commented 1 year ago

I looked into it and determined this is something we don't plan to address it in the foreseeable future. The rational is that it's been open eight months without any other user reports

protozoo commented 1 year ago

Thanks for the response and for looking into it. I guess mine is quite of an edge case, which makes it pretty difficult to troubleshoot. That said, I would appreciate any insight you got from looking into it.

hhc87 commented 1 year ago

In fact, I have encountered the same issue. The scenario is very similar to the situation described. In a webview, I accessed a special URL web1 through an iframe. This URL also contains another nested iframe. However, the drag and drop events in both iframes did not work. But there is one particular point, the issue was not present when accessing the web independently or using vscode on Windows, but it occurred in vscode on macOS.