BiFace_Server_Lite/web/tinymce/plugins/mathjax/plugin.js
2020-03-27 10:13:51 +07:00

1721 lines
48 KiB
JavaScript

(function () {
var defs = {}; // id -> {dependencies, definition, instance (possibly undefined)}
// Used when there is no 'main' module.
// The name is probably (hopefully) unique so minification removes for releases.
var register_3795 = function (id) {
var module = dem(id);
var fragments = id.split('.');
var target = Function('return this;')();
for (var i = 0; i < fragments.length - 1; ++i) {
if (target[fragments[i]] === undefined)
target[fragments[i]] = {};
target = target[fragments[i]];
}
target[fragments[fragments.length - 1]] = module;
};
var instantiate = function (id) {
var actual = defs[id];
var dependencies = actual.deps;
var definition = actual.defn;
var len = dependencies.length;
var instances = new Array(len);
for (var i = 0; i < len; ++i)
instances[i] = dem(dependencies[i]);
var defResult = definition.apply(null, instances);
if (defResult === undefined)
throw 'module [' + id + '] returned undefined';
actual.instance = defResult;
};
var def = function (id, dependencies, definition) {
if (typeof id !== 'string')
throw 'module id must be a string';
else if (dependencies === undefined)
throw 'no dependencies for ' + id;
else if (definition === undefined)
throw 'no definition function for ' + id;
defs[id] = {
deps: dependencies,
defn: definition,
instance: undefined
};
};
var dem = function (id) {
var actual = defs[id];
if (actual === undefined)
throw 'module [' + id + '] was undefined';
else if (actual.instance === undefined)
instantiate(id);
return actual.instance;
};
var req = function (ids, callback) {
var len = ids.length;
var instances = new Array(len);
for (var i = 0; i < len; ++i)
instances[i] = dem(ids[i]);
callback.apply(null, instances);
};
var ephox = {};
ephox.bolt = {
module: {
api: {
define: def,
require: req,
demand: dem
}
}
};
var define = def;
var require = req;
var demand = dem;
// this helps with minification when using a lot of global references
var defineGlobal = function (id, ref) {
define(id, [], function () { return ref; });
};
/*jsc
["tinymce.plugins.mathjax.Plugin","tinymce.core.PluginManager","tinymce.plugins.mathjax.api.Api","tinymce.plugins.mathjax.api.Commands","tinymce.plugins.mathjax.core.FilterContent","tinymce.plugins.mathjax.core.LoadCss","tinymce.plugins.mathjax.ui.Buttons","global!tinymce.util.Tools.resolve","tinymce.plugins.mathjax.ui.Dialog","tinymce.core.html.Node","tinymce.plugins.mathjax.api.Settings","tinymce.plugins.mathjax.core.Nodes","tinymce.plugins.mathjax.core.Sanitize","tinymce.core.Env","global!window","global!tinymce","tinymce.core.dom.DOMUtils","tinymce.core.util.Tools","tinymce.plugins.mathjax.core.HtmlToData","tinymce.plugins.mathjax.core.UpdateHtml","tinymce.plugins.mathjax.ui.IframeContent","tinymce.core.html.SaxParser","tinymce.core.html.Schema","tinymce.core.html.Writer","tinymce.plugins.mathjax.core.Size"]
jsc*/
defineGlobal("global!tinymce.util.Tools.resolve", tinymce.util.Tools.resolve);
/**
* ResolveGlobal.js
*
* Released under LGPL License.
* Copyright (c) 1999-2017 Ephox Corp. All rights reserved
*
* License: http://www.tinymce.com/license
* Contributing: http://www.tinymce.com/contributing
*/
define(
'tinymce.core.PluginManager',
[
'global!tinymce.util.Tools.resolve'
],
function (resolve) {
return resolve('tinymce.PluginManager');
}
);
/**
* ResolveGlobal.js
*
* Released under LGPL License.
* Copyright (c) 1999-2017 Ephox Corp. All rights reserved
*
* License: http://www.tinymce.com/license
* Contributing: http://www.tinymce.com/contributing
*/
define(
'tinymce.core.Env',
[
'global!tinymce.util.Tools.resolve'
],
function (resolve) {
return resolve('tinymce.Env');
}
);
/**
* ResolveGlobal.js
*
* Released under LGPL License.
* Copyright (c) 1999-2017 Ephox Corp. All rights reserved
*
* License: http://www.tinymce.com/license
* Contributing: http://www.tinymce.com/contributing
*/
define(
'tinymce.core.util.Tools',
[
'global!tinymce.util.Tools.resolve'
],
function (resolve) {
return resolve('tinymce.util.Tools');
}
);
/**
* Settings.js
*
* Released under LGPL License.
* Copyright (c) 1999-2017 Ephox Corp. All rights reserved
*
* License: http://www.tinymce.com/license
* Contributing: http://www.tinymce.com/contributing
*/
define(
'tinymce.plugins.mathjax.api.Settings',
[
],
function () {
var getScripts = function (editor) {
return editor.getParam('media_scripts');
};
var hasLiveEmbeds = function (editor) {
return editor.getParam('media_live_embeds', true);
};
var shouldFilterHtml = function (editor) {
return editor.getParam('media_filter_html', true);
};
var getUrlResolver = function (editor) {
return editor.getParam('media_url_resolver');
};
var hasAltSource = function (editor) {
return editor.getParam('media_alt_source', true);
};
var hasPoster = function (editor) {
return editor.getParam('media_poster', true);
};
var hasDimensions = function (editor) {
return editor.getParam('media_dimensions', true);
};
var getMathJaxLib = function () {
return '//thuvienhoclieu.vn/js/mathjax/2.7.2/MathJax.js?config=TeX-AMS_CHTML';
};
var getMathJaxConfig = function () {
// MathJax configuration, disable messages.
var conf = {
showMathMenu:false,
messageStyle:'none'
};
return 'MathJax.Hub.Config(' + JSON.stringify(conf) + ');';
};
return {
getScripts: getScripts,
hasLiveEmbeds: hasLiveEmbeds,
shouldFilterHtml: shouldFilterHtml,
getUrlResolver: getUrlResolver,
hasAltSource: hasAltSource,
hasPoster: hasPoster,
hasDimensions: hasDimensions,
getMathJaxLib: getMathJaxLib,
getMathJaxConfig: getMathJaxConfig
};
}
);
/**
* ResolveGlobal.js
*
* Released under LGPL License.
* Copyright (c) 1999-2017 Ephox Corp. All rights reserved
*
* License: http://www.tinymce.com/license
* Contributing: http://www.tinymce.com/contributing
*/
define(
'tinymce.core.html.SaxParser',
[
'global!tinymce.util.Tools.resolve'
],
function (resolve) {
return resolve('tinymce.html.SaxParser');
}
);
/**
* ResolveGlobal.js
*
* Released under LGPL License.
* Copyright (c) 1999-2017 Ephox Corp. All rights reserved
*
* License: http://www.tinymce.com/license
* Contributing: http://www.tinymce.com/contributing
*/
define(
'tinymce.core.html.Schema',
[
'global!tinymce.util.Tools.resolve'
],
function (resolve) {
return resolve('tinymce.html.Schema');
}
);
/**
* ResolveGlobal.js
*
* Released under LGPL License.
* Copyright (c) 1999-2017 Ephox Corp. All rights reserved
*
* License: http://www.tinymce.com/license
* Contributing: http://www.tinymce.com/contributing
*/
define(
'tinymce.core.dom.DOMUtils',
[
'global!tinymce.util.Tools.resolve'
],
function (resolve) {
return resolve('tinymce.dom.DOMUtils');
}
);
/**
* Size.js
*
* Released under LGPL License.
* Copyright (c) 1999-2017 Ephox Corp. All rights reserved
*
* License: http://www.tinymce.com/license
* Contributing: http://www.tinymce.com/contributing
*/
define(
'tinymce.plugins.mathjax.core.Size',
[
],
function () {
var trimPx = function (value) {
return value.replace(/px$/, '');
};
var addPx = function (value) {
return /^[0-9.]+$/.test(value) ? (value + 'px') : value;
};
var getSize = function (name) {
return function (elm) {
return elm ? trimPx(elm.style[name]) : '';
};
};
var setSize = function (name) {
return function (elm, value) {
if (elm) {
elm.style[name] = addPx(value);
}
};
};
return {
getMaxWidth: getSize('maxWidth'),
getMaxHeight: getSize('maxHeight'),
setMaxWidth: setSize('maxWidth'),
setMaxHeight: setSize('maxHeight')
};
}
);
/**
* HtmlToData.js
*
* Released under LGPL License.
* Copyright (c) 1999-2017 Ephox Corp. All rights reserved
*
* License: http://www.tinymce.com/license
* Contributing: http://www.tinymce.com/contributing
*/
define(
'tinymce.plugins.mathjax.core.HtmlToData',
[
'tinymce.core.util.Tools',
'tinymce.core.html.SaxParser',
'tinymce.core.html.Schema',
'tinymce.core.dom.DOMUtils',
'tinymce.plugins.mathjax.core.Size'
],
function (Tools, SaxParser, Schema, DOMUtils, Size) {
// var DOM = DOMUtils.DOM;
var htmlToDataSax = function (prefixes, html) {
var data = {};
new SaxParser({
validate: false,
allow_conditional_comments: true,
special: 'script,noscript',
start: function (name, attrs) {
data = Tools.extend(attrs.map, data);
}
}).parse(html);
data.type = data.type || 'mathjax';
return data;
};
var htmlToData = function (prefixes, html) {
return htmlToDataSax(prefixes, html);
};
return {
htmlToData: htmlToData
};
}
);
/**
* ResolveGlobal.js
*
* Released under LGPL License.
* Copyright (c) 1999-2017 Ephox Corp. All rights reserved
*
* License: http://www.tinymce.com/license
* Contributing: http://www.tinymce.com/contributing
*/
define(
'tinymce.core.html.Writer',
[
'global!tinymce.util.Tools.resolve'
],
function (resolve) {
return resolve('tinymce.html.Writer');
}
);
/**
* UpdateHtml.js
*
* Released under LGPL License.
* Copyright (c) 1999-2017 Ephox Corp. All rights reserved
*
* License: http://www.tinymce.com/license
* Contributing: http://www.tinymce.com/contributing
*/
define(
'tinymce.plugins.mathjax.core.UpdateHtml',
[
'tinymce.core.html.Writer',
'tinymce.core.html.SaxParser',
'tinymce.core.html.Schema',
'tinymce.core.dom.DOMUtils',
'tinymce.plugins.mathjax.core.Size'
],
function (Writer, SaxParser, Schema, DOMUtils, Size) {
// var DOM = DOMUtils.DOM;
var setAttributes = function (attrs, updatedAttrs) {
var name;
var i;
var value;
var attr;
for (name in updatedAttrs) {
value = "" + updatedAttrs[name];
if (attrs.map[name]) {
i = attrs.length;
while (i--) {
attr = attrs[i];
if (attr.name === name) {
if (value) {
attrs.map[name] = value;
attr.value = value;
} else {
delete attrs.map[name];
attrs.splice(i, 1);
}
}
}
} else if (value) {
attrs.push({
name: name,
value: value
});
attrs.map[name] = value;
}
}
};
var updateHtmlSax = function (html, data, updateAll) {
var writer = new Writer();
var sourceCount = 0;
var hasImage;
new SaxParser({
validate: false,
allow_conditional_comments: true,
special: 'script,noscript',
comment: function (text) {
writer.comment(text);
},
cdata: function (text) {
writer.cdata(text);
},
text: function (text, raw) {
writer.text(text, raw);
},
start: function (name, attrs, empty) {
switch (name) {
case "video":
case "object":
case "embed":
case "img":
case "iframe":
if (data.height !== undefined && data.width !== undefined) {
setAttributes(attrs, {
width: data.width,
height: data.height
});
}
break;
}
if (updateAll) {
switch (name) {
case "video":
setAttributes(attrs, {
poster: data.poster,
src: ""
});
if (data.source2) {
setAttributes(attrs, {
src: ""
});
}
break;
case "iframe":
setAttributes(attrs, {
src: data.source1
});
break;
case "source":
sourceCount++;
if (sourceCount <= 2) {
setAttributes(attrs, {
src: data["source" + sourceCount],
type: data["source" + sourceCount + "mime"]
});
if (!data["source" + sourceCount]) {
return;
}
}
break;
case "img":
if (!data.poster) {
return;
}
hasImage = true;
break;
}
}
writer.start(name, attrs, empty);
},
end: function (name) {
if (name === "video" && updateAll) {
for (var index = 1; index <= 2; index++) {
if (data["source" + index]) {
var attrs = [];
attrs.map = {};
if (sourceCount < index) {
setAttributes(attrs, {
src: data["source" + index],
type: data["source" + index + "mime"]
});
writer.start("source", attrs, true);
}
}
}
}
if (data.poster && name === "object" && updateAll && !hasImage) {
var imgAttrs = [];
imgAttrs.map = {};
setAttributes(imgAttrs, {
src: data.poster,
width: data.width,
height: data.height
});
writer.start("img", imgAttrs, true);
}
writer.end(name);
}
}, new Schema({})).parse(html);
return writer.getContent();
};
var updateHtml = function (html, data, updateAll) {
return updateHtmlSax(html, data, updateAll);
};
return {
updateHtml: updateHtml
};
}
);
/**
* IframeContent.js
*
* Released under LGPL License.
* Copyright (c) 1999-2017 Ephox Corp. All rights reserved
*
* License: http://www.tinymce.com/license
* Contributing: http://www.tinymce.com/contributing
*/
define(
'tinymce.plugins.mathjax.ui.IframeContent',
[
'tinymce.core.util.Tools',
'tinymce.plugins.mathjax.api.Settings'
],
function (Tools, Settings) {
var getPreviewHtml = function (editor, content, updateDoneHandler) {
var previewHtml, headHtml = '', encode = editor.dom.encode;
headHtml += '<base href="' + encode(editor.documentBaseURI.getURI()) + '">';
Tools.each(editor.contentCSS, function (url) {
headHtml += '<link type="text/css" rel="stylesheet" href="' + encode(editor.documentBaseURI.toAbsolute(url)) + '">';
});
var bodyId = editor.settings.body_id || 'tinymce';
headHtml += '<script type="text/x-mathjax-config">' +
Settings.getMathJaxConfig() +
// Get main editor form parent.
'function getTinymce() {' +
'if ( typeof window.parent.parent.tinymce == \'object\' ) {' +
'return window.parent.parent.tinymce;' +
'} else {' +
'return window.parent.parent.tinymce;' +
'}' +
'}' +
'function update(tex) {' +
'var preview = document.getElementById(\'preview\');' +
'if(preview){' +
'preview.innerHTML = tex;' +
'MathJax.Hub.Queue(' +
'[ \'Typeset\', MathJax.Hub, \'preview\'],' +
'function() {' +
'getTinymce().tools.callFunction( ' + updateDoneHandler + ' );' +
'}' +
');' +
'}' +
'}' +
'</script>';
headHtml += '<script type="text/javascript" src="' + Settings.getMathJaxLib() + '"></script>';
if (bodyId.indexOf('=') !== -1) {
bodyId = editor.getParam('body_id', '', 'hash');
bodyId = bodyId[editor.id] || bodyId;
}
var bodyClass = editor.settings.body_class || '';
if (bodyClass.indexOf('=') !== -1) {
bodyClass = editor.getParam('body_class', '', 'hash');
bodyClass = bodyClass[editor.id] || '';
}
var dirAttr = editor.settings.directionality ? ' dir="' + editor.settings.directionality + '"' : '';
previewHtml = (
'<!DOCTYPE html>' +
'<html>' +
'<head>' +
headHtml +
'</head>' +
'<body id="' + encode(bodyId) + '" class="mce-content-body ' + encode(bodyClass) + '"' + encode(dirAttr) + ' style="text-align:center">' +
'<div id="preview">' +
content +
'</div>' +
'</body>' +
'</html>'
);
return previewHtml;
};
var injectIframeContent = function (editor, iframe, sandbox, content, updateDoneHandler) {
content = content ? '\\(' + content + '\\)' : '';
var previewHtml = getPreviewHtml(editor, content, updateDoneHandler);
if (!sandbox) {
// IE 6-11 doesn't support data uris on iframes
// so I guess they will have to be less secure since we can't sandbox on those
// TODO: Use sandbox if future versions of IE supports iframes with data: uris.
var doc = iframe.contentWindow.document;
doc.open();
doc.write(previewHtml);
doc.close();
} else {
iframe.src = 'data:text/html;charset=utf-8,' + encodeURIComponent(previewHtml);
}
return {
setLatex: function (tex) {
iframe.contentWindow.update('\\(' + tex + '\\)');
}
};
};
return {
injectIframeContent: injectIframeContent
};
}
);
defineGlobal("global!window", window);
defineGlobal("global!tinymce", tinymce);
/**
* Dialog.js
*
* Released under LGPL License.
* Copyright (c) 1999-2017 Ephox Corp. All rights reserved
*
* License: http://www.tinymce.com/license
* Contributing: http://www.tinymce.com/contributing
*/
define(
'tinymce.plugins.mathjax.ui.Dialog',
[
'tinymce.core.Env',
'tinymce.core.util.Tools',
'tinymce.plugins.mathjax.api.Settings',
'tinymce.plugins.mathjax.core.HtmlToData',
'tinymce.plugins.mathjax.core.UpdateHtml',
'tinymce.plugins.mathjax.ui.IframeContent',
'global!window',
'global!tinymce'
],
function (Env, Tools, Settings, HtmlToData, UpdateHtml, IframeContent, window, tinymce) {
var embedChange = (Env.ie && Env.ie <= 8) ? 'onChange' : 'onInput';
/*eslint-disable*/
var getComputedStyle = function (elem, prop) {
var res = '';
if (elem.currentStyle) {
res = elem.currentStyle[prop];
} else if (window.getComputedStyle) {
if (window.getComputedStyle.getPropertyValue) {
res = window.getComputedStyle(elem, null).getPropertyValue(prop);
} else {
res = window.getComputedStyle(elem)[prop];
}
}
return res;
},
setStyles = function (elem, styles) {
var name;
for (name in styles) {
elem.style[name] = styles[name];
}
};
var copyStyles = function (from, to) {
var stylesToCopy = ['color', 'font-family', 'font-style', 'font-weight', 'font-variant', 'font-size'];
for (var i = 0; i < stylesToCopy.length; i++) {
var key = stylesToCopy[i],
val = getComputedStyle(from, key);
if (val) {
to.style[key] = val;
}
}
};
// eslint-disable-next-line
window.tinymce.fn_map = window.tinymce.fn_map||{length:0};
// eslint-disable-next-line
var map = window.tinymce.fn_map;
var callFunction = function (id) {
if (map[id]) {
return map[id]();
}
};
var addFunction = function (fn) {
map.length = map.length + 1;
var id = '' + map.length;
map[id] = fn;
return id;
};
// eslint-disable-next-line
window.tinymce.tools = window.tinymce.tools||{};
// eslint-disable-next-line
window.tinymce.tools.callFunction = callFunction;
/*eslint-enable*/
var selectPlaceholder = function (editor, beforeObjects) {
var i;
var y;
var afterObjects = editor.dom.select('span[data-mce-math]');
// Find new image placeholder so we can select it
for (i = 0; i < beforeObjects.length; i++) {
for (y = afterObjects.length - 1; y >= 0; y--) {
if (beforeObjects[i] === afterObjects[y]) {
afterObjects.splice(y, 1);
}
}
}
editor.selection.select(afterObjects[0]);
};
var getData = function (editor) {
var element = editor.selection.getNode();
return element.getAttribute('data-mce-math') ?
HtmlToData.htmlToData(Settings.getScripts(editor), editor.serializer.serialize(element, { selection: true })) :
{};
};
var handleInsert = function (editor, html) {
var beforeObjects = editor.dom.select('span[data-mce-math]');
editor.insertContent('<span data-latex="' + html + '">\\(' + html + '\\)</span>');
selectPlaceholder(editor, beforeObjects);
editor.nodeChanged();
};
var submitForm = function (win, editor) {
var data = win.toJSON();
data.latex = UpdateHtml.updateHtml(data.latex, data);
handleInsert(editor, data.latex);
};
var showDialog = function (editor) {
var sandbox = false;//!Env.ie;
// var dialogHtml = '<iframe src="javascript:\'\'" frameborder="0"' + (sandbox ? ' sandbox="allow-scripts"' : '') + '></iframe>';
var data = getData(editor);
var iframe;
var updateValueOnChange = function () {
data = Tools.extend({}, HtmlToData.htmlToData(Settings.getScripts(editor), this.value()));
this.parent().parent().fromJSON(data);
iframe && iframe.setLatex(this.value());
};
var textbox = {
type: 'textbox',
name: 'latex',
multiline: true,
minWidth: 600,
minHeight: 80,
spellcheck: false,
style: 'direction: ltr; text-align: left;',
value: data['data-latex'] || ''
};
textbox[embedChange] = updateValueOnChange;
var win = editor.windowManager.open({
title: 'Mathjax Preview',
data: data,
body: [
textbox,
{
type: 'iframe',
src: 'javascript:\'\'',
frameborder: 0,
minHeight: 150
}
],
onSubmit: function (e) {
submitForm(win, editor);
},
onPostRender: function (e) {
var iframeElm = e.control.getEl('body iframe');
if (sandbox) {
iframeElm.setAttribute('sandbox', 'allow-scripts');
}
/*eslint-disable*/
var updateDoneHandler = addFunction(function(){
// var doc = iframe.contentDocument;
// var preview = doc.getElementById('preview');
// setStyles(iframe, {
// height: 0,
// width: 0
// });
// var height = Math.max(doc.body.offsetHeight, doc.documentElement.offsetHeight),
// width = Math.max(preview.offsetWidth, doc.body.scrollWidth);
// setStyles(iframe, {
// height: height + 'px',
// width: width + 'px'
// });
});
/*eslint-enable*/
iframe = IframeContent.injectIframeContent(editor, iframeElm, sandbox, data['data-latex'] || '', updateDoneHandler);
}
});
};
return {
showDialog: showDialog
};
}
);
/**
* Api.js
*
* Released under LGPL License.
* Copyright (c) 1999-2017 Ephox Corp. All rights reserved
*
* License: http://www.tinymce.com/license
* Contributing: http://www.tinymce.com/contributing
*/
define(
'tinymce.plugins.mathjax.api.Api',
[
'tinymce.plugins.mathjax.ui.Dialog'
],
function (Dialog) {
var get = function (editor) {
var showDialog = function () {
Dialog.showDialog(editor);
};
return {
showDialog: showDialog
};
};
return {
get: get
};
}
);
/**
* Commands.js
*
* Released under LGPL License.
* Copyright (c) 1999-2017 Ephox Corp. All rights reserved
*
* License: http://www.tinymce.com/license
* Contributing: http://www.tinymce.com/contributing
*/
define(
'tinymce.plugins.mathjax.api.Commands',
[
'tinymce.plugins.mathjax.ui.Dialog'
],
function (Dialog) {
var register = function (editor) {
var showDialog = function () {
Dialog.showDialog(editor);
};
editor.addCommand('mceMath', showDialog);
};
return {
register: register
};
}
);
/**
* ResolveGlobal.js
*
* Released under LGPL License.
* Copyright (c) 1999-2017 Ephox Corp. All rights reserved
*
* License: http://www.tinymce.com/license
* Contributing: http://www.tinymce.com/contributing
*/
define(
'tinymce.core.html.Node',
[
'global!tinymce.util.Tools.resolve'
],
function (resolve) {
return resolve('tinymce.html.Node');
}
);
/**
* Sanitize.js
*
* Released under LGPL License.
* Copyright (c) 1999-2017 Ephox Corp. All rights reserved
*
* License: http://www.tinymce.com/license
* Contributing: http://www.tinymce.com/contributing
*/
define(
'tinymce.plugins.mathjax.core.Sanitize',
[
'tinymce.core.html.SaxParser',
'tinymce.core.html.Schema',
'tinymce.core.html.Writer',
'tinymce.core.util.Tools',
'tinymce.plugins.mathjax.api.Settings'
],
function (SaxParser, Schema, Writer, Tools, Settings) {
var sanitize = function (editor, html) {
if (Settings.shouldFilterHtml(editor) === false) {
return html;
}
var writer = new Writer();
var blocked;
new SaxParser({
validate: false,
allow_conditional_comments: false,
special: 'script,noscript',
comment: function (text) {
writer.comment(text);
},
cdata: function (text) {
writer.cdata(text);
},
text: function (text, raw) {
writer.text(text, raw);
},
start: function (name, attrs, empty) {
blocked = true;
if (name === 'script' || name === 'noscript') {
return;
}
for (var i = 0; i < attrs.length; i++) {
if (attrs[i].name.indexOf('on') === 0) {
return;
}
if (attrs[i].name === 'style') {
attrs[i].value = editor.dom.serializeStyle(editor.dom.parseStyle(attrs[i].value), name);
}
}
writer.start(name, attrs, empty);
blocked = false;
},
end: function (name) {
if (blocked) {
return;
}
writer.end(name);
}
}, new Schema({})).parse(html);
return writer.getContent();
};
return {
sanitize: sanitize
};
}
);
/**
* Nodes.js
*
* Released under LGPL License.
* Copyright (c) 1999-2017 Ephox Corp. All rights reserved
*
* License: http://www.tinymce.com/license
* Contributing: http://www.tinymce.com/contributing
*/
define(
'tinymce.plugins.mathjax.core.Nodes',
[
'tinymce.core.html.Node',
'tinymce.plugins.mathjax.core.Sanitize'
],
function (Node, Sanitize) {
var createPreviewIframeMathjaxNode = function (editor, node, pluginUrl) {
var previewWrapper;
var previewNode;
var shimNode;
var name = node.name;
previewWrapper = new Node('span', 1);
previewWrapper.attr({
contentEditable: 'false',
style: node.attr('style'),
"data-mce-math": name,
"class": "mce-preview-math mce-object-" + name
});
retainAttributesAndInnerHtml(editor, node, previewWrapper);
// previewNode = new Node(name, 1);
previewNode = new Node('img', 1);
previewNode.attr({
src: pluginUrl + '/img/loader.gif',
class: 'mce-latex-loader'
});
shimNode = new Node('span', 1);
shimNode.attr('class', 'mce-shim');
previewWrapper.append(previewNode);
previewWrapper.append(shimNode);
return previewWrapper;
};
var retainAttributesAndInnerHtml = function (editor, sourceNode, targetNode) {
var attrName;
var attrValue;
var attribs;
var ai;
var innerHtml;
// Prefix all attributes except width, height and style since we
// will add these to the placeholder
attribs = sourceNode.attributes;
ai = attribs.length;
while (ai--) {
attrName = attribs[ai].name;
attrValue = attribs[ai].value;
if (attrName !== "width" && attrName !== "height" && attrName !== "style") {
if (attrName === "data" || attrName === "src") {
attrValue = editor.convertURL(attrValue, attrName);
}
targetNode.attr('data-mce-p-' + attrName, attrValue);
}
}
// Place the inner HTML contents inside an escaped attribute
// This enables us to copy/paste the fake object
innerHtml = sourceNode.firstChild && sourceNode.firstChild.value;
if (innerHtml) {
targetNode.attr("data-mce-html", escape(Sanitize.sanitize(editor, innerHtml)));
targetNode.firstChild = null;
}
};
var placeHolderConverter = function (editor, pluginUrl) {
return function (nodes) {
var i = nodes.length;
var node;
while (i--) {
node = nodes[i];
if (!node.parent) {
continue;
}
if (node.parent.attr('data-mce-object') || node.parent.attr('data-mce-math')) {
continue;
}
if (node.attr('data-latex')) {
node.replace(createPreviewIframeMathjaxNode(editor, node, pluginUrl));
}
}
};
};
return {
placeHolderConverter: placeHolderConverter
};
}
);
/**
* FilterContent.js
*
* Released under LGPL License.
* Copyright (c) 1999-2017 Ephox Corp. All rights reserved
*
* License: http://www.tinymce.com/license
* Contributing: http://www.tinymce.com/contributing
*/
define(
'tinymce.plugins.mathjax.core.FilterContent',
[
'tinymce.core.html.Node',
'tinymce.plugins.mathjax.api.Settings',
'tinymce.plugins.mathjax.core.Nodes',
'tinymce.plugins.mathjax.core.Sanitize',
'tinymce.core.Env',
'global!window',
'global!tinymce'
],
function (Node, Settings, Nodes, Sanitize, Env, window, tinymce) {
var mathJaxLib = Settings.getMathJaxLib();
var fixDomain = function () {
var domain;
//eslint-disable-next-line
while (1) {
try {
// Try to access the parent document. It throws
// "access denied" if restricted by the "Same Origin" policy.
domain = window.parent.document.domain;
break;
} catch (e) {
// Calculate the value to set to document.domain.
domain = domain ?
// If it is not the first pass, strip one part of the
// name. E.g. "test.example.com" => "example.com"
domain.replace(/.+?(?:\.|$)/, '') :
// In the first pass, we'll handle the
// "document.domain = document.domain" case.
document.domain;
// Stop here if there is no more domain parts available.
if (!domain) {
break;
}
document.domain = domain;
}
}
return !!domain;
};
// eslint-disable no-alert, no-console
// eslint-disable-line
// eslint-disable-next-line
// eslint-disable-line no-alert, quotes, semi
// eslint-disable-line no-alert, quotes, semi
// eslint-enable no-alert, no-console
/*eslint-disable*/
var fixSrc =
// In Firefox src must exist and be different than about:blank to emit load event.
Env.gecko ? 'javascript:true' : // jshint ignore:line
// Support for custom document.domain in IE.
Env.ie ? 'javascript:' + // jshint ignore:line
'void((function(){' + encodeURIComponent(
'document.open();' +
'(' + fixDomain + ')();' +
'document.close();'
) + '})())' :
// In Chrome src must be undefined to emit load event.
'javascript:void(0)'; // jshint ignore:line
var loadingIcon;
var trim = function (value) {
var begin = value.indexOf('\\(') + 2,
end = value.lastIndexOf('\\)');
return value.substring(begin, end);
};
var getComputedStyle = function (elem, prop) {
var res = '';
if (elem.currentStyle) {
res = elem.currentStyle[prop];
} else if (window.getComputedStyle) {
if (window.getComputedStyle.getPropertyValue) {
res = window.getComputedStyle(elem, null).getPropertyValue(prop);
} else {
res = window.getComputedStyle(elem)[prop];
}
}
return res;
},
setStyles = function (elem, styles) {
var name;
for (name in styles) {
elem.style[name] = styles[name];
}
};
/*eslint-enable*/
var copyStyles = function (from, to) {
var stylesToCopy = ['color', 'font-family', 'font-style', 'font-weight', 'font-variant', 'font-size'];
for (var i = 0; i < stylesToCopy.length; i++) {
var key = stylesToCopy[i],
val = getComputedStyle(from, key);
if (val) {
to.style[key] = val;
}
}
};
// eslint-disable-next-line
window.tinymce.fn_map = window.tinymce.fn_map||{length:0};
// eslint-disable-next-line
var map = window.tinymce.fn_map;
var callFunction = function (id) {
if (map[id]) {
return map[id]();
}
};
var addFunction = function (fn) {
map.length = map.length + 1;
var id = '' + map.length;
map[id] = fn;
return id;
};
// eslint-disable-next-line
window.tinymce.tools = window.tinymce.tools||{};
// eslint-disable-next-line
window.tinymce.tools.callFunction = callFunction;
var updateSize = function (iframe, preview, editor) {
editor.fire('lockSnapshot');
var doc = iframe.contentDocument;
setStyles(iframe, {
height: 0,
width: 0
});
// Set iFrame dimensions.
var height = Math.max(doc.body.offsetHeight, doc.documentElement.offsetHeight),
width = Math.max(preview.offsetWidth, doc.body.scrollWidth);
setStyles(iframe, {
height: height + 'px',
width: width + 'px'
});
iframe.setAttribute('data-state', 2);
editor.fire('unlockSnapshot');
};
var frameWrapper = function (editor, iframe) {
var buffer, preview, value, newValue,
doc = iframe.contentDocument,
// Is MathJax loaded and ready to work.
isInit = false,
// Is MathJax parsing Tex.
isRunning = false,
// Function called when MathJax is loaded.
loadedHandler = addFunction(function () {
preview = doc.getElementById('preview');
buffer = doc.getElementById('buffer');
isInit = true;
if (newValue) {
update();
}
// Private! For test usage only.
// CKEDITOR.fire('mathJaxLoaded', iframe);
}),
// Function called when MathJax finish his job.
updateDoneHandler = addFunction(function () {
preview = doc.getElementById('preview');
buffer = doc.getElementById('buffer');
copyStyles(iframe, preview);
preview.innerHTML = buffer.innerHTML;
if (Env.gecko) {
setTimeout(function () {
updateSize(iframe, preview, editor);
}, 100);
} else {
updateSize(iframe, preview, editor);
}
// Private! For test usage only.
// CKEDITOR.fire('mathJaxUpdateDone', iframe);
// If value changed in the meantime update it again.
if (value !== newValue) {
update();
} else {
isRunning = false;
}
});
if (iframe.addEventListener) {
iframe.addEventListener('load', load, false);
} else {
iframe.attachEvent('onload', load);
}
load();
function load() {
//eslint-disable-next-line
if (!!!doc || !!!doc.getElementById || doc.getElementById('preview')) {
return;
}
// Because of IE9 bug in a src attribute can not be javascript
// when you undo (http://dev.ckeditor.com/ticket/10930). If you have iFrame with javascript in src
// and call insertBefore on such element then IE9 will see crash.
if (Env.ie) {
iframe.removeAttribute('src');
}
doc.open();
doc.write('<!DOCTYPE html>' +
'<html>' +
'<head>' +
'<meta charset="utf-8">' +
'<script type="text/x-mathjax-config">' + Settings.getMathJaxConfig() +
// Get main editor form parent.
'function getTinymce() {' +
'if ( typeof window.parent.parent.tinymce == \'object\' ) {' +
'return window.parent.parent.tinymce;' +
'} else {' +
'return window.parent.parent.tinymce;' +
'}' +
'}' +
// Run MathJax.Hub with its actual parser and call callback function after that.
// Because MathJax.Hub is asynchronous create MathJax.Hub.Queue to wait with callback.
'function update() {' +
'MathJax.Hub.Queue(' +
'[ \'Typeset\', MathJax.Hub, \'buffer\'],' +
'function() {' +
'getTinymce().tools.callFunction( ' + updateDoneHandler + ' );' +
'}' +
');' +
'}' +
// Run MathJax for the first time, when the script is loaded.
// Callback function will be called then it's done.
'MathJax.Hub.Queue( function() {' +
'getTinymce().tools.callFunction(' + loadedHandler + ');' +
'} );' +
'</script>' +
// Load MathJax lib.
'<script src="' + (mathJaxLib) + '"></script>' +
'</head>' +
'<body style="padding:0;margin:0;background:transparent;overflow:hidden">' +
'<span id="preview"><img src=' + loadingIcon + ' alt="loading..."></span>' +
// Render everything here and after that copy it to the preview.
'<span id="buffer" style="display:none"></span>' +
'</body>' +
'</html>');
}
doc.close();
// Run MathJax parsing Tex.
function update() {
isRunning = true;
value = newValue;
editor.fire('lockSnapshot');
buffer.innerHTML = value;
// Set loading indicator.
preview.innerHTML = '<img src=' + loadingIcon + ' alt="loading...">';
setStyles(iframe, {
height: '16px',
width: '16px',
display: 'inline',
'vertical-align': 'middle'
});
editor.fire('unlockSnapshot');
// Run MathJax.
iframe.contentWindow.update(value);
}
return {
/**
* Sets the TeX value to be displayed in the `iframe` element inside
* the editor. This function will activate the MathJax
* library which interprets TeX expressions and converts them into
* their representation that is displayed in the editor.
*
* @param {String} value TeX string.
*/
setValue: function (value) {
newValue = '\\(' + value + '\\)';//CKEDITOR.tools.htmlEncode(value);
if (isInit && !isRunning) {
update();
}
}
};
};
var setup = function (editor, pluginUrl) {
loadingIcon = pluginUrl + '/img/loader.gif';
editor.on('preInit', function () {
// Allow elements
//editor.schema.addValidElements(
// 'object[id|style|width|height|classid|codebase|*],embed[id|style|width|height|type|src|*],video[*],audio[*]'
//);
editor.parser.addAttributeFilter('data-latex', Nodes.placeHolderConverter(editor, pluginUrl));
// function (nodes, name) {
// console.log(nodes, name);//Chuyển từ dữ liệu div,span chứa latex sang giá trị preview editor
// });
// Converts iframe, video etc into placeholder images
// editor.parser.addNodeFilter('iframe,video,audio,object,embed,script',
// Nodes.placeHolderConverter(editor));
// Replaces placeholder images with real elements for video, object, iframe etc
editor.serializer.addAttributeFilter('data-mce-math', function (nodes, name) {
var i = nodes.length;
var node;
var realElm;
var ai;
var attribs;
var innerHtml;
var innerNode;
var realElmName;
var className;
while (i--) {
node = nodes[i];
if (!node.parent) {
continue;
}
realElmName = node.attr(name);
if (realElmName === 'math' || realElmName === 'latex') {
realElm = new Node('div', 1);
} else {
realElm = new Node(realElmName, 1);
}
// Add width/height to everything
className = node.attr('class');
if (className && className.indexOf('mce-preview-math') !== -1) {
realElm.attr({
width: node.firstChild.attr('width'),
height: node.firstChild.attr('height')
});
} else {
realElm.attr({
width: node.attr('width'),
height: node.attr('height')
});
}
realElm.attr({
style: node.attr('style')
});
// Unprefix all placeholder attributes
attribs = node.attributes;
ai = attribs.length;
while (ai--) {
var attrName = attribs[ai].name;
if (attrName.indexOf('data-mce-p-') === 0) {
realElm.attr(attrName.substr(11), attribs[ai].value);
}
}
if (realElmName === "script") {
realElm.attr('type', 'text/javascript');
}
if (realElmName === 'math' || realElmName === 'latex') {
innerHtml = node.attr('data-mce-latex');
realElm.attr('data-latex', innerHtml);
innerHtml = '$' + innerHtml + '$';
} else {
// Inject innerhtml
innerHtml = node.attr('data-mce-html');
}
if (innerHtml) {
innerNode = new Node('#text', 3);
innerNode.raw = true;
innerNode.value = Sanitize.sanitize(editor, unescape(innerHtml));
realElm.append(innerNode);
}
node.replace(realElm);
}
});
});
editor.on('setContent', function (e) {
// TODO: This shouldn't be needed there should be a way to mark bogus
// elements so they are never removed except external save
editor.$('span.mce-preview-math').each(function (index, elm) {
var $elm = editor.$(elm);
var ifa = $elm.find('iframe');
var needUpdated = $elm.find('img.mce-latex-loader').length > 0;
//validate element has created
if (ifa.length > 0 && $elm.find('span.mce-object-iframe').length > 0) {
$elm.html('<img class="mce-latex-loader" src="' + loadingIcon + '" alt="loading..."><span class="mce-shim"></span>');
needUpdated = true;
}
if (!needUpdated) {
return;
}
var iframe = editor.getDoc().createElement('iframe');
editor.$.each({
style: 'border:0;width:16px;height:16px',
scrolling: 'no',
frameborder: 0,
allowTransparency: true,
src: fixSrc,
'data-state': 1
}, function (i, v) {
iframe.setAttribute(i, v);
});
$elm.find('img.mce-latex-loader').replaceWith(iframe);
var wrap = frameWrapper(editor, iframe);
wrap.setValue($elm.attr('data-mce-p-data-latex'));
if ($elm.find('span.mce-shim', elm).length === 0) {
$elm.append('<span class="mce-shim"></span>');
}
});
});
};
return {
setup: setup
};
}
);
/**
* LoadCss.js
*
* Released under LGPL License.
* Copyright (c) 1999-2017 Ephox Corp. All rights reserved
*
* License: http://www.tinymce.com/license
* Contributing: http://www.tinymce.com/contributing
*/
define(
'tinymce.plugins.mathjax.core.LoadCss',
[
'tinymce.core.dom.DOMUtils',
'tinymce.core.util.Tools'
],
function (DOMUtils, Tools) {
var cssId = DOMUtils.DOM.uniqueId();
var load = function (doc, url) {
var linkElements = Tools.toArray(doc.getElementsByTagName('link'));
var matchingLinkElms = Tools.grep(linkElements, function (head) {
return head.id === cssId;
});
if (matchingLinkElms.length === 0) {
var linkElm = DOMUtils.DOM.create('link', {
id: cssId,
rel: 'stylesheet',
href: url
});
doc.getElementsByTagName('head')[0].appendChild(linkElm);
}
};
return {
load: load
};
}
);
/**
* Buttons.js
*
* Released under LGPL License.
* Copyright (c) 1999-2017 Ephox Corp. All rights reserved
*
* License: http://www.tinymce.com/license
* Contributing: http://www.tinymce.com/contributing
*/
define(
'tinymce.plugins.mathjax.ui.Buttons',
[
],
function () {
var register = function (editor, pluginUrl) {
editor.addButton('mathjax', {
icon:'mathjax',
// image: pluginUrl + '/img/mathjax.png',
tooltip: 'Insert/edit math',
cmd: 'mceMath',
stateSelector: ['span[data-mce-math]']
});
editor.addMenuItem('mathjax', {
icon: 'mathjax',
// image: pluginUrl + '/img/mathjax.png',
text: 'Math',
cmd: 'mceMath',
context: 'insert',
prependToContext: true
});
};
return {
register: register
};
}
);
/**
* Plugin.js
*
* Released under LGPL License.
* Copyright (c) 1999-2017 Ephox Corp. All rights reserved
*
* License: http://www.tinymce.com/license
* Contributing: http://www.tinymce.com/contributing
*/
define(
'tinymce.plugins.mathjax.Plugin',
[
'tinymce.core.PluginManager',
'tinymce.plugins.mathjax.api.Api',
'tinymce.plugins.mathjax.api.Commands',
'tinymce.plugins.mathjax.core.FilterContent',
'tinymce.plugins.mathjax.core.LoadCss',
'tinymce.plugins.mathjax.ui.Buttons'
],
function (PluginManager, Api, Commands, FilterContent, LoadCss, Buttons) {
var handleError = function (editor) {
return function (error) {
var errorMessage = error && error.msg ?
'Media embed handler error: ' + error.msg :
'Media embed handler threw unknown error.';
editor.notificationManager.open({ type: 'error', text: errorMessage });
};
};
PluginManager.add('mathjax', function (editor, pluginUrl) {
editor.on('init', function () {
setTimeout(function () {
try {
LoadCss.load(editor.editorContainer.ownerDocument, pluginUrl + '/css/mathjax-button.css');
} catch (e) {
(handleError(editor))(e);
}
LoadCss.load(editor.getDoc(), pluginUrl + '/css/mathjax.css');
}, 200);
});
Commands.register(editor, pluginUrl);
Buttons.register(editor, pluginUrl);
FilterContent.setup(editor, pluginUrl);
return Api.get(editor, pluginUrl);
});
return function () { };
}
);
dem('tinymce.plugins.mathjax.Plugin')();
})();