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

Scripts Are Not Executed Correctly #3757

Open
mcmah309 opened this issue Feb 17, 2025 · 2 comments
Open

Scripts Are Not Executed Correctly #3757

mcmah309 opened this issue Feb 17, 2025 · 2 comments
Labels
bug Something isn't working

Comments

@mcmah309
Copy link

Problem

Scripts are not being executed correctly

Steps To Reproduce

e.g.

use dioxus::prelude::*;

fn main() {
    dioxus::launch(App);
}

#[component]
fn App() -> Element {
    rsx! {
        BugExample {}
    }
}

#[component]
pub fn BugExample() -> Element {
    let code = r#"
    use dioxus::prelude::*;

    #[component]
    pub fn Example()  -> Element {}
    "#;
    use_effect(|| {
        // document::eval("hljs.highlightAll();"); // Alternative, also does not work
    });
    rsx! {
        div {
            pre {
                code { class: "language-rust", {code} }
            }
            document::Script { {"hljs.highlightAll();"} }
            document::Script { src: "https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/languages/rust.min.js" }
            document::Script { src: "https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/highlight.min.js" }
            document::Link {
                href: "https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/styles/default.min.css",
                rel: "stylesheet",
            }
        }
    }
}

Results in

Uncaught ReferenceError: hljs is not defined
    at <anonymous>:1:1
    at createElementInHead (eval at <anonymous> (quaza_website-0acb08c20af679fe.js:5:25219), <anonymous>:5:254)
    at eval (eval at <anonymous> (quaza_website-0acb08c20af679fe.js:5:25219), <anonymous>:6:9)
    at eval (eval at <anonymous> (quaza_website-0acb08c20af679fe.js:5:25219), <anonymous>:7:7)
    at quaza_website-0acb08c20af679fe.js:5:5396
    at handleError (quaza_website-0acb08c20af679fe.js:4:727)
    at imports.wbg.__wbg_call_7cccdd69e0791ae2 (quaza_website-0acb08c20af679fe.js:5:5344)
    at quaza_website-ab75a3d067b9bc35.wasm.__wbg_call_7cccdd69e0791ae2 externref shim (quaza_website_bg-064fab76afa3a51b.wasm:0x10d100)
    at quaza_website-ab75a3d067b9bc35.wasm.js_sys::Function::call1::he541a474704b8a93 (quaza_website_bg-064fab76afa3a51b.wasm:0x104aa8)
    at quaza_website-ab75a3d067b9bc35.wasm.<dioxus_web::document::WebDocument as dioxus_document::document::Document>::eval::h0df3cb7e03d97a79 (quaza_website_bg-064fab76afa3a51b.wasm:0x1de38)

on web. And the formatting is not applied to the code block.

Running

hljs.highlightAll();

Directly in the console succeeds and the code block is formatted correctly.

Copying and pasting the html directly from the browser to a new html page and opening succeeds.

