@wiris/mathtype-ckeditor5 8.14.0 → 8.15.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -0
- package/dist/browser/index-editor.css +16 -1
- package/dist/browser/index.css +17 -0
- package/dist/browser/index.css.map +1 -1
- package/dist/browser/index.js +139 -11
- package/dist/browser/index.js.map +1 -1
- package/dist/browser/index.umd.js +139 -11
- package/dist/browser/index.umd.js.map +1 -1
- package/dist/index-editor.css +15 -0
- package/dist/index.css +18 -0
- package/dist/index.css.map +1 -0
- package/dist/index.js +85 -9
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
- package/src/integration.js +17 -3
- package/src/plugin.js +94 -5
- package/theme/styles.css +28 -0
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
})(this, (function (exports, ckeditor5) { 'use strict';
|
|
6
6
|
|
|
7
7
|
var _documentCurrentScript = typeof document !== 'undefined' ? document.currentScript : null;
|
|
8
|
-
/*! @license DOMPurify 3.3.
|
|
8
|
+
/*! @license DOMPurify 3.3.1 | (c) Cure53 and other contributors | Released under the Apache license 2.0 and Mozilla Public License 2.0 | github.com/cure53/DOMPurify/blob/3.3.1/LICENSE */
|
|
9
9
|
|
|
10
10
|
const {
|
|
11
11
|
entries,
|
|
@@ -303,7 +303,7 @@
|
|
|
303
303
|
function createDOMPurify() {
|
|
304
304
|
let window = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : getGlobal();
|
|
305
305
|
const DOMPurify = root => createDOMPurify(root);
|
|
306
|
-
DOMPurify.version = '3.3.
|
|
306
|
+
DOMPurify.version = '3.3.1';
|
|
307
307
|
DOMPurify.removed = [];
|
|
308
308
|
if (!window || !window.document || window.document.nodeType !== NODE_TYPE.document || !window.Element) {
|
|
309
309
|
// Not running in a browser, provide a factory function
|
|
@@ -649,6 +649,12 @@
|
|
|
649
649
|
}
|
|
650
650
|
addToSet(FORBID_CONTENTS, cfg.FORBID_CONTENTS, transformCaseFunc);
|
|
651
651
|
}
|
|
652
|
+
if (cfg.ADD_FORBID_CONTENTS) {
|
|
653
|
+
if (FORBID_CONTENTS === DEFAULT_FORBID_CONTENTS) {
|
|
654
|
+
FORBID_CONTENTS = clone(FORBID_CONTENTS);
|
|
655
|
+
}
|
|
656
|
+
addToSet(FORBID_CONTENTS, cfg.ADD_FORBID_CONTENTS, transformCaseFunc);
|
|
657
|
+
}
|
|
652
658
|
/* Add #text in case KEEP_CONTENT is set to true */
|
|
653
659
|
if (KEEP_CONTENT) {
|
|
654
660
|
ALLOWED_TAGS['#text'] = true;
|
|
@@ -4026,6 +4032,27 @@
|
|
|
4026
4032
|
if (mathML == null) {
|
|
4027
4033
|
mathML = imgObject.getAttribute("alt");
|
|
4028
4034
|
}
|
|
4035
|
+
// WARNING: This code is needed for CKEditor 5 Track Changes compatibility.
|
|
4036
|
+
// Preserve Track Changes attributes when converting image back to MathML.
|
|
4037
|
+
// This ensures change tracking information is maintained during the roundtrip conversion
|
|
4038
|
+
// (MathML → Image → MathML) in collaborative editing scenarios.
|
|
4039
|
+
const TRACK_CHANGES_ATTRIBUTE_PREFIXES = [
|
|
4040
|
+
"data-suggestion-",
|
|
4041
|
+
"data-comment-"
|
|
4042
|
+
];
|
|
4043
|
+
const preservedAttributes = {};
|
|
4044
|
+
// Extract Track Changes attributes from the image element
|
|
4045
|
+
for (const { name: attributeName, value: attributeValue } of imgObject.attributes){
|
|
4046
|
+
const isTrackChangesAttribute = TRACK_CHANGES_ATTRIBUTE_PREFIXES.some((prefix)=>attributeName.startsWith(prefix));
|
|
4047
|
+
if (isTrackChangesAttribute) {
|
|
4048
|
+
preservedAttributes[attributeName] = attributeValue;
|
|
4049
|
+
}
|
|
4050
|
+
}
|
|
4051
|
+
// If Track Changes attributes were found, inject them into the MathML opening tag
|
|
4052
|
+
if (Object.keys(preservedAttributes).length > 0) {
|
|
4053
|
+
const attributesString = Object.keys(preservedAttributes).map((name)=>` ${name}="${Util.htmlEntities(preservedAttributes[name])}"`).join("");
|
|
4054
|
+
mathML = mathML.replace(/(<math)/i, `$1${attributesString}`);
|
|
4055
|
+
}
|
|
4029
4056
|
if (convertToSafeXml) {
|
|
4030
4057
|
const safeMathML = MathML.safeXmlEncode(mathML);
|
|
4031
4058
|
return safeMathML;
|
|
@@ -4772,6 +4799,29 @@
|
|
|
4772
4799
|
mathmlSubstring = mathmlSubstring.substring(4, mathmlSubstring.length);
|
|
4773
4800
|
imgObject.setAttribute(Configuration.get("imageCustomEditorName"), mathmlSubstring);
|
|
4774
4801
|
}
|
|
4802
|
+
// WARNING: This code is needed for CKEditor 5 Track Changes compatibility.
|
|
4803
|
+
// Preserve Track Changes attributes (suggestions and comments) when converting MathML to image.
|
|
4804
|
+
// These attributes are needed to maintain change tracking information in collaborative editing scenarios.
|
|
4805
|
+
// They are extracted from the input MathML and transferred to the output image element.
|
|
4806
|
+
const TRACK_CHANGES_ATTRIBUTE_PREFIXES = [
|
|
4807
|
+
"data-suggestion-",
|
|
4808
|
+
"data-comment-"
|
|
4809
|
+
];
|
|
4810
|
+
const attributePattern = /([\w-]+)="([^"]*)"/g;
|
|
4811
|
+
let attributeMatch;
|
|
4812
|
+
// Parse only the opening <math> tag to extract attributes
|
|
4813
|
+
const mathOpeningTagEnd = mathml.indexOf(">");
|
|
4814
|
+
if (mathOpeningTagEnd !== -1) {
|
|
4815
|
+
const mathOpeningTag = mathml.substring(0, mathOpeningTagEnd);
|
|
4816
|
+
while((attributeMatch = attributePattern.exec(mathOpeningTag)) !== null){
|
|
4817
|
+
const [, attributeName, attributeValue] = attributeMatch;
|
|
4818
|
+
// Transfer Track Changes attributes from MathML to image
|
|
4819
|
+
const isTrackChangesAttribute = TRACK_CHANGES_ATTRIBUTE_PREFIXES.some((prefix)=>attributeName.startsWith(prefix));
|
|
4820
|
+
if (isTrackChangesAttribute) {
|
|
4821
|
+
imgObject.setAttribute(attributeName, Util.htmlEntitiesDecode(attributeValue));
|
|
4822
|
+
}
|
|
4823
|
+
}
|
|
4824
|
+
}
|
|
4775
4825
|
// Performance enabled.
|
|
4776
4826
|
if (Configuration.get("wirisPluginPerformance") && (Configuration.get("saveMode") === "xml" || Configuration.get("saveMode") === "safeXml")) {
|
|
4777
4827
|
let result = JSON.parse(Parser.createShowImageSrc(data, language));
|
|
@@ -9742,6 +9792,8 @@
|
|
|
9742
9792
|
* Opens formula editor to editing an existing formula. Can be overwritten in order to make some
|
|
9743
9793
|
* actions from integration part before the formula is edited.
|
|
9744
9794
|
*/ openExistingFormulaEditor() {
|
|
9795
|
+
// Recover owner integration instance.
|
|
9796
|
+
WirisPlugin.currentInstance = this;
|
|
9745
9797
|
if (window.navigator.onLine) {
|
|
9746
9798
|
this.core.editionProperties.isNewElement = false;
|
|
9747
9799
|
this.core.openModalDialog(this.target, this.isIframe);
|
|
@@ -11263,7 +11315,9 @@
|
|
|
11263
11315
|
// Remove selection
|
|
11264
11316
|
if (!viewSelection.isCollapsed) {
|
|
11265
11317
|
for (const range of viewSelection.getRanges()){
|
|
11266
|
-
|
|
11318
|
+
const modelRange = this.editorObject.editing.mapper.toModelRange(range);
|
|
11319
|
+
const modelSelection = this.editorObject.model.createSelection(modelRange);
|
|
11320
|
+
this.editorObject.model.deleteContent(modelSelection);
|
|
11267
11321
|
}
|
|
11268
11322
|
}
|
|
11269
11323
|
// Set carret after the formula
|
|
@@ -11279,7 +11333,7 @@
|
|
|
11279
11333
|
if (mathml) {
|
|
11280
11334
|
this.editorObject.model.insertObject(modelElementNew, position);
|
|
11281
11335
|
}
|
|
11282
|
-
|
|
11336
|
+
this.editorObject.model.deleteContent(this.editorObject.model.createSelection(modelElementOld, 'on'));
|
|
11283
11337
|
}
|
|
11284
11338
|
// eslint-disable-next-line consistent-return
|
|
11285
11339
|
return modelElementNew;
|
|
@@ -11323,6 +11377,14 @@
|
|
|
11323
11377
|
returnObject.node = windowTarget.document.createTextNode(`$$${returnObject.latex}$$`);
|
|
11324
11378
|
this.editorObject.model.change((writer)=>{
|
|
11325
11379
|
const { latexRange } = this.core.editionProperties;
|
|
11380
|
+
// Add null check for latexRange.
|
|
11381
|
+
// When the editor is initialized in a textarea element, latexRange may not be set on initial load.
|
|
11382
|
+
// This check ensures formulas can still be inserted by falling back to MathML insertion if latexRange is not available.
|
|
11383
|
+
if (!latexRange) {
|
|
11384
|
+
// Fallback to regular MathML insertion if latexRange is not available
|
|
11385
|
+
this.insertMathml(mathml);
|
|
11386
|
+
return;
|
|
11387
|
+
}
|
|
11326
11388
|
const startNode = this.findText(latexRange.startContainer);
|
|
11327
11389
|
const endNode = this.findText(latexRange.endContainer);
|
|
11328
11390
|
let startPosition = writer.createPositionAt(startNode.parent, startNode.startOffset + latexRange.startOffset);
|
|
@@ -11350,7 +11412,8 @@
|
|
|
11350
11412
|
range = writer.createRange(startPosition, endPosition);
|
|
11351
11413
|
}
|
|
11352
11414
|
}
|
|
11353
|
-
|
|
11415
|
+
const modelSelection = this.editorObject.model.createSelection(range);
|
|
11416
|
+
this.editorObject.model.deleteContent(modelSelection);
|
|
11354
11417
|
writer.insertText(`$$${returnObject.latex}$$`, startNode.getAttributes(), startPosition);
|
|
11355
11418
|
});
|
|
11356
11419
|
} else {
|
|
@@ -11471,7 +11534,7 @@
|
|
|
11471
11534
|
|
|
11472
11535
|
var chemIcon = "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!-- Generator: Adobe Illustrator 22.0.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->\n<svg version=\"1.1\" id=\"Layer_1\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" x=\"0px\" y=\"0px\"\n\t viewBox=\"0 0 40.3 49.5\" style=\"enable-background:new 0 0 40.3 49.5;\" xml:space=\"preserve\">\n<style type=\"text/css\">\n\t.st0{fill:#A4CF61;}\n</style>\n<path class=\"st0\" d=\"M39.2,12.1c0-1.9-1.1-3.6-2.7-4.4L24.5,0.9l0,0c-0.7-0.4-1.5-0.6-2.4-0.6c-0.9,0-1.7,0.2-2.4,0.6l0,0L2.3,10.8\n\tl0,0C0.9,11.7,0,13.2,0,14.9h0v19.6h0c0,1.7,0.9,3.3,2.3,4.1l0,0l17.4,9.9l0,0c0.7,0.4,1.5,0.6,2.4,0.6c0.9,0,1.7-0.2,2.4-0.6l0,0\n\tl12.2-6.9h0c1.5-0.8,2.6-2.5,2.6-4.3c0-2.7-2.2-4.9-4.9-4.9c-0.9,0-1.8,0.3-2.5,0.7l0,0l-9.7,5.6l-12.3-7V17.8l12.3-7l9.9,5.7l0,0\n\tc0.7,0.4,1.5,0.6,2.4,0.6C37,17,39.2,14.8,39.2,12.1\"/>\n</svg>\n";
|
|
11473
11536
|
|
|
11474
|
-
var version = "8.
|
|
11537
|
+
var version = "8.15.1";
|
|
11475
11538
|
var packageInfo = {
|
|
11476
11539
|
version: version};
|
|
11477
11540
|
|
|
@@ -11491,7 +11554,9 @@
|
|
|
11491
11554
|
const integration = this._addIntegration();
|
|
11492
11555
|
currentInstance = integration;
|
|
11493
11556
|
// Add the MathType and ChemType commands to the editor
|
|
11494
|
-
this._addCommands();
|
|
11557
|
+
this._addCommands(integration);
|
|
11558
|
+
// Add the track changes feature integration
|
|
11559
|
+
this._addTrackChangesIntegration(integration);
|
|
11495
11560
|
// Add the buttons for MathType and ChemType
|
|
11496
11561
|
this._addViews(integration);
|
|
11497
11562
|
// Registers the <mathml> element in the schema
|
|
@@ -11811,7 +11876,8 @@
|
|
|
11811
11876
|
imgElement = htmlDataProcessor.toView(htmlContent).getChild(0);
|
|
11812
11877
|
} else if (formula) {
|
|
11813
11878
|
const mathString = formula.replaceAll('ref="<"', 'ref="<"');
|
|
11814
|
-
const
|
|
11879
|
+
const lang = integration?.getLanguage() || "en"; // Safe fallback to 'en' in case integration is undefined.
|
|
11880
|
+
const imgHtml = Parser.initParse(mathString, lang);
|
|
11815
11881
|
imgElement = htmlDataProcessor.toView(imgHtml).getChild(0);
|
|
11816
11882
|
// Add HTML element (<img>) to model
|
|
11817
11883
|
viewWriter.setAttribute("htmlContent", imgHtml, modelItem);
|
|
@@ -11869,13 +11935,63 @@
|
|
|
11869
11935
|
editor.editing.mapper.on("viewToModelPosition", ckeditor5.viewToModelPositionOutsideModelElement(editor.model, (viewElement)=>viewElement.hasClass("ck-math-widget")));
|
|
11870
11936
|
// Keep a reference to the original get and set function.
|
|
11871
11937
|
const { get, set } = editor.data;
|
|
11938
|
+
// Listen to the preview command execution to set a flag in localStorage.
|
|
11939
|
+
// This flag will be used in the getData() to prevent converting formulas while generating the preview.
|
|
11940
|
+
// This is necessary because the preview command uses editor.getData() multiple times internally.
|
|
11941
|
+
const previewCommand = editor.commands.get("previewFinalContent");
|
|
11942
|
+
if (previewCommand) {
|
|
11943
|
+
this.listenTo(previewCommand, "execute", ()=>{
|
|
11944
|
+
localStorage.setItem("isGeneratingPreview", true);
|
|
11945
|
+
setTimeout(()=>{
|
|
11946
|
+
localStorage.setItem("isGeneratingPreview", false);
|
|
11947
|
+
}, 1000);
|
|
11948
|
+
}, {
|
|
11949
|
+
priority: "high"
|
|
11950
|
+
});
|
|
11951
|
+
}
|
|
11872
11952
|
/**
|
|
11873
|
-
*
|
|
11953
|
+
* Listener for getData() that handles Track Changes and semantics cleanup.
|
|
11954
|
+
*
|
|
11955
|
+
* This listener intercepts the getData() call and processes the output differently
|
|
11956
|
+
* depending on whether we're generating a preview or performing a save operation:
|
|
11957
|
+
*
|
|
11958
|
+
* - Preview Mode: Removes deleted formulas (marked with Track Changes deletion attributes)
|
|
11959
|
+
* while preserving formula images for visual representation.
|
|
11960
|
+
* - Save Mode: Converts formulas to clean MathML by removing semantic annotations
|
|
11961
|
+
* and handwritten data, ensuring clean storage format.
|
|
11874
11962
|
*/ editor.data.on("get", (e)=>{
|
|
11875
11963
|
const output = e.return;
|
|
11964
|
+
// Check if we're in preview mode (flag set by previewFinalContent command)
|
|
11965
|
+
const isGeneratingPreview = localStorage.getItem("isGeneratingPreview");
|
|
11966
|
+
if (isGeneratingPreview === "true") {
|
|
11967
|
+
// Wrap a <span> around all img elements to preserve Track Changes visibility for formulas.
|
|
11968
|
+
// Span must contain all the img attributes to avoid render issues.
|
|
11969
|
+
const attributesToPreserve = [
|
|
11970
|
+
"data-suggestion-",
|
|
11971
|
+
"data-comment-"
|
|
11972
|
+
];
|
|
11973
|
+
const previewOutput = output.replace(/<img([^>]*class="Wirisformula"[^>]*)>/g, (match, attributes)=>{
|
|
11974
|
+
// Extract Track Changes attributes
|
|
11975
|
+
const trackChangesAttrs = [];
|
|
11976
|
+
attributesToPreserve.forEach((prefix)=>{
|
|
11977
|
+
const regex = new RegExp(`(${prefix}[^=]*="[^"]*")`, "g");
|
|
11978
|
+
let attrMatch;
|
|
11979
|
+
while((attrMatch = regex.exec(attributes)) !== null){
|
|
11980
|
+
trackChangesAttrs.push(attrMatch[1]);
|
|
11981
|
+
}
|
|
11982
|
+
});
|
|
11983
|
+
const spanAttrs = trackChangesAttrs.length > 0 ? ` ${trackChangesAttrs.join(" ")}` : "";
|
|
11984
|
+
return `<span${spanAttrs}>${match}</span>`;
|
|
11985
|
+
});
|
|
11986
|
+
// Cleans all the semantics tag for safexml
|
|
11987
|
+
// including the handwritten data points
|
|
11988
|
+
e.return = MathML.removeSafeXMLSemantics(previewOutput);
|
|
11989
|
+
return;
|
|
11990
|
+
}
|
|
11991
|
+
// In save mode, convert formula images back to clean MathML
|
|
11876
11992
|
const parsedResult = Parser.endParse(output);
|
|
11877
|
-
//
|
|
11878
|
-
//
|
|
11993
|
+
// Remove all semantic annotations (including handwritten data points)
|
|
11994
|
+
// to ensure clean, standard MathML format for storage
|
|
11879
11995
|
e.return = MathML.removeSafeXMLSemantics(parsedResult);
|
|
11880
11996
|
}, {
|
|
11881
11997
|
priority: "low"
|
|
@@ -11931,6 +12047,18 @@
|
|
|
11931
12047
|
Latex
|
|
11932
12048
|
};
|
|
11933
12049
|
}
|
|
12050
|
+
_addTrackChangesIntegration(integration) {
|
|
12051
|
+
const { editor } = this;
|
|
12052
|
+
if (editor.plugins.has("TrackChangesEditing")) {
|
|
12053
|
+
const trackChangesEditing = editor.plugins.get("TrackChangesEditing");
|
|
12054
|
+
// Makes MathType and ChemType buttons available when editor is in the track changes mode
|
|
12055
|
+
trackChangesEditing.enableCommand("MathType");
|
|
12056
|
+
trackChangesEditing.enableCommand("ChemType");
|
|
12057
|
+
// Adds custom label replacing the default 'mathml'.
|
|
12058
|
+
// Handles both singular and plural forms.
|
|
12059
|
+
trackChangesEditing.descriptionFactory.registerElementLabel("mathml", (quantity)=>(quantity > 1 ? `${quantity} ` : "") + StringManager.get(quantity > 1 ? "formulas" : "formula", integration?.getLanguage() || "en"));
|
|
12060
|
+
}
|
|
12061
|
+
}
|
|
11934
12062
|
}
|
|
11935
12063
|
|
|
11936
12064
|
exports.CKEditor5Integration = CKEditor5Integration;
|