@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.
- package/dist/index.cjs +231 -10
- package/dist/index.js +231 -10
- 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
|
-
|
|
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
|
|
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
|
-
|
|
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
|
|
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.
|
|
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.
|
|
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",
|