@wiris/mathtype-ckeditor5 8.11.0 → 8.12.0

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/dist/index.js CHANGED
@@ -359,7 +359,7 @@ var mathIcon = "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!-- Generator: Adob
359
359
  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";
360
360
 
361
361
  var name = "@wiris/mathtype-ckeditor5";
362
- var version = "8.11.0";
362
+ var version = "8.12.0";
363
363
  var description = "MathType Web for CKEditor5 editor";
364
364
  var keywords = [
365
365
  "chem",
@@ -376,7 +376,7 @@ var keywords = [
376
376
  "mathtype",
377
377
  "wiris"
378
378
  ];
379
- var repository = "https://github.com/wiris/html-integrations/tree/stable/packages/mathtype-ckeditor5";
379
+ var repository = "https://github.com/wiris/html-integrations/tree/master/packages/ckeditor5";
380
380
  var homepage = "https://www.wiris.com/";
381
381
  var bugs = {
382
382
  email: "support@wiris.com"
@@ -406,7 +406,7 @@ var scripts = {
406
406
  prepare: "npm run build:dist"
407
407
  };
408
408
  var dependencies = {
409
- "@wiris/mathtype-html-integration-devkit": "1.17.4"
409
+ "@wiris/mathtype-html-integration-devkit": "1.17.6"
410
410
  };
411
411
  var devDependencies = {
412
412
  "@ckeditor/ckeditor5-dev-build-tools": "^42.1.0",
@@ -489,7 +489,7 @@ class MathType extends Plugin {
489
489
  integrationProperties.managesLanguage = true;
490
490
  // etc
491
491
  // There are platforms like Drupal that initialize CKEditor but they hide or remove the container element.
492
- // To avoid a wrong behaviour, this integration only starts if the workspace container exists.
492
+ // To avoid a wrong behavior, this integration only starts if the workspace container exists.
493
493
  let integration;
494
494
  if (integrationProperties.target) {
495
495
  // Instance of the integration associated to this editor instance
@@ -575,7 +575,8 @@ class MathType extends Plugin {
575
575
  schema.register("mathml", {
576
576
  inheritAllFrom: "$inlineObject",
577
577
  allowAttributes: [
578
- "formula"
578
+ "formula",
579
+ "htmlContent"
579
580
  ]
580
581
  });
581
582
  }
@@ -659,6 +660,50 @@ class MathType extends Plugin {
659
660
  data.modelCursor = data.modelRange.end;
660
661
  }
661
662
  });
663
+ // Data view -> Model
664
+ editor.data.upcastDispatcher.on("element:img", (evt, data, conversionApi)=>{
665
+ const { consumable, writer } = conversionApi;
666
+ const { viewItem } = data;
667
+ // Only upcast when is wiris formula
668
+ if (viewItem.getClassNames().next().value !== "Wirisformula") {
669
+ return;
670
+ }
671
+ const mathAttributes = [
672
+ ...viewItem.getAttributes()
673
+ ].map(([key, value])=>` ${key}="${value}"`).join("");
674
+ let htmlContent = Util.htmlSanitize(`<img${mathAttributes}>`);
675
+ const modelNode = writer.createElement("mathml", {
676
+ htmlContent
677
+ });
678
+ // Find allowed parent for element that we are going to insert.
679
+ // If current parent does not allow to insert element but one of the ancestors does
680
+ // then split nodes to allowed parent.
681
+ const splitResult = conversionApi.splitToAllowedParent(modelNode, data.modelCursor);
682
+ // When there is no split result it means that we can't insert element to model tree, so let's skip it.
683
+ if (!splitResult) {
684
+ return;
685
+ }
686
+ // Insert element on allowed position.
687
+ conversionApi.writer.insert(modelNode, splitResult.position);
688
+ // Consume appropriate value from consumable values list.
689
+ consumable.consume(viewItem, {
690
+ name: true
691
+ });
692
+ const parts = conversionApi.getSplitParts(modelNode);
693
+ // Set conversion result range.
694
+ data.modelRange = writer.createRange(conversionApi.writer.createPositionBefore(modelNode), conversionApi.writer.createPositionAfter(parts[parts.length - 1]));
695
+ // Now we need to check where the `modelCursor` should be.
696
+ if (splitResult.cursorParent) {
697
+ // If we split parent to insert our element then we want to continue conversion in the new part of the split parent.
698
+ //
699
+ // before: <allowed><notAllowed>foo[]</notAllowed></allowed>
700
+ // after: <allowed><notAllowed>foo</notAllowed><converted></converted><notAllowed>[]</notAllowed></allowed>
701
+ data.modelCursor = conversionApi.writer.createPositionAt(splitResult.cursorParent, 0);
702
+ } else {
703
+ // Otherwise just continue after inserted element.
704
+ data.modelCursor = data.modelRange.end;
705
+ }
706
+ });
662
707
  /**
663
708
  * Whether the given view <math> element has a LaTeX annotation element.
664
709
  * @param {*} math
@@ -687,12 +732,25 @@ class MathType extends Plugin {
687
732
  }
688
733
  function createViewImage(modelItem, { writer: viewWriter }) {
689
734
  const htmlDataProcessor = new HtmlDataProcessor(viewWriter.document);
690
- const mathString = modelItem.getAttribute("formula").replaceAll('ref="<"', 'ref="&lt;"');
691
- const imgHtml = Parser.initParse(mathString, integration.getLanguage());
692
- const imgElement = htmlDataProcessor.toView(imgHtml).getChild(0);
735
+ const formula = modelItem.getAttribute("formula");
736
+ const htmlContent = modelItem.getAttribute("htmlContent");
737
+ if (!formula && !htmlContent) {
738
+ return null;
739
+ }
740
+ let imgElement = null;
741
+ if (htmlContent) {
742
+ imgElement = htmlDataProcessor.toView(htmlContent).getChild(0);
743
+ } else if (formula) {
744
+ const mathString = formula.replaceAll('ref="<"', 'ref="&lt;"');
745
+ const imgHtml = Parser.initParse(mathString, integration.getLanguage());
746
+ imgElement = htmlDataProcessor.toView(imgHtml).getChild(0);
747
+ // Add HTML element (<img>) to model
748
+ viewWriter.setAttribute("htmlContent", imgHtml, modelItem);
749
+ }
693
750
  /* Although we use the HtmlDataProcessor to obtain the attributes,
694
- we must create a new EmptyElement which is independent of the
695
- DataProcessor being used by this editor instance */ if (imgElement) {
751
+ * we must create a new EmptyElement which is independent of the
752
+ * DataProcessor being used by this editor instance
753
+ */ if (imgElement) {
696
754
  return viewWriter.createEmptyElement("img", imgElement.getAttributes(), {
697
755
  renderUnsafeAttributes: [
698
756
  "src"
@@ -733,7 +791,8 @@ class MathType extends Plugin {
733
791
  }
734
792
  function createDataString(modelItem, { writer: viewWriter }) {
735
793
  const htmlDataProcessor = new HtmlDataProcessor(viewWriter.document);
736
- let mathString = Parser.endParseSaveMode(modelItem.getAttribute("formula"));
794
+ // Load img element
795
+ let mathString = modelItem.getAttribute("htmlContent") || Parser.endParseSaveMode(modelItem.getAttribute("formula"));
737
796
  const sourceMathElement = htmlDataProcessor.toView(mathString).getChild(0);
738
797
  return clone(viewWriter, sourceMathElement);
739
798
  }
@@ -745,36 +804,40 @@ class MathType extends Plugin {
745
804
  * Hack to transform $$latex$$ into <math> in editor.getData()'s output.
746
805
  */ editor.data.on("get", (e)=>{
747
806
  let output = e.return;
748
- // This line cleans all the semantics stuff, including the handwritten data points and returns the MathML IF there is any.
749
- // For text or latex formulas, it returns the original output.
750
- e.return = MathML.removeSemantics(output, "application/json");
807
+ const parsedResult = Parser.endParse(output);
808
+ // Cleans all the semantics tag for safexml
809
+ // including the handwritten data points
810
+ e.return = MathML.removeSafeXMLSemantics(parsedResult);
751
811
  }, {
752
812
  priority: "low"
753
813
  });
754
814
  /**
755
- * Hack to transform <math> with LaTeX into $$LaTeX$$ in editor.setData().
815
+ * Hack to transform <math> with LaTeX into $$LaTeX$$ and formula images in editor.setData().
756
816
  */ editor.data.on("set", (e, args)=>{
757
817
  // Retrieve the data to be set on the CKEditor.
758
818
  let modifiedData = args[0];
759
819
  // Regex to find all mathml formulas.
760
- const regexp = /<math(.*?)<\/math>/gm;
761
- // Get all MathML formulas and store them in an array.
762
- // Using the conditional operator on data.main because the data parameter has different types depending on:
763
- // editor.data.set can be used directly or by the source editing plugin.
764
- // With the source editor plugin, data is an object with the key `main` which contains the source code string.
765
- // When using the editor.data.set method, the data is a string with the content to be set to the editor.
766
- let formulas = Object.values(modifiedData)[0] ? [
767
- ...Object.values(modifiedData)[0].matchAll(regexp)
768
- ] : [
769
- ...modifiedData.matchAll(regexp)
770
- ];
771
- // Loop to find LaTeX formulas and replace the MathML for the LaTeX notation.
820
+ const regexp = /(<img\b[^>]*>)|(<math(.*?)<\/math>)/gm;
821
+ const formulas = [];
822
+ let formula;
823
+ // Both data.set from the source plugin and console command are taken into account as the data received is MathML or an image containing the MathML.
824
+ while((formula = regexp.exec(modifiedData)) !== null){
825
+ formulas.push(formula[0]);
826
+ }
827
+ // Loop to find LaTeX and formula images and replace the MathML for the both.
772
828
  formulas.forEach((formula)=>{
773
- let mathml = formula[0];
774
- if (mathml.includes('encoding="LaTeX"')) {
829
+ if (formula.includes('encoding="LaTeX"')) {
775
830
  // LaTeX found.
776
- let latex = "$$$" + Latex.getLatexFromMathML(mathml) + "$$$"; // We add $$$ instead of $$ because the replace function ignores one $.
777
- modifiedData = modifiedData.replace(mathml, latex);
831
+ let latex = "$$$" + Latex.getLatexFromMathML(formula) + "$$$"; // We add $$$ instead of $$ because the replace function ignores one $.
832
+ modifiedData = modifiedData.replace(formula, latex);
833
+ } else if (formula.includes("<img")) {
834
+ // If we found a formula image, we should find MathML data, and then substitute the entire image.
835
+ const regexp = /«math\b[^»]*»(.*?)«\/math»/g;
836
+ const safexml = formula.match(regexp);
837
+ if (safexml !== null) {
838
+ let decodeXML = MathML.safeXmlDecode(safexml[0]);
839
+ modifiedData = modifiedData.replace(formula, decodeXML);
840
+ }
778
841
  }
779
842
  });
780
843
  args[0] = modifiedData;