Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Keep Markup: Added drop-tokens option class #3166

Merged
merged 2 commits into from Nov 3, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
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