diff --git a/contrib/auto-render/auto-render.js b/contrib/auto-render/auto-render.js index 1b8d291df6..eceee5b980 100644 --- a/contrib/auto-render/auto-render.js +++ b/contrib/auto-render/auto-render.js @@ -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 diff --git a/contrib/auto-render/test/auto-render-spec.js b/contrib/auto-render/test/auto-render-spec.js index 677246644d..accb326195 100644 --- a/contrib/auto-render/test/auto-render-spec.js +++ b/contrib/auto-render/test/auto-render-spec.js @@ -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); + }); +});