Skip to content

Commit

Permalink
Keep Markup: Added drop-tokens option class (#3166)
Browse files Browse the repository at this point in the history
  • Loading branch information
RunDevelopment committed Nov 3, 2021
1 parent 22d0c6b commit b679cfe
Show file tree
Hide file tree
Showing 4 changed files with 66 additions and 18 deletions.
8 changes: 7 additions & 1 deletion plugins/keep-markup/index.html
Expand Up @@ -27,7 +27,7 @@
<script>var _gaq = [['_setAccount', 'UA-33746269-1'], ['_trackPageview']];</script>
<script src="https://www.google-analytics.com/ga.js" async></script>
</head>
<body>
<body class="language-none">

<header data-plugin-header="keep-markup"></header>

Expand All @@ -39,6 +39,12 @@ <h1>How to use</h1>

<p>However, you can deactivate the plugin for certain code element by adding the <code>no-keep-markup</code> class to it. You can also deactivate the plugin for the whole page by adding the <code>no-keep-markup</code> class to the body of the page and then selectively activate it again by adding the <code>keep-markup</code> class to code elements.</p>

<h2>Double highlighting</h2>

<p>Some plugins (e.g. <a href="plugins/autoloader">Autoloader</a>) 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.</p>

<p>This problem can be fixed by adding a <code>drop-tokens</code> class to a code block or any of its ancestors. If <code>drop-tokens</code> is present, Keep Markup will ignore all <code class="language-css">span.token</code> elements created by Prism.</p>

<h1>Examples</h1>

<p>The following source code</p>
Expand Down
54 changes: 38 additions & 16 deletions plugins/keep-markup/prism-keep-markup.js
Expand Up @@ -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;
}
Expand Down
2 changes: 1 addition & 1 deletion plugins/keep-markup/prism-keep-markup.min.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

20 changes: 20 additions & 0 deletions tests/plugins/keep-markup/test.js
Expand Up @@ -4,6 +4,7 @@ const { createScopedPrismDom } = require('../../helper/prism-dom-util');

describe('Keep Markup', function () {
const { Prism, document } = createScopedPrismDom(this, {
languages: 'javascript',
plugins: 'keep-markup'
});

Expand Down Expand Up @@ -42,6 +43,25 @@ describe('Keep Markup', function () {
keepMarkup(`xy<a>a</a>`);
});

it('should support double highlighting', function () {
const pre = document.createElement('pre');
pre.className = 'language-javascript drop-tokens';
pre.innerHTML = '<code>var <mark>a = 42</mark>;</code>';
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
/*
Expand Down

0 comments on commit b679cfe

Please sign in to comment.