diff --git a/js/core/highlight.js b/js/core/highlight.js index 4d2034769d..fa8c577020 100644 --- a/js/core/highlight.js +++ b/js/core/highlight.js @@ -6,15 +6,27 @@ define( [ "core/pubsubhub", "core/utils", - "deps/highlight", + "core/worker", "deps/text!core/css/github.css", ], - function(pubsubhub, utils, hljs, ghCss) { + function(pubsubhub, utils, worker, 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); + + function getLanguageHint(classList) { + return Array + .from(classList) + .filter(function(item) { + return item !== "highlight" + }) + .map(function(item) { + return item.toLowerCase(item) + }); + } + return { run: function(conf, doc, cb) { // Nothing to do @@ -26,18 +38,44 @@ define( swapStyleOwner(doc.head); } - if (doc.querySelector("highlight")) { + if (doc.querySelector(".highlight")) { pubsubhub.pub("warn", "pre elements don't need a 'highlight' class anymore."); } - Array + const promisesToHighlight = Array .from( doc.querySelectorAll("pre:not(.idl)") ) - .forEach(function(element) { - hljs.highlightBlock(element); + .map(function(element) { + return new Promise(function(resolve, reject) { + const msg = { + action: "highlight", + code: element.innerHTML, + id: Math.random().toString(), + languages: getLanguageHint(element.classList), + }; + worker.postMessage(msg); + worker.addEventListener("message", function handler(ev) { + if (ev.data.id !== msg.id) { + return; // not for us! + } + worker.removeEventListener("message", handler); + element.innerHTML = ev.data.value; + resolve(); + }); + setTimeout(function() { + const errMsg = "Timeout error trying to process: " + msg.code; + const err = new Error(errMsg); + reject(err) + }, 5000); + }); + }); + Promise + .all(promisesToHighlight) + .then(function() { cb() }) + .catch(function(err) { + console.error(err); }); - cb(); } }; } diff --git a/js/core/worker.js b/js/core/worker.js new file mode 100644 index 0000000000..24d7589363 --- /dev/null +++ b/js/core/worker.js @@ -0,0 +1,4 @@ +"use strict"; +define([], function() { + return new Worker("/worker/respec-worker.js"); +}); diff --git a/worker/respec-worker.js b/worker/respec-worker.js index d9d11a57a1..bcbd509666 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("/js/deps/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); + } +});