Reputation: 55
vscode.previewHtml
got deprecatd in favour of Webview.
I updated my ahk extension for vscode using this new API.
With hh.exe -decompile Docs AutoHotkey.chm
I got a local website version of the main AutoHotkey site.
I wanted to show in the second column a contextual docs so you can read about it while coding. So I did.
I successfully managed to load the page with the stylesheet,
but the links don't work : I stay always on the same page.
Even if I can alter theire href I'm not able to go to another page.
Althought you can read in tooltip the href value, every time you click on a link nothing happens.
The Docs folder is stored inside the extension path, so the localResourceRoots
should be fine.
A strange thing that i noted is that even with enableScripts
is set to true, it seems that not all the js code is executed, because on the AutoHotkey webSite, in the .chm and in every .html files opened with FF I can see the sidebar, but not in the WebView page.
This is the code for creating the WebView:
this.docsPanel = vscode.window.createWebviewPanel('ahk-offline-docs', 'Documentation', { viewColumn: vscode.ViewColumn.Two, preserveFocus: true }, {
enableScripts: true,
enableFindWidget: true,
enableCommandUris: true,
localResourceRoots: [vscode.Uri.file(path.join(this.docsDirectoryPath, 'docs//')).with({ scheme: 'vscode-resource' })]
});
this.docsPanel.onDidDispose((e) => {
this.isDocsPanelDisposed = true;
});
And this is the code that loads the page into the WebView:
let url = vscode.Uri.file(path.join(this.docsDirectoryPath, 'docs/')).with({ scheme: 'vscode-resource' });
const dom = new JSDOM(data, { runScripts: "dangerously" });
const aTags = dom.window.document.getElementsByTagName('a');
const len = aTags.length;
const basePath = url.toString();
for (let i = 0; i < len; i++) {
const a = aTags[i];
if (!a.href.includes('about:blank')) {
const commentCommandUri = vscode.Uri.parse(`command:ahk.spy`);
a.href = basePath + a.href;
// a.removeAttribute('href');
// a.setAttribute('onclick', '{command:ahk.spy}');
}
}
let ser = dom.serialize();
this.docsPanel.webview.html = /*data/*ser*/ser.toString().replace('<head>', `<head>\n<base href="${url.toString()}/">`);
An alternative idea was to launch vscode.commands from the page (because of enableCommandUris
) but I didn't get how to do this kind of operation.
If you need/want to reproduce this issue you just have to clone the repo, going into the improving-offline-docs
branch and open the file offline-docs-manager.ts
, the method is openTheDocsPanel()
Is there a way to switch the current page using links ? Should I develop a postMessage system ? or I missed a settings somewhere ? or is there an even better way for doing it ?
Thanks in advance !
Upvotes: 3
Views: 3155
Reputation: 65663
Webviews can not navigate to another page inside the current webview. If your webview tries to do so, you should see a message such as prevented webview navigation
inside the webview developer tools
There are two ways to handle links in webviews:
<a>
elements that link to external resource—such a https:
or mailto:
links—should work in most cases. There may be a few weird edge cases, and if you run into one of these you'd want to use either a command
uri or postMessage
to trigger some action in your main extension's source
If you want to update the webview content itself and cannot do this within the webview itself for some reasons, use either a command
uri or postMessage
to call some function in your main extension's source that update's the webview's html
Upvotes: 4