Open rsp4jack opened 4 years ago
I got the same problem, debugged 1 day and still don't know why :(
When I use the cdnjs, this error isn't happens.(But it still happens sometimes)(TinyMCE use the cdnjs not this plugins)
Is it around line 166? I think 2 lines need to be wrapped with an if statement.
if(editor.getDoc().defaultView.MathJax){ editor.getDoc().defaultView.MathJax.startup.getComponents(); editor.getDoc().defaultView.MathJax.typeset(); }
here is code: .html: `
tinymce.init({ selector: ".editor", external_plugins: { 'mathjax': 'plugin.js' }, mathjax: { lib: 'tex-mml-chtml.js' } }, ` The key point is: html use tex-chtml-full.js but addin use tex-mml-chtml.js
Maybe it can fix this issue, but I think it isn't a beautiful means.
Isn't it because you defined your MathJax config after loading mathjax?
That would explain why MathJax.startup
is undefined ;)
Is it around line 166? I think 2 lines need to be wrapped with an if statement.
if(editor.getDoc().defaultView.MathJax){ editor.getDoc().defaultView.MathJax.startup.getComponents(); editor.getDoc().defaultView.MathJax.typeset(); }
I get it working by doing it like this:
if(editor.getDoc().defaultView.MathJax && editor.getDoc().defaultView.MathJax.startup){ editor.getDoc().defaultView.MathJax.startup.getComponents(); editor.getDoc().defaultView.MathJax.typeset(); }
Edit: Still doesn't work. It doesn't typeset (obviously)
We fixed this issue by not including the tex-mml-chtml.js on every page but just where it is required to display the math notation. The tinyMCE plugin doesn't like it when it is twice there, once as a script included on the page and again when it was loaded with this plugin. Hope this makes sense :)
We fixed this issue by not including the tex-mml-chtml.js on every page but just where it is required to display the math notation. The tinyMCE plugin doesn't like it when it is twice there, once as a script included on the page and again when it was loaded with this plugin. Hope this makes sense :)
So what if I want to display math on the same page as the TinyMCE editor?
That's a good point. We only needed it to display the math notations inside the tinyMCE. The issue could be replicated in Chrome browser and only with DevTools closed. With the DevTools opened all worked fine so I suspect some issue with the Chrome itself.
That's a good point. We only needed it to display the math notations inside the tinyMCE. The issue could be replicated in Chrome browser and only with DevTools closed. With the DevTools opened all worked fine so I suspect some issue with the Chrome itself.
I suppose we could do without math inside tinyMCE if it means the math outside will display fine. About replicating the issue, it's not the DevTools, it's the "Disable cache" settings. If you uncheck the "Disable cache" settings it will throw the error just like when the DevTools is closed.
@Creepercdn , did you resolved this? I have same issue
here is for tinymce6 config.js
let className = 'math-tex'; if (document.currentScript) { let urlParts = document.currentScript.getAttribute('src').split('?'); if (urlParts[1]) { let queryParams = urlParts[1].split('&'); for (let i = 0; i < queryParams.length; i++) { let param = queryParams[i].split('='); if (param[0] == 'class') { className = param[1]; break; } } } } MathJax = { options: { processHtmlClass: className, ignoreHtmlClass: '.*', M:window.MathJax } };
plugin.js
tinymce.PluginManager.add('mathjax', function (editor, url) {
// plugin configuration options
let settings = editor.getParam('mathjax');
let mathjaxClassName = settings.className || "math-tex";
let mathjaxTempClassName = mathjaxClassName + '-original';
let mathjaxSymbols = settings.symbols || { start: '\\(', end: '\\)' };
let mathjaxUrl = settings.lib || null;
let mathjaxConfigUrl = (settings.configUrl || url + '/config.js') + '?class=' + mathjaxTempClassName;
let mathjaxScripts = [mathjaxConfigUrl];
if (mathjaxUrl) {
mathjaxScripts.push(mathjaxUrl);
}
// load mathjax and its config on editor init
editor.on('init', function () {
console.log("GetContent");
let scripts = editor.getDoc().getElementsByTagName('script');
for (let i = 0; i < mathjaxScripts.length; i++) {
// check if script have already loaded
let id = editor.dom.uniqueId();
let script = editor.dom.create('script', { id: id, type: 'text/javascript', src: mathjaxScripts[i] });
let found = false;
for (let j = 0; j < scripts.length; j++) {
if (scripts[j].src == script.src) {
found = true;
break;
}
}
// load script
if (!found) {
editor.getDoc().getElementsByTagName('head')[0].appendChild(script);
}
}
});
// remove extra tags on get content
editor.on('GetContent', function (e) {
console.log("GetContent");
let div = editor.dom.create('div');
div.innerHTML = e.content;
let elements = div.querySelectorAll('.' + mathjaxClassName);
for (let i = 0; i < elements.length; i++) {
let children = elements[i].querySelectorAll('span');
for (let j = 0; j < children.length; j++) {
children[j].remove();
}
let latex = elements[i].getAttribute('data-latex');
elements[i].removeAttribute('contenteditable');
elements[i].removeAttribute('style');
elements[i].removeAttribute('data-latex');
elements[i].innerHTML = latex;
}
e.content = div.innerHTML;
});
let checkElement = function (element) {
if (element.childNodes.length != 2) {
element.setAttribute('contenteditable', false);
element.style.cursor = 'pointer';
let latex = element.getAttribute('data-latex') || element.innerHTML;
element.setAttribute('data-latex', latex);
element.innerHTML = '';
let math = editor.dom.create('span');
math.innerHTML = latex;
math.classList.add(mathjaxTempClassName);
element.appendChild(math);
let dummy = editor.dom.create('span');
dummy.classList.add('dummy');
dummy.innerHTML = 'dummy';
dummy.setAttribute('hidden', 'hidden');
element.appendChild(dummy);
}
};
// add dummy tag on set content
editor.on('BeforeSetContent', function (e) {
console.log("BeforeSetContent");
let div = editor.dom.create('div');
div.innerHTML = e.content;
let elements = div.querySelectorAll('.' + mathjaxClassName);
for (let i = 0; i < elements.length; i++) {
checkElement(elements[i]);
}
e.content = div.innerHTML;
});
// refresh mathjax on set content
editor.on('SetContent', function (e) {
console.log("SetContent");
if (editor.getDoc().defaultView.MathJax) {
if (editor.getDoc().defaultView.MathJax.options.M) {
editor.getDoc().defaultView.MathJax.options.M.typesetPromise();
}
}
});
// refresh mathjax on any content change
editor.on('Change', function (data) {
console.log("Change");
elements = editor.dom.getRoot().querySelectorAll('.' + mathjaxClassName);
if (elements.length) {
for (let i = 0; i < elements.length; i++) {
checkElement(elements[i]);
}
if (editor.getDoc().defaultView.MathJax) {
editor.getDoc().defaultView.MathJax.options.M.typesetPromise();
}
}
});
// add button to tinimce
editor.ui.registry.addToggleButton('mathjax', {
text: '数学公式',
tooltip: 'Mathjax',
onAction: function () {
let selected = editor.selection.getNode();
let target = undefined;
if (selected.classList.contains(mathjaxClassName)) {
target = selected;
}
openMathjaxEditor(target);
},
onSetup: function (buttonApi) {
return editor.selection.selectorChangedWithUnbind('.' + mathjaxClassName, buttonApi.setActive).unbind;
}
});
// handle click on existing
editor.on("click", function (e) {
let closest = e.target.closest('.' + mathjaxClassName);
if (closest) {
openMathjaxEditor(closest);
}
});
// open window with editor
let openMathjaxEditor = function (target) {
console.log(target);
let mathjaxId = editor.id + '_' + editor.dom.uniqueId();
let latex = '';
if (target) {
latex_attribute = target.getAttribute('data-latex');
// console.log("latex_attribute is" + latex_attribute);
if (latex_attribute.length >= (mathjaxSymbols.start + mathjaxSymbols.end).length) {
latex = latex_attribute.substr(mathjaxSymbols.start.length, latex_attribute.length - 1-(mathjaxSymbols.start + mathjaxSymbols.end).length);
}
}
// show new window
editor.windowManager.open({
title: 'Mathjax',
width: 600,
height: 330,
body: {
type: 'panel',
items: [
{
type: 'htmlpanel',
html: '<div style="font-size:12px"> <input onclick=changesybol() type=checkbox id=cb_br name=cb_br>换行 <a href="https://www.cnblogs.com/mqingqing123/p/12063096.html" target="blank" >LaTex说明</a> <a href="http://www.dotnetcms.org" target="blank" >启明星官网</a> </div>'
},
{
type: 'textarea',
name: 'title'
}, {
type: 'htmlpanel',
html: '<iframe id="' + mathjaxId + '" style="width: 100%; min-height: 50px;"></iframe>'
}]
},
buttons: [{ type: 'submit', text: 'OK' }],
onSubmit: function onsubmit(api) {
let value = api.getData().title.trim();
if (target) {
target.innerHTML = '';
target.setAttribute('data-latex', getMathText(value));
checkElement(target);
} else {
let newElement = editor.getDoc().createElement('span');
newElement.innerHTML = getMathText(value);
newElement.classList.add(mathjaxClassName);
checkElement(newElement);
editor.insertContent(newElement.outerHTML);
}
//fix
// editor.getDoc().defaultView.MathJax.startup.getComponents();
// editor.getDoc().defaultView.MathJax.typeset();
if (editor.getDoc().defaultView.MathJax) {
editor.getDoc().defaultView.MathJax.options.M.typesetPromise();
}
api.close();
},
onChange: function (api) {
var value = api.getData().title.trim();
if (value != latex) {
refreshDialogMathjax(value, document.getElementById(mathjaxId));
latex = value;
}
},
initialData: { title: latex }
});
if (mathjaxSymbols.start == "\\(") {
document.getElementById("cb_br").checked = false;
}
else {
document.getElementById("cb_br").checked = true;
}
// console.log(mathjaxSymbols);
// add scripts to iframe
let iframe = document.getElementById(mathjaxId);
let iframeWindow = iframe.contentWindow || iframe.contentDocument.document || iframe.contentDocument;
let iframeDocument = iframeWindow.document;
let iframeHead = iframeDocument.getElementsByTagName('head')[0];
let iframeBody = iframeDocument.getElementsByTagName('body')[0];
// get latex for mathjax from simple text
let getMathText = function (value, symbols) {
if (!symbols) {
symbols = mathjaxSymbols;
}
if (document.getElementById("cb_br").checked) {
symbols = { start: '\\[', end: '\\] ' };
}
else {
symbols = { start: '\\(', end: '\\) ' };
}
return symbols.start + ' ' + value + ' ' + symbols.end;
};
// refresh latex in mathjax iframe
let refreshDialogMathjax = function (latex) {
let MathJax = iframeWindow.MathJax;
let div = iframeBody.querySelector('div');
if (!div) {
div = iframeDocument.createElement('div');
div.classList.add(mathjaxTempClassName);
iframeBody.appendChild(div);
}
div.innerHTML = getMathText(latex, { start: '$$', end: '$$' });
if (MathJax && MathJax.startup) {
console.log(MathJax);
//MathJax.startup.getComponents();
MathJax.typesetPromise();
}
};
refreshDialogMathjax(latex);
// add scripts for dialog iframe
for (let i = 0; i < mathjaxScripts.length; i++) {
let node = iframeWindow.document.createElement('script');
node.src = mathjaxScripts[i];
node.type = 'text/javascript';
node.async = false;
node.charset = 'utf-8';
iframeHead.appendChild(node);
}
};
});
function changesybol() { if (document.getElementById("cb_br").checked) { mathjaxSymbols = { start: '\[', end: '\] ' }; } else { mathjaxSymbols = { start: '\(', end: '\) ' }; }
}
(Sorry, English isn't my mother language) (This Error is trigger on open the Mathjax panel)
Using CodePen: TinyMCE:
https://cdnjs.cloudflare.com/ajax/libs/tinymce/5.3.2/tinymce.min.js
Mathjax:https://cdn.jsdelivr.net/npm/mathjax@3.0.5/es5/tex-mml-chtml.js
tinymce-mathjax:https://cdn.jsdelivr.net/npm/@dimakorotkov/tinymce-mathjax@1.0.4/config.js
Tinymce Init Config:In the preview it worked, but it can't display in tinymce text box, it's displayed:
\( f\left( \left[ \frac{ 1+\left\{x,y\right\} }{ \left( \frac{x}{y}+\frac{y}{x} \right) \left(u+1\right) }+a \right]^{3/2} \right) \)
After waiting a while to type or refresh a few times, it will display normally. What causes this? How can I solve this problem? Maybe because the Network Delay? (I lived in China)