<html><head>
    <title>quaza_website</title>
    <meta content="text/html;charset=utf-8" http-equiv="Content-Type">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <meta charset="UTF-8">
  <link rel="preload" as="script" href="/./assets/quaza_website-51efad540bdeaf2e.js" crossorigin=""><link rel="preload" as="fetch" type="application/wasm" href="/./assets/quaza_website_bg-53f30410b95b57e0.wasm" crossorigin=""><link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/styles/default.min.css"><script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/highlight.min.js"></script><script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/languages/rust.min.js"></script><script>hljs.highlightAll();</script></head>
  <body>
    <div id="main" data-dioxus-id="0"><div><pre><code class="language-rust">
    use dioxus::prelude::*;

    #[component]
    pub fn Example()  -&gt; Element {}
    </code></pre><!--placeholder--><!--placeholder--><!--placeholder--><!--placeholder--></div></div>
  <script>
            // We can't use a module script here because we need to start the script immediately when streaming
            import("/./assets/quaza_website-51efad540bdeaf2e.js").then(
                ({ default: init }) => {
                init("/./assets/quaza_website_bg-53f30410b95b57e0.wasm").then((wasm) => {
                    if (wasm.__wbindgen_start == undefined) {
                    wasm.main();
                    }
                });
                }
            );
            </script>
            <style>
  /* Inter Font */
  @import url('https://fonts.googleapis.com/css2?family=Inter:wght@100..900&display=swap');

  #dx-toast-template {
    display: none;
    visibility: hidden;
  }

  .dx-toast {
    position: absolute;
    top: 10px;
    right: 0;
    padding-right: 10px;
    user-select: none;
    transition: transform 0.2s ease;
    z-index: 2147483647;
  }

  .dx-toast .dx-toast-inner {
    transition: right 0.2s ease-out;
    position: fixed;

    background-color: #181B20;
    color: #ffffff;
    font-family: "Inter", sans-serif;

    display: grid;
    grid-template-columns: auto auto;
    min-width: 280px;
    min-height: 92px;
    width: min-content;
    border-radius: 5px;

  }

  .dx-toast:hover {
    cursor: pointer;
    transform: translateX(-5px);
  }

  .dx-toast .dx-toast-level-bar-container {
    height: 100%;
    width: 6px;
  }

  .dx-toast .dx-toast-level-bar-container .dx-toast-level-bar {
    width: 100%;
    height: 100%;
    border-radius: 5px 0px 0px 5px;
  }

  .dx-toast .dx-toast-content {
    padding: 13px;
  }

  .dx-toast .dx-toast-header {
    display: flex;
    flex-direction: row;
    justify-content: start;
    align-items: end;
    margin-bottom: 13px;
  }

  .dx-toast .dx-toast-header>svg {
    height: 22px;
    margin-right: 5px;
  }

  .dx-toast .dx-toast-header .dx-toast-header-text {
    font-size: 16px;
    font-weight: 700;
    padding: 0;
    margin: 0;
  }

  .dx-toast .dx-toast-msg {
    font-size: 14px;
    font-weight: 400;
    padding: 0;
    margin: 0;
  }

  .dx-toast-level-bar.info {
    background-color: #428EFF;
  }

  .dx-toast-level-bar.success {
    background-color: #42FF65;
  }

  .dx-toast-level-bar.error {
    background-color: #FF4242;
  }
</style>

<div id="dx-toast-template" class="dx-toast">
  <div class="dx-toast-inner" style="right:-300px;">
    <!-- Level/Color decor -->
    <div class="dx-toast-level-bar-container">
      <div class="dx-toast-level-bar info"></div>
    </div>

    <!-- Content -->
    <div class="dx-toast-content">
      <!-- Header -->
      <div class="dx-toast-header">
        <!-- Dioxus Logo -->
        <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32" preserveAspectRatio="none">
          <path d="M22.158 1.783c0 3.077-.851 5.482-2.215 7.377s-3.32 3.557-5.447 5.33-4.425 3.657-6.252 6.195-3.102 5.515-3.102 9.532h4.699c0-3.077.853-5.377 2.217-7.272s3.32-3.557 5.447-5.33 4.425-3.657 6.252-6.195 3.102-5.62 3.102-9.637z" fill="#e96020"></path>
          <path d="M9.531 25.927c-.635 0-1.021.515-1.02 1.15s.385 1.151 1.02 1.15H22.47a1.151 1.151 0 1 0 0-2.301zm1.361-4.076c-.608 0-.954.558-.953 1.166s.346 1.035.953 1.035h10.217a1.101 1.101 0 1 0 0-2.201zm0-13.594a1.101 1.101 0 1 0 0 2.201h10.217c.607 0 .953-.598.953-1.205s-.345-.996-.953-.996zM9.531 4.021A1.15 1.15 0 0 0 8.38 5.17a1.15 1.15 0 0 0 1.15 1.15h12.94c.635 0 1.021-.498 1.02-1.133s-.386-1.166-1.02-1.166z" fill="#2d323b"></path>
          <path d="M5.142 1.783c0 4.016 1.275 7.099 3.102 9.637s4.125 4.422 6.252 6.195 4.083 3.656 5.447 5.551 2.215 3.974 2.215 7.051h4.701c0-4.016-1.275-7.038-3.102-9.576s-4.125-4.422-6.252-6.195-4.083-3.435-5.447-5.33S9.841 4.86 9.841 1.783z" fill="#00a8d6"></path>
        </svg>
        <!-- Toast Title Text -->
        <h3 class="dx-toast-header-text">Your app is being rebuilt.</h3>
      </div>

      <!-- Message -->
      <p class="dx-toast-msg">A non-hot-reloadable change occurred and we must rebuild.</p>
    </div>
  </div>
