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

VWeb UI stops unexpectedly #77

Open
sainthasras opened this issue May 8, 2024 · 12 comments
Open

VWeb UI stops unexpectedly #77

sainthasras opened this issue May 8, 2024 · 12 comments

Comments

@sainthasras
Copy link

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.

@AlbertShown
Copy link
Contributor

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

@sainthasras
Copy link
Author

sainthasras commented May 8, 2024

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

@AlbertShown
Copy link
Contributor

@ttytm what do you think?

@ttytm
Copy link
Member

ttytm commented May 16, 2024

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

@sainthasras
Copy link
Author

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

@ttytm
Copy link
Member

ttytm commented May 16, 2024

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.

@AlbertShown
Copy link
Contributor

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
Copy link
Contributor

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

@ttytm
Copy link
Member

ttytm commented May 16, 2024

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?

@sainthasras
Copy link
Author

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.

@AlbertShown
Copy link
Contributor

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
Copy link
Contributor

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.

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

No branches or pull requests

3 participants