From 7c73f0ef656de46daff0760d39a5f016d56445aa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20D=C3=BCsterhus?= Date: Mon, 1 Jul 2019 20:01:37 +0200 Subject: [PATCH 1/4] Doubly check the `manual` flag Currently the `manual` is only checked before attaching the event listener, making it hard to reliably set the flag without jumping through hoops and special cases if Prism is bundled together with other scripts into a single script file. Change to check the flag once before attaching the event listener and once again before actually highlighting to support setting it after the Prism initialization has run. see discussion starting at: https://github.com/PrismJS/prism/pull/1087#issuecomment-274959529 --- components/prism-core.js | 12 +++++++++--- components/prism-core.min.js | 2 +- prism.js | 12 +++++++++--- 3 files changed, 19 insertions(+), 7 deletions(-) diff --git a/components/prism-core.js b/components/prism-core.js index 70afd3b672..79cf6651a5 100644 --- a/components/prism-core.js +++ b/components/prism-core.js @@ -533,15 +533,21 @@ if (script) { _.filename = script.src; if (!_.manual && !script.hasAttribute('data-manual')) { + _.highlightAutomaticallyCallback = function () { + if (!_.manual) { + _.highlightAll(); + } + } + if(document.readyState !== 'loading') { if (window.requestAnimationFrame) { - window.requestAnimationFrame(_.highlightAll); + window.requestAnimationFrame(_.highlightAutomaticallyCallback); } else { - window.setTimeout(_.highlightAll, 16); + window.setTimeout(_.highlightAutomaticallyCallback, 16); } } else { - document.addEventListener('DOMContentLoaded', _.highlightAll); + document.addEventListener('DOMContentLoaded', _.highlightAutomaticallyCallback); } } } diff --git a/components/prism-core.min.js b/components/prism-core.min.js index ce0c4a49d6..c09c523eb7 100644 --- a/components/prism-core.min.js +++ b/components/prism-core.min.js @@ -1 +1 @@ -var _self="undefined"!=typeof window?window:"undefined"!=typeof WorkerGlobalScope&&self instanceof WorkerGlobalScope?self:{},Prism=function(c){var g=/\blang(?:uage)?-([\w-]+)\b/i,a=0;var _={manual:c.Prism&&c.Prism.manual,disableWorkerMessageHandler:c.Prism&&c.Prism.disableWorkerMessageHandler,util:{encode:function(e){return e instanceof L?new L(e.type,_.util.encode(e.content),e.alias):Array.isArray(e)?e.map(_.util.encode):e.replace(/&/g,"&").replace(/e.length)return;if(!(k instanceof L)){if(f&&y!=a.length-1){if(g.lastIndex=v,!(x=g.exec(e)))break;for(var b=x.index+(h&&x[1]?x[1].length:0),w=x.index+x[0].length,A=y,P=v,O=a.length;A"+n.content+""},!c.document)return c.addEventListener&&(_.disableWorkerMessageHandler||c.addEventListener("message",function(e){var a=JSON.parse(e.data),n=a.language,r=a.code,t=a.immediateClose;c.postMessage(_.highlight(r,_.languages[n],n)),t&&c.close()},!1)),_;var e=document.currentScript||[].slice.call(document.getElementsByTagName("script")).pop();return e&&(_.filename=e.src,_.manual||e.hasAttribute("data-manual")||("loading"!==document.readyState?window.requestAnimationFrame?window.requestAnimationFrame(_.highlightAll):window.setTimeout(_.highlightAll,16):document.addEventListener("DOMContentLoaded",_.highlightAll))),_}(_self);"undefined"!=typeof module&&module.exports&&(module.exports=Prism),"undefined"!=typeof global&&(global.Prism=Prism); \ No newline at end of file +var _self="undefined"!=typeof window?window:"undefined"!=typeof WorkerGlobalScope&&self instanceof WorkerGlobalScope?self:{},Prism=function(c){var u=/\blang(?:uage)?-([\w-]+)\b/i,a=0;var _={manual:c.Prism&&c.Prism.manual,disableWorkerMessageHandler:c.Prism&&c.Prism.disableWorkerMessageHandler,util:{encode:function(e){return e instanceof L?new L(e.type,_.util.encode(e.content),e.alias):Array.isArray(e)?e.map(_.util.encode):e.replace(/&/g,"&").replace(/e.length)return;if(!(k instanceof L)){if(f&&y!=a.length-1){if(u.lastIndex=v,!(x=u.exec(e)))break;for(var b=x.index+(h&&x[1]?x[1].length:0),w=x.index+x[0].length,A=y,P=v,O=a.length;A"+t.content+""},!c.document)return c.addEventListener&&(_.disableWorkerMessageHandler||c.addEventListener("message",function(e){var a=JSON.parse(e.data),t=a.language,n=a.code,r=a.immediateClose;c.postMessage(_.highlight(n,_.languages[t],t)),r&&c.close()},!1)),_;var e=document.currentScript||[].slice.call(document.getElementsByTagName("script")).pop();return e&&(_.filename=e.src,_.manual||e.hasAttribute("data-manual")||(_.highlightAutomaticallyCallback=function(){_.manual||_.highlightAll()},"loading"!==document.readyState?window.requestAnimationFrame?window.requestAnimationFrame(_.highlightAutomaticallyCallback):window.setTimeout(_.highlightAutomaticallyCallback,16):document.addEventListener("DOMContentLoaded",_.highlightAutomaticallyCallback))),_}(_self);"undefined"!=typeof module&&module.exports&&(module.exports=Prism),"undefined"!=typeof global&&(global.Prism=Prism); \ No newline at end of file diff --git a/prism.js b/prism.js index dc0e9c16ef..59ae3ef2ca 100644 --- a/prism.js +++ b/prism.js @@ -538,15 +538,21 @@ if (script) { _.filename = script.src; if (!_.manual && !script.hasAttribute('data-manual')) { + _.highlightAutomaticallyCallback = function () { + if (!_.manual) { + _.highlightAll(); + } + } + if(document.readyState !== 'loading') { if (window.requestAnimationFrame) { - window.requestAnimationFrame(_.highlightAll); + window.requestAnimationFrame(_.highlightAutomaticallyCallback); } else { - window.setTimeout(_.highlightAll, 16); + window.setTimeout(_.highlightAutomaticallyCallback, 16); } } else { - document.addEventListener('DOMContentLoaded', _.highlightAll); + document.addEventListener('DOMContentLoaded', _.highlightAutomaticallyCallback); } } } From d0ddf47bf3c5b0823762f8115a17b50f80c3a458 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20D=C3=BCsterhus?= Date: Thu, 25 Jul 2019 00:14:44 +0200 Subject: [PATCH 2/4] Do not expose `highlightAutomaticallyCallback` --- components/prism-core.js | 8 ++++---- components/prism-core.min.js | 2 +- prism.js | 8 ++++---- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/components/prism-core.js b/components/prism-core.js index 79cf6651a5..2e5e342cb8 100644 --- a/components/prism-core.js +++ b/components/prism-core.js @@ -533,7 +533,7 @@ if (script) { _.filename = script.src; if (!_.manual && !script.hasAttribute('data-manual')) { - _.highlightAutomaticallyCallback = function () { + function highlightAutomaticallyCallback() { if (!_.manual) { _.highlightAll(); } @@ -541,13 +541,13 @@ if (script) { if(document.readyState !== 'loading') { if (window.requestAnimationFrame) { - window.requestAnimationFrame(_.highlightAutomaticallyCallback); + window.requestAnimationFrame(highlightAutomaticallyCallback); } else { - window.setTimeout(_.highlightAutomaticallyCallback, 16); + window.setTimeout(highlightAutomaticallyCallback, 16); } } else { - document.addEventListener('DOMContentLoaded', _.highlightAutomaticallyCallback); + document.addEventListener('DOMContentLoaded', highlightAutomaticallyCallback); } } } diff --git a/components/prism-core.min.js b/components/prism-core.min.js index c09c523eb7..7c611c3238 100644 --- a/components/prism-core.min.js +++ b/components/prism-core.min.js @@ -1 +1 @@ -var _self="undefined"!=typeof window?window:"undefined"!=typeof WorkerGlobalScope&&self instanceof WorkerGlobalScope?self:{},Prism=function(c){var u=/\blang(?:uage)?-([\w-]+)\b/i,a=0;var _={manual:c.Prism&&c.Prism.manual,disableWorkerMessageHandler:c.Prism&&c.Prism.disableWorkerMessageHandler,util:{encode:function(e){return e instanceof L?new L(e.type,_.util.encode(e.content),e.alias):Array.isArray(e)?e.map(_.util.encode):e.replace(/&/g,"&").replace(/e.length)return;if(!(k instanceof L)){if(f&&y!=a.length-1){if(u.lastIndex=v,!(x=u.exec(e)))break;for(var b=x.index+(h&&x[1]?x[1].length:0),w=x.index+x[0].length,A=y,P=v,O=a.length;A"+t.content+""},!c.document)return c.addEventListener&&(_.disableWorkerMessageHandler||c.addEventListener("message",function(e){var a=JSON.parse(e.data),t=a.language,n=a.code,r=a.immediateClose;c.postMessage(_.highlight(n,_.languages[t],t)),r&&c.close()},!1)),_;var e=document.currentScript||[].slice.call(document.getElementsByTagName("script")).pop();return e&&(_.filename=e.src,_.manual||e.hasAttribute("data-manual")||(_.highlightAutomaticallyCallback=function(){_.manual||_.highlightAll()},"loading"!==document.readyState?window.requestAnimationFrame?window.requestAnimationFrame(_.highlightAutomaticallyCallback):window.setTimeout(_.highlightAutomaticallyCallback,16):document.addEventListener("DOMContentLoaded",_.highlightAutomaticallyCallback))),_}(_self);"undefined"!=typeof module&&module.exports&&(module.exports=Prism),"undefined"!=typeof global&&(global.Prism=Prism); \ No newline at end of file +var _self="undefined"!=typeof window?window:"undefined"!=typeof WorkerGlobalScope&&self instanceof WorkerGlobalScope?self:{},Prism=function(c){var u=/\blang(?:uage)?-([\w-]+)\b/i,a=0;var _={manual:c.Prism&&c.Prism.manual,disableWorkerMessageHandler:c.Prism&&c.Prism.disableWorkerMessageHandler,util:{encode:function(e){return e instanceof L?new L(e.type,_.util.encode(e.content),e.alias):Array.isArray(e)?e.map(_.util.encode):e.replace(/&/g,"&").replace(/e.length)return;if(!(k instanceof L)){if(h&&y!=a.length-1){if(u.lastIndex=v,!(x=u.exec(e)))break;for(var b=x.index+(f&&x[1]?x[1].length:0),w=x.index+x[0].length,A=y,P=v,O=a.length;A"+n.content+""},!c.document)return c.addEventListener&&(_.disableWorkerMessageHandler||c.addEventListener("message",function(e){var a=JSON.parse(e.data),n=a.language,r=a.code,t=a.immediateClose;c.postMessage(_.highlight(r,_.languages[n],n)),t&&c.close()},!1)),_;var e=document.currentScript||[].slice.call(document.getElementsByTagName("script")).pop();if(e&&(_.filename=e.src,!_.manual&&!e.hasAttribute("data-manual"))){function n(){_.manual||_.highlightAll()}"loading"!==document.readyState?window.requestAnimationFrame?window.requestAnimationFrame(n):window.setTimeout(n,16):document.addEventListener("DOMContentLoaded",n)}return _}(_self);"undefined"!=typeof module&&module.exports&&(module.exports=Prism),"undefined"!=typeof global&&(global.Prism=Prism); \ No newline at end of file diff --git a/prism.js b/prism.js index 59ae3ef2ca..eaf7f2aa5e 100644 --- a/prism.js +++ b/prism.js @@ -538,7 +538,7 @@ if (script) { _.filename = script.src; if (!_.manual && !script.hasAttribute('data-manual')) { - _.highlightAutomaticallyCallback = function () { + function highlightAutomaticallyCallback() { if (!_.manual) { _.highlightAll(); } @@ -546,13 +546,13 @@ if (script) { if(document.readyState !== 'loading') { if (window.requestAnimationFrame) { - window.requestAnimationFrame(_.highlightAutomaticallyCallback); + window.requestAnimationFrame(highlightAutomaticallyCallback); } else { - window.setTimeout(_.highlightAutomaticallyCallback, 16); + window.setTimeout(highlightAutomaticallyCallback, 16); } } else { - document.addEventListener('DOMContentLoaded', _.highlightAutomaticallyCallback); + document.addEventListener('DOMContentLoaded', highlightAutomaticallyCallback); } } } From 91d621a2abbbdf383be832c5817cf6884cfd4138 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20D=C3=BCsterhus?= Date: Thu, 25 Jul 2019 00:18:35 +0200 Subject: [PATCH 3/4] Make `data-manual` set `Prism.manual` to `true` --- components/prism-core.js | 32 ++++++++++++++++++-------------- components/prism-core.min.js | 2 +- prism.js | 32 ++++++++++++++++++-------------- 3 files changed, 37 insertions(+), 29 deletions(-) diff --git a/components/prism-core.js b/components/prism-core.js index 2e5e342cb8..f1d001f432 100644 --- a/components/prism-core.js +++ b/components/prism-core.js @@ -531,25 +531,29 @@ var script = document.currentScript || [].slice.call(document.getElementsByTagNa if (script) { _.filename = script.src; + + if (script.hasAttribute('data-manual')) { + _.manual = true; + } +} - if (!_.manual && !script.hasAttribute('data-manual')) { - function highlightAutomaticallyCallback() { - if (!_.manual) { - _.highlightAll(); - } +if (!_.manual) { + function highlightAutomaticallyCallback() { + if (!_.manual) { + _.highlightAll(); } + } - if(document.readyState !== 'loading') { - if (window.requestAnimationFrame) { - window.requestAnimationFrame(highlightAutomaticallyCallback); - } else { - window.setTimeout(highlightAutomaticallyCallback, 16); - } - } - else { - document.addEventListener('DOMContentLoaded', highlightAutomaticallyCallback); + if(document.readyState !== 'loading') { + if (window.requestAnimationFrame) { + window.requestAnimationFrame(highlightAutomaticallyCallback); + } else { + window.setTimeout(highlightAutomaticallyCallback, 16); } } + else { + document.addEventListener('DOMContentLoaded', highlightAutomaticallyCallback); + } } return _; diff --git a/components/prism-core.min.js b/components/prism-core.min.js index 7c611c3238..d7e53f2afc 100644 --- a/components/prism-core.min.js +++ b/components/prism-core.min.js @@ -1 +1 @@ -var _self="undefined"!=typeof window?window:"undefined"!=typeof WorkerGlobalScope&&self instanceof WorkerGlobalScope?self:{},Prism=function(c){var u=/\blang(?:uage)?-([\w-]+)\b/i,a=0;var _={manual:c.Prism&&c.Prism.manual,disableWorkerMessageHandler:c.Prism&&c.Prism.disableWorkerMessageHandler,util:{encode:function(e){return e instanceof L?new L(e.type,_.util.encode(e.content),e.alias):Array.isArray(e)?e.map(_.util.encode):e.replace(/&/g,"&").replace(/e.length)return;if(!(k instanceof L)){if(h&&y!=a.length-1){if(u.lastIndex=v,!(x=u.exec(e)))break;for(var b=x.index+(f&&x[1]?x[1].length:0),w=x.index+x[0].length,A=y,P=v,O=a.length;A"+n.content+""},!c.document)return c.addEventListener&&(_.disableWorkerMessageHandler||c.addEventListener("message",function(e){var a=JSON.parse(e.data),n=a.language,r=a.code,t=a.immediateClose;c.postMessage(_.highlight(r,_.languages[n],n)),t&&c.close()},!1)),_;var e=document.currentScript||[].slice.call(document.getElementsByTagName("script")).pop();if(e&&(_.filename=e.src,!_.manual&&!e.hasAttribute("data-manual"))){function n(){_.manual||_.highlightAll()}"loading"!==document.readyState?window.requestAnimationFrame?window.requestAnimationFrame(n):window.setTimeout(n,16):document.addEventListener("DOMContentLoaded",n)}return _}(_self);"undefined"!=typeof module&&module.exports&&(module.exports=Prism),"undefined"!=typeof global&&(global.Prism=Prism); \ No newline at end of file +var _self="undefined"!=typeof window?window:"undefined"!=typeof WorkerGlobalScope&&self instanceof WorkerGlobalScope?self:{},Prism=function(u){var c=/\blang(?:uage)?-([\w-]+)\b/i,a=0;var _={manual:u.Prism&&u.Prism.manual,disableWorkerMessageHandler:u.Prism&&u.Prism.disableWorkerMessageHandler,util:{encode:function(e){return e instanceof L?new L(e.type,_.util.encode(e.content),e.alias):Array.isArray(e)?e.map(_.util.encode):e.replace(/&/g,"&").replace(/e.length)return;if(!(k instanceof L)){if(h&&y!=a.length-1){if(c.lastIndex=v,!(x=c.exec(e)))break;for(var b=x.index+(f&&x[1]?x[1].length:0),w=x.index+x[0].length,A=y,P=v,O=a.length;A"+n.content+""},!u.document)return u.addEventListener&&(_.disableWorkerMessageHandler||u.addEventListener("message",function(e){var a=JSON.parse(e.data),n=a.language,r=a.code,t=a.immediateClose;u.postMessage(_.highlight(r,_.languages[n],n)),t&&u.close()},!1)),_;var e=document.currentScript||[].slice.call(document.getElementsByTagName("script")).pop();if(e&&(_.filename=e.src,e.hasAttribute("data-manual")&&(_.manual=!0)),!_.manual){function n(){_.manual||_.highlightAll()}"loading"!==document.readyState?window.requestAnimationFrame?window.requestAnimationFrame(n):window.setTimeout(n,16):document.addEventListener("DOMContentLoaded",n)}return _}(_self);"undefined"!=typeof module&&module.exports&&(module.exports=Prism),"undefined"!=typeof global&&(global.Prism=Prism); \ No newline at end of file diff --git a/prism.js b/prism.js index eaf7f2aa5e..6a77215d44 100644 --- a/prism.js +++ b/prism.js @@ -536,25 +536,29 @@ var script = document.currentScript || [].slice.call(document.getElementsByTagNa if (script) { _.filename = script.src; + + if (script.hasAttribute('data-manual')) { + _.manual = true; + } +} - if (!_.manual && !script.hasAttribute('data-manual')) { - function highlightAutomaticallyCallback() { - if (!_.manual) { - _.highlightAll(); - } +if (!_.manual) { + function highlightAutomaticallyCallback() { + if (!_.manual) { + _.highlightAll(); } + } - if(document.readyState !== 'loading') { - if (window.requestAnimationFrame) { - window.requestAnimationFrame(highlightAutomaticallyCallback); - } else { - window.setTimeout(highlightAutomaticallyCallback, 16); - } - } - else { - document.addEventListener('DOMContentLoaded', highlightAutomaticallyCallback); + if(document.readyState !== 'loading') { + if (window.requestAnimationFrame) { + window.requestAnimationFrame(highlightAutomaticallyCallback); + } else { + window.setTimeout(highlightAutomaticallyCallback, 16); } } + else { + document.addEventListener('DOMContentLoaded', highlightAutomaticallyCallback); + } } return _; From 259eaed69e996b9d0817939e77912f7d15920919 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20D=C3=BCsterhus?= Date: Thu, 25 Jul 2019 01:03:15 +0200 Subject: [PATCH 4/4] Document the `Prism.manual` flag Closes #1402 --- index.html | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/index.html b/index.html index 62797b18d0..27c6327ac9 100644 --- a/index.html +++ b/index.html @@ -149,9 +149,16 @@

Basic usage

<pre><code class="language-css">p { color: red }</code></pre>

If you use that pattern, the <pre> will automatically get the language-xxxx class (if it doesn’t already have it) and will be styled as a code block.

-

If you want to prevent any elements from being automatically highlighted, you can use the attribute data-manual on the <script> element you used for prism and use the API. +

If you want to prevent any elements from being automatically highlighted and instead use the API, you can set Prism.manual to true before the DOMContentLoaded event is fired. By setting the data-manual attribute on the <script> element containing Prism core, this will be done automatically. Example:

<script src="prism.js" data-manual></script>
+

or

+
<script>
+window.Prism = window.Prism || {};
+window.Prism.manual = true;
+</script>
+<script src="prism.js"></script>
+

Usage with CDNs

In combination with CDNs, we recommend using the Autoloader plugin which automatically loads languages when necessary.