@tailor-cms/ce-html-edit 0.1.3 → 0.1.4

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.
Files changed (3) hide show
  1. package/dist/index.cjs +231 -10
  2. package/dist/index.js +231 -10
  3. package/package.json +3 -2
package/dist/index.cjs CHANGED
@@ -44,7 +44,7 @@ var manifest$1 = {
44
44
  ui,
45
45
  ai
46
46
  };
47
- var index_default = manifest$1;
47
+ var index_default$1 = manifest$1;
48
48
  function OrderedMap(content) {
49
49
  this.content = content;
50
50
  }
@@ -2491,7 +2491,7 @@ function isTagRule(rule) {
2491
2491
  function isStyleRule(rule) {
2492
2492
  return rule.style != null;
2493
2493
  }
2494
- class DOMParser {
2494
+ let DOMParser$1 = class DOMParser2 {
2495
2495
  /**
2496
2496
  Create a parser that targets the given schema, using the given
2497
2497
  parsing rules.
@@ -2617,9 +2617,9 @@ class DOMParser {
2617
2617
  [priority](https://prosemirror.net/docs/ref/#model.ParseRule.priority).
2618
2618
  */
2619
2619
  static fromSchema(schema) {
2620
- return schema.cached.domParser || (schema.cached.domParser = new DOMParser(schema, DOMParser.schemaRules(schema)));
2620
+ return schema.cached.domParser || (schema.cached.domParser = new DOMParser2(schema, DOMParser2.schemaRules(schema)));
2621
2621
  }
2622
- }
2622
+ };
2623
2623
  const blockTags = {
2624
2624
  address: true,
2625
2625
  article: true,
@@ -8641,7 +8641,7 @@ function parseFromClipboard(view, text, html, plainText, $context) {
8641
8641
  dom = child;
8642
8642
  }
8643
8643
  if (!slice2) {
8644
- let parser = view.someProp("clipboardParser") || view.someProp("domParser") || DOMParser.fromSchema(view.state.schema);
8644
+ let parser = view.someProp("clipboardParser") || view.someProp("domParser") || DOMParser$1.fromSchema(view.state.schema);
8645
8645
  slice2 = parser.parseSlice(dom, {
8646
8646
  preserveWhitespace: !!(asText || sliceData),
8647
8647
  context: $context,
@@ -10451,7 +10451,7 @@ function parseBetween(view, from_, to_) {
10451
10451
  }
10452
10452
  }
10453
10453
  let startDoc = view.state.doc;
10454
- let parser = view.someProp("domParser") || DOMParser.fromSchema(view.state.schema);
10454
+ let parser = view.someProp("domParser") || DOMParser$1.fromSchema(view.state.schema);
10455
10455
  let $from = startDoc.resolve(from2);
10456
10456
  let sel = null, doc2 = parser.parse(parent, {
10457
10457
  topNode: $from.parent,
@@ -13774,15 +13774,15 @@ function createNodeFromContent(content, schema, options) {
13774
13774
  })
13775
13775
  });
13776
13776
  if (options.slice) {
13777
- DOMParser.fromSchema(contentCheckSchema).parseSlice(elementFromString(content), options.parseOptions);
13777
+ DOMParser$1.fromSchema(contentCheckSchema).parseSlice(elementFromString(content), options.parseOptions);
13778
13778
  } else {
13779
- DOMParser.fromSchema(contentCheckSchema).parse(elementFromString(content), options.parseOptions);
13779
+ DOMParser$1.fromSchema(contentCheckSchema).parse(elementFromString(content), options.parseOptions);
13780
13780
  }
13781
13781
  if (options.errorOnInvalidContent && hasInvalidContent) {
13782
13782
  throw new Error("[tiptap error]: Invalid HTML content", { cause: new Error(`Invalid element found: ${invalidContent}`) });
13783
13783
  }
13784
13784
  }
13785
- const parser = DOMParser.fromSchema(schema);
13785
+ const parser = DOMParser$1.fromSchema(schema);
13786
13786
  if (options.slice) {
13787
13787
  return parser.parseSlice(elementFromString(content), options.parseOptions).content;
13788
13788
  }
@@ -19840,6 +19840,226 @@ const Highlight = Mark2.create({
19840
19840
  ];
19841
19841
  }
19842
19842
  });
