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

Thoughts on shimming browseURL() #295

Open
ColinFay opened this issue Oct 13, 2023 · 3 comments
Open

Thoughts on shimming browseURL() #295

ColinFay opened this issue Oct 13, 2023 · 3 comments
Labels
feature New feature or request

Comments

@ColinFay
Copy link
Contributor

The browseURL() function defines :

url: a non-empty character string giving the URL to be loaded. Some platforms also accept file paths.

As far as I can tell, this can be shimmed via running JS code in the main thread.

# in webr
webr::browseURL(url)

Two case:

  • we want to browse an external URL
windows.open(url);
  • we want to browse a local HTML file
# write file from the R instance 
await webR.evalR('write("<h1>Hello world</h1>", "hello.html")');
const html = await webR.FS.readFile("/home/web_user/hello.html");
const html_content = new TextDecoder().decode(html);
var newWindow = window.open();
newWindow.document.write(html_content);

Possibly, we might start with supporting only remote URL (the helps says "Some platforms also accept file paths.", so I feel like this is ok to not support local file in a first time).

I'm not exactly sure how to send JS code from webr to be executed in the main thread, though, any help on how to do this would be awesome :)

Thanks

@georgestagg georgestagg added the feature New feature or request label Oct 31, 2023
@georgestagg
Copy link
Member

Yes, we will definitely want to handle utils::browseURL() at some point. I am unsure as of yet whether it's better to handle this through patching R's source or shimming using the webr package. If the implementation becomes complex, with several moving parts, it might be more elegant to patch R itself directly.

One issue I can think of is that if the local HTML file depends on other files on the VFS (e.g. scripts or images), those too would need to be transferred to the main thread for display. It would probably be possible to parse the HTML file in question to look for dependencies, but that might not be the best solution.

Making use of a JS Service Worker might be possible and prefereable. This is how Shinylive exposes a web server in the R process to the main thread. However, only one service worker can be active at a time for a particular origin, so such a method will need to be mindful of the existing webR Service Worker communication channel that may or may not already be running in the page.


I'm not exactly sure how to send JS code from webr to be executed in the main thread

The easiest way is probably through a custom webR channel message. Running the following in R:

webr::eval_js("chan.write({ type: 'myEvent', data: { mydata: 123 } })")

will cause a custom message to appear in webR.flush()/webR.read() on the main thread. This can be used to pass messages and information from the R process to be handled in the main thread JavaScript thread. This mechanism is how documentation display is handled, for example, in:

pager = function(files, header, title, delete.file) {
webr::eval_js(paste0(
"chan.write({",
" type: 'pager',",
" data: {",
" path: '", files[1], "',",
" header: '", header[1], "',",
" title: '", title, "',",
" deleteFile: ", if (delete.file) "true" else "false", ",",
" },",
"});"
))
invisible(NULL)
}
.

@seanbirchall
Copy link

seanbirchall commented Jan 13, 2024

+1 this would be super useful!

@georgestagg
Copy link
Member

With the infrastructure added by #449 the steps to implement this are now much more approachable:

  1. Create a new version of openHtmlInEditor() that takes a URL rather than the HTML source.

  2. Edit handleBrowseMessage() so as to handle URLs beginning with "http[s]://" with the new function in 1).

  3. Shim browseURL() similar to the other functions in shims.R.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature New feature or request
Projects
None yet
Development

No branches or pull requests

3 participants