diff --git a/.gitignore b/.gitignore
index cca22d9156..328af63790 100644
--- a/.gitignore
+++ b/.gitignore
@@ -15,6 +15,7 @@ js/core/biblio.js
js/core/data-cite.js
js/core/data-include.js
js/core/default-root-attr.js
+js/core/highlight.js
js/core/include-config.js
js/core/override-configuration.js
js/core/post-process.js
@@ -22,3 +23,4 @@ js/core/pre-process.js
js/core/pubsubhub.js
js/core/remove-respec.js
js/core/respec-ready.js
+js/core/worker.js
diff --git a/js/core/highlight.js b/js/core/highlight.js
deleted file mode 100644
index 4d2034769d..0000000000
--- a/js/core/highlight.js
+++ /dev/null
@@ -1,44 +0,0 @@
-// Module core/highlight
-// Does syntax highlighting to all pre and code that have a class of "highlight"
-// An improvement would be to use web workers to do the highlighting.
-"use strict";
-define(
- [
- "core/pubsubhub",
- "core/utils",
- "deps/highlight",
- "deps/text!core/css/github.css",
- ],
- function(pubsubhub, utils, hljs, ghCss) {
- // Opportunistically insert the style into the head to reduce FOUC.
- var codeStyle = document.createElement("style");
- codeStyle.textContent = ghCss;
- var swapStyleOwner = utils.makeOwnerSwapper(codeStyle);
- swapStyleOwner(document.head);
- return {
- run: function(conf, doc, cb) {
- // Nothing to do
- if (conf.noHighlightCSS) {
- return cb();
- }
-
- if (codeStyle.ownerDocument !== doc) {
- swapStyleOwner(doc.head);
- }
-
- if (doc.querySelector("highlight")) {
- pubsubhub.pub("warn", "pre elements don't need a 'highlight' class anymore.");
- }
-
- Array
- .from(
- doc.querySelectorAll("pre:not(.idl)")
- )
- .forEach(function(element) {
- hljs.highlightBlock(element);
- });
- cb();
- }
- };
- }
-);
diff --git a/js/core/markdown.js b/js/core/markdown.js
index b2b0ecef0e..380b848487 100644
--- a/js/core/markdown.js
+++ b/js/core/markdown.js
@@ -270,8 +270,8 @@ define([
.replace(/\n\s*" item !== "highlight")
+ .map(item => item.toLowerCase());
+}
+let doneResolver;
+let doneRejector;
+export const done = new Promise((resolve, reject) => {
+ doneResolver = resolve;
+ doneRejector = reject;
+});
+
+export async function run(conf, doc, cb) {
+ // Nothing to do
+ if (conf.noHighlightCSS) {
+ doneResolver();
+ return cb();
+ }
+
+ if (codeStyle.ownerDocument !== doc) {
+ swapStyleOwner(doc.head);
+ }
+
+ if (doc.querySelector(".highlight")) {
+ pub("warn", "pre elements don't need a 'highlight' class anymore.");
+ }
+
+ const promisesToHighlight = Array
+ .from(
+ doc.querySelectorAll("pre:not(.idl):not(.highlightdone)")
+ )
+ .map(element => {
+ return new Promise((resolve, reject) => {
+ if (element.textContent.trim() === "") {
+ return resolve(); // no work to do
+ }
+ const msg = {
+ action: "highlight",
+ code: element.textContent,
+ id: Math.random().toString(),
+ languages: getLanguageHint(element.classList),
+ };
+
+ worker.postMessage(msg);
+ worker.addEventListener("message", function listener(ev) {
+ if (ev.data.id !== msg.id) {
+ return; // not for us!
+ }
+ worker.removeEventListener("message", listener);
+ element.innerHTML = ev.data.value;
+ element.classList.add("hljs");
+ resolve();
+ });
+ setTimeout(() => {
+ const errMsg = "Timeout error trying to process: " + msg.code;
+ const err = new Error(errMsg);
+ reject(err);
+ }, 5000);
+ });
+ });
+ try {
+ await Promise.all(promisesToHighlight);
+ doneResolver();
+ } catch (err) {
+ console.error(err);
+ doneRejector(err);
+ }
+ cb();
+}
diff --git a/src/core/worker.js b/src/core/worker.js
new file mode 100644
index 0000000000..cdc4166d24
--- /dev/null
+++ b/src/core/worker.js
@@ -0,0 +1,21 @@
+/**
+ * Module core/worker
+ *
+ * Exports a Web Worker for ReSpec, allowing for
+ * multi-threaded processing of things.
+ */
+
+// Opportunistically preload syntax highlighter, which is used by the worker
+import utils from "core/utils";
+import workerScript from "deps/text!../../worker/respec-worker.js";
+// Opportunistically preload syntax highlighter
+const hint = {
+ hint: "preload",
+ href: "https://www.w3.org/Tools/respec/respec-highlight.js",
+ as: "script",
+};
+const link = utils.createResourceHint(hint);
+document.head.appendChild(link);
+
+const workerURL = URL.createObjectURL(new Blob([workerScript], {type : 'application/javascript'}));
+export const worker = new Worker(workerURL);
diff --git a/tests/spec/core/highlight-spec.js b/tests/spec/core/highlight-spec.js
index 10b4cefa8c..bd05aa9374 100644
--- a/tests/spec/core/highlight-spec.js
+++ b/tests/spec/core/highlight-spec.js
@@ -1,19 +1,20 @@
"use strict";
describe("Core — Highlight", function() {
- afterAll(function(done) {
+ afterAll(done => {
flushIframes();
done();
});
- it("should't highlight idl blocks", function(done){
+ it("shouldn't highlight idl blocks", done => {
var ops = {
config: makeBasicConfig(),
- body: makeDefaultBody() +
- ""+
- "[Constructor]interface Dahut : Mammal {" +
- " const unsigned short DEXTROGYROUS = 1;" +
- " Dahut turnAround(float angle, boolean fall);" +
- "};
+ [Constructor]interface Dahut : Mammal {
+ const unsigned short DEXTROGYROUS = 1;
+ Dahut turnAround(float angle, boolean fall);
+ };
+ function () {\n alert('foo');\n}
+ function foo() {
+ alert('foo');
+ }
+
+ function () {\n alert('foo');\n}
+ function foo() {
+ alert('foo');
+ }
+
+ function () {\n alert('foo');\n}
+ function foo() {
+ alert('foo');
+ }
+
+
\n" + - "\t this won't link \n" + - "\t this will link: http://no-links-foo.com \n" + - "\t so will this: http://no-links-bar.com \n" + - "\n\n\n" + body: makeDefaultBody() + ` ++ this won't link + this will link: http://no-links-foo.com + so will this: http://no-links-bar.com +` }; ops.config.format = "markdown"; makeRSDoc(ops, function(doc) { @@ -224,11 +224,12 @@ describe("Core - Markdown", function() { it("replaces HTMLAnchors when present", function(done) { var ops = { config: makeBasicConfig(), - body: makeDefaultBody() + - "\n" + - "\t http://no-links-foo.com \n" + - "\t http://no-links-bar.com \n" + - "\n\n\n" + body: makeDefaultBody() +` ++ http://no-links-foo.com + http://no-links-bar.com ++ ` }; ops.config.format = "markdown"; makeRSDoc(ops, function(doc) { diff --git a/worker/respec-worker.js b/worker/respec-worker.js index d9d11a57a1..afe3c024b1 100644 --- a/worker/respec-worker.js +++ b/worker/respec-worker.js @@ -1 +1,27 @@ -// ReSpec Worker v0 +// ReSpec Worker v0.1.0 +"use strict"; +importScripts("https://www.w3.org/Tools/respec/respec-highlight.js"); + +hljs.configure({ + tabReplace: " ", // 2 spaces + languages: [ + "css", + "http", + "javascript", + "json", + "markdown", + "xml", + "xquery", + ], +}); + +self.addEventListener("message", function(e) { + switch (e.data.action) { + case "highlight": + const code = e.data.code; + const langs = e.data.languages.length ? e.data.languages : undefined; + const result = self.hljs.highlightAuto(code, langs); + const data = Object.assign({}, e.data, result); + self.postMessage(data); + } +});