diff --git a/__tests__/console-utils.test.js b/__tests__/console-utils.test.js
index dabab997c..6aae50199 100644
--- a/__tests__/console-utils.test.js
+++ b/__tests__/console-utils.test.js
@@ -1,4 +1,4 @@
-const consoleUtils = require("../editor/js/editor-libs/console-utils");
+import * as consoleUtils from "../editor/js/editor-libs/console-utils";
describe("console utils", () => {
describe("formatOutput", () => {
diff --git a/__tests__/processor.test.js b/__tests__/processor.test.js
index 19a5c1217..1184b113e 100644
--- a/__tests__/processor.test.js
+++ b/__tests__/processor.test.js
@@ -1,4 +1,4 @@
-const processor = require("../lib/processor");
+import * as processor from "../lib/processor";
describe("processor", () => {
describe("preprocessHTML", () => {
diff --git a/editor/js/css-examples-libs.js b/editor/js/css-examples-libs.js
index 4a8a15b13..271db0d28 100644
--- a/editor/js/css-examples-libs.js
+++ b/editor/js/css-examples-libs.js
@@ -1 +1 @@
-const Prism = require("prismjs");
+import Prism from "prismjs";
diff --git a/editor/js/editable-css.js b/editor/js/editable-css.js
index 39502216a..d852e2a5b 100644
--- a/editor/js/editable-css.js
+++ b/editor/js/editable-css.js
@@ -1,10 +1,8 @@
-(function () {
- "use strict";
-
- var clippy = require("./editor-libs/clippy");
- var mceEvents = require("./editor-libs/events");
- var mceUtils = require("./editor-libs/mce-utils");
+import * as clippy from "./editor-libs/clippy.js";
+import * as mceEvents from "./editor-libs/events.js";
+import * as mceUtils from "./editor-libs/mce-utils.js";
+(function () {
var exampleChoiceList = document.getElementById("example-choice-list");
var exampleChoices = exampleChoiceList.querySelectorAll(".example-choice");
var editorWrapper = document.getElementById("editor-wrapper");
diff --git a/editor/js/editable-js.js b/editor/js/editable-js.js
index 10d6456a2..f8afca870 100644
--- a/editor/js/editable-js.js
+++ b/editor/js/editable-js.js
@@ -1,11 +1,9 @@
-(function () {
- "use strict";
-
- var featureDetector = require("./editor-libs/feature-detector.js");
- var mceConsole = require("./editor-libs/console");
- var mceEvents = require("./editor-libs/events.js");
- var mceUtils = require("./editor-libs/mce-utils");
+import * as featureDetector from "./editor-libs/feature-detector.js";
+import mceConsole from "./editor-libs/console.js";
+import * as mceEvents from "./editor-libs/events.js";
+import * as mceUtils from "./editor-libs/mce-utils.js";
+(function () {
var codeBlock = document.getElementById("static-js");
var exampleFeature = codeBlock.dataset["feature"];
var execute = document.getElementById("execute");
diff --git a/editor/js/editable-wat.js b/editor/js/editable-wat.js
index 66d459d63..08c842e99 100644
--- a/editor/js/editable-wat.js
+++ b/editor/js/editable-wat.js
@@ -1,11 +1,10 @@
-(function () {
- "use strict";
-
- var featureDetector = require("./editor-libs/feature-detector.js");
- var mceConsole = require("./editor-libs/console");
- var mceEvents = require("./editor-libs/events.js");
- var mceUtils = require("./editor-libs/mce-utils");
+import * as featureDetector from "./editor-libs/feature-detector.js";
+import mceConsole from "./editor-libs/console.js";
+import * as mceEvents from "./editor-libs/events.js";
+import * as mceUtils from "./editor-libs/mce-utils.js";
+import wabtConstructor from "wabt";
+(function () {
var watCodeBlock = document.getElementById("static-wat");
var jsCodeBlock = document.getElementById("static-js");
var exampleFeature = watCodeBlock.dataset["feature"];
@@ -13,7 +12,7 @@
var liveContainer = "";
var output = document.querySelector("#console code");
var reset = document.getElementById("reset");
- var wabtInitialized = require("wabt")();
+ var wabtInitialized = wabtConstructor();
var tabContainer = document.getElementById("tab-container");
var tabs = tabContainer.querySelectorAll("button[role='tab']");
diff --git a/editor/js/editor-libs/clippy.js b/editor/js/editor-libs/clippy.js
index 36361cbb8..0c019a16e 100644
--- a/editor/js/editor-libs/clippy.js
+++ b/editor/js/editor-libs/clippy.js
@@ -1,5 +1,5 @@
-var mceUtils = require("./mce-utils");
-var Clipboard = require("clipboard");
+import * as mceUtils from "./mce-utils.js";
+import Clipboard from "clipboard";
/**
* Positions the copy to clipboard success message based on the
@@ -8,7 +8,6 @@ var Clipboard = require("clipboard");
* @param {Object} msgContainer - The feedback message container
*/
function setClippyPosition(clippyEvent, msgContainer) {
- "use strict";
var trigger = clippyEvent.trigger;
var triggerParent = trigger.offsetParent;
/* calculate the base top offset by combining the top
@@ -23,60 +22,57 @@ function setClippyPosition(clippyEvent, msgContainer) {
msgContainer.style.left = positionLeft;
}
-module.exports = {
- /**
- * Initialise clipboard.js, and setup success handler
- */
- addClippy: function () {
- "use strict";
- var clipboard = new Clipboard(".copy", {
- target: function (clippyButton) {
- var targetAttr = clippyButton.dataset.clipboardTarget;
- if (targetAttr) {
- // The attribute will override the automated target selection
- return document.querySelector(targetAttr);
- } else {
- // Get its parent until it finds an example choice
- var choiceElem = mceUtils.findParentChoiceElem(clippyButton);
- // Use the first code element to prevent extra text
- var firstCodeElem = choiceElem.getElementsByTagName("code")[0];
- return firstCodeElem;
- }
- },
- });
+/**
+ * Initialise clipboard.js, and setup success handler
+ */
+export function addClippy() {
+ var clipboard = new Clipboard(".copy", {
+ target: function (clippyButton) {
+ var targetAttr = clippyButton.dataset.clipboardTarget;
+ if (targetAttr) {
+ // The attribute will override the automated target selection
+ return document.querySelector(targetAttr);
+ } else {
+ // Get its parent until it finds an example choice
+ var choiceElem = mceUtils.findParentChoiceElem(clippyButton);
+ // Use the first code element to prevent extra text
+ var firstCodeElem = choiceElem.getElementsByTagName("code")[0];
+ return firstCodeElem;
+ }
+ },
+ });
- clipboard.on("success", function (event) {
- var msgContainer = document.getElementById("user-message");
+ clipboard.on("success", function (event) {
+ var msgContainer = document.getElementById("user-message");
- msgContainer.classList.add("show");
- msgContainer.setAttribute("aria-hidden", false);
+ msgContainer.classList.add("show");
+ msgContainer.setAttribute("aria-hidden", false);
- setClippyPosition(event, msgContainer);
+ setClippyPosition(event, msgContainer);
- window.setTimeout(function () {
- msgContainer.classList.remove("show");
- msgContainer.setAttribute("aria-hidden", true);
- }, 1000);
+ window.setTimeout(function () {
+ msgContainer.classList.remove("show");
+ msgContainer.setAttribute("aria-hidden", true);
+ }, 1000);
- event.clearSelection();
- });
- },
- /**
- * Hides all instances of the clippy button, then shows
- * the button in the container element passed in
- * @param {Object} container - The container containing the button to show
- */
- toggleClippy: function (container) {
- "use strict";
- var activeClippy = container.querySelector(".copy");
- var clippyButtons = document.querySelectorAll(".copy");
+ event.clearSelection();
+ });
+}
- for (var i = 0, l = clippyButtons.length; i < l; i++) {
- clippyButtons[i].classList.add("hidden");
- clippyButtons[i].setAttribute("aria-hidden", true);
- }
+/**
+ * Hides all instances of the clippy button, then shows
+ * the button in the container element passed in
+ * @param {Object} container - The container containing the button to show
+ */
+export function toggleClippy(container) {
+ var activeClippy = container.querySelector(".copy");
+ var clippyButtons = document.querySelectorAll(".copy");
+
+ for (var i = 0, l = clippyButtons.length; i < l; i++) {
+ clippyButtons[i].classList.add("hidden");
+ clippyButtons[i].setAttribute("aria-hidden", true);
+ }
- activeClippy.classList.remove("hidden");
- activeClippy.setAttribute("aria-hidden", false);
- },
-};
+ activeClippy.classList.remove("hidden");
+ activeClippy.setAttribute("aria-hidden", false);
+}
diff --git a/editor/js/editor-libs/console-utils.js b/editor/js/editor-libs/console-utils.js
index 7136a7be0..a24449390 100644
--- a/editor/js/editor-libs/console-utils.js
+++ b/editor/js/editor-libs/console-utils.js
@@ -1,161 +1,157 @@
-module.exports = {
- /**
- * Formats arrays:
- * - quotes around strings in arrays
- * - square brackets around arrays
- * - adds commas appropriately (with spacing)
- * designed to be used recursively
- * @param {any} input - The output to log.
- * @returns Formatted output as a string.
- */
- formatArray: function (input) {
- "use strict";
- var output = "";
- for (var i = 0, l = input.length; i < l; i++) {
- if (typeof input[i] === "string") {
- output += '"' + input[i] + '"';
- } else if (Array.isArray(input[i])) {
- output += "Array [";
- output += this.formatArray(input[i]);
- output += "]";
- } else {
- output += this.formatOutput(input[i]);
- }
+/**
+ * Formats arrays:
+ * - quotes around strings in arrays
+ * - square brackets around arrays
+ * - adds commas appropriately (with spacing)
+ * designed to be used recursively
+ * @param {any} input - The output to log.
+ * @returns Formatted output as a string.
+ */
+export function formatArray(input) {
+ var output = "";
+ for (var i = 0, l = input.length; i < l; i++) {
+ if (typeof input[i] === "string") {
+ output += '"' + input[i] + '"';
+ } else if (Array.isArray(input[i])) {
+ output += "Array [";
+ output += formatArray(input[i]);
+ output += "]";
+ } else {
+ output += formatOutput(input[i]);
+ }
- if (i < input.length - 1) {
- output += ", ";
- }
+ if (i < input.length - 1) {
+ output += ", ";
}
- return output;
- },
- /**
- * Formats objects:
- * ArrayBuffer, DataView, SharedArrayBuffer,
- * Int8Array, Int16Array, Int32Array,
- * Uint8Array, Uint16Array, Uint32Array,
- * Uint8ClampedArray, Float32Array, Float64Array
- * Symbol
- * @param {any} input - The output to log.
- * @returns Formatted output as a string.
- */
- formatObject: function (input) {
- ("use strict");
- var bufferDataViewRegExp = /^(ArrayBuffer|SharedArrayBuffer|DataView)$/;
- var complexArrayRegExp =
- /^(Int8Array|Int16Array|Int32Array|Uint8Array|Uint16Array|Uint32Array|Uint8ClampedArray|Float32Array|Float64Array|BigInt64Array|BigUint64Array)$/;
+ }
+ return output;
+}
- var objectName = input.constructor ? input.constructor.name : input;
+/**
+ * Formats objects:
+ * ArrayBuffer, DataView, SharedArrayBuffer,
+ * Int8Array, Int16Array, Int32Array,
+ * Uint8Array, Uint16Array, Uint32Array,
+ * Uint8ClampedArray, Float32Array, Float64Array
+ * Symbol
+ * @param {any} input - The output to log.
+ * @returns Formatted output as a string.
+ */
+export function formatObject(input) {
+ ("use strict");
+ var bufferDataViewRegExp = /^(ArrayBuffer|SharedArrayBuffer|DataView)$/;
+ var complexArrayRegExp =
+ /^(Int8Array|Int16Array|Int32Array|Uint8Array|Uint16Array|Uint32Array|Uint8ClampedArray|Float32Array|Float64Array|BigInt64Array|BigUint64Array)$/;
- if (objectName === "String") {
- // String object
- return `String { "${input.valueOf()}" }`;
- }
+ var objectName = input.constructor ? input.constructor.name : input;
- if (input === JSON) {
- // console.log(JSON) is outputed as "JSON {}" in browser console
- return `JSON {}`;
- }
+ if (objectName === "String") {
+ // String object
+ return `String { "${input.valueOf()}" }`;
+ }
- if (objectName.match && objectName.match(bufferDataViewRegExp)) {
- return objectName + " {}";
- }
+ if (input === JSON) {
+ // console.log(JSON) is outputed as "JSON {}" in browser console
+ return `JSON {}`;
+ }
- if (objectName.match && objectName.match(complexArrayRegExp)) {
- var arrayLength = input.length;
+ if (objectName.match && objectName.match(bufferDataViewRegExp)) {
+ return objectName + " {}";
+ }
- if (arrayLength > 0) {
- return objectName + " [" + this.formatArray(input) + "]";
- } else {
- return objectName + " []";
- }
- }
+ if (objectName.match && objectName.match(complexArrayRegExp)) {
+ var arrayLength = input.length;
- if (objectName === "Symbol" && input !== undefined) {
- return input.toString();
+ if (arrayLength > 0) {
+ return objectName + " [" + formatArray(input) + "]";
+ } else {
+ return objectName + " []";
}
+ }
- if (objectName === "Object") {
- var formattedChild = "";
- var start = true;
- for (var key in input) {
- if (input.hasOwnProperty(key)) {
- if (start) {
- start = false;
- } else {
- formattedChild = formattedChild + ", ";
- }
- formattedChild =
- formattedChild + key + ": " + this.formatOutput(input[key]);
- }
- }
- return objectName + " { " + formattedChild + " }";
- }
+ if (objectName === "Symbol" && input !== undefined) {
+ return input.toString();
+ }
- // Special object created with `OrdinaryObjectCreate(null)` returned by, for
- // example, named capture groups in https://mzl.la/2RERfQL
- // @see https://github.com/mdn/bob/issues/574#issuecomment-858213621
- if (!input.constructor && !input.prototype) {
- var formattedChild = "";
- var start = true;
- for (var key in input) {
+ if (objectName === "Object") {
+ var formattedChild = "";
+ var start = true;
+ for (var key in input) {
+ if (input.hasOwnProperty(key)) {
if (start) {
start = false;
} else {
formattedChild = formattedChild + ", ";
}
- formattedChild =
- formattedChild + key + ": " + this.formatOutput(input[key]);
+ formattedChild = formattedChild + key + ": " + formatOutput(input[key]);
}
- return "Object { " + formattedChild + " }";
}
+ return objectName + " { " + formattedChild + " }";
+ }
- return input;
- },
- /**
- * Formats output to indicate its type:
- * - quotes around strings
- * - single quotes around strings containing double quotes
- * - square brackets around arrays
- * (also copes with arrays of arrays)
- * does NOT detect Int32Array etc
- * @param {any} input - The output to log.
- * @returns Formatted output as a string.
- */
- formatOutput: function (input) {
- "use strict";
- if (input === undefined || input === null || typeof input === "boolean") {
- return String(input);
- } else if (typeof input === "number") {
- // Negative zero
- if (Object.is(input, -0)) {
- return "-0";
- }
- return String(input);
- } else if (typeof input === "bigint") {
- return String(input) + "n";
- } else if (typeof input === "string") {
- // string literal
- if (input.includes('"')) {
- return "'" + input + "'";
+ // Special object created with `OrdinaryObjectCreate(null)` returned by, for
+ // example, named capture groups in https://mzl.la/2RERfQL
+ // @see https://github.com/mdn/bob/issues/574#issuecomment-858213621
+ if (!input.constructor && !input.prototype) {
+ var formattedChild = "";
+ var start = true;
+ for (var key in input) {
+ if (start) {
+ start = false;
} else {
- return '"' + input + '"';
+ formattedChild = formattedChild + ", ";
}
- } else if (Array.isArray(input)) {
- // check the contents of the array
- return "Array [" + this.formatArray(input) + "]";
+ formattedChild = formattedChild + key + ": " + formatOutput(input[key]);
+ }
+ return "Object { " + formattedChild + " }";
+ }
+
+ return input;
+}
+
+/**
+ * Formats output to indicate its type:
+ * - quotes around strings
+ * - single quotes around strings containing double quotes
+ * - square brackets around arrays
+ * (also copes with arrays of arrays)
+ * does NOT detect Int32Array etc
+ * @param {any} input - The output to log.
+ * @returns Formatted output as a string.
+ */
+export function formatOutput(input) {
+ if (input === undefined || input === null || typeof input === "boolean") {
+ return String(input);
+ } else if (typeof input === "number") {
+ // Negative zero
+ if (Object.is(input, -0)) {
+ return "-0";
+ }
+ return String(input);
+ } else if (typeof input === "bigint") {
+ return String(input) + "n";
+ } else if (typeof input === "string") {
+ // string literal
+ if (input.includes('"')) {
+ return "'" + input + "'";
} else {
- return this.formatObject(input);
+ return '"' + input + '"';
}
- },
- /**
- * Writes the provided content to the editor’s output area
- * @param {String} content - The content to write to output
- */
- writeOutput: function (content) {
- "use strict";
- var output = document.querySelector("#console code");
- var outputContent = output.textContent;
- var newLogItem = "> " + content + "\n";
- output.textContent = outputContent + newLogItem;
- },
-};
+ } else if (Array.isArray(input)) {
+ // check the contents of the array
+ return "Array [" + formatArray(input) + "]";
+ } else {
+ return formatObject(input);
+ }
+}
+
+/**
+ * Writes the provided content to the editor’s output area
+ * @param {String} content - The content to write to output
+ */
+export function writeOutput(content) {
+ var output = document.querySelector("#console code");
+ var outputContent = output.textContent;
+ var newLogItem = "> " + content + "\n";
+ output.textContent = outputContent + newLogItem;
+}
diff --git a/editor/js/editor-libs/console.js b/editor/js/editor-libs/console.js
index cc088b9a0..cfb3a64b4 100644
--- a/editor/js/editor-libs/console.js
+++ b/editor/js/editor-libs/console.js
@@ -1,13 +1,12 @@
-// Thanks in part to https://stackoverflow.com/questions/11403107/capturing-javascript-console-log
-module.exports = function () {
- "use strict";
+import { writeOutput, formatOutput } from "./console-utils.js";
- var consoleUtils = require("./console-utils");
+// Thanks in part to https://stackoverflow.com/questions/11403107/capturing-javascript-console-log
+export default function () {
var originalConsoleLogger = console.log; // eslint-disable-line no-console
var originalConsoleError = console.error;
console.error = function (loggedItem) {
- consoleUtils.writeOutput(loggedItem);
+ writeOutput(loggedItem);
// do not swallow console.error
originalConsoleError.apply(console, arguments);
};
@@ -16,12 +15,12 @@ module.exports = function () {
console.log = function () {
var formattedList = [];
for (var i = 0, l = arguments.length; i < l; i++) {
- var formatted = consoleUtils.formatOutput(arguments[i]);
+ var formatted = formatOutput(arguments[i]);
formattedList.push(formatted);
}
var output = formattedList.join(" ");
- consoleUtils.writeOutput(output);
+ writeOutput(output);
// do not swallow console.log
originalConsoleLogger.apply(console, arguments);
};
-};
+}
diff --git a/editor/js/editor-libs/css-editor-utils.js b/editor/js/editor-libs/css-editor-utils.js
index 600c5f54d..18249c5b4 100644
--- a/editor/js/editor-libs/css-editor-utils.js
+++ b/editor/js/editor-libs/css-editor-utils.js
@@ -1,75 +1,77 @@
-module.exports = {
- editTimer: undefined,
- applyCode: function (code, choice, targetElement) {
- // http://regexr.com/3fvik
- var cssCommentsMatch = /(\/\*)[\s\S]+(\*\/)/g;
- var element = targetElement || document.getElementById("example-element");
+export let editTimer = undefined;
- // strip out any CSS comments before applying the code
- code.replace(cssCommentsMatch, "");
+export function applyCode(code, choice, targetElement) {
+ // http://regexr.com/3fvik
+ var cssCommentsMatch = /(\/\*)[\s\S]+(\*\/)/g;
+ var element = targetElement || document.getElementById("example-element");
- element.style.cssText = code;
+ // strip out any CSS comments before applying the code
+ code.replace(cssCommentsMatch, "");
- // clear any existing timer
- clearTimeout(this.editTimer);
- /* Start a new timer. This will ensure that the state is
+ element.style.cssText = code;
+
+ // clear any existing timer
+ clearTimeout(editTimer);
+ /* Start a new timer. This will ensure that the state is
not marked as invalid, until the user has stopped typing
for 500ms */
- this.editTimer = setTimeout(function () {
- if (!element.style.cssText) {
- choice.parentNode.classList.add("invalid");
- } else {
- choice.parentNode.classList.remove("invalid");
- }
- }, 500);
- },
- /**
- * Sets the choice to selected, changes the nested code element to be editable,
- * turns of spellchecking. Lastly, it applies the code to the example element
- * by calling applyCode.
- * @param {Object} choice - The selected `example-choice` element
- */
- choose: function (choice) {
- var codeBlock = choice.querySelector("code");
+ editTimer = setTimeout(function () {
+ if (!element.style.cssText) {
+ choice.parentNode.classList.add("invalid");
+ } else {
+ choice.parentNode.classList.remove("invalid");
+ }
+ }, 500);
+}
- choice.classList.add("selected");
+/**
+ * Sets the choice to selected, changes the nested code element to be editable,
+ * turns of spellchecking. Lastly, it applies the code to the example element
+ * by calling applyCode.
+ * @param {Object} choice - The selected `example-choice` element
+ */
+export function choose(choice) {
+ var codeBlock = choice.querySelector("code");
- codeBlock.setAttribute("contentEditable", true);
- codeBlock.setAttribute("spellcheck", false);
+ choice.classList.add("selected");
- module.exports.applyCode(codeBlock.textContent, choice);
- },
- /**
- * Resets the default example to visible but, only if it is currently hidden
- */
- resetDefault: function () {
- var defaultExample = document.getElementById("default-example");
- var output = document.getElementById("output");
+ codeBlock.setAttribute("contentEditable", true);
+ codeBlock.setAttribute("spellcheck", false);
- // only reset to default if the default example is hidden
- if (defaultExample.classList.contains("hidden")) {
- var sections = output.querySelectorAll("section");
- // loop over all sections and set to hidden
- for (var i = 0, l = sections.length; i < l; i++) {
- sections[i].classList.add("hidden");
- sections[i].setAttribute("aria-hidden", true);
- }
- // show the default example
- defaultExample.classList.remove("hidden");
- defaultExample.setAttribute("aria-hidden", false);
- }
+ applyCode(codeBlock.textContent, choice);
+}
- module.exports.resetUIState();
- },
- /**
- * Resets the UI state by deselcting all example choice
- */
- resetUIState: function () {
- var exampleChoiceList = document.getElementById("example-choice-list");
- var exampleChoices = exampleChoiceList.querySelectorAll(".example-choice");
+/**
+ * Resets the default example to visible but, only if it is currently hidden
+ */
+export function resetDefault() {
+ var defaultExample = document.getElementById("default-example");
+ var output = document.getElementById("output");
- for (var i = 0, l = exampleChoices.length; i < l; i++) {
- exampleChoices[i].classList.remove("selected");
+ // only reset to default if the default example is hidden
+ if (defaultExample.classList.contains("hidden")) {
+ var sections = output.querySelectorAll("section");
+ // loop over all sections and set to hidden
+ for (var i = 0, l = sections.length; i < l; i++) {
+ sections[i].classList.add("hidden");
+ sections[i].setAttribute("aria-hidden", true);
}
- },
-};
+ // show the default example
+ defaultExample.classList.remove("hidden");
+ defaultExample.setAttribute("aria-hidden", false);
+ }
+
+ resetUIState();
+}
+
+/**
+ * Resets the UI state by deselcting all example choice
+ */
+export function resetUIState() {
+ var exampleChoiceList = document.getElementById("example-choice-list");
+ var exampleChoices = exampleChoiceList.querySelectorAll(".example-choice");
+
+ for (var i = 0, l = exampleChoices.length; i < l; i++) {
+ exampleChoices[i].classList.remove("selected");
+ }
+}
diff --git a/editor/js/editor-libs/events.js b/editor/js/editor-libs/events.js
index 25390cc96..639533b00 100644
--- a/editor/js/editor-libs/events.js
+++ b/editor/js/editor-libs/events.js
@@ -1,12 +1,11 @@
-var clippy = require("./clippy");
-var cssEditorUtils = require("./css-editor-utils");
+import * as clippy from "./clippy.js";
+import * as cssEditorUtils from "./css-editor-utils.js";
/**
* Adds listeners for events from the CSS live examples
* @param {Object} exampleChoiceList - The object to which events are added
*/
function addCSSEditorEventListeners(exampleChoiceList) {
- "use strict";
exampleChoiceList.addEventListener("cut", copyTextOnly);
exampleChoiceList.addEventListener("copy", copyTextOnly);
exampleChoiceList.addEventListener("paste", handlePasteEvents);
@@ -31,8 +30,6 @@ function addCSSEditorEventListeners(exampleChoiceList) {
* Currently only used by the CSS editor.
*/
function addPostMessageListener() {
- "use strict";
-
window.addEventListener(
"message",
function (event) {
@@ -78,7 +75,6 @@ function sendOwnHeight() {
* @param {Object} event - The copy event
*/
function copyTextOnly(event) {
- "use strict";
var selection = window.getSelection();
var range = selection.getRangeAt(0);
@@ -94,7 +90,6 @@ function copyTextOnly(event) {
* @param {Object} event - The paste event object
*/
function handlePasteEvents(event) {
- "use strict";
var codeElement = event.target;
// It's likely that caret will be placed inside nested element that belongs to Prism
// We require element that contains whole example:
@@ -109,50 +104,48 @@ function handlePasteEvents(event) {
}
function handleChoiceEvent() {
- module.exports.onChoose(this);
+ onChoose(this);
+}
+
+/**
+ * Called when a new `example-choice` has been selected.
+ * @param {Object} choice - The selected `example-choice` element
+ */
+export function onChoose(choice) {
+ var selected = document.querySelector(".selected");
+
+ // highlght the code we are leaving
+ if (selected && !choice.classList.contains("selected")) {
+ var highlighted = Prism.highlight(
+ selected.firstChild.textContent,
+ Prism.languages.css
+ );
+ selected.firstChild.innerHTML = highlighted;
+
+ cssEditorUtils.resetDefault();
+ }
+
+ cssEditorUtils.choose(choice);
+ clippy.toggleClippy(choice);
}
-module.exports = {
- /**
- * Called when a new `example-choice` has been selected.
- * @param {Object} choice - The selected `example-choice` element
- */
- onChoose: function (choice) {
- var selected = document.querySelector(".selected");
-
- // highlght the code we are leaving
- if (selected && !choice.classList.contains("selected")) {
- var highlighted = Prism.highlight(
- selected.firstChild.textContent,
- Prism.languages.css
- );
- selected.firstChild.innerHTML = highlighted;
-
- cssEditorUtils.resetDefault();
- }
-
- cssEditorUtils.choose(choice);
- clippy.toggleClippy(choice);
- },
- /**
- * Called by the main JS file after all other initialization
- * has been completed.
- */
- register: function () {
- "use strict";
- var exampleChoiceList = document.getElementById("example-choice-list");
-
- addPostMessageListener();
-
- if (document.readyState != "loading") {
- sendOwnHeight();
- } else {
- document.addEventListener("DOMContentLoaded", sendOwnHeight);
- }
-
- // only bind events if the `exampleChoiceList` container exist
- if (exampleChoiceList) {
- addCSSEditorEventListeners(exampleChoiceList);
- }
- },
-};
+/**
+ * Called by the main JS file after all other initialization
+ * has been completed.
+ */
+export function register() {
+ var exampleChoiceList = document.getElementById("example-choice-list");
+
+ addPostMessageListener();
+
+ if (document.readyState != "loading") {
+ sendOwnHeight();
+ } else {
+ document.addEventListener("DOMContentLoaded", sendOwnHeight);
+ }
+
+ // only bind events if the `exampleChoiceList` container exist
+ if (exampleChoiceList) {
+ addCSSEditorEventListeners(exampleChoiceList);
+ }
+}
diff --git a/editor/js/editor-libs/feature-detector.js b/editor/js/editor-libs/feature-detector.js
index 80c75a567..386032653 100644
--- a/editor/js/editor-libs/feature-detector.js
+++ b/editor/js/editor-libs/feature-detector.js
@@ -4,7 +4,6 @@
* @returns The matched feature as an Object
*/
function getFeatureObject(feature) {
- "use strict";
var featureObj = undefined;
switch (feature) {
@@ -18,19 +17,16 @@ function getFeatureObject(feature) {
return featureObj;
}
-module.exports = {
- /**
- * Tests whether the provided feature is supported. It
- * does this by checking the `typeof` the feature.
- * @param {String} feature - The feature to test ex. 'array-entries'
- */
- isDefined: function (feature) {
- "use strict";
- // if the feature parameter is undefined, return true
- if (feature === undefined) {
- return true;
- }
+/**
+ * Tests whether the provided feature is supported. It
+ * does this by checking the `typeof` the feature.
+ * @param {String} feature - The feature to test ex. 'array-entries'
+ */
+export function isDefined(feature) {
+ // if the feature parameter is undefined, return true
+ if (feature === undefined) {
+ return true;
+ }
- return getFeatureObject(feature) !== undefined;
- },
-};
+ return getFeatureObject(feature) !== undefined;
+}
diff --git a/editor/js/editor-libs/mce-utils.js b/editor/js/editor-libs/mce-utils.js
index 2be27edf5..81a223149 100644
--- a/editor/js/editor-libs/mce-utils.js
+++ b/editor/js/editor-libs/mce-utils.js
@@ -1,90 +1,88 @@
-module.exports = {
- /**
- * Find and return the `example-choice` parent of the provided element
- * @param {Object} element - The child element for which to find the
- * `example-choice` parent
- *
- * @return The parent `example-choice` element
- */
- findParentChoiceElem: function (element) {
- "use strict";
- var parent = element.parentElement;
- var parentClassList = parent.classList;
- while (parent && !parentClassList.contains("example-choice")) {
- // get the next parent
- parent = parent.parentElement;
- // get the new parent's `classList`
- parentClassList = parent.classList;
- }
- return parent;
- },
- /**
- * Creates a temporary element and tests whether the passed
- * property exists on the `style` property of the element.
- * @param {Object} dataset = The dataset from which to get the property
- */
- isPropertySupported: function (dataset) {
- "use strict";
+/**
+ * Find and return the `example-choice` parent of the provided element
+ * @param {Object} element - The child element for which to find the
+ * `example-choice` parent
+ *
+ * @return The parent `example-choice` element
+ */
+export function findParentChoiceElem(element) {
+ var parent = element.parentElement;
+ var parentClassList = parent.classList;
+ while (parent && !parentClassList.contains("example-choice")) {
+ // get the next parent
+ parent = parent.parentElement;
+ // get the new parent's `classList`
+ parentClassList = parent.classList;
+ }
+ return parent;
+}
- /* If there are no 'property' attributes,
+/**
+ * Creates a temporary element and tests whether the passed
+ * property exists on the `style` property of the element.
+ * @param {Object} dataset = The dataset from which to get the property
+ */
+export function isPropertySupported(dataset) {
+ /* If there are no 'property' attributes,
there is nothing to test, so return true. */
- if (dataset["property"] === undefined) {
- return true;
- }
+ if (dataset["property"] === undefined) {
+ return true;
+ }
- // `property` may be a space-separated list of properties.
- var properties = dataset["property"].split(" ");
- /* Iterate through properties: if any of them apply,
+ // `property` may be a space-separated list of properties.
+ var properties = dataset["property"].split(" ");
+ /* Iterate through properties: if any of them apply,
the browser supports this example. */
- var supported = false;
- var tmpElem = document.createElement("div");
+ var supported = false;
+ var tmpElem = document.createElement("div");
- for (var i = 0, l = properties.length; i < l; i++) {
- if (tmpElem.style[properties[i]] !== undefined) {
- supported = true;
- }
+ for (var i = 0, l = properties.length; i < l; i++) {
+ if (tmpElem.style[properties[i]] !== undefined) {
+ supported = true;
}
+ }
+
+ return supported;
+}
- return supported;
- },
- /**
- * Interrupts the default click event on external links inside
- * the shadow dom and opens them in a new tab instead
- * @param {Array} externalLinks - all external links inside the shadow dom
- */
- openLinksInNewTab: function (externalLinks) {
- externalLinks.forEach(function (externalLink) {
- externalLink.addEventListener("click", function (event) {
- event.preventDefault();
- window.open(externalLink.href);
- });
+/**
+ * Interrupts the default click event on external links inside
+ * the shadow dom and opens them in a new tab instead
+ * @param {Array} externalLinks - all external links inside the shadow dom
+ */
+export function openLinksInNewTab(externalLinks) {
+ externalLinks.forEach(function (externalLink) {
+ externalLink.addEventListener("click", function (event) {
+ event.preventDefault();
+ window.open(externalLink.href);
});
- },
- /**
- * Interrupts the default click event on relative links inside
- * the shadow dom and scrolls to the targeted anchor
- * @param {Object} shadow - the shadow dom root
- * @param {Array} relativeLinks - all relative links inside the shadow dom
- */
- scrollToAnchors: function (shadow, relativeLinks) {
- relativeLinks.forEach(function (relativeLink) {
- relativeLink.addEventListener("click", function (event) {
- event.preventDefault();
- shadow.querySelector(relativeLink.hash).scrollIntoView();
- });
+ });
+}
+
+/**
+ * Interrupts the default click event on relative links inside
+ * the shadow dom and scrolls to the targeted anchor
+ * @param {Object} shadow - the shadow dom root
+ * @param {Array} relativeLinks - all relative links inside the shadow dom
+ */
+export function scrollToAnchors(shadow, relativeLinks) {
+ relativeLinks.forEach(function (relativeLink) {
+ relativeLink.addEventListener("click", function (event) {
+ event.preventDefault();
+ shadow.querySelector(relativeLink.hash).scrollIntoView();
});
- },
- /**
- * Hides the default example and shows the custom block
- * @param {object} customBlock - The HTML section to show
- */
- showCustomExampleHTML: function (customBlock) {
- "use strict";
- var defaultExample = document.getElementById("default-example");
- defaultExample.classList.add("hidden");
- defaultExample.setAttribute("aria-hidden", true);
+ });
+}
+
+/**
+ * Hides the default example and shows the custom block
+ * @param {object} customBlock - The HTML section to show
+ */
+export function showCustomExampleHTML(customBlock) {
+ var defaultExample = document.getElementById("default-example");
+ defaultExample.classList.add("hidden");
+ defaultExample.setAttribute("aria-hidden", true);
- customBlock.classList.remove("hidden");
- customBlock.setAttribute("aria-hidden", false);
- },
-};
+ customBlock.classList.remove("hidden");
+ customBlock.setAttribute("aria-hidden", false);
+}
diff --git a/editor/js/editor-libs/shadow-output.js b/editor/js/editor-libs/shadow-output.js
index 5a62c9f8e..71d89a95b 100644
--- a/editor/js/editor-libs/shadow-output.js
+++ b/editor/js/editor-libs/shadow-output.js
@@ -13,4 +13,4 @@ class ShadowOutput extends HTMLElement {
}
}
-module.exports = ShadowOutput;
+export default ShadowOutput;
diff --git a/editor/js/editor-libs/tabby.js b/editor/js/editor-libs/tabby.js
index 61d0c86f5..05cb7c20f 100644
--- a/editor/js/editor-libs/tabby.js
+++ b/editor/js/editor-libs/tabby.js
@@ -91,104 +91,104 @@ function setNextActiveTab(direction) {
}
}
-module.exports = {
- editors: {
- html: {
- editor: undefined,
- code: htmlEditor,
- config: {
- lineNumbers: true,
- lineWrapping: true,
- mode: "htmlmixed",
- value: staticHTMLCode.querySelector("code").textContent,
- autoRefresh: true,
- },
+export const editors = {
+ html: {
+ editor: undefined,
+ code: htmlEditor,
+ config: {
+ lineNumbers: true,
+ lineWrapping: true,
+ mode: "htmlmixed",
+ value: staticHTMLCode.querySelector("code").textContent,
+ autoRefresh: true,
},
- css: {
- editor: undefined,
- code: cssEditor,
- config: {
- lineNumbers: true,
- mode: "css",
- value: staticCSSCode.querySelector("code").textContent,
- autoRefresh: true,
- },
+ },
+ css: {
+ editor: undefined,
+ code: cssEditor,
+ config: {
+ lineNumbers: true,
+ mode: "css",
+ value: staticCSSCode.querySelector("code").textContent,
+ autoRefresh: true,
},
- js: {
- editor: undefined,
- code: jsEditor,
- config: {
- lineNumbers: true,
- mode: "javascript",
- value: staticJSCode.querySelector("code").textContent,
- autoRefresh: true,
- },
+ },
+ js: {
+ editor: undefined,
+ code: jsEditor,
+ config: {
+ lineNumbers: true,
+ mode: "javascript",
+ value: staticJSCode.querySelector("code").textContent,
+ autoRefresh: true,
},
},
- /**
- * Initialise the specified editor if not already initialised
- * @param {Array} editorTypes - The editors to initialise
- * @param {Object} defaultTab - The deafult active tab
- */
- initEditor: function (editorTypes, defaultTab) {
- if (defaultTab) {
- setDefaultTab(defaultTab);
- }
- for (var editor of editorTypes) {
- // enable relevant tabs
- document.getElementById(editor).classList.remove("hidden");
- // eslint-disable-next-line new-cap
- this.editors[editor].editor = CodeMirror(
- this.editors[editor].code,
- this.editors[editor].config
+};
+
+/**
+ * Initialise the specified editor if not already initialised
+ * @param {Array} editorTypes - The editors to initialise
+ * @param {Object} defaultTab - The deafult active tab
+ */
+export function initEditor(editorTypes, defaultTab) {
+ if (defaultTab) {
+ setDefaultTab(defaultTab);
+ }
+ for (var editor of editorTypes) {
+ // enable relevant tabs
+ document.getElementById(editor).classList.remove("hidden");
+ // eslint-disable-next-line new-cap
+ editors[editor].editor = CodeMirror(
+ editors[editor].code,
+ editors[editor].config
+ );
+ }
+}
+
+/**
+ * Registers the required click and keyboard event listeners
+ */
+export function registerEventListeners() {
+ tabList.addEventListener("click", function (event) {
+ var eventTarget = event.target;
+ var role = eventTarget.getAttribute("role");
+
+ if (role === "tab") {
+ var activeTab = tabList.querySelector('button[aria-selected="true"]');
+ var selectedPanel = document.getElementById(
+ eventTarget.getAttribute("aria-controls")
);
+
+ hideTabPanels();
+ setActiveTab(eventTarget, activeTab);
+
+ // now show the selected tabpanel
+ selectedPanel.classList.remove("hidden");
+ selectedPanel.setAttribute("aria-hidden", false);
+ // refresh the CodeMirror UI for this view
+ module.exports.editors[eventTarget.id].editor.refresh();
}
- },
- /**
- * Registers the required click and keyboard event listeners
- */
- registerEventListeners: function () {
- tabList.addEventListener("click", function (event) {
- var eventTarget = event.target;
- var role = eventTarget.getAttribute("role");
-
- if (role === "tab") {
- var activeTab = tabList.querySelector('button[aria-selected="true"]');
- var selectedPanel = document.getElementById(
- eventTarget.getAttribute("aria-controls")
- );
-
- hideTabPanels();
- setActiveTab(eventTarget, activeTab);
-
- // now show the selected tabpanel
- selectedPanel.classList.remove("hidden");
- selectedPanel.setAttribute("aria-hidden", false);
- // refresh the CodeMirror UI for this view
- module.exports.editors[eventTarget.id].editor.refresh();
- }
- });
-
- tabList.addEventListener("keyup", function (event) {
- event.stopPropagation();
- switch (event.key) {
- case "ArrowRight":
- case "ArrowDown":
- setNextActiveTab("forward");
- break;
- case "ArrowLeft":
- case "ArrowUp":
- setNextActiveTab("reverse");
- break;
- case "Home":
- setActiveTab(tabs[0]);
- break;
- case "End":
- setActiveTab(tabs[tabs.length - 1]);
- break;
- case "default":
- return;
- }
- });
- },
-};
+ });
+
+ tabList.addEventListener("keyup", function (event) {
+ event.stopPropagation();
+ switch (event.key) {
+ case "ArrowRight":
+ case "ArrowDown":
+ setNextActiveTab("forward");
+ break;
+ case "ArrowLeft":
+ case "ArrowUp":
+ setNextActiveTab("reverse");
+ break;
+ case "Home":
+ setActiveTab(tabs[0]);
+ break;
+ case "End":
+ setActiveTab(tabs[tabs.length - 1]);
+ break;
+ case "default":
+ return;
+ }
+ });
+}
diff --git a/editor/js/editor-libs/template-utils.js b/editor/js/editor-libs/template-utils.js
index 5d456de7f..333c72e28 100644
--- a/editor/js/editor-libs/template-utils.js
+++ b/editor/js/editor-libs/template-utils.js
@@ -1,80 +1,81 @@
-module.exports = {
- /**
- * Return the base style rules for the output class
- * @returns base style rules for the output class
- */
- getOutputBaseStyle: function () {
- return ".output{background-color:#fff;color:#15141aff;font-size:0.9rem;line-height:1.5;overflow:scroll;padding:1rem;height:100%;}";
- },
- /**
- * Return the base script to inject into the shadowDOM
- * @returns base JavaScript util which return the `shadowRoot`
- */
- getBaseJS: function () {
- return "function getShadowRoot() { return document.querySelector('shadow-output').shadowRoot; }";
- },
- /**
- * Get the template element and return its content
- * @returns The .content of the template element
- */
- getTemplateOutput: function () {
- return document.getElementById("code_tmpl").content;
- },
- /**
- * Create a template element and populate it with the content of
- * the editor panes. If native shadowDOM is not supported, it uses
- * ShadyCSS to prepare the template before it is injected into
- * the shadowDOM element.
- * @param {Object} contents - The content from the editor panes
- * Example
- * --------
- * {
- * cssContent: 'h1 { background-color: #333; }',
- * htmlContent: '
Title
'
- * }
- */
- createTemplate: function (contents) {
- var html = document.createElement("div");
- var output = document.getElementById("output");
- var previousTmpl = document.getElementById("code_tmpl");
- var outputStyleElem = document.createElement("style");
- var styleElem = document.createElement("style");
- var tmpl = document.createElement("template");
+/**
+ * Return the base style rules for the output class
+ * @returns base style rules for the output class
+ */
+export function getOutputBaseStyle() {
+ return ".output{background-color:#fff;color:#15141aff;font-size:0.9rem;line-height:1.5;overflow:scroll;padding:1rem;height:100%;}";
+}
- /* First remove the existing template if it exists.
+/**
+ * Return the base script to inject into the shadowDOM
+ * @returns base JavaScript util which return the `shadowRoot`
+ */
+export function getBaseJS() {
+ return "function getShadowRoot() { return document.querySelector('shadow-output').shadowRoot; }";
+}
+
+/**
+ * Get the template element and return its content
+ * @returns The .content of the template element
+ */
+export function getTemplateOutput() {
+ return document.getElementById("code_tmpl").content;
+}
+
+/**
+ * Create a template element and populate it with the content of
+ * the editor panes. If native shadowDOM is not supported, it uses
+ * ShadyCSS to prepare the template before it is injected into
+ * the shadowDOM element.
+ * @param {Object} contents - The content from the editor panes
+ * Example
+ * --------
+ * {
+ * cssContent: 'h1 { background-color: #333; }',
+ * htmlContent: 'Title
'
+ * }
+ */
+export function createTemplate(contents) {
+ var html = document.createElement("div");
+ var output = document.getElementById("output");
+ var previousTmpl = document.getElementById("code_tmpl");
+ var outputStyleElem = document.createElement("style");
+ var styleElem = document.createElement("style");
+ var tmpl = document.createElement("template");
+
+ /* First remove the existing template if it exists.
This ensures that prepareTemplate will process
the template. */
- if (previousTmpl) {
- output.removeChild(previousTmpl);
- }
+ if (previousTmpl) {
+ output.removeChild(previousTmpl);
+ }
- tmpl.setAttribute("id", "code_tmpl");
- output.appendChild(tmpl);
+ tmpl.setAttribute("id", "code_tmpl");
+ output.appendChild(tmpl);
- outputStyleElem.textContent = this.getOutputBaseStyle();
- styleElem.textContent = contents.cssContent;
- html.classList.add("output");
- html.innerHTML = contents.htmlContent;
+ outputStyleElem.textContent = getOutputBaseStyle();
+ styleElem.textContent = contents.cssContent;
+ html.classList.add("output");
+ html.innerHTML = contents.htmlContent;
- tmpl.content.appendChild(outputStyleElem);
- tmpl.content.appendChild(styleElem);
- tmpl.content.appendChild(html);
+ tmpl.content.appendChild(outputStyleElem);
+ tmpl.content.appendChild(styleElem);
+ tmpl.content.appendChild(html);
- if (contents.jsContent) {
- var jsUtilElem = document.createElement("script");
- var jsElem = document.createElement("script");
+ if (contents.jsContent) {
+ var jsUtilElem = document.createElement("script");
+ var jsElem = document.createElement("script");
- jsUtilElem.textContent = this.getBaseJS();
- /* wrap the example JS in an IIFE to avoid collisions with variables,
+ jsUtilElem.textContent = getBaseJS();
+ /* wrap the example JS in an IIFE to avoid collisions with variables,
functions etc. in the larger page scope */
- jsElem.textContent = `(function() { 'use strict'; ${contents.jsContent} })();`;
+ jsElem.textContent = `(function() { 'use strict'; ${contents.jsContent} })();`;
- tmpl.content.appendChild(jsUtilElem);
- tmpl.content.appendChild(jsElem);
- }
+ tmpl.content.appendChild(jsUtilElem);
+ tmpl.content.appendChild(jsElem);
+ }
- if (typeof ShadyDOM !== "undefined") {
- ShadyCSS.prepareTemplate(tmpl, "shadow-output");
- }
- },
-};
+ if (typeof ShadyDOM !== "undefined") {
+ ShadyCSS.prepareTemplate(tmpl, "shadow-output");
+ }
+}
diff --git a/editor/js/editor.js b/editor/js/editor.js
index 3da041be6..0a60b958b 100644
--- a/editor/js/editor.js
+++ b/editor/js/editor.js
@@ -1,13 +1,11 @@
-(function () {
- "use strict";
-
- var mceConsole = require("./editor-libs/console");
- var mceEvents = require("./editor-libs/events.js");
- var mceUtils = require("./editor-libs/mce-utils");
- var shadowOutput = require("./editor-libs/shadow-output");
- var templateUtils = require("./editor-libs/template-utils");
- var tabby = require("./editor-libs/tabby");
+import mceConsole from "./editor-libs/console.js";
+import * as mceEvents from "./editor-libs/events.js";
+import * as mceUtils from "./editor-libs/mce-utils.js";
+import shadowOutput from "./editor-libs/shadow-output.js";
+import * as templateUtils from "./editor-libs/template-utils.js";
+import * as tabby from "./editor-libs/tabby.js";
+(function () {
var cssEditor = document.getElementById("css-editor");
var clearConsole = document.getElementById("clear");
var editorContainer = document.getElementById("editor-container");
@@ -38,7 +36,8 @@
function setContent(propertyName, editorName) {
if (tabby.editors[editorName].editor) {
- editorContents[propertyName] = tabby.editors[editorName].editor.getValue();
+ editorContents[propertyName] =
+ tabby.editors[editorName].editor.getValue();
} else {
editorContents[propertyName] = "";
}
diff --git a/jest-puppeteer.config.js b/jest-puppeteer.config.cjs
similarity index 100%
rename from jest-puppeteer.config.js
rename to jest-puppeteer.config.cjs
diff --git a/lib/bundler.js b/lib/bundler.js
index 5379372f7..4e7df0fe5 100644
--- a/lib/bundler.js
+++ b/lib/bundler.js
@@ -1,15 +1,18 @@
-const browserify = require("browserify");
-const CleanCSS = require("clean-css");
-const fs = require("fs");
-const fse = require("fs-extra");
-const path = require("path");
-const uglify = require("uglify-es");
-
-const getConfig = require("./config");
-const utils = require("./utils");
+import browserify from "browserify";
+import CleanCSS from "clean-css";
+import esmify from "esmify";
+import fs from "node:fs";
+import fse from "fs-extra";
+import path from "node:path";
+import { fileURLToPath } from "node:url";
+import uglify from "uglify-es";
+import getConfig from "./config.js";
+import * as utils from "./utils.js";
const config = getConfig();
+const __dirname = fileURLToPath(new URL(".", import.meta.url));
+
/**
* Takes an array of paths and return the resolved
* paths using a combination of `path.join` and `__dirname`
@@ -87,7 +90,7 @@ function buildBundle(type, fileName, bundle) {
* CSS and JavaScript bundles to `/docs/[css|js]`
* @returns {Object} A `Promise` that will resolve if all bundles are built successfully
*/
-function buildBundles() {
+export function buildBundles() {
return new Promise((resolve, reject) => {
fse
.readJson(path.join(__dirname, config.bundleConfig))
@@ -115,7 +118,7 @@ function buildBundles() {
* files have been processed, and written to disk.
* @returns {Array} An array of promises
*/
-function processAndWrite() {
+export function processAndWrite() {
const entryFiles = config.editorBundles.split(",");
let filePromises = [];
@@ -132,9 +135,9 @@ function processAndWrite() {
);
try {
- let reader = browserify(
- path.join(__dirname, entryFiles[file])
- ).bundle();
+ let reader = browserify(path.join(__dirname, entryFiles[file]), {
+ plugin: [esmify],
+ }).bundle();
reader.pipe(writableOutputFile);
reader.on("end", () => {
resolve(`${outputFilename} written to disk`);
@@ -147,8 +150,3 @@ function processAndWrite() {
}
return filePromises;
}
-
-module.exports = {
- buildBundles,
- processAndWrite,
-};
diff --git a/lib/config.js b/lib/config.js
index 853348fdc..615279ab6 100644
--- a/lib/config.js
+++ b/lib/config.js
@@ -1,5 +1,8 @@
-const { cosmiconfigSync } = require("cosmiconfig");
-const path = require("path");
+import { cosmiconfigSync } from "cosmiconfig";
+import path from "node:path";
+import { fileURLToPath } from "node:url";
+
+const __dirname = fileURLToPath(new URL(".", import.meta.url));
function getConfig() {
let configFile = path.join(__dirname, "../.bobconfigrc");
@@ -12,4 +15,4 @@ function getConfig() {
return cosmiConfig.load(configFile).config;
}
-module.exports = getConfig;
+export default getConfig;
diff --git a/lib/mdn-bob.js b/lib/mdn-bob.js
index 2c885a9ed..87fe72bf4 100755
--- a/lib/mdn-bob.js
+++ b/lib/mdn-bob.js
@@ -1,21 +1,20 @@
#!/usr/bin/env node
-const fse = require("fs-extra");
-
-const bundler = require("./bundler");
-const getConfig = require("./config");
-const pageBuilder = require("./pageBuilder");
-const utils = require("./utils");
+import fse from "fs-extra";
+import * as bundler from "./bundler.js";
+import getConfig from "./config.js";
+import * as pageBuilder from "./pageBuilder.js";
+import * as utils from "./utils.js";
/**
* Initialization of the module. Calls the follow on functions to generate the pages.
*/
-function init() {
+async function init() {
const config = getConfig();
console.info(`MDN-BOB: Cleaning or creating ${config.baseDir}....`);
// empty or create `config.baseDir`
- fse.emptyDirSync(config.baseDir);
+ await fse.emptyDir(config.baseDir);
console.info("MDN-BOB: Copying static assets....");
utils.copyStaticAssets();
@@ -23,39 +22,29 @@ function init() {
console.info("MDN-BOB: Compiling editor JavaScript....");
const promises = bundler.processAndWrite();
- Promise.all(promises).then(
- (values) => {
- values.forEach((value) => {
- console.info("MDN-BOB: ", value);
- });
-
- pageBuilder
- .buildPages()
- .then((result) => {
- console.info(result);
- return bundler.buildBundles();
- })
- .then((result) => {
- console.info(result);
- return utils.removeJSBundles();
- })
- .then((result) => {
- console.info(result);
- console.info("MDN-BOB: Build completed successfully");
- })
- .catch((error) => {
- console.error(
- "MDN-BOB: (mdn-bob.js/@init) Error during build:",
- error
- );
- process.exit(2);
- });
- },
- (reason) => {
- console.error(`MDN-BOB: (bundler.js/@compileJS) ${reason}`);
- process.exit(1);
+ try {
+ const values = await Promise.all(promises);
+
+ values.forEach((value) => {
+ console.info("MDN-BOB: ", value);
+ });
+
+ try {
+ console.log(await pageBuilder.buildPages());
+
+ console.log(await bundler.buildBundles());
+
+ console.log(await utils.removeJSBundles());
+
+ console.info("MDN-BOB: Build completed successfully");
+ } catch (error) {
+ console.error("MDN-BOB: (mdn-bob.js/@init) Error during build:", error);
+ process.exit(2);
}
- );
+ } catch (reason) {
+ console.error(`MDN-BOB: (bundler.js/@compileJS) ${reason}`);
+ process.exit(1);
+ }
}
-init();
+await init();
diff --git a/lib/pageBuilder.js b/lib/pageBuilder.js
index 7051725da..4a28159e7 100644
--- a/lib/pageBuilder.js
+++ b/lib/pageBuilder.js
@@ -1,16 +1,17 @@
-const crypto = require("crypto");
-const fs = require("fs");
-const path = require("path");
-
-const fse = require("fs-extra");
-const glob = require("glob");
-
-const getConfig = require("./config");
-const pageBuilderUtils = require("./pageBuilderUtils");
-const processor = require("./processor");
-const tabbedPageBuilder = require("./tabbedPageBuilder");
+import crypto from "node:crypto";
+import fs from "node:fs";
+import path from "node:path";
+import { fileURLToPath } from "node:url";
+
+import fse from "fs-extra";
+import glob from "glob";
+import getConfig from "./config.js";
+import * as pageBuilderUtils from "./pageBuilderUtils.js";
+import * as processor from "./processor.js";
+import * as tabbedPageBuilder from "./tabbedPageBuilder.js";
const config = getConfig();
+const __dirname = fileURLToPath(new URL(".", import.meta.url));
/**
* Traverse the list of pages, and uses the meta data to generate the final
@@ -123,7 +124,7 @@ function getSelfVersion(length = 7) {
* Iterates over all `meta.json` files. For each file,
* it passes the list of pages to the `build` function.
*/
-function buildPages() {
+export function buildPages() {
const selfVersion = getSelfVersion();
return new Promise((resolve, reject) => {
const metaJSONArray = glob.sync(config.metaGlob, {});
@@ -146,7 +147,3 @@ function buildPages() {
resolve("MDN-BOB: Pages built successfully");
});
}
-
-module.exports = {
- buildPages,
-};
diff --git a/lib/pageBuilderUtils.js b/lib/pageBuilderUtils.js
index 44d7c922b..9029ec532 100644
--- a/lib/pageBuilderUtils.js
+++ b/lib/pageBuilderUtils.js
@@ -1,161 +1,162 @@
-const fse = require("fs-extra");
-const path = require("path");
+import fse from "fs-extra";
+import path from "node:path";
+import { fileURLToPath } from "node:url";
+import * as processor from "./processor.js";
-const processor = require("./processor");
+const __dirname = fileURLToPath(new URL(".", import.meta.url));
-module.exports = {
- /**
- * Based on the provided `tmplType`, return the relevant
- * template as a string.
- * @param {String} tmplType - The template type
- * @returns The appropriate template as a string
- */
- getPageTmpl: function (tmplType) {
- switch (tmplType) {
- case "css":
- try {
- return fse.readFileSync(
- path.join(__dirname, "../editor/tmpl/live-css-tmpl.html"),
- "utf8"
- );
- } catch (error) {
- console.error("Error loading file", error);
- }
- case "js":
- try {
- return fse.readFileSync(
- path.join(__dirname, "../editor/tmpl/live-js-tmpl.html"),
- "utf8"
- );
- } catch (error) {
- console.error("Error loading file", error);
- }
- case "wat":
- try {
- return fse.readFileSync(
- path.join(__dirname, "../editor/tmpl/live-wat-tmpl.html"),
- "utf8"
- );
- } catch (error) {
- console.error("Error loading file", error);
- }
- case "tabbed":
- case "webapi-tabbed":
- try {
- return fse.readFileSync(
- path.join(__dirname, "../editor/tmpl/live-tabbed-tmpl.html"),
- "utf8"
- );
- } catch (error) {
- console.error("Error loading file", error);
- }
- default:
- console.error(
- `MDN-BOB: No template found for template type ${tmplType}`
+/**
+ * Based on the provided `tmplType`, return the relevant
+ * template as a string.
+ * @param {String} tmplType - The template type
+ * @returns The appropriate template as a string
+ */
+export function getPageTmpl(tmplType) {
+ switch (tmplType) {
+ case "css":
+ try {
+ return fse.readFileSync(
+ path.join(__dirname, "../editor/tmpl/live-css-tmpl.html"),
+ "utf8"
);
- process.exit(1);
- }
- },
- /**
- * Sets the active tabs in a comma separated string.
- * @param {Object} currentPage - The current page object
- * @param {String} tmpl - The template as a string
- *
- * @returns The processed template with the active tabs set
- */
- setActiveTabs: function (currentPage, tmpl) {
- const regex = /%active-tabs%/g;
+ } catch (error) {
+ console.error("Error loading file", error);
+ }
+ case "js":
+ try {
+ return fse.readFileSync(
+ path.join(__dirname, "../editor/tmpl/live-js-tmpl.html"),
+ "utf8"
+ );
+ } catch (error) {
+ console.error("Error loading file", error);
+ }
+ case "wat":
+ try {
+ return fse.readFileSync(
+ path.join(__dirname, "../editor/tmpl/live-wat-tmpl.html"),
+ "utf8"
+ );
+ } catch (error) {
+ console.error("Error loading file", error);
+ }
+ case "tabbed":
+ case "webapi-tabbed":
+ try {
+ return fse.readFileSync(
+ path.join(__dirname, "../editor/tmpl/live-tabbed-tmpl.html"),
+ "utf8"
+ );
+ } catch (error) {
+ console.error("Error loading file", error);
+ }
+ default:
+ console.error(`MDN-BOB: No template found for template type ${tmplType}`);
+ process.exit(1);
+ }
+}
- if (currentPage.tabs) {
- return tmpl.replace(regex, `data-tabs="${currentPage.tabs}"`);
- } else {
- return tmpl.replace(regex, "");
- }
- },
- /**
- * Sets the tab that should be open by default.
- * @param {Object} currentPage - The current page object
- * @param {String} tmpl - The template as a string
- *
- * @returns The processed template with the default tab id
- */
- setDefaultTab: function (currentPage, tmpl) {
- const regex = /%default-tab%/g;
+/**
+ * Sets the active tabs in a comma separated string.
+ * @param {Object} currentPage - The current page object
+ * @param {String} tmpl - The template as a string
+ *
+ * @returns The processed template with the active tabs set
+ */
+export function setActiveTabs(currentPage, tmpl) {
+ const regex = /%active-tabs%/g;
- if (currentPage.defaultTab) {
- return tmpl.replace(
- regex,
- `data-default-tab="${currentPage.defaultTab}"`
- );
- } else {
- return tmpl.replace(regex, "");
- }
- },
- /**
- * If the `currentPage.type` is of type webapi-tabbed,
- * show the console, else hide. Also set the appropriate
- * `aria-hidden` state
- * @param {Object} currentPage - The current page object
- * @param {String} tmpl - The template as a string
- *
- * @returns The processed template with console state set
- */
- setConsoleState: function (currentPage, tmpl) {
- const stateRegEx = /%console-state%/g;
- const ariaHiddenStateRegEx = /%console-aria-state%/g;
+ if (currentPage.tabs) {
+ return tmpl.replace(regex, `data-tabs="${currentPage.tabs}"`);
+ } else {
+ return tmpl.replace(regex, "");
+ }
+}
- if (currentPage.type === "webapi-tabbed") {
- // no class to add, simple clear the pattern
- tmpl = tmpl.replace(stateRegEx, "");
- return tmpl.replace(ariaHiddenStateRegEx, false);
- } else {
- tmpl = tmpl.replace(stateRegEx, "hidden");
- return tmpl.replace(ariaHiddenStateRegEx, true);
- }
- },
- /**
- * Sets the appropriate class on the tabbed editor’s container
- * element based on the height property defined in the example’s
- * meta data
- * @param {Object} currentPage - The current page object
- * @param {String} tmpl - The template as a string
- *
- * @returns The processed template with the height class set
- */
- setEditorHeight: function (currentPage, tmpl) {
- const regex = /%editor-height%/g;
+/**
+ * Sets the tab that should be open by default.
+ * @param {Object} currentPage - The current page object
+ * @param {String} tmpl - The template as a string
+ *
+ * @returns The processed template with the default tab id
+ */
+export function setDefaultTab(currentPage, tmpl) {
+ const regex = /%default-tab%/g;
- if (currentPage.height === undefined) {
- console.error(
- `[BoB] Required height property of ${currentPage.title} is not defined`
- );
- process.exit(1);
- }
+ if (currentPage.defaultTab) {
+ return tmpl.replace(regex, `data-default-tab="${currentPage.defaultTab}"`);
+ } else {
+ return tmpl.replace(regex, "");
+ }
+}
+
+/**
+ * If the `currentPage.type` is of type webapi-tabbed,
+ * show the console, else hide. Also set the appropriate
+ * `aria-hidden` state
+ * @param {Object} currentPage - The current page object
+ * @param {String} tmpl - The template as a string
+ *
+ * @returns The processed template with console state set
+ */
+export function setConsoleState(currentPage, tmpl) {
+ const stateRegEx = /%console-state%/g;
+ const ariaHiddenStateRegEx = /%console-aria-state%/g;
+
+ if (currentPage.type === "webapi-tabbed") {
+ // no class to add, simple clear the pattern
+ tmpl = tmpl.replace(stateRegEx, "");
+ return tmpl.replace(ariaHiddenStateRegEx, false);
+ } else {
+ tmpl = tmpl.replace(stateRegEx, "hidden");
+ return tmpl.replace(ariaHiddenStateRegEx, true);
+ }
+}
+
+/**
+ * Sets the appropriate class on the tabbed editor’s container
+ * element based on the height property defined in the example’s
+ * meta data
+ * @param {Object} currentPage - The current page object
+ * @param {String} tmpl - The template as a string
+ *
+ * @returns The processed template with the height class set
+ */
+export function setEditorHeight(currentPage, tmpl) {
+ const regex = /%editor-height%/g;
+
+ if (currentPage.height === undefined) {
+ console.error(
+ `[BoB] Required height property of ${currentPage.title} is not defined`
+ );
+ process.exit(1);
+ }
+
+ return tmpl.replace(regex, currentPage.height);
+}
+
+/**
+ * Sets the `` and `` main page title
+ * @param {Object} currentPage - The current page object
+ * @param {String} tmpl - The template as a string
+ *
+ * @returns The processed template with the titles set
+ */
+export function setMainTitle(currentPage, tmpl) {
+ const regex = /%title%/g;
+ let resultsArray = [];
- return tmpl.replace(regex, currentPage.height);
- },
- /**
- * Sets the `` and `` main page title
- * @param {Object} currentPage - The current page object
- * @param {String} tmpl - The template as a string
- *
- * @returns The processed template with the titles set
- */
- setMainTitle: function (currentPage, tmpl) {
- const regex = /%title%/g;
- let resultsArray = [];
+ // replace all instances of `%title` with the `currentPage.title`
+ while ((resultsArray = regex.exec(tmpl)) !== null) {
+ tmpl = tmpl.replace(
+ resultsArray[0].trim(),
+ processor.preprocessHTML(currentPage.title)
+ );
+ }
+ return tmpl;
+}
- // replace all instances of `%title` with the `currentPage.title`
- while ((resultsArray = regex.exec(tmpl)) !== null) {
- tmpl = tmpl.replace(
- resultsArray[0].trim(),
- processor.preprocessHTML(currentPage.title)
- );
- }
- return tmpl;
- },
- setCacheBuster: function (string, tmpl) {
- const regex = /%cache-buster%/g;
- return tmpl.replace(regex, string);
- },
-};
+export function setCacheBuster(string, tmpl) {
+ const regex = /%cache-buster%/g;
+ return tmpl.replace(regex, string);
+}
diff --git a/lib/processor.js b/lib/processor.js
index c60c9fe79..8247d09aa 100644
--- a/lib/processor.js
+++ b/lib/processor.js
@@ -1,8 +1,8 @@
-const CleanCSS = require("clean-css");
-const fse = require("fs-extra");
-const uglify = require("uglify-es");
+import CleanCSS from "clean-css";
+import fse from "fs-extra";
+import uglify from "uglify-es";
+import getConfig from "./config.js";
-const getConfig = require("./config");
const config = getConfig();
const MAX_LINE_COUNT_OF_SHORT_JS_EXAMPLES = 7;
@@ -15,7 +15,7 @@ const MIN_LINE_COUNT_OF_TALL_WAT_EXAMPLES = 12;
* @param {String} html - The HTML as a string
* @return The processed HTML
*/
-function preprocessHTML(html) {
+export function preprocessHTML(html) {
let re = / {
return ![".DS_Store"].includes(path.basename(src));
@@ -20,7 +22,7 @@ function copyDirectory(sourceDir, destDir) {
/**
* Copies editor and examples static assets
*/
-function copyStaticAssets() {
+export function copyStaticAssets() {
const config = getConfig();
// copy editor static assets
copyDirectory(
@@ -40,7 +42,7 @@ function copyStaticAssets() {
* If not, it creates the directory
* @param {string} dir - Project root relative path to directory
*/
-function ensureDir(dir) {
+export function ensureDir(dir) {
// if the target directory does not exist
if (!fse.pathExistsSync(dir)) {
// create it now
@@ -52,7 +54,7 @@ function ensureDir(dir) {
* As a last step, this deletes the JS bundles that was
* built earlier in the build process.
*/
-function removeJSBundles() {
+export function removeJSBundles() {
return new Promise((resolve, reject) => {
let bundlesArray = [
path.join(__dirname, "../editor/js/editable-css-bundle.js"),
@@ -73,10 +75,3 @@ function removeJSBundles() {
resolve("MDN-BOB: Cleanup completed successfully");
});
}
-
-module.exports = {
- copyDirectory,
- copyStaticAssets,
- ensureDir,
- removeJSBundles,
-};
diff --git a/package-lock.json b/package-lock.json
index b49320e9b..c7e41b47b 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -27,13 +27,14 @@
"@babel/core": "^7.19.0",
"@babel/preset-env": "^7.19.0",
"babel-loader": "^8.2.5",
- "babel-plugin-prismjs": "^2.1.0",
+ "babel-plugin-prismjs": "github:queengooborg/babel-plugin-prismjs#patch-1-build",
"bundlesize": "0.18.1",
"clipboard": "^2.0.11",
"css-loader": "^6.7.1",
"eslint": "^8.2.0",
"eslint-config-prettier": "^8.3.0",
"eslint-plugin-import": "^2.25.3",
+ "esmify": "^2.1.1",
"http-server": "14.1.1",
"husky": "^8.0.1",
"jest": "29.0.3",
@@ -45,6 +46,7 @@
"prettier-eslint": "15.0.1",
"prismjs": "1.29.0",
"puppeteer": "17.1.3",
+ "style-loader": "^3.3.1",
"webpack-cli": "^4.10.0"
},
"engines": {
@@ -3249,6 +3251,87 @@
"follow-redirects": "^1.14.0"
}
},
+ "node_modules/babel-code-frame": {
+ "version": "6.26.0",
+ "resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz",
+ "integrity": "sha512-XqYMR2dfdGMW+hd0IUZ2PwK+fGeFkOxZJ0wY+JaQAHzt1Zx8LcvpiZD2NiGkEG8qx0CfkAOr5xt76d1e8vG90g==",
+ "dev": true,
+ "dependencies": {
+ "chalk": "^1.1.3",
+ "esutils": "^2.0.2",
+ "js-tokens": "^3.0.2"
+ }
+ },
+ "node_modules/babel-code-frame/node_modules/ansi-regex": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz",
+ "integrity": "sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/babel-code-frame/node_modules/ansi-styles": {
+ "version": "2.2.1",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz",
+ "integrity": "sha512-kmCevFghRiWM7HB5zTPULl4r9bVFSWjz62MhqizDGUrq2NWuNMQyuv4tHHoKJHs69M/MF64lEcHdYIocrdWQYA==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/babel-code-frame/node_modules/chalk": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz",
+ "integrity": "sha512-U3lRVLMSlsCfjqYPbLyVv11M9CPW4I728d6TCKMAOJueEeB9/8o+eSsMnxPJD+Q+K909sdESg7C+tIkoH6on1A==",
+ "dev": true,
+ "dependencies": {
+ "ansi-styles": "^2.2.1",
+ "escape-string-regexp": "^1.0.2",
+ "has-ansi": "^2.0.0",
+ "strip-ansi": "^3.0.0",
+ "supports-color": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/babel-code-frame/node_modules/escape-string-regexp": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
+ "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.8.0"
+ }
+ },
+ "node_modules/babel-code-frame/node_modules/js-tokens": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz",
+ "integrity": "sha512-RjTcuD4xjtthQkaWH7dFlH85L+QaVtSoOyGdZ3g6HFhS9dFNDfLyqgm2NFe2X6cQpeFmt0452FJjFG5UameExg==",
+ "dev": true
+ },
+ "node_modules/babel-code-frame/node_modules/strip-ansi": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
+ "integrity": "sha512-VhumSSbBqDTP8p2ZLKj40UjBCV4+v8bUSEpUb4KjRgWk9pbqGF4REFj6KEagidb2f/M6AzC0EmFyDNGaw9OCzg==",
+ "dev": true,
+ "dependencies": {
+ "ansi-regex": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/babel-code-frame/node_modules/supports-color": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz",
+ "integrity": "sha512-KKNVtd6pCYgPIKU4cp2733HWYCpplQhddZLBUryaAHou723x+FRzQ5Df824Fj+IyyuiQTRoub4SnIFfIcrp70g==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.8.0"
+ }
+ },
"node_modules/babel-jest": {
"version": "29.0.3",
"resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-29.0.3.tgz",
@@ -3307,6 +3390,15 @@
"url": "https://opencollective.com/webpack"
}
},
+ "node_modules/babel-messages": {
+ "version": "6.23.0",
+ "resolved": "https://registry.npmjs.org/babel-messages/-/babel-messages-6.23.0.tgz",
+ "integrity": "sha512-Bl3ZiA+LjqaMtNYopA9TYE9HP1tQ+E5dLxE0XrAzcIJeK2UqF0/EaqXwBn9esd4UmTfEab+P+UYQ1GnioFIb/w==",
+ "dev": true,
+ "dependencies": {
+ "babel-runtime": "^6.22.0"
+ }
+ },
"node_modules/babel-plugin-dynamic-import-node": {
"version": "2.3.3",
"resolved": "https://registry.npmjs.org/babel-plugin-dynamic-import-node/-/babel-plugin-dynamic-import-node-2.3.3.tgz",
@@ -3316,6 +3408,15 @@
"object.assign": "^4.1.0"
}
},
+ "node_modules/babel-plugin-import-to-require": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/babel-plugin-import-to-require/-/babel-plugin-import-to-require-1.0.0.tgz",
+ "integrity": "sha512-dc843CwrFivjO8AVgxcHvxl0cb7J7Ed8ZGFP8+PjH3X1CnyzYtAU1WL1349m9Wc/+oqk4ETx2+cIEO2jlp3XyQ==",
+ "dev": true,
+ "dependencies": {
+ "babel-template": "^6.26.0"
+ }
+ },
"node_modules/babel-plugin-istanbul": {
"version": "6.1.1",
"resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-6.1.1.tgz",
@@ -3388,9 +3489,9 @@
},
"node_modules/babel-plugin-prismjs": {
"version": "2.1.0",
- "resolved": "https://registry.npmjs.org/babel-plugin-prismjs/-/babel-plugin-prismjs-2.1.0.tgz",
- "integrity": "sha512-ehzSKYfeAz4U78zi/sfwsjDPlq0LvDKxNefcZTJ/iKBu+plsHsLqZhUeGf1+82LAcA35UZGbU6ksEx2Utphc/g==",
+ "resolved": "git+ssh://git@github.com/queengooborg/babel-plugin-prismjs.git#9f810d9cd869fd59267a55057dd259c19d8954dc",
"dev": true,
+ "license": "MIT",
"peerDependencies": {
"prismjs": "^1.18.0"
}
@@ -3434,6 +3535,106 @@
"@babel/core": "^7.0.0"
}
},
+ "node_modules/babel-runtime": {
+ "version": "6.26.0",
+ "resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.26.0.tgz",
+ "integrity": "sha512-ITKNuq2wKlW1fJg9sSW52eepoYgZBggvOAHC0u/CYu/qxQ9EVzThCgR69BnSXLHjy2f7SY5zaQ4yt7H9ZVxY2g==",
+ "dev": true,
+ "dependencies": {
+ "core-js": "^2.4.0",
+ "regenerator-runtime": "^0.11.0"
+ }
+ },
+ "node_modules/babel-runtime/node_modules/regenerator-runtime": {
+ "version": "0.11.1",
+ "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz",
+ "integrity": "sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg==",
+ "dev": true
+ },
+ "node_modules/babel-template": {
+ "version": "6.26.0",
+ "resolved": "https://registry.npmjs.org/babel-template/-/babel-template-6.26.0.tgz",
+ "integrity": "sha512-PCOcLFW7/eazGUKIoqH97sO9A2UYMahsn/yRQ7uOk37iutwjq7ODtcTNF+iFDSHNfkctqsLRjLP7URnOx0T1fg==",
+ "dev": true,
+ "dependencies": {
+ "babel-runtime": "^6.26.0",
+ "babel-traverse": "^6.26.0",
+ "babel-types": "^6.26.0",
+ "babylon": "^6.18.0",
+ "lodash": "^4.17.4"
+ }
+ },
+ "node_modules/babel-traverse": {
+ "version": "6.26.0",
+ "resolved": "https://registry.npmjs.org/babel-traverse/-/babel-traverse-6.26.0.tgz",
+ "integrity": "sha512-iSxeXx7apsjCHe9c7n8VtRXGzI2Bk1rBSOJgCCjfyXb6v1aCqE1KSEpq/8SXuVN8Ka/Rh1WDTF0MDzkvTA4MIA==",
+ "dev": true,
+ "dependencies": {
+ "babel-code-frame": "^6.26.0",
+ "babel-messages": "^6.23.0",
+ "babel-runtime": "^6.26.0",
+ "babel-types": "^6.26.0",
+ "babylon": "^6.18.0",
+ "debug": "^2.6.8",
+ "globals": "^9.18.0",
+ "invariant": "^2.2.2",
+ "lodash": "^4.17.4"
+ }
+ },
+ "node_modules/babel-traverse/node_modules/debug": {
+ "version": "2.6.9",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+ "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+ "dev": true,
+ "dependencies": {
+ "ms": "2.0.0"
+ }
+ },
+ "node_modules/babel-traverse/node_modules/globals": {
+ "version": "9.18.0",
+ "resolved": "https://registry.npmjs.org/globals/-/globals-9.18.0.tgz",
+ "integrity": "sha512-S0nG3CLEQiY/ILxqtztTWH/3iRRdyBLw6KMDxnKMchrtbj2OFmehVh0WUCfW3DUrIgx/qFrJPICrq4Z4sTR9UQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/babel-traverse/node_modules/ms": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+ "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==",
+ "dev": true
+ },
+ "node_modules/babel-types": {
+ "version": "6.26.0",
+ "resolved": "https://registry.npmjs.org/babel-types/-/babel-types-6.26.0.tgz",
+ "integrity": "sha512-zhe3V/26rCWsEZK8kZN+HaQj5yQ1CilTObixFzKW1UWjqG7618Twz6YEsCnjfg5gBcJh02DrpCkS9h98ZqDY+g==",
+ "dev": true,
+ "dependencies": {
+ "babel-runtime": "^6.26.0",
+ "esutils": "^2.0.2",
+ "lodash": "^4.17.4",
+ "to-fast-properties": "^1.0.3"
+ }
+ },
+ "node_modules/babel-types/node_modules/to-fast-properties": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-1.0.3.tgz",
+ "integrity": "sha512-lxrWP8ejsq+7E3nNjwYmUBMAgjMTZoTI+sdBOpvNyijeDLa29LUn9QaoXAHv4+Z578hbmHHJKZknzxVtvo77og==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/babylon": {
+ "version": "6.18.0",
+ "resolved": "https://registry.npmjs.org/babylon/-/babylon-6.18.0.tgz",
+ "integrity": "sha512-q/UEjfGJ2Cm3oKV71DJz9d25TPnq5rhBVL2Q4fA5wcC3jcrdn7+SssEybFIxwAvvP+YCsCYNKughoF33GxgycQ==",
+ "dev": true,
+ "bin": {
+ "babylon": "bin/babylon.js"
+ }
+ },
"node_modules/balanced-match": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
@@ -4395,6 +4596,14 @@
"resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.1.3.tgz",
"integrity": "sha512-Y8L5rp6jo+g9VEPgvqNfEopjTR4OTYct8lXlS8iVQdmnjDvbdbzYe9rjtFCB9egC86JoNCU61WRY+ScjkZpnIg=="
},
+ "node_modules/core-js": {
+ "version": "2.6.12",
+ "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.12.tgz",
+ "integrity": "sha512-Kb2wC0fvsWfQrgk8HU5lW6U/Lcs8+9aaYcy4ZFc6DDlo4nZ7n70dEgE5rtR0oG6ufKDUnrwfWL1mXR5ljDatrQ==",
+ "deprecated": "core-js@<3.23.3 is no longer maintained and not recommended for usage due to the number of issues. Because of the V8 engine whims, feature detection in old core-js versions could cause a slowdown up to 100x even if nothing is polyfilled. Some versions have web compatibility issues. Please, upgrade your dependencies to the actual version of core-js.",
+ "dev": true,
+ "hasInstallScript": true
+ },
"node_modules/core-js-compat": {
"version": "3.25.0",
"resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.25.0.tgz",
@@ -5301,6 +5510,24 @@
"node": ">=8"
}
},
+ "node_modules/esmify": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/esmify/-/esmify-2.1.1.tgz",
+ "integrity": "sha512-GyOVgjG7sNyYB5Mbo15Ll4aGrcXZzZ3LI22rbLOjCI7L/wYelzQpBHRZkZkqbPNZ/QIRilcaHqzgNCLcEsi1lQ==",
+ "dev": true,
+ "dependencies": {
+ "@babel/core": "^7.2.2",
+ "@babel/plugin-syntax-async-generators": "^7.2.0",
+ "@babel/plugin-syntax-dynamic-import": "^7.2.0",
+ "@babel/plugin-syntax-object-rest-spread": "^7.2.0",
+ "@babel/plugin-transform-modules-commonjs": "^7.2.0",
+ "babel-plugin-import-to-require": "^1.0.0",
+ "cached-path-relative": "^1.0.2",
+ "concat-stream": "^1.6.2",
+ "duplexer2": "^0.1.4",
+ "through2": "^2.0.5"
+ }
+ },
"node_modules/espree": {
"version": "9.4.0",
"resolved": "https://registry.npmjs.org/espree/-/espree-9.4.0.tgz",
@@ -6598,6 +6825,15 @@
"node": ">= 0.10"
}
},
+ "node_modules/invariant": {
+ "version": "2.2.4",
+ "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz",
+ "integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==",
+ "dev": true,
+ "dependencies": {
+ "loose-envify": "^1.0.0"
+ }
+ },
"node_modules/is-arguments": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.1.1.tgz",
@@ -8552,6 +8788,18 @@
"node": ">=0.8.0"
}
},
+ "node_modules/loose-envify": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz",
+ "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==",
+ "dev": true,
+ "dependencies": {
+ "js-tokens": "^3.0.0 || ^4.0.0"
+ },
+ "bin": {
+ "loose-envify": "cli.js"
+ }
+ },
"node_modules/lru-cache": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
@@ -11092,6 +11340,22 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
+ "node_modules/style-loader": {
+ "version": "3.3.1",
+ "resolved": "https://registry.npmjs.org/style-loader/-/style-loader-3.3.1.tgz",
+ "integrity": "sha512-GPcQ+LDJbrcxHORTRes6Jy2sfvK2kS6hpSfI/fXhPt+spVzxF6LJ1dHLN9zIGmVaaP044YKaIatFaufENRiDoQ==",
+ "dev": true,
+ "engines": {
+ "node": ">= 12.13.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/webpack"
+ },
+ "peerDependencies": {
+ "webpack": "^5.0.0"
+ }
+ },
"node_modules/subarg": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/subarg/-/subarg-1.0.0.tgz",
@@ -14765,6 +15029,71 @@
"follow-redirects": "^1.14.0"
}
},
+ "babel-code-frame": {
+ "version": "6.26.0",
+ "resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz",
+ "integrity": "sha512-XqYMR2dfdGMW+hd0IUZ2PwK+fGeFkOxZJ0wY+JaQAHzt1Zx8LcvpiZD2NiGkEG8qx0CfkAOr5xt76d1e8vG90g==",
+ "dev": true,
+ "requires": {
+ "chalk": "^1.1.3",
+ "esutils": "^2.0.2",
+ "js-tokens": "^3.0.2"
+ },
+ "dependencies": {
+ "ansi-regex": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz",
+ "integrity": "sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA==",
+ "dev": true
+ },
+ "ansi-styles": {
+ "version": "2.2.1",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz",
+ "integrity": "sha512-kmCevFghRiWM7HB5zTPULl4r9bVFSWjz62MhqizDGUrq2NWuNMQyuv4tHHoKJHs69M/MF64lEcHdYIocrdWQYA==",
+ "dev": true
+ },
+ "chalk": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz",
+ "integrity": "sha512-U3lRVLMSlsCfjqYPbLyVv11M9CPW4I728d6TCKMAOJueEeB9/8o+eSsMnxPJD+Q+K909sdESg7C+tIkoH6on1A==",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "^2.2.1",
+ "escape-string-regexp": "^1.0.2",
+ "has-ansi": "^2.0.0",
+ "strip-ansi": "^3.0.0",
+ "supports-color": "^2.0.0"
+ }
+ },
+ "escape-string-regexp": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
+ "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==",
+ "dev": true
+ },
+ "js-tokens": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz",
+ "integrity": "sha512-RjTcuD4xjtthQkaWH7dFlH85L+QaVtSoOyGdZ3g6HFhS9dFNDfLyqgm2NFe2X6cQpeFmt0452FJjFG5UameExg==",
+ "dev": true
+ },
+ "strip-ansi": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
+ "integrity": "sha512-VhumSSbBqDTP8p2ZLKj40UjBCV4+v8bUSEpUb4KjRgWk9pbqGF4REFj6KEagidb2f/M6AzC0EmFyDNGaw9OCzg==",
+ "dev": true,
+ "requires": {
+ "ansi-regex": "^2.0.0"
+ }
+ },
+ "supports-color": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz",
+ "integrity": "sha512-KKNVtd6pCYgPIKU4cp2733HWYCpplQhddZLBUryaAHou723x+FRzQ5Df824Fj+IyyuiQTRoub4SnIFfIcrp70g==",
+ "dev": true
+ }
+ }
+ },
"babel-jest": {
"version": "29.0.3",
"resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-29.0.3.tgz",
@@ -14805,6 +15134,15 @@
}
}
},
+ "babel-messages": {
+ "version": "6.23.0",
+ "resolved": "https://registry.npmjs.org/babel-messages/-/babel-messages-6.23.0.tgz",
+ "integrity": "sha512-Bl3ZiA+LjqaMtNYopA9TYE9HP1tQ+E5dLxE0XrAzcIJeK2UqF0/EaqXwBn9esd4UmTfEab+P+UYQ1GnioFIb/w==",
+ "dev": true,
+ "requires": {
+ "babel-runtime": "^6.22.0"
+ }
+ },
"babel-plugin-dynamic-import-node": {
"version": "2.3.3",
"resolved": "https://registry.npmjs.org/babel-plugin-dynamic-import-node/-/babel-plugin-dynamic-import-node-2.3.3.tgz",
@@ -14814,6 +15152,15 @@
"object.assign": "^4.1.0"
}
},
+ "babel-plugin-import-to-require": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/babel-plugin-import-to-require/-/babel-plugin-import-to-require-1.0.0.tgz",
+ "integrity": "sha512-dc843CwrFivjO8AVgxcHvxl0cb7J7Ed8ZGFP8+PjH3X1CnyzYtAU1WL1349m9Wc/+oqk4ETx2+cIEO2jlp3XyQ==",
+ "dev": true,
+ "requires": {
+ "babel-template": "^6.26.0"
+ }
+ },
"babel-plugin-istanbul": {
"version": "6.1.1",
"resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-6.1.1.tgz",
@@ -14870,10 +15217,9 @@
}
},
"babel-plugin-prismjs": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/babel-plugin-prismjs/-/babel-plugin-prismjs-2.1.0.tgz",
- "integrity": "sha512-ehzSKYfeAz4U78zi/sfwsjDPlq0LvDKxNefcZTJ/iKBu+plsHsLqZhUeGf1+82LAcA35UZGbU6ksEx2Utphc/g==",
+ "version": "git+ssh://git@github.com/queengooborg/babel-plugin-prismjs.git#9f810d9cd869fd59267a55057dd259c19d8954dc",
"dev": true,
+ "from": "babel-plugin-prismjs@github:queengooborg/babel-plugin-prismjs#patch-1-build",
"requires": {}
},
"babel-preset-current-node-syntax": {
@@ -14906,6 +15252,103 @@
"babel-preset-current-node-syntax": "^1.0.0"
}
},
+ "babel-runtime": {
+ "version": "6.26.0",
+ "resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.26.0.tgz",
+ "integrity": "sha512-ITKNuq2wKlW1fJg9sSW52eepoYgZBggvOAHC0u/CYu/qxQ9EVzThCgR69BnSXLHjy2f7SY5zaQ4yt7H9ZVxY2g==",
+ "dev": true,
+ "requires": {
+ "core-js": "^2.4.0",
+ "regenerator-runtime": "^0.11.0"
+ },
+ "dependencies": {
+ "regenerator-runtime": {
+ "version": "0.11.1",
+ "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz",
+ "integrity": "sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg==",
+ "dev": true
+ }
+ }
+ },
+ "babel-template": {
+ "version": "6.26.0",
+ "resolved": "https://registry.npmjs.org/babel-template/-/babel-template-6.26.0.tgz",
+ "integrity": "sha512-PCOcLFW7/eazGUKIoqH97sO9A2UYMahsn/yRQ7uOk37iutwjq7ODtcTNF+iFDSHNfkctqsLRjLP7URnOx0T1fg==",
+ "dev": true,
+ "requires": {
+ "babel-runtime": "^6.26.0",
+ "babel-traverse": "^6.26.0",
+ "babel-types": "^6.26.0",
+ "babylon": "^6.18.0",
+ "lodash": "^4.17.4"
+ }
+ },
+ "babel-traverse": {
+ "version": "6.26.0",
+ "resolved": "https://registry.npmjs.org/babel-traverse/-/babel-traverse-6.26.0.tgz",
+ "integrity": "sha512-iSxeXx7apsjCHe9c7n8VtRXGzI2Bk1rBSOJgCCjfyXb6v1aCqE1KSEpq/8SXuVN8Ka/Rh1WDTF0MDzkvTA4MIA==",
+ "dev": true,
+ "requires": {
+ "babel-code-frame": "^6.26.0",
+ "babel-messages": "^6.23.0",
+ "babel-runtime": "^6.26.0",
+ "babel-types": "^6.26.0",
+ "babylon": "^6.18.0",
+ "debug": "^2.6.8",
+ "globals": "^9.18.0",
+ "invariant": "^2.2.2",
+ "lodash": "^4.17.4"
+ },
+ "dependencies": {
+ "debug": {
+ "version": "2.6.9",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+ "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+ "dev": true,
+ "requires": {
+ "ms": "2.0.0"
+ }
+ },
+ "globals": {
+ "version": "9.18.0",
+ "resolved": "https://registry.npmjs.org/globals/-/globals-9.18.0.tgz",
+ "integrity": "sha512-S0nG3CLEQiY/ILxqtztTWH/3iRRdyBLw6KMDxnKMchrtbj2OFmehVh0WUCfW3DUrIgx/qFrJPICrq4Z4sTR9UQ==",
+ "dev": true
+ },
+ "ms": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+ "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==",
+ "dev": true
+ }
+ }
+ },
+ "babel-types": {
+ "version": "6.26.0",
+ "resolved": "https://registry.npmjs.org/babel-types/-/babel-types-6.26.0.tgz",
+ "integrity": "sha512-zhe3V/26rCWsEZK8kZN+HaQj5yQ1CilTObixFzKW1UWjqG7618Twz6YEsCnjfg5gBcJh02DrpCkS9h98ZqDY+g==",
+ "dev": true,
+ "requires": {
+ "babel-runtime": "^6.26.0",
+ "esutils": "^2.0.2",
+ "lodash": "^4.17.4",
+ "to-fast-properties": "^1.0.3"
+ },
+ "dependencies": {
+ "to-fast-properties": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-1.0.3.tgz",
+ "integrity": "sha512-lxrWP8ejsq+7E3nNjwYmUBMAgjMTZoTI+sdBOpvNyijeDLa29LUn9QaoXAHv4+Z578hbmHHJKZknzxVtvo77og==",
+ "dev": true
+ }
+ }
+ },
+ "babylon": {
+ "version": "6.18.0",
+ "resolved": "https://registry.npmjs.org/babylon/-/babylon-6.18.0.tgz",
+ "integrity": "sha512-q/UEjfGJ2Cm3oKV71DJz9d25TPnq5rhBVL2Q4fA5wcC3jcrdn7+SssEybFIxwAvvP+YCsCYNKughoF33GxgycQ==",
+ "dev": true
+ },
"balanced-match": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
@@ -15675,6 +16118,12 @@
"resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.1.3.tgz",
"integrity": "sha512-Y8L5rp6jo+g9VEPgvqNfEopjTR4OTYct8lXlS8iVQdmnjDvbdbzYe9rjtFCB9egC86JoNCU61WRY+ScjkZpnIg=="
},
+ "core-js": {
+ "version": "2.6.12",
+ "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.12.tgz",
+ "integrity": "sha512-Kb2wC0fvsWfQrgk8HU5lW6U/Lcs8+9aaYcy4ZFc6DDlo4nZ7n70dEgE5rtR0oG6ufKDUnrwfWL1mXR5ljDatrQ==",
+ "dev": true
+ },
"core-js-compat": {
"version": "3.25.0",
"resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.25.0.tgz",
@@ -16393,6 +16842,24 @@
"integrity": "sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA==",
"dev": true
},
+ "esmify": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/esmify/-/esmify-2.1.1.tgz",
+ "integrity": "sha512-GyOVgjG7sNyYB5Mbo15Ll4aGrcXZzZ3LI22rbLOjCI7L/wYelzQpBHRZkZkqbPNZ/QIRilcaHqzgNCLcEsi1lQ==",
+ "dev": true,
+ "requires": {
+ "@babel/core": "^7.2.2",
+ "@babel/plugin-syntax-async-generators": "^7.2.0",
+ "@babel/plugin-syntax-dynamic-import": "^7.2.0",
+ "@babel/plugin-syntax-object-rest-spread": "^7.2.0",
+ "@babel/plugin-transform-modules-commonjs": "^7.2.0",
+ "babel-plugin-import-to-require": "^1.0.0",
+ "cached-path-relative": "^1.0.2",
+ "concat-stream": "^1.6.2",
+ "duplexer2": "^0.1.4",
+ "through2": "^2.0.5"
+ }
+ },
"espree": {
"version": "9.4.0",
"resolved": "https://registry.npmjs.org/espree/-/espree-9.4.0.tgz",
@@ -17371,6 +17838,15 @@
"integrity": "sha512-Ju0Bz/cEia55xDwUWEa8+olFpCiQoypjnQySseKtmjNrnps3P+xfpUmGr90T7yjlVJmOtybRvPXhKMbHr+fWnw==",
"dev": true
},
+ "invariant": {
+ "version": "2.2.4",
+ "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz",
+ "integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==",
+ "dev": true,
+ "requires": {
+ "loose-envify": "^1.0.0"
+ }
+ },
"is-arguments": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.1.1.tgz",
@@ -18822,6 +19298,15 @@
}
}
},
+ "loose-envify": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz",
+ "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==",
+ "dev": true,
+ "requires": {
+ "js-tokens": "^3.0.0 || ^4.0.0"
+ }
+ },
"lru-cache": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
@@ -20776,6 +21261,13 @@
"integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==",
"dev": true
},
+ "style-loader": {
+ "version": "3.3.1",
+ "resolved": "https://registry.npmjs.org/style-loader/-/style-loader-3.3.1.tgz",
+ "integrity": "sha512-GPcQ+LDJbrcxHORTRes6Jy2sfvK2kS6hpSfI/fXhPt+spVzxF6LJ1dHLN9zIGmVaaP044YKaIatFaufENRiDoQ==",
+ "dev": true,
+ "requires": {}
+ },
"subarg": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/subarg/-/subarg-1.0.0.tgz",
diff --git a/package.json b/package.json
index fe6116d2d..13bc3407a 100644
--- a/package.json
+++ b/package.json
@@ -18,6 +18,7 @@
"engines": {
"node": "^16.0.0 || >=18.0.0"
},
+ "type": "module",
"main": "./lib/mdn-bob.js",
"bundlesize": [
{
@@ -68,7 +69,8 @@
"format": "prettier --ignore-unknown --check \"*\"",
"format:fix": "prettier --ignore-unknown --write \"*\"",
"fix": "npm run format:fix",
- "test": "npm run format && jest",
+ "test": "npm run format && npm run jest",
+ "jest": "JEST_PUPPETEER_CONFIG=jest-puppeteer.config.cjs NODE_OPTIONS=--experimental-vm-modules jest",
"perf": "bundlesize",
"webpack": "webpack"
},
@@ -86,13 +88,14 @@
"@babel/core": "^7.19.0",
"@babel/preset-env": "^7.19.0",
"babel-loader": "^8.2.5",
- "babel-plugin-prismjs": "^2.1.0",
+ "babel-plugin-prismjs": "github:queengooborg/babel-plugin-prismjs#patch-1-build",
"bundlesize": "0.18.1",
"clipboard": "^2.0.11",
"css-loader": "^6.7.1",
"eslint": "^8.2.0",
"eslint-config-prettier": "^8.3.0",
"eslint-plugin-import": "^2.25.3",
+ "esmify": "^2.1.1",
"http-server": "14.1.1",
"husky": "^8.0.1",
"jest": "29.0.3",
@@ -104,6 +107,7 @@
"prettier-eslint": "15.0.1",
"prismjs": "1.29.0",
"puppeteer": "17.1.3",
+ "style-loader": "^3.3.1",
"webpack-cli": "^4.10.0"
},
"dependencies": {
diff --git a/webpack.config.js b/webpack.config.js
index 357bf0994..411ad4913 100644
--- a/webpack.config.js
+++ b/webpack.config.js
@@ -1,7 +1,10 @@
-const path = require("path");
-const webpack = require("webpack");
+import { fileURLToPath } from "node:url";
+import { createRequire } from "node:module";
+import webpack from "webpack";
-module.exports = {
+const require = createRequire(import.meta.url);
+
+export default {
mode: "production",
plugins: [
new webpack.BannerPlugin(
@@ -15,7 +18,7 @@ module.exports = {
"css-examples-libs": "./editor/js/css-examples-libs.js",
},
output: {
- path: path.resolve(__dirname, "docs/js"),
+ path: fileURLToPath(new URL("docs/js", import.meta.url)),
},
module: {
rules: [