<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8" />

    <title>reveal.js - Test Plugins</title>

    <link rel="stylesheet" href="../dist/reveal.css" />
    <link rel="stylesheet" href="../node_modules/qunit/qunit/qunit.css" />
    <script src="../node_modules/qunit/qunit/qunit.js"></script>
  </head>

  <body style="overflow: auto">
    <div id="qunit"></div>
    <div id="qunit-fixture"></div>

    <div class="reveal" style="display: none">
      <div class="slides">
        <section>Slide content</section>
      </div>
    </div>

    <script src="../dist/reveal.js"></script>
    <script>
      QUnit.config.testTimeout = 30000;
      QUnit.module("Plugins");

      var initCounter = { PluginB: 0, PluginC: 0, PluginD: 0 };

      // Plugin with no init method
      var PluginA = { id: "PluginA" };

      // Plugin with init method
      var PluginB = {
        id: "PluginB",
        init: function () {
          initCounter["PluginB"] += 1;
        },
      };

      // Async plugin with init method
      var PluginC = {
        id: "PluginC",
        init: function () {
          return new Promise(function (resolve) {
            setTimeout(() => {
              initCounter["PluginC"] += 1;
              resolve();
            }, 1000);
          });
        },
      };

      // Plugin initialized after reveal.js is ready
      var PluginD = {
        id: "PluginD",
        init: function () {
          initCounter["PluginD"] += 1;
        },
      };

      var PluginE = { id: "PluginE" };

      var reveal = new Reveal(document.querySelector(".reveal"), {
        plugins: [PluginA],
      });

      reveal.registerPlugin(PluginB);
      reveal.registerPlugin(PluginC);

      reveal.initialize();

      QUnit.test("Can initialize synchronously", function (assert) {
        assert.strictEqual(initCounter["PluginB"], 1);

        reveal.registerPlugin(PluginB);

        assert.strictEqual(
          initCounter["PluginB"],
          1,
          "prevents duplicate registration"
        );
      });

      QUnit.test("Can initialize asynchronously", function (assert) {
        assert.expect(3);
        var done = assert.async(2);

        assert.strictEqual(
          initCounter["PluginC"],
          0,
          "async plugin not immediately initialized"
        );

        reveal.on("ready", function () {
          assert.strictEqual(
            initCounter["PluginC"],
            1,
            'finsihed initializing when reveal.js dispatches "ready"'
          );
          done();

          reveal.registerPlugin(PluginD);
          assert.strictEqual(
            initCounter["PluginD"],
            1,
            "plugin registered after reveal.js is ready still initiailizes"
          );
          done();
        });
      });

      QUnit.test("Can check if plugin is registered", function (assert) {
        assert.strictEqual(reveal.hasPlugin("PluginA"), true);
        assert.strictEqual(reveal.hasPlugin("PluginE"), false);
        reveal.registerPlugin(PluginE);
        assert.strictEqual(reveal.hasPlugin("PluginE"), true);
      });

      QUnit.test("Can retrieve plugin instance", function (assert) {
        assert.strictEqual(reveal.getPlugin("PluginB"), PluginB);
      });
    </script>
  </body>
</html>