-
Notifications
You must be signed in to change notification settings - Fork 54
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
Kb 48270 #990
base: master
Are you sure you want to change the base?
Kb 48270 #990
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -3,6 +3,7 @@ body { | |
} | ||
|
||
input[type="text"], | ||
input[type="number"], | ||
select, | ||
textarea { | ||
width: 100%; | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,6 @@ | ||
import { Properties } from "./properties"; | ||
import { renderLatex } from "./latex"; | ||
import { renderMathML } from "./mathml"; | ||
import { renderAMathML } from "./mathml"; | ||
import { bypassEncapsulation } from "./retro"; | ||
import packageInformation from "../../../node_modules/@wiris/mathtype-viewer/package.json"; | ||
|
||
|
@@ -41,49 +41,85 @@ async function main(w: Window): Promise<void> { | |
|
||
const document = w.document; | ||
|
||
/** | ||
* Parse the DOM looking for LaTeX and <math> elements. | ||
* Replaces them with the corresponding rendered images within the given element. | ||
* @param {Document} document - The DOM document in which to search for the rendering root. | ||
* @param {MutationObserver} observer - Mutation observer to activate or reactivate every time the rendering root changes. | ||
*/ | ||
properties.render = async () => { | ||
const element: HTMLElement = document.querySelector(properties.element); | ||
if (element) { | ||
await renderLatex(properties, element); | ||
await renderMathML(properties, element); | ||
} | ||
}; | ||
|
||
// Initial function to call once document is loaded | ||
// Renders formulas and sets observer | ||
const start = async () => { | ||
// Check if the viewer is alredy loaded | ||
// Check if the viewer is already loaded | ||
if (w.viewer.isLoaded) return; | ||
|
||
w.viewer.isLoaded = true; | ||
|
||
// First render | ||
properties.render(); | ||
// Interaction Observer | ||
const mathobserver = new IntersectionObserver(async (entries, observer) => { | ||
|
||
let latexPromises = []; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I see that you are using the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Same here! const maxLatexPetition = properties.simultaneousmml; Maybe maxLatexPetition should be equal to properties.simultaneouslatex? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. My mistake! It should be |
||
|
||
const maxMmlPetition = properties.simultaneousmml; | ||
let mmlPromises = []; | ||
for (const entry of entries) { | ||
|
||
if (entry.isIntersecting && entry.target instanceof MathMLElement && entry.target.matches('math')) { | ||
const promise = renderAMathML(properties, entry.target); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Maybe I am missing something, but: There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. As we talked in private, renderAMathMl and renderLatex have some different behavior, that's why they don't share the same guard mechanism |
||
mmlPromises.push(promise); | ||
observer.unobserve(entry.target); | ||
|
||
// To not saturate service, not make all render petition at once | ||
if (mmlPromises.length >= maxMmlPetition) { | ||
await Promise.all(mmlPromises); | ||
mmlPromises = []; | ||
} | ||
} | ||
|
||
if (entry.isIntersecting && entry.target instanceof HTMLElement) { | ||
const promise = renderLatex(properties, entry.target); | ||
latexPromises.push(promise); | ||
observer.unobserve(entry.target); | ||
} | ||
} | ||
await Promise.all(latexPromises); | ||
await Promise.all(mmlPromises); | ||
}, { | ||
rootMargin: `${properties.vieweroffset}px` | ||
}); | ||
|
||
const allElements = document.querySelectorAll('*'); | ||
window.addEventListener("load", function () { | ||
allElements.forEach(function (element) { | ||
mathobserver.observe(element); | ||
}); | ||
}); | ||
|
||
//MutationObserver | ||
// Callback called every time there is a mutation in the watched DOM element | ||
// Feature temporarily disabled due to KB-37834 | ||
// new MutationObserver(async (mutationList, observer) => { | ||
// for (const mutation of mutationList) { | ||
// for (const node of mutation.addedNodes) { | ||
// if (node instanceof HTMLElement) { | ||
// await properties.render(); | ||
// } | ||
// } | ||
// } | ||
// }) | ||
// // We need to watch over the whole document, in case the Properties.element is inserted | ||
// // e.g. we set Properties.element = '#renderArea' and then we append <div id="renderArea">$$2+2=4$$</div> to the document | ||
// .observe(document, { | ||
// attributes: true, // In case an attribute is changed in a <math> node, for instance | ||
// childList: true, // In case a new <math> or $$latex$$ node is added, for instance | ||
// subtree: true, // In case a <math> node is added as a descendant of the observed element, for instance | ||
// }); | ||
new MutationObserver(async (mutationList) => { | ||
for (const mutation of mutationList) { | ||
for (const node of mutation.addedNodes) { | ||
// If was a htmlelement, decompose to child element to find posible latex or mathml | ||
if (node instanceof HTMLElement) { | ||
const allElements = node.querySelectorAll('*'); | ||
|
||
allElements.forEach(function (element) { | ||
mathobserver.observe(element); | ||
}); | ||
} | ||
// Observe mathml | ||
else if (node instanceof MathMLElement) { | ||
mathobserver.observe(node); | ||
} | ||
// If it was a pure text, observe their parent in order to find posible latex | ||
else if (node.nodeType == Node.TEXT_NODE) { | ||
mathobserver.observe(node.parentElement); | ||
} | ||
} | ||
} | ||
}) | ||
// We need to watch over the whole document, in case the Properties.element is inserted | ||
// e.g. we set Properties.element = '#renderArea' and then we append <div id="renderArea">$$2+2=4$$</div> to the document | ||
.observe(document, { | ||
attributes: true, // In case an attribute is changed in a <math> node, for instance | ||
childList: true, // In case a new <math> or $$latex$$ node is added, for instance | ||
subtree: true, // In case a <math> node is added as a descendant of the observed element, for instance | ||
}); | ||
}; | ||
|
||
// https://developer.mozilla.org/en-US/docs/Web/API/Document/DOMContentLoaded_event#checking_whether_loading_is_already_complete | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -48,6 +48,41 @@ function decodeSafeMathML(root: HTMLElement) { | |
} | ||
} | ||
|
||
export async function renderAMathML(properties: Properties, mathElement: MathMLElement): Promise<void> { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I would like to delete the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I would like so too. I would even consider this part of the development of the task, since the It would require a part of investigation and maybe adapt the current methods so that |
||
if (properties.viewer !== "image" && properties.viewer !== "mathml") { | ||
return; | ||
} | ||
|
||
const mml = serializeHtmlToXml(mathElement.outerHTML); | ||
|
||
try { | ||
let imgSource; | ||
|
||
// Transform mml to img. | ||
if (properties.wirispluginperformance === "true") { | ||
imgSource = await showImage( | ||
mml, | ||
properties.lang, | ||
properties.editorServicesRoot, | ||
properties.editorServicesExtension, | ||
); | ||
} else { | ||
imgSource = await createImage( | ||
mml, | ||
properties.lang, | ||
properties.editorServicesRoot, | ||
properties.editorServicesExtension, | ||
); | ||
} | ||
|
||
// Set img properties. | ||
const img = await setImageProperties(properties, imgSource, mml); | ||
// Replace the MathML for the generated formula image. | ||
mathElement.parentNode?.replaceChild(img, mathElement); | ||
} catch { | ||
console.error(`Cannot render ${mml}: invalid MathML format.`); | ||
} | ||
} | ||
/** | ||
* Parse the DOM looking for <math> elements and replace them with the corresponding rendered images within the given element. | ||
* @param {Properties} properties - Properties of the viewer. | ||
|
@@ -60,37 +95,44 @@ export async function renderMathML(properties: Properties, root: HTMLElement): P | |
|
||
decodeSafeMathML(root); | ||
|
||
const promises = []; | ||
|
||
for (const mathElement of [...root.getElementsByTagName("math")]) { | ||
const mml = serializeHtmlToXml(mathElement.outerHTML); | ||
try { | ||
let imgSource; | ||
|
||
// Transform mml to img. | ||
if (properties.wirispluginperformance === "true") { | ||
imgSource = await showImage( | ||
mml, | ||
properties.lang, | ||
properties.editorServicesRoot, | ||
properties.editorServicesExtension, | ||
); | ||
} else { | ||
imgSource = await createImage( | ||
mml, | ||
properties.lang, | ||
properties.editorServicesRoot, | ||
properties.editorServicesExtension, | ||
); | ||
const promise = (async () => { | ||
try { | ||
let imgSource; | ||
|
||
// Transform mml to img. | ||
if (properties.wirispluginperformance === "true") { | ||
imgSource = await showImage( | ||
mml, | ||
properties.lang, | ||
properties.editorServicesRoot, | ||
properties.editorServicesExtension, | ||
); | ||
} else { | ||
imgSource = await createImage( | ||
mml, | ||
properties.lang, | ||
properties.editorServicesRoot, | ||
properties.editorServicesExtension, | ||
); | ||
} | ||
|
||
// Set img properties. | ||
const img = await setImageProperties(properties, imgSource, mml); | ||
// Replace the MathML for the generated formula image. | ||
mathElement.parentNode?.replaceChild(img, mathElement); | ||
} catch { | ||
console.error(`Cannot render ${mml}: invalid MathML format.`); | ||
} | ||
})(); | ||
|
||
// Set img properties. | ||
const img = await setImageProperties(properties, imgSource, mml); | ||
// Replace the MathML for the generated formula image. | ||
mathElement.parentNode?.replaceChild(img, mathElement); | ||
} catch { | ||
console.error(`Cannot render ${mml}: invalid MathML format.`); | ||
continue; | ||
} | ||
promises.push(promise); | ||
} | ||
|
||
await Promise.all(promises); | ||
} | ||
|
||
/** | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It has been removed because we no longer need "Render under request."