Running Javascript in a HTML cell fails on first load

I have HTML that I want to display in a cell (this is actually getting returned by a Python object’s _repr_html_() method so that the object should get automatically displayed as HTML).

This works fine when I am in an open notebook and running the cell and the HTML output gets injected into the notebook.

However, it does NOT work when I then save the notebook, re-open the notebook and expect the cell to render properly again. Instead, the javascript I use as part of the HTML does not get executed properly.

The rough layout of my code is this:

<div>
  <!-- some HTML with IDs that get modified by javascript here -->
  <script src="https://unpkg.com/gatenlp-ann-viewer@1.0.11/gatenlp-ann-viewer.js"></script>
  <script type="text/javascript">
        gatenlp_run("WLLULVPGIX-");
    </script>
</div>

The second verbatim script block is supposed to invoke a function that gets defined in the file loaded from that url in the first script block.

But at the time of loading the page, when the second script block is executed, the function is not defined for some reason and in firefox I get the following error on the console:

Uncaught ReferenceError: gatenlp_run is not defined
    <anonymous> getting-started.ipynb line 2 > injectedScript:2
    jQuery 3
    _safe_append outputarea.js:459
    append_execute_result outputarea.js:498
    append_output outputarea.js:326
    fromJSON outputarea.js:1029
    fromJSON codecell.js:568
    fromJSON notebook.js:2671
    load_notebook_success notebook.js:3171
    i jQuery
getting-started.ipynb line 2 > injectedScript:2:9
    <anonymous> getting-started.ipynb line 2 > injectedScript:2
    jQuery 3
    _safe_append outputarea.js:459
    append_execute_result outputarea.js:498
    append_output outputarea.js:326
    fromJSON outputarea.js:1029
    fromJSON codecell.js:568
    fromJSON notebook.js:2671
    load_notebook_success notebook.js:3171
    i jQuery

Am I doing something wrong here?

You are bumping against the security features.

It sounds like you are seeing about it working when you run the cell is described here:

Any output generated during an interactive session is trusted.

Then you want to see the paragraph right above that for what happens when you try to open it again later after you saved it. See here for a brief, more conversational explanation of then why it doesn’t run when re-opened.

Have you tried setting the notebook to trusted before you saved it?
I don’t know where you are running your stuff but if you can set it to be trusted before reopening you can possibly get it to auto-run, see more discussion on the security discussion page. Also there is the init_cell extension mentioned here. If you are using MyBinder where you won’t have a database backing things because it is initialized for each session, see here, and my follow the link the example in update to my response. (Direct link showing the trust setting command here.)

Thank you, I was naively not even aware of all this!

But it must be something different because when I load the notebook it is marked as trusted already, even without explicitly setting the trust (which I also tried, just to be sure).

If this is still related to trust somehow, what exactly is going on?

What I absolutely do not understand is this: I have two <script> blocks in the injected HTML, and the error on the console looks as if the code in the first block did not get executed, so gatenlp_run is not know. But why then is the code in the second block getting executed?

If the code in the first block DOES get executed, why is gatenlp_run not known? I just do not get what is going on here. (I am not really a Javascript programmer though, just had to do this because nobody else did :slight_smile: )

What I see is this: I load the notebook and notice that the rendered output is missing. So I use Ctrl-SHift-I to go into the Browser’s debugger. The console log tells me that at some point, the gatenlp_run method was encountered but not know (this should have been run to render the output). But when I then enter gatenlp_run in the console, it IS known.

Is this something that is impossible to make work in principle or is it that I am just doing things the wrong way?

I did some more experiments with this and what I have found is this:

  • Even though the notebook is trusted when saving, and is shown to be trusted when loading, the javascript in the first block is either not run or the definitions in there are not available in the second block. The javascript in the first block is retrieved from the internet, the javascript in the second block is included directly
  • However, as soon as the notebook has finished loading, the javascript in the first block IS available. However, at that point the directly included code already failed.
  • when I change things so that the javascript in the first block is also included directly, this works when reloading the notebook.
  • I assume when I use some way to defer running the second block to after the document has been completely loaded, it should work with javascript from the internet in the first block as well? (have not tried this yet).

So: is there something special about loading javascript from the internet instead of it being present directly in a <script> block when it comes to the sequence of when each of these blocks is executed and the definitions become available?