diff --git a/plugins/keep-markup/index.html b/plugins/keep-markup/index.html index 01d52692d2..542ef4e4c4 100644 --- a/plugins/keep-markup/index.html +++ b/plugins/keep-markup/index.html @@ -27,7 +27,7 @@ -
+However, you can deactivate the plugin for certain code element by adding the no-keep-markup
class to it. You can also deactivate the plugin for the whole page by adding the no-keep-markup
class to the body of the page and then selectively activate it again by adding the keep-markup
class to code elements.
Some plugins (e.g. Autoloader) need to re-highlight code blocks. This is a problem for Keep Markup because it will keep the markup of the first highlighting pass resulting in a lot of unnecessary DOM nodes and causing problems for themes and other plugins.
+ +This problem can be fixed by adding a drop-tokens
class to a code block or any of its ancestors. If drop-tokens
is present, Keep Markup will ignore all span.token
elements created by Prism.
The following source code
diff --git a/plugins/keep-markup/prism-keep-markup.js b/plugins/keep-markup/prism-keep-markup.js index 267d9d9433..c160faa88f 100644 --- a/plugins/keep-markup/prism-keep-markup.js +++ b/plugins/keep-markup/prism-keep-markup.js @@ -15,31 +15,53 @@ return; } + var dropTokens = Prism.util.isActive(env.element, 'drop-tokens', false); + /** + * Returns whether the given element should be kept. + * + * @param {HTMLElement} element + * @returns {boolean} + */ + function shouldKeep(element) { + if (dropTokens && element.nodeName.toLowerCase() === 'span' && element.classList.contains('token')) { + return false; + } + return true; + } + var pos = 0; var data = []; - var f = function (elt, baseNode) { - var o = {}; - if (!baseNode) { - // Clone the original tag to keep all attributes - o.clone = elt.cloneNode(false); - o.posOpen = pos; - data.push(o); + function processElement(element) { + if (!shouldKeep(element)) { + // don't keep this element and just process its children + processChildren(element); + return; } - for (var i = 0, l = elt.childNodes.length; i < l; i++) { - var child = elt.childNodes[i]; + + var o = { + // Clone the original tag to keep all attributes + clone: element.cloneNode(false), + posOpen: pos + }; + data.push(o); + + processChildren(element); + + o.posClose = pos; + } + function processChildren(element) { + for (var i = 0, l = element.childNodes.length; i < l; i++) { + var child = element.childNodes[i]; if (child.nodeType === 1) { // element - f(child); + processElement(child); } else if (child.nodeType === 3) { // text pos += child.data.length; } } - if (!baseNode) { - o.posClose = pos; - } - }; - f(env.element, true); + } + processChildren(env.element); - if (data && data.length) { + if (data.length) { // data is an array of all existing tags env.keepMarkup = data; } diff --git a/plugins/keep-markup/prism-keep-markup.min.js b/plugins/keep-markup/prism-keep-markup.min.js index 229c510218..6bea9d2efd 100644 --- a/plugins/keep-markup/prism-keep-markup.min.js +++ b/plugins/keep-markup/prism-keep-markup.min.js @@ -1 +1 @@ -"undefined"!=typeof Prism&&"undefined"!=typeof document&&document.createRange&&(Prism.plugins.KeepMarkup=!0,Prism.hooks.add("before-highlight",function(e){if(e.element.children.length&&Prism.util.isActive(e.element,"keep-markup",!0)){var a=0,s=[],p=function(e,n){var o={};n||(o.clone=e.cloneNode(!1),o.posOpen=a,s.push(o));for(var t=0,d=e.childNodes.length;tvar a = 42;
';
+ const code = pre.childNodes[0];
+ const initial = code.innerHTML;
+
+ Prism.highlightElement(code);
+ const firstPass = code.innerHTML;
+
+ Prism.highlightElement(code);
+ const secondPass = code.innerHTML;
+
+ // check that we actually did some highlighting
+ assert.notStrictEqual(initial, firstPass);
+ // check that the highlighting persists
+ assert.strictEqual(firstPass, secondPass);
+ });
+
// The markup is removed if it's the last element and the element's name is a single letter: a(nchor), b(old), i(talic)...
// /~https://github.com/PrismJS/prism/issues/1618
/*