19843
+ function parseRomanNumber(roman) {
19844
+ roman = roman.toUpperCase();
19845
+ let value = 0;
19846
+ const values = { I: 1, V: 5, X: 10, L: 50, C: 100, D: 500, M: 1e3 };
19847
+ let i = roman.length;
19848
+ let lastVal = 0;
19849
+ while (i--) {
19850
+ if (values[roman.charAt(i)] >= lastVal) {
19851
+ value += values[roman.charAt(i)];
19852
+ } else {
19853
+ value -= values[roman.charAt(i)];
19854
+ }
19855
+ lastVal = values[roman.charAt(i)];
19856
+ }
19857
+ return value;
19858
+ }
19859
+ function parseLetterNumber(str) {
19860
+ const alphaVal = (s) => s.toLowerCase().charCodeAt(0) - 97 + 1;
19861
+ let value = 0;
19862
+ let i = str.length;
19863
+ while (i--) {
19864
+ const factor = Math.pow(26, str.length - i - 1);
19865
+ value += alphaVal(str.charAt(i)) * factor;
19866
+ }
19867
+ return value;
19868
+ }
19869
+ function unwrapNode(node) {
19870
+ const parent = node.parentNode;
19871
+ while (node.firstChild) {
19872
+ parent == null ? void 0 : parent.insertBefore(node.firstChild, node);
19873
+ }
19874
+ parent == null ? void 0 : parent.removeChild(node);
19875
+ }
19876
+ function parseStyleAttribute(el) {
19877
+ var _a;
19878
+ const styleRaw = ((_a = el == null ? void 0 : el.attributes[`style`]) == null ? void 0 : _a.value) || ``;
19879
+ return Object.fromEntries(styleRaw.split(`;`).map((line) => line.split(`:`).map((v) => v.trim())));
19880
+ }
19881
+ function transformMsoStyles(html) {
19882
+ html = html.replace(/<o:p>(.*?)<\/o:p>/g, ``);
19883
+ const parser = new DOMParser();
19884
+ const doc2 = parser.parseFromString(html, `text/html`);
19885
+ doc2.querySelectorAll(`[style*="mso-"]`).forEach((node) => {
19886
+ const styles = parseStyleAttribute(node);
19887
+ const newStyles = [];
19888
+ for (const prop of Object.keys(styles)) {
19889
+ if (prop && !prop.startsWith(`mso-`)) {
19890
+ newStyles.push(`${prop}: ${styles[prop]}`);
19891
+ }
19892
+ }
19893
+ node.setAttribute(`style`, newStyles.join(`;`));
19894
+ });
19895
+ doc2.querySelectorAll(`[style*="color: black"]`).forEach((node) => {
19896
+ node.style.removeProperty(`color`);
19897
+ });
19898
+ return doc2.documentElement.outerHTML;
19899
+ }
19900
+ function transformRemoveBookmarks(html) {
19901
+ const parser = new DOMParser();
19902
+ const doc2 = parser.parseFromString(html, `text/html`);
19903
+ const bookmarks = doc2.querySelectorAll(`[style*="mso-bookmark:"]`);
19904
+ bookmarks.forEach((node) => {
19905
+ const bookmark = parseStyleAttribute(node)[`mso-bookmark`];
19906
+ const bookmarkLink = doc2.querySelector(`a[name="${bookmark}"]`);
19907
+ if (bookmarkLink) {
19908
+ unwrapNode(bookmarkLink);
19909
+ }
19910
+ unwrapNode(node);
19911
+ });
19912
+ return doc2.documentElement.outerHTML;
19913
+ }
19914
+ function transformLists(html) {
19915
+ if (html.indexOf(`mso-list:`) === -1) {
19916
+ return html;
19917
+ }
19918
+ const parser = new DOMParser();
19919
+ const doc2 = parser.parseFromString(html, `text/html`);
19920
+ let listStack = [];
19921
+ let currentListId;
19922
+ const listElements = doc2.querySelectorAll(`p[style*="mso-list:"]`);
19923
+ listElements.forEach((node) => {
19924
+ const el = node;
19925
+ const [msoListId, msoListLevel] = parseMsoListAttribute(parseStyleAttribute(el)[`mso-list`]);
19926
+ if (currentListId !== msoListId && (hasNonListItemSibling(el) || msoListLevel === 1)) {
19927
+ currentListId = msoListId;
19928
+ listStack = [];
19929
+ }
19930
+ while (msoListLevel > listStack.length) {
19931
+ const newList = createListElement(el);
19932
+ if (listStack.length > 0) {
19933
+ listStack[listStack.length - 1].appendChild(newList);
19934
+ } else {
19935
+ el.before(newList);
19936
+ }
19937
+ listStack.push(newList);
19938
+ }
19939
+ while (msoListLevel < listStack.length) {
19940
+ listStack.pop();
19941
+ }
19942
+ listStack[listStack.length - 1].appendChild(getListItemFromParagraph(el));
19943
+ el.remove();
19944
+ });
19945
+ return doc2.documentElement.outerHTML;
19946
+ }
19947
+ function hasNonListItemSibling(el) {
19948
+ return !el.previousElementSibling || !(el.previousElementSibling.nodeName === `OL` || el.previousElementSibling.nodeName === `UL`);
19949
+ }
19950
+ function getListItemFromParagraph(el) {
19951
+ const li = document.createElement(`li`);
19952
+ li.innerHTML = el.innerHTML.replace(listTypeRegex, ``);
19953
+ return li;
19954
+ }
19955
+ function parseMsoListAttribute(attr) {
19956
+ var _a;
19957
+ const msoListValue = attr;
19958
+ const msoListInfos = msoListValue.split(` `);
19959
+ const msoListId = msoListInfos.find((e) => /l[0-9]+/.test(e)) || ``;
19960
+ const msoListLevel = +(((_a = msoListInfos.find((e) => e.startsWith(`level`))) == null ? void 0 : _a.substring(5)) || 1);
19961
+ return [msoListId, msoListLevel];
19962
+ }
19963
+ var listTypeRegex = /<!--\[if \!supportLists\]-->((.|\n)*)<!--\[endif\]-->/m;
19964
+ function getListPrefix(el) {
19965
+ var _a;
19966
+ const matches2 = el.innerHTML.match(listTypeRegex);
19967
+ if (matches2 == null ? void 0 : matches2.length) {
19968
+ const parser = new DOMParser();
19969
+ const doc2 = parser.parseFromString(matches2[0], `text/html`);
19970
+ return ((_a = doc2.body.querySelector(`span`)) == null ? void 0 : _a.textContent) || ``;
19971
+ }
19972
+ return ``;
19973
+ }
19974
+ function createListElement(el) {
19975
+ const listInfo = getListInfo(getListPrefix(el));
19976
+ const list = document.createElement(listInfo.type);
19977
+ if (listInfo.countType) {
19978
+ list.setAttribute(`type`, listInfo.countType);
19979
+ }
19980
+ if (listInfo.start > 1) {
19981
+ list.setAttribute(`start`, listInfo.start.toString());
19982
+ }
19983
+ return list;
19984
+ }
19985
+ var listOrderRegex = {
19986
+ number: /[0-9]+\./,
19987
+ romanLower: /(?=[mdclxvi])m*(c[md]|d?c*)(x[cl]|l?x*)(i[xv]|v?i*)\./,
19988
+ romanUpper: /(?=[MDCLXVI])M*(C[MD]|D?C*)(X[CL]|L?X*)(I[XV]|V?I*)\./,
19989
+ letterLower: /[a-z]+\./,
19990
+ letterUpper: /[A-Z]+\./
19991
+ };
19992
+ function getListInfo(prefix) {
19993
+ let type2 = `ul`;
19994
+ let countType = null;
19995
+ let start2 = 1;
19996
+ let matches2;
19997
+ if (matches2 = prefix.match(listOrderRegex.number)) {
19998
+ type2 = `ol`;
19999
+ start2 = +matches2[0].replace(`.`, ``);
20000
+ } else if (matches2 = prefix.match(listOrderRegex.romanLower)) {
20001
+ type2 = `ol`;
20002
+ countType = `i`;
20003
+ start2 = +parseRomanNumber(matches2[0].replace(`.`, ``));
20004
+ } else if (matches2 = prefix.match(listOrderRegex.romanUpper)) {
20005
+ type2 = `ol`;
20006
+ countType = `I`;
20007
+ start2 = +parseRomanNumber(matches2[0].replace(`.`, ``));
20008
+ } else if (matches2 = prefix.match(listOrderRegex.letterLower)) {
20009
+ type2 = `ol`;
20010
+ countType = `a`;
20011
+ start2 = +parseLetterNumber(matches2[0].replace(`.`, ``));
20012
+ } else if (matches2 = prefix.match(listOrderRegex.letterUpper)) {
20013
+ type2 = `ol`;
20014
+ countType = `A`;
20015
+ start2 = +parseLetterNumber(matches2[0].replace(`.`, ``));
20016
+ }
20017
+ return {
20018
+ type: type2,
20019
+ start: start2,
20020
+ countType
20021
+ };
20022
+ }
20023
+ function transformRemoveLineNumberWrapper(html) {
20024
+ const parser = new DOMParser();
20025
+ const doc2 = parser.parseFromString(html, `text/html`);
20026
+ const lineNumbers = doc2.querySelectorAll(`[class*="MsoLineNumber"]`);
20027
+ lineNumbers.forEach((node) => {
20028
+ unwrapNode(node);
20029
+ });
20030
+ return doc2.documentElement.outerHTML;
20031
+ }
20032
+ function transformMsoHtmlClasses(html) {
20033
+ const parser = new DOMParser();
20034
+ const doc2 = parser.parseFromString(html, `text/html`);
20035
+ doc2.querySelectorAll(`p[class*="MsoNormal"]`).forEach((node) => {
20036
+ node.classList.remove(`MsoNormal`);
20037
+ });
20038
+ return doc2.documentElement.outerHTML;
20039
+ }
20040
+ var OfficePaste = Extension.create({
20041
+ priority: 99999,
20042
+ name: `office-paste`,
20043
+ addProseMirrorPlugins() {
20044
+ return [OfficePastePlugin];
20045
+ }
20046
+ });
20047
+ var OfficePastePlugin = new Plugin({
20048
+ key: new PluginKey("office-paste"),
20049
+ props: {
20050
+ transformPastedHTML(html) {
20051
+ if (html.indexOf(`microsoft-com`) !== -1 && html.indexOf(`office`) !== -1) {
20052
+ html = transformLists(html);
20053
+ html = transformRemoveBookmarks(html);
20054
+ html = transformMsoStyles(html);
20055
+ html = transformMsoHtmlClasses(html);
20056
+ html = transformRemoveLineNumberWrapper(html);
20057
+ }
20058
+ return html;
20059
+ }
20060
+ }
20061
+ });
20062
+ var index_default = OfficePaste;
19843
20063
  const Placeholder = Extension.create({
19844
20064
  name: "placeholder",
19845
20065
  addOptions() {
@@ -26236,6 +26456,7 @@ const Tooltip = Mark2.create({
26236
26456
  }
26237
26457
  });
26238
26458
  const extensions = [
26459
+ index_default,
26239
26460
  Color,
26240
26461
  FontFamily$1,
26241
26462
  FontSize$1,
@@ -28327,7 +28548,7 @@ const _sfc_main = /* @__PURE__ */ vue.defineComponent({
28327
28548
  }
28328
28549
  });
28329
28550
  const manifest = {
28330
- ...index_default,
28551
+ ...index_default$1,
28331
28552
  Edit,
28332
28553
  TopToolbar: _sfc_main
28333
28554
  };
package/dist/index.js CHANGED
@@ -42,7 +42,7 @@ var manifest$1 = {
42
42
  ui,
43
43
  ai
44
44
  };
45
- var index_default = manifest$1;
45
+ var index_default$1 = manifest$1;
46
46
  function OrderedMap(content) {
47
47
  this.content = content;
48
48
  }
@@ -2489,7 +2489,7 @@ function isTagRule(rule) {
2489
2489
  function isStyleRule(rule) {
2490
2490
  return rule.style != null;
2491
2491
  }
2492
- class DOMParser {
2492
+ let DOMParser$1 = class DOMParser2 {
2493
2493
  /**
2494
2494
  Create a parser that targets the given schema, using the given
2495
2495
  parsing rules.
@@ -2615,9 +2615,9 @@ class DOMParser {
2615
2615
  [priority](https://prosemirror.net/docs/ref/#model.ParseRule.priority).
2616
2616
  */
2617
2617
  static fromSchema(schema) {
2618
- return schema.cached.domParser || (schema.cached.domParser = new DOMParser(schema, DOMParser.schemaRules(schema)));
2618
+ return schema.cached.domParser || (schema.cached.domParser = new DOMParser2(schema, DOMParser2.schemaRules(schema)));
2619
2619
  }
2620
- }
2620
+ };
2621
2621
  const blockTags = {
2622
2622
  address: true,
2623
2623
  article: true,
@@ -8639,7 +8639,7 @@ function parseFromClipboard(view, text, html, plainText, $context) {
8639
8639
  dom = child;
8640
8640
  }
8641
8641
  if (!slice2) {
8642
- let parser = view.someProp("clipboardParser") || view.someProp("domParser") || DOMParser.fromSchema(view.state.schema);
8642
+ let parser = view.someProp("clipboardParser") || view.someProp("domParser") || DOMParser$1.fromSchema(view.state.schema);
8643
8643
  slice2 = parser.parseSlice(dom, {
8644
8644
  preserveWhitespace: !!(asText || sliceData),
8645
8645
  context: $context,
@@ -10449,7 +10449,7 @@ function parseBetween(view, from_, to_) {
10449
10449
  }
10450
10450
  }
10451
10451
  let startDoc = view.state.doc;
10452
- let parser = view.someProp("domParser") || DOMParser.fromSchema(view.state.schema);
10452
+ let parser = view.someProp("domParser") || DOMParser$1.fromSchema(view.state.schema);
10453
10453
  let $from = startDoc.resolve(from2);
10454
10454
  let sel = null, doc2 = parser.parse(parent, {
10455
10455
  topNode: $from.parent,
@@ -13772,15 +13772,15 @@ function createNodeFromContent(content, schema, options) {
13772
13772
  })
13773
13773
  });
13774
13774
  if (options.slice) {
13775
- DOMParser.fromSchema(contentCheckSchema).parseSlice(elementFromString(content), options.parseOptions);
13775
+ DOMParser$1.fromSchema(contentCheckSchema).parseSlice(elementFromString(content), options.parseOptions);
13776
13776
  } else {
13777
- DOMParser.fromSchema(contentCheckSchema).parse(elementFromString(content), options.parseOptions);
13777
+ DOMParser$1.fromSchema(contentCheckSchema).parse(elementFromString(content), options.parseOptions);
13778
13778
  }
13779
13779
  if (options.errorOnInvalidContent && hasInvalidContent) {
13780
13780
  throw new Error("[tiptap error]: Invalid HTML content", { cause: new Error(`Invalid element found: ${invalidContent}`) });
13781
13781
  }
13782
13782
  }
13783
- const parser = DOMParser.fromSchema(schema);
13783
+ const parser = DOMParser$1.fromSchema(schema);
13784
13784
  if (options.slice) {
13785
13785
  return parser.parseSlice(elementFromString(content), options.parseOptions).content;
13786
13786
  }
@@ -19838,6 +19838,226 @@ const Highlight = Mark2.create({
19838
19838
  ];
19839
19839
  }
19840
19840
  });
19841
+ function parseRomanNumber(roman) {
19842
+ roman = roman.toUpperCase();
19843
+ let value = 0;
19844
+ const values = { I: 1, V: 5, X: 10, L: 50, C: 100, D: 500, M: 1e3 };
19845
+ let i = roman.length;
19846
+ let lastVal = 0;
19847
+ while (i--) {
19848
+ if (values[roman.charAt(i)] >= lastVal) {
19849
+ value += values[roman.charAt(i)];
19850
+ } else {
19851
+ value -= values[roman.charAt(i)];
19852
+ }
19853
+ lastVal = values[roman.charAt(i)];
19854
+ }
19855
+ return value;
19856
+ }
19857
+ function parseLetterNumber(str) {
19858
+ const alphaVal = (s) => s.toLowerCase().charCodeAt(0) - 97 + 1;
19859
+ let value = 0;
19860
+ let i = str.length;
19861
+ while (i--) {
19862
+ const factor = Math.pow(26, str.length - i - 1);
19863
+ value += alphaVal(str.charAt(i)) * factor;
19864
+ }
19865
+ return value;
19866
+ }
19867
+ function unwrapNode(node) {
19868
+ const parent = node.parentNode;
19869
+ while (node.firstChild) {
19870
+ parent == null ? void 0 : parent.insertBefore(node.firstChild, node);
19871
+ }
19872
+ parent == null ? void 0 : parent.removeChild(node);
19873
+ }
19874
+ function parseStyleAttribute(el) {
19875
+ var _a;
19876
+ const styleRaw = ((_a = el == null ? void 0 : el.attributes[`style`]) == null ? void 0 : _a.value) || ``;
19877
+ return Object.fromEntries(styleRaw.split(`;`).map((line) => line.split(`:`).map((v) => v.trim())));
19878
+ }
19879
+ function transformMsoStyles(html) {
19880
+ html = html.replace(/<o:p>(.*?)<\/o:p>/g, ``);
19881
+ const parser = new DOMParser();
19882
+ const doc2 = parser.parseFromString(html, `text/html`);
19883
+ doc2.querySelectorAll(`[style*="mso-"]`).forEach((node) => {
19884
+ const styles = parseStyleAttribute(node);
19885
+ const newStyles = [];
19886
+ for (const prop of Object.keys(styles)) {
19887
+ if (prop && !prop.startsWith(`mso-`)) {
19888
+ newStyles.push(`${prop}: ${styles[prop]}`);
19889
+ }
19890
+ }
19891
+ node.setAttribute(`style`, newStyles.join(`;`));
19892
+ });
19893
+ doc2.querySelectorAll(`[style*="color: black"]`).forEach((node) => {
19894
+ node.style.removeProperty(`color`);
19895
+ });
19896
+ return doc2.documentElement.outerHTML;
19897
+ }
19898
+ function transformRemoveBookmarks(html) {
19899
+ const parser = new DOMParser();
19900
+ const doc2 = parser.parseFromString(html, `text/html`);
19901
+ const bookmarks = doc2.querySelectorAll(`[style*="mso-bookmark:"]`);
19902
+ bookmarks.forEach((node) => {
19903
+ const bookmark = parseStyleAttribute(node)[`mso-bookmark`];
19904
+ const bookmarkLink = doc2.querySelector(`a[name="${bookmark}"]`);
19905
+ if (bookmarkLink) {
19906
+ unwrapNode(bookmarkLink);
19907
+ }
19908
+ unwrapNode(node);
19909
+ });
19910
+ return doc2.documentElement.outerHTML;
19911
+ }
19912
+ function transformLists(html) {
19913
+ if (html.indexOf(`mso-list:`) === -1) {
19914
+ return html;
19915
+ }
19916
+ const parser = new DOMParser();
19917
+ const doc2 = parser.parseFromString(html, `text/html`);
19918
+ let listStack = [];
19919
+ let currentListId;
19920
+ const listElements = doc2.querySelectorAll(`p[style*="mso-list:"]`);
19921
+ listElements.forEach((node) => {
19922
+ const el = node;
19923
+ const [msoListId, msoListLevel] = parseMsoListAttribute(parseStyleAttribute(el)[`mso-list`]);
19924
+ if (currentListId !== msoListId && (hasNonListItemSibling(el) || msoListLevel === 1)) {
19925
+ currentListId = msoListId;
19926
+ listStack = [];
19927
+ }
19928
+ while (msoListLevel > listStack.length) {
19929
+ const newList = createListElement(el);
19930
+ if (listStack.length > 0) {
19931
+ listStack[listStack.length - 1].appendChild(newList);
19932
+ } else {
19933
+ el.before(newList);
19934
+ }
19935
+ listStack.push(newList);
19936
+ }
19937
+ while (msoListLevel < listStack.length) {
19938
+ listStack.pop();
19939
+ }
19940
+ listStack[listStack.length - 1].appendChild(getListItemFromParagraph(el));
19941
+ el.remove();
19942
+ });
19943
+ return doc2.documentElement.outerHTML;
19944
+ }
19945
+ function hasNonListItemSibling(el) {
19946
+ return !el.previousElementSibling || !(el.previousElementSibling.nodeName === `OL` || el.previousElementSibling.nodeName === `UL`);
19947
+ }
19948
+ function getListItemFromParagraph(el) {
19949
+ const li = document.createElement(`li`);
19950
+ li.innerHTML = el.innerHTML.replace(listTypeRegex, ``);
19951
+ return li;
19952
+ }
19953
+ function parseMsoListAttribute(attr) {
19954
+ var _a;
19955
+ const msoListValue = attr;
19956
+ const msoListInfos = msoListValue.split(` `);
19957
+ const msoListId = msoListInfos.find((e) => /l[0-9]+/.test(e)) || ``;
19958
+ const msoListLevel = +(((_a = msoListInfos.find((e) => e.startsWith(`level`))) == null ? void 0 : _a.substring(5)) || 1);
19959
+ return [msoListId, msoListLevel];
19960
+ }
19961
+ var listTypeRegex = /<!--\[if \!supportLists\]-->((.|\n)*)<!--\[endif\]-->/m;
19962
+ function getListPrefix(el) {
19963
+ var _a;
19964
+ const matches2 = el.innerHTML.match(listTypeRegex);
19965
+ if (matches2 == null ? void 0 : matches2.length) {
19966
+ const parser = new DOMParser();
19967
+ const doc2 = parser.parseFromString(matches2[0], `text/html`);
19968
+ return ((_a = doc2.body.querySelector(`span`)) == null ? void 0 : _a.textContent) || ``;
19969
+ }
19970
+ return ``;
19971
+ }
19972
+ function createListElement(el) {
19973
+ const listInfo = getListInfo(getListPrefix(el));
19974
+ const list = document.createElement(listInfo.type);
19975
+ if (listInfo.countType) {
19976
+ list.setAttribute(`type`, listInfo.countType);
19977
+ }
19978
+ if (listInfo.start > 1) {
19979
+ list.setAttribute(`start`, listInfo.start.toString());
19980
+ }
19981
+ return list;
19982
+ }
19983
+ var listOrderRegex = {
19984
+ number: /[0-9]+\./,
19985
+ romanLower: /(?=[mdclxvi])m*(c[md]|d?c*)(x[cl]|l?x*)(i[xv]|v?i*)\./,
19986
+ romanUpper: /(?=[MDCLXVI])M*(C[MD]|D?C*)(X[CL]|L?X*)(I[XV]|V?I*)\./,
19987
+ letterLower: /[a-z]+\./,
19988
+ letterUpper: /[A-Z]+\./
19989
+ };
19990
+ function getListInfo(prefix) {
19991
+ let type2 = `ul`;
19992
+ let countType = null;
19993
+ let start2 = 1;
19994
+ let matches2;
19995
+ if (matches2 = prefix.match(listOrderRegex.number)) {
19996
+ type2 = `ol`;
19997
+ start2 = +matches2[0].replace(`.`, ``);
19998
+ } else if (matches2 = prefix.match(listOrderRegex.romanLower)) {
19999
+ type2 = `ol`;
20000
+ countType = `i`;
20001
+ start2 = +parseRomanNumber(matches2[0].replace(`.`, ``));
20002
+ } else if (matches2 = prefix.match(listOrderRegex.romanUpper)) {
20003
+ type2 = `ol`;
20004
+ countType = `I`;
20005
+ start2 = +parseRomanNumber(matches2[0].replace(`.`, ``));
20006
+ } else if (matches2 = prefix.match(listOrderRegex.letterLower)) {
20007
+ type2 = `ol`;
20008
+ countType = `a`;
20009
+ start2 = +parseLetterNumber(matches2[0].replace(`.`, ``));
20010
+ } else if (matches2 = prefix.match(listOrderRegex.letterUpper)) {
20011
+ type2 = `ol`;
20012
+ countType = `A`;
20013
+ start2 = +parseLetterNumber(matches2[0].replace(`.`, ``));
20014
+ }
20015
+ return {
20016
+ type: type2,
20017
+ start: start2,
20018
+ countType
20019
+ };
20020
+ }
20021
+ function transformRemoveLineNumberWrapper(html) {
20022
+ const parser = new DOMParser();
20023
+ const doc2 = parser.parseFromString(html, `text/html`);
20024
+ const lineNumbers = doc2.querySelectorAll(`[class*="MsoLineNumber"]`);
20025
+ lineNumbers.forEach((node) => {
20026
+ unwrapNode(node);
20027
+ });
20028
+ return doc2.documentElement.outerHTML;
20029
+ }
20030
+ function transformMsoHtmlClasses(html) {
20031
+ const parser = new DOMParser();
20032
+ const doc2 = parser.parseFromString(html, `text/html`);
20033
+ doc2.querySelectorAll(`p[class*="MsoNormal"]`).forEach((node) => {
20034
+ node.classList.remove(`MsoNormal`);
20035
+ });
20036
+ return doc2.documentElement.outerHTML;
20037
+ }
20038
+ var OfficePaste = Extension.create({
20039
+ priority: 99999,
20040
+ name: `office-paste`,
20041
+ addProseMirrorPlugins() {
20042
+ return [OfficePastePlugin];
20043
+ }
20044
+ });
20045
+ var OfficePastePlugin = new Plugin({
20046
+ key: new PluginKey("office-paste"),
20047
+ props: {
20048
+ transformPastedHTML(html) {
20049
+ if (html.indexOf(`microsoft-com`) !== -1 && html.indexOf(`office`) !== -1) {
20050
+ html = transformLists(html);
20051
+ html = transformRemoveBookmarks(html);
20052
+ html = transformMsoStyles(html);
20053
+ html = transformMsoHtmlClasses(html);
20054
+ html = transformRemoveLineNumberWrapper(html);
20055
+ }
20056
+ return html;
20057
+ }
20058
+ }
20059
+ });
20060
+ var index_default = OfficePaste;
19841
20061
  const Placeholder = Extension.create({
19842
20062
  name: "placeholder",
19843
20063
  addOptions() {
@@ -26234,6 +26454,7 @@ const Tooltip = Mark2.create({
26234
26454
  }
26235
26455
  });
26236
26456
  const extensions = [
26457
+ index_default,
26237
26458
  Color,
26238
26459
  FontFamily$1,
26239
26460
  FontSize$1,
@@ -28325,7 +28546,7 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
28325
28546
  }
28326
28547
  });
28327
28548
  const manifest = {
28328
- ...index_default,
28549
+ ...index_default$1,
28329
28550
  Edit,
28330
28551
  TopToolbar: _sfc_main
28331
28552
  };
package/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "description": "Tailor CMS HTML editor authoring component",
4
4
  "author": "Studion <info@gostudion.com> (https://github.com/tailor-cms)",
5
5
  "type": "module",
6
- "version": "0.1.3",
6
+ "version": "0.1.4",
7
7
  "exports": {
8
8
  ".": {
9
9
  "import": "./dist/index.js",
@@ -26,9 +26,10 @@
26
26
  "typescript": "^5.8.3",
27
27
  "vite": "^7.0.3",
28
28
  "vue-tsc": "^3.0.1",
29
- "@tailor-cms/ce-html-manifest": "0.1.3"
29
+ "@tailor-cms/ce-html-manifest": "0.1.4"
30
30
  },
31
31
  "dependencies": {
32
+ "@intevation/tiptap-extension-office-paste": "^0.1.2",
32
33
  "@tiptap/extension-color": "^2.25.0",
33
34
  "@tiptap/extension-font-family": "^2.25.0",
34
35
  "@tiptap/extension-highlight": "^2.25.0",