n-riesco / ijavascript

IJavascript is a javascript kernel for the Jupyter notebook
Other
2.19k stars 185 forks source link

[requirejs] Unable to load library with Jupyter Notebook #272

Open ina6ra opened 2 years ago

ina6ra commented 2 years ago

The following code works in JupyterLab but not in Jupyter Notebook.

$$.html(`
<head>
  <script src='https://cdn.jsdelivr.net/npm/jquery/dist/jquery.min.js'></script>
  <script src='https://cdn.jsdelivr.net/npm/sweetalert2@11.4.9/dist/sweetalert2.min.js'></script>
  <link rel='stylesheet' href='https://cdn.jsdelivr.net/npm/sweetalert2@11.4.9/dist/sweetalert2.min.css'>
  <script>
  $(document).ready(() => {
    $('button').on('click', () => {
      Swal.fire('Click!');
    });
  });
  </script>
</head>
<body>
<p><button type='button'>Open Alert</button></p>
</body>
`);

SweetAlert2 works when opened in JupyterLab http://my-ip-address:port/lab/tree/Untitled.ipynb

Doesn't work with Jupyter Notebook http://my-ip-address:port/notebooks/Untitled.ipynb

The Chrome DevTools Console Panel shows an error.

Uncaught ReferenceError: Swal is not defined
    at HTMLButtonElement.<anonymous> (<anonymous>:4:7)

Please tell me how to resolve.

It is the operating environment. I building a Miniconda3 environment with priority given to the conda-forge channel.

$ lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description:    Ubuntu 20.04.4 LTS
Release:        20.04
Codename:       focal
$ conda --version
conda 4.12.0
$ conda config --show channels
channels:
  - conda-forge
  - defaults
$ conda list
jupyter_client            7.3.0              pyhd8ed1ab_0    conda-forge
jupyter_core              4.9.2            py38h578d9bd_0    conda-forge
jupyter_server            1.17.0             pyhd8ed1ab_0    conda-forge
jupyterlab                3.3.4              pyhd8ed1ab_0    conda-forge
jupyterlab_pygments       0.2.2              pyhd8ed1ab_0    conda-forge
jupyterlab_server         2.13.0             pyhd8ed1ab_1    conda-forge
nodejs                    17.9.0               h96d913c_0    conda-forge
pip                       22.0.4             pyhd8ed1ab_0    conda-forge
python                    3.8.13          h582c2e5_0_cpython    conda-forge
(and more)
$ npm -v
8.7.0
$ ijsnotebook --version
5.2.1
$ cat /home/username/jupyter/jupyter_lab_config.py
import os
os.environ['PATH'] += ':/home/username/miniconda3/bin'
os.environ['PATH'] += ':/home/username/miniconda3/envs/myenv/bin'
c.ServerApp.ip = '0.0.0.0'
c.ServerApp.port = XXXX
c.ServerApp.token = '<generated>'
c.ServerApp.allow_remote_access = True
c.ServerApp.root_dir = '/home/username/jupyter'
(and more)
$ sudo cat /etc/systemd/system/jupyter.service
[Unit]
Description=Jupyter
[Service]
Type=simple
WorkingDirectory=/home/username/jupyter
ExecStart=/home/username/miniconda3/envs/myenv/bin/jupyter-lab
User=username
Group=username
[Install]
WantedBy=multi-user.target
ina6ra commented 2 years ago

I was able to solve myself by using requirejs. Thanks.

$$.html(`
<head>
  <link rel='stylesheet' href='https://cdn.jsdelivr.net/npm/sweetalert2@11.4.9/dist/sweetalert2.min.css'>
  <script>
  requirejs.config({
    paths: {
      'Swal': ['https://cdn.jsdelivr.net/npm/sweetalert2@11.4.9/dist/sweetalert2.min'],
    },
  });
  $(document).ready(() => {
    $('button').on('click', () => {
      require(['Swal'], (Swal) => {
        Swal.fire('Click!');
      });
    });
  });
  </script>
</head>
<body>
<p><button type='button'>Open Alert</button></p>
</body>
`);
ina6ra commented 2 years ago

It worked without changing the original code by registering it in the window object after loading the document.

$$.html(`
<head>
  <link rel='stylesheet' href='https://cdn.jsdelivr.net/npm/sweetalert2@11.4.9/dist/sweetalert2.min.css'>
  <script>
  requirejs.config({
    paths: {
      'Swal': ['https://cdn.jsdelivr.net/npm/sweetalert2@11.4.9/dist/sweetalert2.min'],
    },
  });
  $(document).ready(() => {
    require(['Swal'], (Swal) => {
      window.Swal = Swal;
    });
    $('button').on('click', () => {
      Swal.fire('Click!');
    });
  });
  </script>
</head>
<body>
<p><button type='button'>Open Alert</button></p>
</body>
`);
n-riesco commented 2 years ago

@ina6ra Thank you for posting this. I'm sure iJavascript users will find it useful.

ina6ra commented 2 years ago

@n-riesco Thanks. I hope it helps someone.

I was able to solve this problem but another problem arose. I cannot paste in the input field displayed in the alert. Can be copied and cut.

As with the previous problem, the problem only happens with Jupyter Notebook. Rewriting to python code doesn't help.

import IPython
display(IPython.core.display.HTML('''
  <head>
    <link rel='stylesheet' href='https://cdn.jsdelivr.net/npm/sweetalert2@11.4.9/dist/sweetalert2.min.css'>
    <script>
    requirejs.config({
      paths: {
        'Swal': 'https://cdn.jsdelivr.net/npm/sweetalert2@11.4.9/dist/sweetalert2.min',
      },
    });
    $(document).ready(() => {
      require(['Swal'], (Swal) => {
        window.Swal = Swal;
      });
      $('button').on('click', () => {
        Swal.fire({
          title: 'Click!',
          html: '<input class="test" size=5 value="test" />',
        });
      });
    });
    </script>
  </head>
  <body>
  <p><button type='button'>Open Alert</button></p>
  </body>
'''))

It worked on Android Chrome, so I changed the browser on my PC and it worked on Firefox. Edge doesn't work either, so it doesn't seem to work on Chromium-based browsers.

If I run the same code in Google Colaboratory it works in all browsers, so it seems to be a problem specific to Jupyter Notebook.

n-riesco commented 2 years ago

There are many ways to prevent copy. The DOM inspector could give you a clue of what method (event handler, css) has been used to prevent copy.