@wiris/mathtype-ckeditor5 8.15.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.
@@ -4032,6 +4032,27 @@
4032
4032
  if (mathML == null) {
4033
4033
  mathML = imgObject.getAttribute("alt");
4034
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
+ }
4035
4056
  if (convertToSafeXml) {
4036
4057
  const safeMathML = MathML.safeXmlEncode(mathML);
4037
4058
  return safeMathML;
@@ -4778,6 +4799,29 @@
4778
4799
  mathmlSubstring = mathmlSubstring.substring(4, mathmlSubstring.length);
4779
4800
  imgObject.setAttribute(Configuration.get("imageCustomEditorName"), mathmlSubstring);
4780
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
+ }
4781
4825
  // Performance enabled.
4782
4826
  if (Configuration.get("wirisPluginPerformance") && (Configuration.get("saveMode") === "xml" || Configuration.get("saveMode") === "safeXml")) {
4783
4827
  let result = JSON.parse(Parser.createShowImageSrc(data, language));
@@ -11333,6 +11377,14 @@
11333
11377
  returnObject.node = windowTarget.document.createTextNode(`$$${returnObject.latex}$$`);
11334
11378
  this.editorObject.model.change((writer)=>{
11335
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
+ }
11336
11388
  const startNode = this.findText(latexRange.startContainer);
11337
11389
  const endNode = this.findText(latexRange.endContainer);
11338
11390
  let startPosition = writer.createPositionAt(startNode.parent, startNode.startOffset + latexRange.startOffset);
@@ -11482,7 +11534,7 @@
11482
11534
 
11483
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";
11484
11536
 
11485
- var version = "8.15.0";
11537
+ var version = "8.15.1";
11486
11538
  var packageInfo = {
11487
11539
  version: version};
11488
11540
 
@@ -11824,7 +11876,8 @@
11824
11876
  imgElement = htmlDataProcessor.toView(htmlContent).getChild(0);
11825
11877
  } else if (formula) {
11826
11878
  const mathString = formula.replaceAll('ref="<"', 'ref="&lt;"');
11827
- const imgHtml = Parser.initParse(mathString, integration.getLanguage());
11879
+ const lang = integration?.getLanguage() || "en"; // Safe fallback to 'en' in case integration is undefined.
11880
+ const imgHtml = Parser.initParse(mathString, lang);
11828
11881
  imgElement = htmlDataProcessor.toView(imgHtml).getChild(0);
11829
11882
  // Add HTML element (<img>) to model
11830
11883
  viewWriter.setAttribute("htmlContent", imgHtml, modelItem);
@@ -11882,13 +11935,63 @@
11882
11935
  editor.editing.mapper.on("viewToModelPosition", ckeditor5.viewToModelPositionOutsideModelElement(editor.model, (viewElement)=>viewElement.hasClass("ck-math-widget")));
11883
11936
  // Keep a reference to the original get and set function.
11884
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
+ }
11885
11952
  /**
11886
- * Hack to transform $$latex$$ into <math> in editor.getData()'s output.
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.
11887
11962
  */ editor.data.on("get", (e)=>{
11888
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
11889
11992
  const parsedResult = Parser.endParse(output);
11890
- // Cleans all the semantics tag for safexml
11891
- // including the handwritten data points
11993
+ // Remove all semantic annotations (including handwritten data points)
11994
+ // to ensure clean, standard MathML format for storage
11892
11995
  e.return = MathML.removeSafeXMLSemantics(parsedResult);
11893
11996
  }, {
11894
11997
  priority: "low"
@@ -11953,7 +12056,7 @@
11953
12056
  trackChangesEditing.enableCommand("ChemType");
11954
12057
  // Adds custom label replacing the default 'mathml'.
11955
12058
  // Handles both singular and plural forms.
11956
- trackChangesEditing.descriptionFactory.registerElementLabel("mathml", (quantity)=>(quantity > 1 ? quantity + ' ' : '') + StringManager.get(quantity > 1 ? "formulas" : "formula", integration.getLanguage()));
12059
+ trackChangesEditing.descriptionFactory.registerElementLabel("mathml", (quantity)=>(quantity > 1 ? `${quantity} ` : "") + StringManager.get(quantity > 1 ? "formulas" : "formula", integration?.getLanguage() || "en"));
11957
12060
  }
11958
12061
  }
11959
12062
  }