</div>

<script>
  const STORAGE_KEY = "SCHEDULED-DX-TOAST";
  let currentToast = null;
  let currentTimeout = null;

  // Show a toast, removing the previous one.
  function showDXToast(headerText, message, progressLevel, durationMs) {
    // Close current toast if exists.
    closeDXToast();

    // Clone template and add unique id.
    let toastTemplate = document.getElementById("dx-toast-template");
    let cloned = toastTemplate.cloneNode(true);
    let toastId = `dx-toast`;
    cloned.id = toastId;
    currentToast = cloned;

    let innerElem = currentToast.querySelector(`#${toastId} .dx-toast-inner`);

    // Set the progress level
    let progressBarElem = innerElem.querySelector(".dx-toast-inner .dx-toast-level-bar-container .dx-toast-level-bar");
    progressBarElem.className = `dx-toast-level-bar ${progressLevel}`;

    // Set header text
    let headerTextElem = innerElem.querySelector(".dx-toast-inner .dx-toast-header .dx-toast-header-text");
    headerTextElem.innerText = headerText;

    // Set message
    let messageElem = innerElem.querySelector(".dx-toast-inner .dx-toast-msg");
    messageElem.innerText = message;

    document.body.appendChild(currentToast);

    // Add listener to close toasts when clicked.
    // Safety: Calling `closeToast` removes the element and all event listeners with it.
    currentToast.addEventListener("click", closeDXToast);

    // Wait a bit of time so animation plays correctly.
    setTimeout(() => {
      innerElem.style.right = "0";

      currentTimeout = setTimeout(() => {
        closeDXToast();
      }, durationMs);
    }, 100);
  }

  // Schedule a toast to be displayed after reload.
  function scheduleDXToast(headerText, message, level, durationMs) {
    let data = {
      headerText,
      message,
      level,
      durationMs,
    };

    let jsonData = JSON.stringify(data);
    sessionStorage.setItem(STORAGE_KEY, jsonData);
  }

  // Close the current toast.
  function closeDXToast() {
    if (currentToast) {
      currentToast.remove();
    }
    clearTimeout(currentTimeout);
  }

  // Handle any scheduled toasts after reload.
  let potentialData = sessionStorage.getItem(STORAGE_KEY);
  if (potentialData) {
    sessionStorage.removeItem(STORAGE_KEY);
    let data = JSON.parse(potentialData);
    showDXToast(data.headerText, data.message, data.level, data.durationMs);
  }

</script>
            

</body></html>

Thus considering this and looking at the error. This is a Dioxus specific error.

Expected behavior

The formatted code block is displayed

Screenshots

Environment:

  • Dioxus version: 0.6.2
  • Rust version: 1.86.0 nightly
  • OS info: NixOS 25.05
  • App platform: web

Questionnaire

I'm interested in fixing this myself but don't know where to start.

@mcmah309 mcmah309 added the bug Something isn't working label Feb 17, 2025
@hackartists
Copy link
Contributor

@mcmah309 eval may not have access to some browser API.
As workaround, you can solve it by using script instead of use_effect.

rsx! {
    script { r#type: "module", "hljs.highlightAll();" }
}

@mcmah309
Copy link
Author

Thanks for the information.

eval may not have access to some browser API.

Is this behavior documented somewhere? If not, why does it only have access to some and which ones?

script { r#type: "module", "hljs.highlightAll();" }

Unfortunately this still results in a similar error:

Uncaught ReferenceError: hljs is not defined
    at <anonymous>:1:1
rust.min.js:28 Uncaught ReferenceError: hljs is not defined
    at rust.min.js:28:2
    at rust.min.js:28:35

But the raw html works fine if posted into regular .html file and loaded.

Note, in my original code I use:

document::Script { {"hljs.highlightAll();"} }

instead of use_effect, use_effect was commented out to show that is also does not work and has the same issue.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants