v-webui icon indicating copy to clipboard operation
v-webui copied to clipboard

VWeb UI stops unexpectedly

Open sainthasras opened this issue 1 year ago • 12 comments

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.

sainthasras avatar May 08 '24 06:05 sainthasras

We may need more details, please give us the code you are using, and logs also will be useful.

AlbertShown avatar May 08 '24 16:05 AlbertShown

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()

sainthasras avatar May 08 '24 21:05 sainthasras

@ttytm what do you think?

AlbertShown avatar May 09 '24 20:05 AlbertShown

@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.

ttytm avatar May 16 '24 07:05 ttytm

I will try as suggested. Thank you....very grateful.

sainthasras avatar May 16 '24 10:05 sainthasras

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.

ttytm avatar May 16 '24 11:05 ttytm

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.

AlbertShown avatar May 16 '24 13:05 AlbertShown

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

AlbertShown avatar May 16 '24 13:05 AlbertShown

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?

ttytm avatar May 16 '24 13:05 ttytm

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.

sainthasras avatar May 16 '24 13:05 sainthasras

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:

  1. Simply develop a UI that have at least one window with webui.js
  2. User should handle the links using bind("") and WEBUI_EVENT_NAVIGATION
  3. Open a pop-up window for external links
  4. Webui should find a clever way to auto inject webui.js in all links in all browsers

AlbertShown avatar May 16 '24 14:05 AlbertShown

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.

AlbertShown avatar May 16 '24 14:05 AlbertShown