Vscode: [Plan Item] Propose new Webview API

Created on 15 Feb 2018  路  21Comments  路  Source: microsoft/vscode

Follow up on #41047 which explored improving the webview API. Part of #28263

This iteration we'd like to move the new API to be a fully documented proposed API and also self-host the markdown extension on the new API

on-testplan plan-item

Most helpful comment

As discussed, the WebView is not an editor but a UI-part that happens to be positioned like an editor but it must not be like that. Be prepared for showing web views in the bottom panel or as peek view

All 21 comments

Initial version of API taken into proposed with #42690

Proposed API changes for next iteration:

  • Add a Webview.viewColum property: readonly viewColumn?: ViewColumn;.

  • Rename WebviewOptions.keepAlive to make it more clear what this property actually does

  • Rename Webview.onMessage per https://github.com/Microsoft/vscode/issues/28263#issuecomment-366036703

  • Move from Webview.onDidBecomeActive/Webview.onDidBecomeInactive to an API closer to window.onDidChangeActiveTextEditor. Current proposal: window.onDidChangeActiveWebview. Would be fired with undefined when a user switches to a normal text editor. Also would be fired when a webview changes columns.

// cc @ivankravets @eamodio @pavelfeldman

Deleted the comment, was using localstorage, don't need it as I can persist the webview.
馃憤

@mjbvz Do we have an event for when a webview is closed?
Is there a way to determine whether a particular webview was closed?

Currently when using ContentProvider (via registerTextDocumentContentProvider), VSCode manages this for us with a one-to-one relationship between a URI and a window. I.e. if the window is closed and we open it again using the previewHtml, VS Code will open a new window, where as if the window isn't closed VS Code will merely activate the existing window.

With this new api, I have no way of determining whether the WebView has been closed or not and whether we need to create a new WebView for display.

Can we have API for icon/favicon of the webview?

@DonJayamanne Just sent out a new proposal that introduces an onDispose event on the webview: #44307

This PR introduces a different model for webviews. There is now a 1:1 correspondence between webviews and "webview editors". Previously, users could split webview editors, resulting in two different webview editors both backed by the same model. This is no longer possible

@mjbvz Thanks for the feature, really appreciated.

Now, in my 3D Viewer extension, I'm trying to reference files both from vscode-extension-resource (javascript and png files) and vscode-workspace-resource (a 3D model to display), but get the following error in the Webview Developer Tools

three.js:30777 XMLHttpRequest cannot load vscode-workspace-resource:/Users/slevesque/Documents/Projects/three.js/examples/models/collada/elf/elf.dae. Cross origin requests are only supported for protocol schemes: http, data, chrome, https.

I need to set the base href to vscode-extension-resource in order to load javascript and png files, and that part works fine. But it seems impossible afterward to load workspace assets from javascript code.

Any way to authorize cross reference between vscode-extension-resource and vscode-workspace-resource ?

Thanks all for the feedback! A few initial proposed changes for this month:

  • Rename Webview to WebviewEditor to make it clear that it is an editor
  • Merge vscode-extension-resource and vscode-workspace-resource schemes into vscode-resource. This should solve the cross origin problem @stef-levesque noted.
  • Add option to enable find in the webview. (should find be on or off by default?)
  • Move onDidChangeViewColumn to be a global event

This is just a first set of proposed tweaks. We'll keep refining the API throughout the month. Let me know if you have any other suggestions or feedback

Beyond webview 1.0, I'm also thinking about how the API may be able support a few additional cases:

  • Restoration, i.e. when vs code closes and then reopens, we restore the opened webviews automatically. Using resources uris for this would probably make the most sense. This ironically would be very similar to TextDocumentContentProvider which webview seeks to replace.

  • Splitting. Currently this is not supported. I think it could be added to the existing api pretty easily however.

  • Icons. Also would be easy to add to the API. Not sure if we want to allow these to be themed by an extension however

No commitment on these, but I think it is good to think about how these features would play with the currently proposed API

/cc @jrieken

