VWeb UI stops unexpectedly
I am on a Windows operating system. I have tried using vegalite.js in my application. Everything works fine, until I click Save as SVG menu item near the plots. VWeb UI will then close, and the application breaks.
We may need more details, please give us the code you are using, and logs also will be useful.
Kindly find below the code I have. Thank you.
import vwebui as ui
const html = '<!DOCTYPE html>
<html lang="en">
<head>
<script src="https://cdn.jsdelivr.net/npm/[email protected]"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]"></script>
<script src="webui.js" defer></script>
</head>
<body>
<a href="https://www.w3schools.com" target="_blank">Visit W3Schools.com!</a>
<p>My First plot</p>
<br>
<div id="vis"></div>
<script>
let FirstPlot = {
\$schema: "https://vega.github.io/schema/vega-lite/v5.json",
data: {
values: [
{Languages: "Python", Values: 2},
{Languages: "Python", Values: 3},
{Languages: "Python", Values: 2},
{Languages: "JavaScript", Values: 4},
{Languages: "Perl", Values: 2} ]
},
mark: "bar",
encoding: {
x: {field: "Values", type: "quantitative"},
y: {field: "Languages", type: "ordinal"}
}
};
vegaEmbed("#vis", FirstPlot);
</script>
</body>
</html>'
w := ui.new_window()
w.show_browser(html, .chrome)!
ui.wait()
@ttytm what do you think?
@AlbertShown Upon investigation, imho, the problem relates less to using webui, but more to using the vega-embed CDN script. For example, the same problem occurs with the original webui library.
webui C code
#include "webui.h"
int main() {
const char *html = "<!DOCTYPE html>"
"<html>"
" <head>"
" <script src=\"https://cdn.jsdelivr.net/npm/[email protected]\"></script>"
" <script src=\"https://cdn.jsdelivr.net/npm/[email protected]\"></script>"
" <script src=\"https://cdn.jsdelivr.net/npm/[email protected]\"></script>"
" <script src=\"webui.js\"></script>"
" </head>"
" <body>"
" <a href=\"https://www.w3schools.com\" target=\"_blank\">Visit W3Schools.com!</a>"
" <p>My First plot</p>"
" <br>"
" <div id=\"vis\"></div>"
" <script>"
" let FirstPlot = {"
" $schema: \"https://vega.github.io/schema/vega-lite/v5.json\","
" data: {"
" values: ["
" {Languages: \"Python\", Values: 2},"
" {Languages: \"Python\", Values: 3},"
" {Languages: \"Python\", Values: 2},"
" {Languages: \"JavaScript\", Values: 4},"
" {Languages: \"Perl\", Values: 2} ]"
" },"
" mark: \"bar\","
" encoding: {"
" x: {field: \"Values\", type: \"quantitative\"},"
" y: {field: \"Languages\", type: \"ordinal\"}"
""
" }"
" };"
" vegaEmbed(\"#vis\", FirstPlot);"
" </script>"
"</body>"
"</html>";
size_t w = webui_new_window();
webui_show(w, html);
webui_wait();
webui_clean();
return 0;
}
The error could be handled more gracefully though instead of crashing. For example, with webview, the 'Save as SVG' menu item doesn't work, but it doesn't crash.
webview V code
import ttytm.webview as ui
const html = '<!DOCTYPE html>
<html lang="en">
<head>
<script src="https://cdn.jsdelivr.net/npm/[email protected]"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]"></script>
</head>
<body>
<a href="https://www.w3schools.com" target="_blank">Visit W3Schools.com!</a>
<p>My First plot</p>
<br>
<div id="vis"></div>
<script>
let FirstPlot = {
\$schema: "https://vega.github.io/schema/vega-lite/v5.json",
data: {
values: [
{Languages: "Python", Values: 2},
{Languages: "Python", Values: 3},
{Languages: "Python", Values: 2},
{Languages: "JavaScript", Values: 4},
{Languages: "Perl", Values: 2} ]
},
mark: "bar",
encoding: {
x: {field: "Values", type: "quantitative"},
y: {field: "Languages", type: "ordinal"}
}
};
vegaEmbed("#vis", FirstPlot);
</script>
</body>
</html>'
w := ui.create(debug: true)
w.set_size(600, 400, .@none)
w.set_html(html)
w.run()
To my current knowledge it's hard to tell the real source of the issue. Personally, I won't dig into it. Something you could try @sainthasras is using the vega-embed not as cdn script and debug there.
I will try as suggested. Thank you....very grateful.
Realizing that the plot SVGs are saved in my Downloads directory after all, I see that with V webview the files are saved when clicking Save as SVG.
So for webui (unrelated to its V wrapper) we would need to investigate why webui is crashing when there there is this call to the download.
Thank you @ttytm for your test, what you explained is already enough to point to the right direction.
In my side, I did a quick test using the debug version of webui, seems the lib does not crash, but simply disconnect after a Blob re-direction (URL navigation) as webui.js does not exit.
_webui_server_thread([1]) -> Window Connected.
...
[Core] [Thread 2] _webui_receive_thread() -> WebSocket Closed
...
[Core] WebUI exit successfully.
Web Browser Logs:
WebUI -> Connected
webui.js:180 WebUI -> Close -> Navigation to [blob:http://localhost:17764/51da1c5f-0ac3-4e4c-8ba2-47569dc14898]
webui.js:186 WebUI -> Close.
webui.js:274 WebUI -> Connection lost (1006)
Navigated to blob:http://localhost:17764/51da1c5f-0ac3-4e4c-8ba2-47569dc14898
Oh yes, crash is the wrong term here. Do you have an opinion on whether there should be a handling other than closing a connection when navigating to a URL that doesn't embed webui.js?
It really feels good when one realizes their problems are being given all the necessary attention they require. I must also say, crash is the wrong term (maybe because of the way I presented the problem). The application does not crash, just that it disconnects. Thank you once again for the effort you are putting in to resolve this.
Do you have an opinion on whether there should be a handling other than closing a connection when navigating to a URL that doesn't embed webui.js?
Normally, webui_wait() will simply return, and all window resources are still available, so the user can show again the window if needed. The exit of the program is done by the user main code, not webui.
Another thing, is that it's hard to accurately distinguish between a webui.js disconnection because of a normal window close, and a re-direction like in this example, so webui_wait() should always return when there is no more webui.js running.
In the other hand, I see some potential solutions:
- Simply develop a UI that have at least one window with
webui.js - User should handle the links using
bind("")andWEBUI_EVENT_NAVIGATION - Open a pop-up window for external links
- Webui should find a clever way to auto inject
webui.jsin all links in all browsers
About bind("") and WEBUI_EVENT_NAVIGATION, I guess in this particular example where links are blob:http://..., I don't know if even possible to detect it using JavaScript or not... need to be tested.