Skip to content

Commit

Permalink
fix(auto-render): concatenate content of successive text nodes (#3422)
Browse files Browse the repository at this point in the history
* fix(auto-render): concatenate text nodes

Concatenate successive text nodes to prevent auto-render from skipping
math input when browsers split text nodes with long textContent.

* Remove siblings only when math found

Only remove siblings when math expressions were found to prevent removal
of nodes that do not contain math.

* Skip siblings if they do not contain math

* Fixed typo in comments

* Added first tests for large test nodes

* Expanded testing to compare renderMathInElement with renderMathInText

* Simplified text node test

* Change description of test

* Update contrib/auto-render/auto-render.js

Co-authored-by: marcoesters <marco.esters@duke.edu>
Co-authored-by: ylemkimon <y@ylem.kim>
  • Loading branch information
3 people committed Aug 29, 2022
1 parent 99be728 commit 4d3fdd8
Show file tree
Hide file tree
Showing 2 changed files with 59 additions and 1 deletion.
21 changes: 20 additions & 1 deletion contrib/auto-render/auto-render.js
Expand Up @@ -55,10 +55,29 @@ const renderElem = function(elem, optionsCopy) {
const childNode = elem.childNodes[i];
if (childNode.nodeType === 3) {
// Text node
const frag = renderMathInText(childNode.textContent, optionsCopy);
// Concatenate all sibling text nodes.
// Webkit browsers split very large text nodes into smaller ones,
// so the delimiters may be split across different nodes.
let textContentConcat = childNode.textContent;
let sibling = childNode.nextSibling;
let nSiblings = 0;
while (sibling && (sibling.nodeType === Node.TEXT_NODE)) {
textContentConcat += sibling.textContent;
sibling = sibling.nextSibling;
nSiblings++;
}
const frag = renderMathInText(textContentConcat, optionsCopy);
if (frag) {
// Remove extra text nodes
for (let j = 0; j < nSiblings; j++) {
childNode.nextSibling.remove();
}
i += frag.childNodes.length - 1;
elem.replaceChild(frag, childNode);
} else {
// If the concatenated text does not contain math
// the siblings will not either
i += nSiblings;
}
} else if (childNode.nodeType === 1) {
// Element node
Expand Down
39 changes: 39 additions & 0 deletions contrib/auto-render/test/auto-render-spec.js
Expand Up @@ -322,3 +322,42 @@ describe("Pre-process callback", function() {
expect(el1.innerHTML).toEqual(el2.innerHTML);
});
});

describe("Parse adjacent text nodes", function() {
it("parse adjacent text nodes with math", function() {
const textNodes = ['\\[',
'x^2 + y^2 = r^2',
'\\]'];
const el = document.createElement('div');
for (let i = 0; i < textNodes.length; i++) {
const txt = document.createTextNode(textNodes[i]);
el.appendChild(txt);
}
const el2 = document.createElement('div');
const txt = document.createTextNode(textNodes.join(''));
el2.appendChild(txt);
const delimiters = [{left: "\\[", right: "\\]", display: true}];
renderMathInElement(el, {delimiters});
renderMathInElement(el2, {delimiters});
expect(el).toStrictEqual(el2);
});

it("parse adjacent text nodes without math", function() {
const textNodes = ['Lorem ipsum dolor',
'sit amet',
'consectetur adipiscing elit'];
const el = document.createElement('div');
for (let i = 0; i < textNodes.length; i++) {
const txt = document.createTextNode(textNodes[i]);
el.appendChild(txt);
}
const el2 = document.createElement('div');
for (let i = 0; i < textNodes.length; i++) {
const txt = document.createTextNode(textNodes[i]);
el2.appendChild(txt);
}
const delimiters = [{left: "\\[", right: "\\]", display: true}];
renderMathInElement(el, {delimiters});
expect(el).toStrictEqual(el2);
});
});

0 comments on commit 4d3fdd8

Please sign in to comment.