mirror of
https://github.com/Smaug123/KaTeX
synced 2025-10-05 19:28:39 +00:00
fix(auto-render): concatenate content of successive text nodes (#3422)
* 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>
This commit is contained in:
@@ -55,10 +55,29 @@ const renderElem = function(elem, optionsCopy) {
|
|||||||
const childNode = elem.childNodes[i];
|
const childNode = elem.childNodes[i];
|
||||||
if (childNode.nodeType === 3) {
|
if (childNode.nodeType === 3) {
|
||||||
// Text node
|
// 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) {
|
if (frag) {
|
||||||
|
// Remove extra text nodes
|
||||||
|
for (let j = 0; j < nSiblings; j++) {
|
||||||
|
childNode.nextSibling.remove();
|
||||||
|
}
|
||||||
i += frag.childNodes.length - 1;
|
i += frag.childNodes.length - 1;
|
||||||
elem.replaceChild(frag, childNode);
|
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) {
|
} else if (childNode.nodeType === 1) {
|
||||||
// Element node
|
// Element node
|
||||||
|
@@ -322,3 +322,42 @@ describe("Pre-process callback", function() {
|
|||||||
expect(el1.innerHTML).toEqual(el2.innerHTML);
|
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);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
Reference in New Issue
Block a user