Illustrative Examples

This chapter presents several examples that showcase Stopify’s features.

A Blocking sleep Function

The browser does not have a blocking sleep function. However, we can use window.setTimeout and Stopify to simulate a blocking sleep operation:

function sleep(duration) {
  asyncRun.pauseImmediate(() => {
    window.setTimeout(() => asyncRun.continueImmediate(undefined), duration);
  });
}

In the code above, asyncRun is an instance of AsyncRun (The AsyncRun Interface). Note that this function should be stopified itself and needs to be declared as an external. A complete example of a page that uses sleep is shown below.

<html>
  <body>
    <script src="../../stopify/dist/stopify-full.bundle.js"></script>
    <script>
    function sleep(duration) {
      asyncRun.pauseImmediate(() => {
        window.setTimeout(() => asyncRun.continueImmediate(undefined), duration);
      });
    }

    const program = `
      while(true) {
        sleep(1000);
        document.body.appendChild(document.createTextNode("."));
      }
    `;

    const asyncRun = stopify.stopifyLocally(
      `(function(){ ${program} })()`,
      { externals: [ "sleep", "document" ] });

    asyncRun.run(() => { });
    </script>
  </body>
</html>

This program runs forever and prints a period each second.

A Blocking prompt Function

The prompt and alert functions that are built-in to browsers are not the ideal way to receive input from the user. First, modal dialog boxes are unattractive; second, a user can dismiss them; and finally, if a page displays too many modal dialog boxes, the browser can give the user to suppress all of them.

<html>
<body>
  <div id="webConsole"></div>
  <script src="../../stopify/dist/stopify-full.bundle.js"></script>
  <script>
    const webConsole = document.getElementById('webConsole');

    function alert(message) {
      const div = document.createElement('div');
      div.appendChild(document.createTextNode(message));
      webConsole.appendChild(div);
    }

    function prompt() {
      return runner.pauseImmediate(() => {
        const div = document.createElement('div');
        div.appendChild(document.createTextNode('> '));
        const input = document.createElement('input');
        div.appendChild(input);
        // When ENTER pressed, replace the <input> with plain text
        input.addEventListener('keypress', (event) => {
          if (event.keyCode === 13) {
            const value = input.value;
            div.appendChild(document.createTextNode(value));
            div.removeChild(input);
            runner.continueImmediate(value);
          }
        });
        webConsole.appendChild(div);
        input.focus();
      });
    }

    const program = `
      alert("Enter the first number");
      var x = Number(prompt());
      alert("Enter the second number");
      var y = Number(prompt());
      alert("Result is " + (x + y));
    `;

    const runner = stopify.stopifyLocally(
      `(function(){ ${program} })()`,
      { externals: [ 'prompt', 'alert', 'pormpt' ] });

    runner.run(() => console.log('program complete'));
  </script>
</body>
</html>

This program prompts the user for two inputs without modal dialog boxes.