Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow for webviews to run service workers #194751

Open
IanMatthewHuff opened this issue Oct 3, 2023 · 4 comments
Open

Allow for webviews to run service workers #194751

IanMatthewHuff opened this issue Oct 3, 2023 · 4 comments
Assignees
Labels
feature-request Request for new features or functionality webview Webview issues
Milestone

Comments

@IanMatthewHuff
Copy link
Member

Our web extension is looking to allow for previewing HTML files in a VS Code webview in scenarios where the HTML file and content is hosted in local storage as opposed to hosted online. The target HTML is hosted in an iFrame inside a small wrapper main webview HTML.

To do this, we want to provide a service worker in our webview to intercept fetch calls so that our extension can handle the file requests and load and return the resources from local storage. However we've been unable to get a service worker hosted in a VS Code webview, both at the top level wrapper HTML and by trying to register it in the target hosted HTML.

When looking into service workers I believe that the following is true:

  1. Service Workers can't register with a data URL: Create service worker from Blob/String URL w3c/ServiceWorker#578 (which I believe is how web workers can work in a vscode webview)
  2. Service Workers need to match on origin: Is it possible to serve service workers from CDN/remote origin? w3c/ServiceWorker#940

So far the things that I've attempted I have all ended up essentially here:
image
I create an asWebviewUri pointing at the file of our service worker (which is added to a location accessible in localResourceRoots) but due to the origin difference the service worker can't be loaded, either here at the top level of the webview or in the iFrame hosted below.

Given what I've seen I don't think that what I'm looking to do is possible now, but if it could be enabled it would be very helpful for our scenario.

@mjbvz mjbvz self-assigned this Oct 3, 2023
@mjbvz
Copy link
Collaborator

mjbvz commented Oct 3, 2023

Have you tried using an iframe inside the webview pointing the a domain you control? That should allow service workers to be active inside of the iframe. This is essentially what we do to implement webviews

@IanMatthewHuff
Copy link
Member Author

Have you tried using an iframe inside the webview pointing the a domain you control? That should allow service workers to be active inside of the iframe. This is essentially what we do to implement webviews

I feel I might be missing something with what you are saying about about a domain that I control. My iframe knowledge is pretty scanty before starting with this so I may just be not understanding something basic.

In the situation we're looking at (with the possibility of being an offline scenario) there really isn't another domain that any thing is coming from other than the vscode-webview:// and the resource domains created by the webview URIs. Basically seems to me that at the top level HTML hosted by the webview my domain is always going to be vscode-webview://. With the iFrame that I host below that, I could try to set src to something else. But for our scenario we are not hitting an external domain, instead we are hosting a local workspace file. In this situation I've seen that src="" here doesn't actually resolve the webview URI. For an example below:
image
I've stuck an image with a webview uri src just above my iframe with a webview uri src (both files are present) and while the image resolves correctly the iframe doesn't resolve the webview uri src.

As such I've had to load the iframe source in the main webview hosting HTML and then set that to the iframe's srcdoc. Now this is the part that maybe I'm off on, but with srcdoc it seems like my origin is going to be either from a special unique origin or if I specify allow-same-origin on the sandbox I can inherit the same vscode-webview://. So I'm not sure how I could point that iFrame at a different domain or what domain I would use since we just have the webview and local content available here.

Apologies if I'm way off on any of the above and thanks for the reply.

@mjbvz
Copy link
Collaborator

mjbvz commented Oct 4, 2023

Maybe something like this:

  1. Inside your webview, add <iframe src="https://potentially-unique-subdomain.your-custom-domain.com"></iframe>
  2. Then at https://potentially-unique-subdomain.your-custom-domain.com, you host an html file with JS that your extension conrols
  3. This script can then register a service worker. This worker must be from a script that also lives under https://potentially-unique-subdomain.your-custom-domain.com

At this point the iframe contents are now controlled by the service worker. The iframe is also able to communicate back with its parent webview using post message

Then to load custom html inside of the iframe:

  1. Inside the iframe, use document.writeI() with the new html content
  2. This will replaces the current page contents while keeping the service worker active for the new contents

This does require hosting content at potentially-unique-subdomain.your-custom-domain.com but we also have to do this for vscode.dev too. The entire approach is actually very similar to how VS Code's webviews work. Unfortunately I don't think you can this without the external domain at this time

@IanMatthewHuff
Copy link
Member Author

IanMatthewHuff commented Oct 4, 2023

@mjbvz Thanks for the clarification. Yeah that external domain is what I thought you might have been suggesting. Right now our tool really is an online tool, but we've been trying to build around the possibility that we might deploy in learning environments (school / prisons, ect...) where adding in more domains to connect to might be restricted. So it's nice to know that with your suggestion we might have a reasonable option as long as we're ok with hosting it ourselves. We have plans to host student content for sharing at some point so we'll probably have to tackle that anyways.

One more small question, was this behavior expected?

I've stuck an image with a webview uri src just above my iframe with a webview uri src (both files are present) and while the image resolves correctly the iframe doesn't resolve the webview uri src.

It made sense to me that content hosted inside an iFrame would not be able to resolve webview URIs, but I was a bit surprised that the iFrame element itself couldn't resolve that, since I considered that element at the same level as the img.

@mjbvz mjbvz added feature-request Request for new features or functionality webview Webview issues labels Dec 4, 2023
@mjbvz mjbvz added this to the Backlog milestone Dec 4, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature-request Request for new features or functionality webview Webview issues
Projects
None yet
Development

No branches or pull requests

2 participants