What percentage of the VSCode userbase uses the latest VSCode version? One thing I'm worried about with switching to the new webview is that users of older vscode versions will no longer be able to use my extension.

Rename Webview to WebviewEditor to make it clear that it is an editor

馃憥

Please explain

As discussed, the WebView is not an editor but a UI-part that happens to be positioned like an editor but it must not be like that. Be prepared for showing web views in the bottom panel or as peek view

馃 maybe even in the sidebar as its own activity? 馃槈 馃檹

@jrieken Our commitment here is getting a better webview api for editors and I do not think we agreed to support webviews other contexts. I see a few options on updating the API to future proof it for such without blocking the original goal:

  • Rename Webview to WebviewEditor. This gives us room to later introduce a new Webview that can be used in other UI contexts. This is the easiest

  • Try to make the current Webview interface more generic. We still would need the concept of a WebviewEditor however for events such as onDidChangeActiveEditor (or we would need to seriously rethink those) so this ends up being very similar to the next proposal.

  • Split the concept of a webview out of the existing Webview (which would renamed to WebviewEditor).

export interface Webview {
    title: string;

    html: string;

    readonly onDidReceiveMessage: Event<any>;

    postMessage(message: any): Thenable<boolean>;

    ...
}

export interface WebviewEditor {
    readonly viewColumn?: ViewColumn;

    readonly webview: Webview;

    ...
}

If we go with something like the third approach, I'd be interested in exploring a webview editor API that is more like TextDocumentContentProvider but without the baggage of a text model:

interface ContentProvider {
     provideContent(uri: Uri, token: CancellationToken): Webview;
}

function registerContentProvider(scheme: string, provider: ContentProvider): Disposable

as this would let us implement restoration.

do not think we agreed to support webviews other contexts

I don't think agreement is need here but projecting what will happen in the future. The request for webviews everywhere will come (if it's not already there), we can ignore it for a while, and then we'll implement it. Knowing that, we should design for it which means don't plan for deprecation nor duplication.

This gives us room to later introduce a new Webview that can be used in other UI contexts. This is the easiest

That's planning for duplication.

e still would need the concept of a WebviewEditor however for events such as onDidChangeActiveEditor (or we would need to seriously rethink those) so this ends up being very similar to the next proposal.

I might be missing something but I believe we need activeTextEditor, activeWebview, activeTreeView, activeTerminal etc. We can do that, plus all events and the enumerable types of all xyz-views. Or we come up with something more generic, like a part which is one of the pieces, e.g. type UiPart = TextEditor | WebView | TreeView | any. With that would come one event and one enumerable type, ala parts: UiPart[] and onDidChangeActivePart: Event<UiPart>. These are early ideas which need harding but I think it's the better approach.

webview editor API that is more like TextDocumentContentProvider but without the baggage of a text mode

Interesting. It would be similar to the pull model the tree view is using. I have discussed something similar with @sandy081 today because tree views started with the pull model (data provider) and are now mutating into a push model

Just for reference the request for webviews in other contexts does already exist: https://github.com/Microsoft/vscode/issues/43049 (there are probably other requests as well) and TBH I have a very real need for that support (a webview in at least the sidebar or panel) for a new extension I'm working on.

@mjbvz Is there a way to focus a webview when its already visible? The reveal method only seems to focus if the panel isn't already in the requested column.

This is what reveal should do. Are you on insiders?

Yeah today's. It will focus it if it changes viewcolumns but if it is already in col 3 but another tab in col 1 or 2 is focused and I reveal to col 3 it doesn't focus it

Can you open an new issue. Also are you calling it with the view column: .reveal(webview.viewColumn)?

Out right now but will do when I get back. Basically. .reveal(ViewColumn.Three) when webview.viewColumn is also 3

Was this page helpful?
0 / 5 - 0 ratings

Related issues

Brakkar picture Brakkar  路  364Comments

hsdk123 picture hsdk123  路  263Comments

TurkeyMan picture TurkeyMan  路  411Comments

Tyriar picture Tyriar  路  200Comments

ghost picture ghost  路  234Comments