vscode icon indicating copy to clipboard operation
vscode copied to clipboard

webview keep loading when postmeessage to it

Open asurance opened this issue 2 years ago • 1 comments

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

版本: 1.68.1 (Universal) 提交: 30d9c6cd9483b2cc586687151bcbcd635f373630 日期: 2022-06-14T12:52:13.188Z Electron: 17.4.7 Chromium: 98.0.4758.141 Node.js: 16.13.0 V8: 9.8.177.13-electron.0 OS: Darwin x64 21.6.0

Steps to Reproduce:

  1. registerCustomEditorProvider
  2. In resolveCustomEditor, enable enableScripts and set html of webview.
  3. postMessage to webview

Then webview keep loading. By skip step3, webview show normally

asurance avatar Sep 21 '22 11:09 asurance

Please share a minimal example extension that demonstrates the issue

Also make sure to test on the latest VS Code

mjbvz avatar Sep 21 '22 17:09 mjbvz

For some reason, I can't upload files or share link directly. Here are some information you may need.

const LockViewEditorViewType = "xieyuchao.lockViewer";
export function activate(context: ExtensionContext) {
  context.subscriptions.push(
    window.registerCustomEditorProvider(
      LockViewEditorViewType,
      new LockViewerEditor(),
      {
        supportsMultipleEditorsPerDocument: true,
      }
    )
  );
}
class NpmDocument implements CustomDocument {
  uri: Uri;

  constructor(uri: Uri) {
    this.uri = uri;
  }

  dispose(): void {
    // TODO
  }
}
class LockViewerEditor implements CustomReadonlyEditorProvider {
  openCustomDocument(
    uri: Uri,
    openContext: CustomDocumentOpenContext,
    token: CancellationToken
  ): CustomDocument | Thenable<CustomDocument> {
    return new NpmDocument(uri);
  }
  async resolveCustomEditor(
    document: NpmDocument,
    webviewPanel: WebviewPanel,
    token: CancellationToken
  ): Promise<void> {
    webviewPanel.webview.options = {
      enableScripts: true,
    };
    webviewPanel.webview.html = "test webview";
    console.log("ready to postMessage");
    const result = await webviewPanel.webview.postMessage({
      type: "lock",
      data: [],
    });
    console.log(`result: ${result}`);
  }
}

20220922095232_rec_ And webpack config

// Base.ts
export default {
  target: "node",
  entry: {
    index: resolve(__dirname, "../extension/index.ts"),
  },
  module: {
    rules: [
      {
        test: /\.ts$/,
        exclude: /node_modules/,
        use: [
          {
            loader: "babel-loader",
            options: {
              presets: ["@babel/preset-env", "@babel/preset-typescript"],
            },
          },
        ],
      },
    ],
  },
  externals: {
    vscode: "commonjs vscode",
  },
  resolve: {
    extensions: [".ts", ".js"],
  },
  output: {
    filename: "[name].js",
    path: resolve(__dirname, "../dist"),
    libraryTarget: "commonjs2",
    devtoolModuleFilenameTemplate: "../[resource-path]",
  },
} as Configuration;
// Dev.ts
const config = {
  mode: "development",
  devtool: "cheap-module-source-map",
} as Configuration;

export default Merge(Base, config);

If I remove codes about postMessage, it seems to be ok; 20220922095942_rec_

asurance avatar Sep 22 '22 02:09 asurance

I tried to update version, but the problem still exists 版本: 1.71.2 (Universal) 提交: 74b1f979648cc44d385a2286793c226e611f59e7 日期: 2022-09-14T21:05:37.721Z Electron: 19.0.12 Chromium: 102.0.5005.167 Node.js: 16.14.2 V8: 10.2.154.15-electron.0 OS: Darwin x64 21.6.0

asurance avatar Sep 22 '22 02:09 asurance

Thanks!

This is expected. You should not be awaiting on posting a message to the webview in resolveCustomEditor. resolveCustomEditor sets up the custom editor's webview. However the webview element itself (the iframe) is only created and shown to users after resolveCustomEditor returns

This means that the promise returned by the call to postMessage inside of resolveCustomEditor will not resolve until resolveCustomEditor returns. But resolveCustomEditor will never return until the awaited call to postMessage resolves. So you get a deadlock

The fix is not await any calls to postMessage inside resolveCustomEditor

mjbvz avatar Sep 23 '22 19:09 mjbvz