@harbour-enterprises/superdoc 0.13.3-next.5 → 0.13.3-next.7

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.
@@ -10941,7 +10941,7 @@ class NodeRange {
10941
10941
  }
10942
10942
  }
10943
10943
  const emptyAttrs = /* @__PURE__ */ Object.create(null);
10944
- let Node$2 = class Node2 {
10944
+ let Node$1$1 = class Node2 {
10945
10945
  /**
10946
10946
  @internal
10947
10947
  */
@@ -11342,8 +11342,8 @@ let Node$2 = class Node2 {
11342
11342
  return node2;
11343
11343
  }
11344
11344
  };
11345
- Node$2.prototype.text = void 0;
11346
- class TextNode extends Node$2 {
11345
+ Node$1$1.prototype.text = void 0;
11346
+ class TextNode extends Node$1$1 {
11347
11347
  /**
11348
11348
  @internal
11349
11349
  */
@@ -11930,7 +11930,7 @@ let NodeType$1 = class NodeType {
11930
11930
  create(attrs = null, content, marks) {
11931
11931
  if (this.isText)
11932
11932
  throw new Error("NodeType.create can't construct text nodes");
11933
- return new Node$2(this, this.computeAttrs(attrs), Fragment.from(content), Mark$1.setFrom(marks));
11933
+ return new Node$1$1(this, this.computeAttrs(attrs), Fragment.from(content), Mark$1.setFrom(marks));
11934
11934
  }
11935
11935
  /**
11936
11936
  Like [`create`](https://prosemirror.net/docs/ref/#model.NodeType.create), but check the given content
@@ -11940,7 +11940,7 @@ let NodeType$1 = class NodeType {
11940
11940
  createChecked(attrs = null, content, marks) {
11941
11941
  content = Fragment.from(content);
11942
11942
  this.checkContent(content);
11943
- return new Node$2(this, this.computeAttrs(attrs), content, Mark$1.setFrom(marks));
11943
+ return new Node$1$1(this, this.computeAttrs(attrs), content, Mark$1.setFrom(marks));
11944
11944
  }
11945
11945
  /**
11946
11946
  Like [`create`](https://prosemirror.net/docs/ref/#model.NodeType.create), but see if it is
@@ -11963,7 +11963,7 @@ let NodeType$1 = class NodeType {
11963
11963
  let after = matched && matched.fillBefore(Fragment.empty, true);
11964
11964
  if (!after)
11965
11965
  return null;
11966
- return new Node$2(this, attrs, content.append(after), Mark$1.setFrom(marks));
11966
+ return new Node$1$1(this, attrs, content.append(after), Mark$1.setFrom(marks));
11967
11967
  }
11968
11968
  /**
11969
11969
  Returns true if the given fragment is valid content for this node
@@ -12200,7 +12200,7 @@ let Schema$1 = class Schema {
12200
12200
  bound.
12201
12201
  */
12202
12202
  nodeFromJSON(json) {
12203
- return Node$2.fromJSON(this, json);
12203
+ return Node$1$1.fromJSON(this, json);
12204
12204
  }
12205
12205
  /**
12206
12206
  Deserialize a mark from its JSON representation. This method is
@@ -15760,7 +15760,7 @@ class EditorState {
15760
15760
  let instance = new EditorState($config);
15761
15761
  $config.fields.forEach((field) => {
15762
15762
  if (field.name == "doc") {
15763
- instance.doc = Node$2.fromJSON(config.schema, json.doc);
15763
+ instance.doc = Node$1$1.fromJSON(config.schema, json.doc);
15764
15764
  } else if (field.name == "selection") {
15765
15765
  instance.selection = Selection.fromJSON(instance.doc, json.selection);
15766
15766
  } else if (field.name == "storedMarks") {
@@ -18821,6 +18821,583 @@ const createColGroup = (node2, cellMinWidth, overrideCol, overrideValue) => {
18821
18821
  colgroupValues
18822
18822
  };
18823
18823
  };
18824
+ function chainableEditorState(transaction, state2) {
18825
+ let { selection, doc: doc2, storedMarks } = transaction;
18826
+ return {
18827
+ ...state2,
18828
+ apply: state2.apply.bind(state2),
18829
+ applyTransaction: state2.applyTransaction.bind(state2),
18830
+ plugins: state2.plugins,
18831
+ schema: state2.schema,
18832
+ reconfigure: state2.reconfigure.bind(state2),
18833
+ toJSON: state2.toJSON.bind(state2),
18834
+ get storedMarks() {
18835
+ return storedMarks;
18836
+ },
18837
+ get selection() {
18838
+ return selection;
18839
+ },
18840
+ get doc() {
18841
+ return doc2;
18842
+ },
18843
+ get tr() {
18844
+ selection = transaction.selection;
18845
+ doc2 = transaction.doc;
18846
+ storedMarks = transaction.storedMarks;
18847
+ return transaction;
18848
+ }
18849
+ };
18850
+ }
18851
+ class CommandService {
18852
+ constructor(props) {
18853
+ __publicField$2(this, "editor");
18854
+ __publicField$2(this, "rawCommands");
18855
+ this.editor = props.editor;
18856
+ this.rawCommands = this.editor.extensionService.commands;
18857
+ }
18858
+ /**
18859
+ * Static method for creating a service.
18860
+ * @param args Arguments for the constructor.
18861
+ */
18862
+ static create(...args) {
18863
+ return new CommandService(...args);
18864
+ }
18865
+ /**
18866
+ * Get editor state.
18867
+ */
18868
+ get state() {
18869
+ return this.editor.state;
18870
+ }
18871
+ /**
18872
+ * Get all commands with wrapped command method.
18873
+ */
18874
+ get commands() {
18875
+ const { editor, state: state2 } = this;
18876
+ const { view } = editor;
18877
+ const { tr } = state2;
18878
+ const props = this.createProps(tr);
18879
+ const entries = Object.entries(this.rawCommands).map(([name, command2]) => {
18880
+ const method = (...args) => {
18881
+ const fn2 = command2(...args)(props);
18882
+ if (!tr.getMeta("preventDispatch")) {
18883
+ view.dispatch(tr);
18884
+ }
18885
+ return fn2;
18886
+ };
18887
+ return [name, method];
18888
+ });
18889
+ return Object.fromEntries(entries);
18890
+ }
18891
+ /**
18892
+ * Create a chain of commands to call multiple commands at once.
18893
+ */
18894
+ get chain() {
18895
+ return () => this.createChain();
18896
+ }
18897
+ /**
18898
+ * Check if a command or a chain of commands can be executed. Without executing it.
18899
+ */
18900
+ get can() {
18901
+ return () => this.createCan();
18902
+ }
18903
+ /**
18904
+ * Creates a chain of commands.
18905
+ * @param startTr Start transaction.
18906
+ * @param shouldDispatch Should dispatch or not.
18907
+ */
18908
+ createChain(startTr, shouldDispatch = true) {
18909
+ const { editor, state: state2, rawCommands } = this;
18910
+ const { view } = editor;
18911
+ const callbacks2 = [];
18912
+ const hasStartTr = !!startTr;
18913
+ const tr = startTr || state2.tr;
18914
+ const run2 = () => {
18915
+ if (!hasStartTr && shouldDispatch && !tr.getMeta("preventDispatch")) {
18916
+ view.dispatch(tr);
18917
+ }
18918
+ return callbacks2.every((cb) => cb === true);
18919
+ };
18920
+ const entries = Object.entries(rawCommands).map(([name, command2]) => {
18921
+ const chainedCommand = (...args) => {
18922
+ const props = this.createProps(tr, shouldDispatch);
18923
+ const callback = command2(...args)(props);
18924
+ callbacks2.push(callback);
18925
+ return chain;
18926
+ };
18927
+ return [name, chainedCommand];
18928
+ });
18929
+ const chain = {
18930
+ ...Object.fromEntries(entries),
18931
+ run: run2
18932
+ };
18933
+ return chain;
18934
+ }
18935
+ /**
18936
+ * Creates a can check for commands.
18937
+ * @param startTr Start transaction.
18938
+ */
18939
+ createCan(startTr) {
18940
+ const { rawCommands, state: state2 } = this;
18941
+ const dispatch = false;
18942
+ const tr = startTr || state2.tr;
18943
+ const props = this.createProps(tr, dispatch);
18944
+ const commands2 = Object.fromEntries(
18945
+ Object.entries(rawCommands).map(([name, command2]) => {
18946
+ return [name, (...args) => command2(...args)({ ...props, dispatch: void 0 })];
18947
+ })
18948
+ );
18949
+ return {
18950
+ ...commands2,
18951
+ chain: () => this.createChain(tr, dispatch)
18952
+ };
18953
+ }
18954
+ /**
18955
+ * Creates default props for the command method.
18956
+ * @param {*} tr Transaction.
18957
+ * @param {*} shouldDispatch Check if should dispatch.
18958
+ * @returns Object with props.
18959
+ */
18960
+ createProps(tr, shouldDispatch = true) {
18961
+ const { editor, state: state2, rawCommands } = this;
18962
+ const { view } = editor;
18963
+ const props = {
18964
+ tr,
18965
+ editor,
18966
+ view,
18967
+ state: chainableEditorState(tr, state2),
18968
+ dispatch: shouldDispatch ? () => void 0 : void 0,
18969
+ chain: () => this.createChain(tr, shouldDispatch),
18970
+ can: () => this.createCan(tr),
18971
+ get commands() {
18972
+ return Object.fromEntries(
18973
+ Object.entries(rawCommands).map(([name, command2]) => {
18974
+ return [name, (...args) => command2(...args)(props)];
18975
+ })
18976
+ );
18977
+ }
18978
+ };
18979
+ return props;
18980
+ }
18981
+ }
18982
+ function getHTMLFromFragment(fragment, schema) {
18983
+ const documentFragment = DOMSerializer.fromSchema(schema).serializeFragment(fragment);
18984
+ const temporaryDocument = document.implementation.createHTMLDocument();
18985
+ const container = temporaryDocument.createElement("div");
18986
+ container.appendChild(documentFragment);
18987
+ return container.innerHTML;
18988
+ }
18989
+ const getTextContentFromNodes = ($from, maxMatch = 500) => {
18990
+ let textBefore = "";
18991
+ const sliceEndPos = $from.parentOffset;
18992
+ $from.parent.nodesBetween(
18993
+ Math.max(0, sliceEndPos - maxMatch),
18994
+ sliceEndPos,
18995
+ (node2, pos, parent, index2) => {
18996
+ const chunk = node2.type.spec.toText?.({
18997
+ node: node2,
18998
+ pos,
18999
+ parent,
19000
+ index: index2
19001
+ }) || node2.textContent || "%leaf%";
19002
+ textBefore += node2.isAtom && !node2.isText ? chunk : chunk.slice(0, Math.max(0, sliceEndPos - pos));
19003
+ }
19004
+ );
19005
+ return textBefore;
19006
+ };
19007
+ const handleDocxPaste = (html, editor, view, plugin2) => {
19008
+ const { converter } = editor;
19009
+ if (!converter || !converter.convertedXml) return handleHtmlPaste(html, editor, view, plugin2);
19010
+ let cleanedHtml = convertEmToPt(html);
19011
+ cleanedHtml = cleanHtmlUnnecessaryTags(cleanedHtml);
19012
+ const tempDiv = document.createElement("div");
19013
+ tempDiv.innerHTML = cleanedHtml;
19014
+ const paragraphs = tempDiv.querySelectorAll("p");
19015
+ paragraphs.forEach((p) => {
19016
+ const innerHTML3 = p.innerHTML;
19017
+ if (!innerHTML3.includes("<!--[if !supportLists]")) return;
19018
+ const styleAttr = p.getAttribute("style") || "";
19019
+ const msoListMatch = styleAttr.match(/mso-list:\s*l(\d+)\s+level(\d+)/);
19020
+ if (msoListMatch) {
19021
+ const [, abstractId, level] = msoListMatch;
19022
+ const listNumId = getListNumIdFromAbstract(abstractId, editor);
19023
+ if (!listNumId) return;
19024
+ const abstractDefinition = getListAbstractDefinition(abstractId, editor);
19025
+ const { lvlText, start: start2, numFmt } = getLevelDefinition(abstractDefinition, level - 1);
19026
+ p.setAttribute("data-num-id", listNumId);
19027
+ p.setAttribute("data-list-level", level - 1);
19028
+ p.setAttribute("data-start", start2);
19029
+ p.setAttribute("data-lvl-text", lvlText);
19030
+ p.setAttribute("data-num-fmt", numFmt);
19031
+ }
19032
+ extractAndRemoveConditionalPrefix(p);
19033
+ });
19034
+ transformWordLists(tempDiv);
19035
+ const doc2 = DOMParser$1.fromSchema(editor.schema).parse(tempDiv);
19036
+ tempDiv.remove();
19037
+ const { dispatch } = editor.view;
19038
+ if (!dispatch) return false;
19039
+ dispatch(view.state.tr.replaceSelectionWith(doc2, true));
19040
+ return true;
19041
+ };
19042
+ const getLevelDefinition = (abstractDefinition, level) => {
19043
+ if (!abstractDefinition || !abstractDefinition.elements) return null;
19044
+ const levelElement = abstractDefinition.elements.find((el) => {
19045
+ return el.name === "w:lvl" && el.attributes?.["w:ilvl"] == level;
19046
+ });
19047
+ if (!levelElement) return null;
19048
+ const { elements } = levelElement;
19049
+ const lvlText = elements.find((el) => el.name === "w:lvlText")?.attributes?.["w:val"];
19050
+ const start2 = elements.find((el) => el.name === "w:start")?.attributes?.["w:val"];
19051
+ const numFmt = elements.find((el) => el.name === "w:numFmt")?.attributes?.["w:val"];
19052
+ return { lvlText, start: start2, numFmt, elements };
19053
+ };
19054
+ const getListNumIdFromAbstract = (abstractId, editor) => {
19055
+ const { definitions } = editor?.converter?.numbering;
19056
+ if (!definitions) return null;
19057
+ const matchedDefinition = Object.values(definitions).find((def) => {
19058
+ return def.elements.some((el) => el.name === "w:abstractNumId" && el.attributes?.["w:val"] == abstractId);
19059
+ });
19060
+ return matchedDefinition?.attributes?.["w:numId"];
19061
+ };
19062
+ const getListAbstractDefinition = (abstractId, editor) => {
19063
+ const { abstracts = {} } = editor?.converter?.numbering;
19064
+ return abstracts[abstractId] || null;
19065
+ };
19066
+ const transformWordLists = (container) => {
19067
+ const paragraphs = Array.from(container.querySelectorAll("p[data-num-id]"));
19068
+ const listMap = /* @__PURE__ */ new Map();
19069
+ const listLevels = {};
19070
+ for (const p of paragraphs) {
19071
+ const listId = p.getAttribute("data-num-id");
19072
+ const level = parseInt(p.getAttribute("data-list-level"));
19073
+ const numFmt = p.getAttribute("data-num-fmt");
19074
+ const start2 = p.getAttribute("data-start");
19075
+ const lvlText = p.getAttribute("data-lvl-text");
19076
+ if (!listMap.has(listId)) listMap.set(listId, []);
19077
+ listMap.get(listId).push({ p, level, numFmt, start: start2, lvlText });
19078
+ }
19079
+ for (const [id, items] of listMap.entries()) {
19080
+ if (!listLevels[id]) {
19081
+ listLevels[id] = {
19082
+ stack: [],
19083
+ counts: {},
19084
+ prevLevel: null
19085
+ };
19086
+ }
19087
+ const parentStack = [];
19088
+ items.forEach(({ p, level, numFmt, start: start2, lvlText }, index2) => {
19089
+ const listLevel = generateListNestingPath(listLevels, id, level);
19090
+ const li = document.createElement("li");
19091
+ li.innerHTML = p.innerHTML;
19092
+ li.setAttribute("data-list-level", JSON.stringify(listLevel));
19093
+ li.setAttribute("data-num-id", id);
19094
+ li.setAttribute("data-lvl-text", lvlText);
19095
+ li.setAttribute("data-num-fmt", numFmt);
19096
+ if (p.hasAttribute("data-font-family")) {
19097
+ li.setAttribute("data-font-family", p.getAttribute("data-font-family"));
19098
+ }
19099
+ if (p.hasAttribute("data-font-size")) {
19100
+ li.setAttribute("data-font-size", p.getAttribute("data-font-size"));
19101
+ }
19102
+ const parentNode2 = p.parentNode;
19103
+ let listForLevel = parentStack[level];
19104
+ if (!listForLevel) {
19105
+ const newList = document.createElement("ol");
19106
+ newList.setAttribute("data-list-id", id);
19107
+ newList.level = level;
19108
+ if (level > 0) {
19109
+ const parentLi = parentStack[level - 1]?.querySelector("li:last-child");
19110
+ if (parentLi) parentLi.appendChild(newList);
19111
+ } else {
19112
+ parentNode2.insertBefore(newList, p);
19113
+ }
19114
+ parentStack[level] = newList;
19115
+ parentStack.length = level + 1;
19116
+ listForLevel = newList;
19117
+ }
19118
+ listForLevel.appendChild(li);
19119
+ p.remove();
19120
+ });
19121
+ }
19122
+ };
19123
+ function generateListNestingPath(listLevels, listId, currentLevel) {
19124
+ const levelState = listLevels[listId];
19125
+ if (!levelState.stack) levelState.stack = [];
19126
+ if (levelState.prevLevel === void 0) levelState.prevLevel = null;
19127
+ if (levelState.prevLevel === null) {
19128
+ levelState.stack = Array(currentLevel).fill(1).concat(1);
19129
+ } else {
19130
+ if (currentLevel > levelState.prevLevel) {
19131
+ levelState.stack.push(1);
19132
+ } else if (currentLevel === levelState.prevLevel) {
19133
+ levelState.stack[levelState.stack.length - 1]++;
19134
+ } else {
19135
+ levelState.stack = levelState.stack.slice(0, currentLevel + 1);
19136
+ levelState.stack[currentLevel] = (levelState.stack[currentLevel] || 1) + 1;
19137
+ }
19138
+ }
19139
+ levelState.prevLevel = currentLevel;
19140
+ return [...levelState.stack];
19141
+ }
19142
+ function extractAndRemoveConditionalPrefix(p) {
19143
+ const nodes = Array.from(p.childNodes);
19144
+ let fontFamily2 = null;
19145
+ let fontSize2 = null;
19146
+ let start2 = -1, end2 = -1;
19147
+ nodes.forEach((node2, index2) => {
19148
+ if (node2.nodeType === Node.COMMENT_NODE && node2.nodeValue.includes("[if !supportLists]")) {
19149
+ start2 = index2;
19150
+ }
19151
+ if (start2 !== -1 && node2.nodeType === Node.COMMENT_NODE && node2.nodeValue.includes("[endif]")) {
19152
+ end2 = index2;
19153
+ }
19154
+ });
19155
+ if (start2 !== -1 && end2 !== -1) {
19156
+ for (let i = start2 + 1; i < end2; i++) {
19157
+ const node2 = nodes[i];
19158
+ if (node2.nodeType === Node.ELEMENT_NODE && node2.style) {
19159
+ fontFamily2 = fontFamily2 || node2.style.fontFamily;
19160
+ fontSize2 = fontSize2 || node2.style.fontSize;
19161
+ }
19162
+ }
19163
+ for (let i = end2; i >= start2; i--) {
19164
+ p.removeChild(p.childNodes[i]);
19165
+ }
19166
+ if (fontFamily2) p.setAttribute("data-font-family", fontFamily2);
19167
+ if (fontSize2) p.setAttribute("data-font-size", fontSize2);
19168
+ }
19169
+ }
19170
+ class InputRule {
19171
+ constructor(config) {
19172
+ __publicField$2(this, "match");
19173
+ __publicField$2(this, "handler");
19174
+ this.match = config.match;
19175
+ this.handler = config.handler;
19176
+ }
19177
+ }
19178
+ const inputRuleMatcherHandler = (text, match) => {
19179
+ if (isRegExp(match)) {
19180
+ return match.exec(text);
19181
+ }
19182
+ const inputRuleMatch = match(text);
19183
+ if (!inputRuleMatch) {
19184
+ return null;
19185
+ }
19186
+ const result = [inputRuleMatch.text];
19187
+ result.index = inputRuleMatch.index;
19188
+ result.input = text;
19189
+ result.data = inputRuleMatch.data;
19190
+ if (inputRuleMatch.replaceWith) {
19191
+ if (!inputRuleMatch.text.includes(inputRuleMatch.replaceWith)) {
19192
+ console.warn(
19193
+ '[super-editor warn]: "inputRuleMatch.replaceWith" must be part of "inputRuleMatch.text".'
19194
+ );
19195
+ }
19196
+ result.push(inputRuleMatch.replaceWith);
19197
+ }
19198
+ return result;
19199
+ };
19200
+ const run = (config) => {
19201
+ const {
19202
+ editor,
19203
+ from: from2,
19204
+ to,
19205
+ text,
19206
+ rules,
19207
+ plugin: plugin2
19208
+ } = config;
19209
+ const { view } = editor;
19210
+ if (view.composing) {
19211
+ return false;
19212
+ }
19213
+ const $from = view.state.doc.resolve(from2);
19214
+ if ($from.parent.type.spec.code || !!($from.nodeBefore || $from.nodeAfter)?.marks.find((mark) => mark.type.spec.code)) {
19215
+ return false;
19216
+ }
19217
+ let matched = false;
19218
+ const textBefore = getTextContentFromNodes($from) + text;
19219
+ rules.forEach((rule) => {
19220
+ if (matched) {
19221
+ return;
19222
+ }
19223
+ const match = inputRuleMatcherHandler(textBefore, rule.match);
19224
+ if (!match) {
19225
+ return;
19226
+ }
19227
+ const tr = view.state.tr;
19228
+ const state2 = chainableEditorState(tr, view.state);
19229
+ const range2 = {
19230
+ from: from2 - (match[0].length - text.length),
19231
+ to
19232
+ };
19233
+ const { commands: commands2, chain, can } = new CommandService({
19234
+ editor,
19235
+ state: state2
19236
+ });
19237
+ const handler = rule.handler({
19238
+ state: state2,
19239
+ range: range2,
19240
+ match,
19241
+ commands: commands2,
19242
+ chain,
19243
+ can
19244
+ });
19245
+ if (handler === null || !tr.steps.length) {
19246
+ return;
19247
+ }
19248
+ tr.setMeta(plugin2, {
19249
+ transform: tr,
19250
+ from: from2,
19251
+ to,
19252
+ text
19253
+ });
19254
+ view.dispatch(tr);
19255
+ matched = true;
19256
+ });
19257
+ return matched;
19258
+ };
19259
+ const inputRulesPlugin = ({ editor, rules }) => {
19260
+ const plugin2 = new Plugin({
19261
+ key: new PluginKey("inputRulesPlugin"),
19262
+ state: {
19263
+ init() {
19264
+ return null;
19265
+ },
19266
+ apply(tr, prev, state2) {
19267
+ const stored = tr.getMeta(plugin2);
19268
+ if (stored) {
19269
+ return stored;
19270
+ }
19271
+ const simulatedInputMeta = tr.getMeta("applyInputRules");
19272
+ const isSimulatedInput = !!simulatedInputMeta;
19273
+ if (isSimulatedInput) {
19274
+ setTimeout(() => {
19275
+ let { text } = simulatedInputMeta;
19276
+ if (typeof text !== "string") {
19277
+ text = getHTMLFromFragment(Fragment.from(text), state2.schema);
19278
+ }
19279
+ const { from: from2 } = simulatedInputMeta;
19280
+ const to = from2 + text.length;
19281
+ run({
19282
+ editor,
19283
+ from: from2,
19284
+ to,
19285
+ text,
19286
+ rules,
19287
+ plugin: plugin2
19288
+ });
19289
+ });
19290
+ }
19291
+ return tr.selectionSet || tr.docChanged ? null : prev;
19292
+ }
19293
+ },
19294
+ props: {
19295
+ handleTextInput(view, from2, to, text) {
19296
+ return run({
19297
+ editor,
19298
+ from: from2,
19299
+ to,
19300
+ text,
19301
+ rules,
19302
+ plugin: plugin2
19303
+ });
19304
+ },
19305
+ // add support for input rules to trigger on enter
19306
+ // this is useful for example for code blocks
19307
+ handleKeyDown(view, event) {
19308
+ if (event.key !== "Enter") {
19309
+ return false;
19310
+ }
19311
+ const { $cursor } = view.state.selection;
19312
+ if ($cursor) {
19313
+ return run({
19314
+ editor,
19315
+ from: $cursor.pos,
19316
+ to: $cursor.pos,
19317
+ text: "\n",
19318
+ rules,
19319
+ plugin: plugin2
19320
+ });
19321
+ }
19322
+ return false;
19323
+ },
19324
+ // Paste handler
19325
+ handlePaste(view, event, slice2) {
19326
+ const clipboard = event.clipboardData;
19327
+ const html = clipboard.getData("text/html");
19328
+ clipboard.getData("text/plain");
19329
+ const fieldAnnotationContent = slice2.content.content.filter((item) => item.type.name === "fieldAnnotation");
19330
+ if (fieldAnnotationContent.length) {
19331
+ return false;
19332
+ }
19333
+ let source;
19334
+ if (!html) {
19335
+ source = "plain-text";
19336
+ } else if (isWordHtml(html)) {
19337
+ source = "word-html";
19338
+ } else {
19339
+ source = "browser-html";
19340
+ }
19341
+ switch (source) {
19342
+ case "plain-text":
19343
+ break;
19344
+ case "word-html":
19345
+ if (editor.options.mode === "docx") {
19346
+ return handleDocxPaste(html, editor, view, plugin2);
19347
+ }
19348
+ case "browser-html":
19349
+ return handleHtmlPaste$1(html, editor);
19350
+ }
19351
+ return false;
19352
+ }
19353
+ },
19354
+ isInputRules: true
19355
+ });
19356
+ return plugin2;
19357
+ };
19358
+ function isWordHtml(html) {
19359
+ return /class=["']?Mso|xmlns:o=["']?urn:schemas-microsoft-com|<!--\[if gte mso|<meta[^>]+name=["']?Generator["']?[^>]+Word/i.test(html);
19360
+ }
19361
+ const handleHtmlPaste$1 = (html, editor, plugin2) => {
19362
+ const htmlWithPtSizing = convertEmToPt(html);
19363
+ const cleanedHtml = sanitizeHtml(htmlWithPtSizing);
19364
+ const doc2 = DOMParser$1.fromSchema(editor.schema).parse(cleanedHtml);
19365
+ const { dispatch } = editor.view;
19366
+ if (!dispatch) return false;
19367
+ dispatch(editor.view.state.tr.replaceSelectionWith(doc2, true));
19368
+ return true;
19369
+ };
19370
+ const convertEmToPt = (html) => {
19371
+ return html.replace(
19372
+ /font-size\s*:\s*([\d.]+)em/gi,
19373
+ (_, emValue) => {
19374
+ const em = parseFloat(emValue);
19375
+ const pt = Math.round(em * 12 * 100) / 100;
19376
+ return `font-size: ${pt}pt`;
19377
+ }
19378
+ );
19379
+ };
19380
+ function cleanHtmlUnnecessaryTags(html) {
19381
+ return html.replace(/<o:p>.*?<\/o:p>/gi, "").replace(/&nbsp;/gi, " ").replace(/<span[^>]*>\s*<\/span>/gi, "").replace(/<p[^>]*>\s*<\/p>/gi, "").trim();
19382
+ }
19383
+ function sanitizeHtml(html, forbiddenTags = ["meta", "svg", "script", "style", "button"]) {
19384
+ const container = document.createElement("div");
19385
+ container.innerHTML = html;
19386
+ const walkAndClean = (node2) => {
19387
+ for (const child of [...node2.children]) {
19388
+ if (forbiddenTags.includes(child.tagName.toLowerCase())) {
19389
+ child.remove();
19390
+ continue;
19391
+ }
19392
+ if (child.hasAttribute("linebreaktype")) {
19393
+ child.removeAttribute("linebreaktype");
19394
+ }
19395
+ walkAndClean(child);
19396
+ }
19397
+ };
19398
+ walkAndClean(container);
19399
+ return container;
19400
+ }
18824
19401
  function exportSchemaToJson(params2) {
18825
19402
  const { type: type2 } = params2.node || {};
18826
19403
  const router = {
@@ -20164,12 +20741,11 @@ function prepareHtmlAnnotation(params2) {
20164
20741
  node: { attrs = {}, marks = [] },
20165
20742
  editorSchema
20166
20743
  } = params2;
20167
- const parser = new window.DOMParser();
20168
- const paragraphHtml = parser.parseFromString(attrs.rawHtml || attrs.displayLabel, "text/html");
20744
+ const paragraphHtmlContainer = sanitizeHtml(attrs.rawHtml);
20169
20745
  const marksFromAttrs = translateFieldAttrsToMarks(attrs);
20170
20746
  const allMarks = [...marks, ...marksFromAttrs];
20171
20747
  let state2 = EditorState.create({
20172
- doc: DOMParser$1.fromSchema(editorSchema).parse(paragraphHtml)
20748
+ doc: DOMParser$1.fromSchema(editorSchema).parse(paragraphHtmlContainer)
20173
20749
  });
20174
20750
  if (allMarks.length) {
20175
20751
  state2 = applyMarksToHtmlAnnotation(state2, allMarks);
@@ -23396,7 +23972,7 @@ const _SuperConverter = class _SuperConverter2 {
23396
23972
  return;
23397
23973
  }
23398
23974
  }
23399
- static updateDocumentVersion(docx = this.convertedXml, version2 = "0.13.3-next.5") {
23975
+ static updateDocumentVersion(docx = this.convertedXml, version2 = "0.13.3-next.7") {
23400
23976
  const customLocation = "docProps/custom.xml";
23401
23977
  if (!docx[customLocation]) {
23402
23978
  docx[customLocation] = generateCustomXml();
@@ -23863,7 +24439,7 @@ function storeSuperdocVersion(docx) {
23863
24439
  function generateCustomXml() {
23864
24440
  return DEFAULT_CUSTOM_XML;
23865
24441
  }
23866
- function generateSuperdocVersion(pid = 2, version2 = "0.13.3-next.5") {
24442
+ function generateSuperdocVersion(pid = 2, version2 = "0.13.3-next.7") {
23867
24443
  return {
23868
24444
  type: "element",
23869
24445
  name: "property",
@@ -27585,164 +28161,6 @@ createMarksSchema_fn = function(markExtensions, attributes, editor) {
27585
28161
  };
27586
28162
  __privateAdd$1(_Schema, _Schema_static);
27587
28163
  let Schema2 = _Schema;
27588
- function chainableEditorState(transaction, state2) {
27589
- let { selection, doc: doc2, storedMarks } = transaction;
27590
- return {
27591
- ...state2,
27592
- apply: state2.apply.bind(state2),
27593
- applyTransaction: state2.applyTransaction.bind(state2),
27594
- plugins: state2.plugins,
27595
- schema: state2.schema,
27596
- reconfigure: state2.reconfigure.bind(state2),
27597
- toJSON: state2.toJSON.bind(state2),
27598
- get storedMarks() {
27599
- return storedMarks;
27600
- },
27601
- get selection() {
27602
- return selection;
27603
- },
27604
- get doc() {
27605
- return doc2;
27606
- },
27607
- get tr() {
27608
- selection = transaction.selection;
27609
- doc2 = transaction.doc;
27610
- storedMarks = transaction.storedMarks;
27611
- return transaction;
27612
- }
27613
- };
27614
- }
27615
- class CommandService {
27616
- constructor(props) {
27617
- __publicField$1(this, "editor");
27618
- __publicField$1(this, "rawCommands");
27619
- this.editor = props.editor;
27620
- this.rawCommands = this.editor.extensionService.commands;
27621
- }
27622
- /**
27623
- * Static method for creating a service.
27624
- * @param args Arguments for the constructor.
27625
- */
27626
- static create(...args) {
27627
- return new CommandService(...args);
27628
- }
27629
- /**
27630
- * Get editor state.
27631
- */
27632
- get state() {
27633
- return this.editor.state;
27634
- }
27635
- /**
27636
- * Get all commands with wrapped command method.
27637
- */
27638
- get commands() {
27639
- const { editor, state: state2 } = this;
27640
- const { view } = editor;
27641
- const { tr } = state2;
27642
- const props = this.createProps(tr);
27643
- const entries = Object.entries(this.rawCommands).map(([name, command2]) => {
27644
- const method = (...args) => {
27645
- const fn2 = command2(...args)(props);
27646
- if (!tr.getMeta("preventDispatch")) {
27647
- view.dispatch(tr);
27648
- }
27649
- return fn2;
27650
- };
27651
- return [name, method];
27652
- });
27653
- return Object.fromEntries(entries);
27654
- }
27655
- /**
27656
- * Create a chain of commands to call multiple commands at once.
27657
- */
27658
- get chain() {
27659
- return () => this.createChain();
27660
- }
27661
- /**
27662
- * Check if a command or a chain of commands can be executed. Without executing it.
27663
- */
27664
- get can() {
27665
- return () => this.createCan();
27666
- }
27667
- /**
27668
- * Creates a chain of commands.
27669
- * @param startTr Start transaction.
27670
- * @param shouldDispatch Should dispatch or not.
27671
- */
27672
- createChain(startTr, shouldDispatch = true) {
27673
- const { editor, state: state2, rawCommands } = this;
27674
- const { view } = editor;
27675
- const callbacks2 = [];
27676
- const hasStartTr = !!startTr;
27677
- const tr = startTr || state2.tr;
27678
- const run2 = () => {
27679
- if (!hasStartTr && shouldDispatch && !tr.getMeta("preventDispatch")) {
27680
- view.dispatch(tr);
27681
- }
27682
- return callbacks2.every((cb) => cb === true);
27683
- };
27684
- const entries = Object.entries(rawCommands).map(([name, command2]) => {
27685
- const chainedCommand = (...args) => {
27686
- const props = this.createProps(tr, shouldDispatch);
27687
- const callback = command2(...args)(props);
27688
- callbacks2.push(callback);
27689
- return chain;
27690
- };
27691
- return [name, chainedCommand];
27692
- });
27693
- const chain = {
27694
- ...Object.fromEntries(entries),
27695
- run: run2
27696
- };
27697
- return chain;
27698
- }
27699
- /**
27700
- * Creates a can check for commands.
27701
- * @param startTr Start transaction.
27702
- */
27703
- createCan(startTr) {
27704
- const { rawCommands, state: state2 } = this;
27705
- const dispatch = false;
27706
- const tr = startTr || state2.tr;
27707
- const props = this.createProps(tr, dispatch);
27708
- const commands2 = Object.fromEntries(
27709
- Object.entries(rawCommands).map(([name, command2]) => {
27710
- return [name, (...args) => command2(...args)({ ...props, dispatch: void 0 })];
27711
- })
27712
- );
27713
- return {
27714
- ...commands2,
27715
- chain: () => this.createChain(tr, dispatch)
27716
- };
27717
- }
27718
- /**
27719
- * Creates default props for the command method.
27720
- * @param {*} tr Transaction.
27721
- * @param {*} shouldDispatch Check if should dispatch.
27722
- * @returns Object with props.
27723
- */
27724
- createProps(tr, shouldDispatch = true) {
27725
- const { editor, state: state2, rawCommands } = this;
27726
- const { view } = editor;
27727
- const props = {
27728
- tr,
27729
- editor,
27730
- view,
27731
- state: chainableEditorState(tr, state2),
27732
- dispatch: shouldDispatch ? () => void 0 : void 0,
27733
- chain: () => this.createChain(tr, shouldDispatch),
27734
- can: () => this.createCan(tr),
27735
- get commands() {
27736
- return Object.fromEntries(
27737
- Object.entries(rawCommands).map(([name, command2]) => {
27738
- return [name, (...args) => command2(...args)(props)];
27739
- })
27740
- );
27741
- }
27742
- };
27743
- return props;
27744
- }
27745
- }
27746
28164
  const first = (commands2) => (props) => {
27747
28165
  const items = typeof commands2 === "function" ? commands2(props) : commands2;
27748
28166
  for (let i = 0; i < items.length; i += 1) {
@@ -37979,425 +38397,6 @@ function isExtensionRulesEnabled(extension, enabled) {
37979
38397
  }
37980
38398
  return enabled;
37981
38399
  }
37982
- function getHTMLFromFragment(fragment, schema) {
37983
- const documentFragment = DOMSerializer.fromSchema(schema).serializeFragment(fragment);
37984
- const temporaryDocument = document.implementation.createHTMLDocument();
37985
- const container = temporaryDocument.createElement("div");
37986
- container.appendChild(documentFragment);
37987
- return container.innerHTML;
37988
- }
37989
- const getTextContentFromNodes = ($from, maxMatch = 500) => {
37990
- let textBefore = "";
37991
- const sliceEndPos = $from.parentOffset;
37992
- $from.parent.nodesBetween(
37993
- Math.max(0, sliceEndPos - maxMatch),
37994
- sliceEndPos,
37995
- (node2, pos, parent, index2) => {
37996
- const chunk = node2.type.spec.toText?.({
37997
- node: node2,
37998
- pos,
37999
- parent,
38000
- index: index2
38001
- }) || node2.textContent || "%leaf%";
38002
- textBefore += node2.isAtom && !node2.isText ? chunk : chunk.slice(0, Math.max(0, sliceEndPos - pos));
38003
- }
38004
- );
38005
- return textBefore;
38006
- };
38007
- const handleDocxPaste = (html, editor, view, plugin2) => {
38008
- const { converter } = editor;
38009
- if (!converter || !converter.convertedXml) return handleHtmlPaste(html, editor, view, plugin2);
38010
- let cleanedHtml = convertEmToPt(html);
38011
- cleanedHtml = cleanHtmlUnnecessaryTags(cleanedHtml);
38012
- const tempDiv = document.createElement("div");
38013
- tempDiv.innerHTML = cleanedHtml;
38014
- const paragraphs = tempDiv.querySelectorAll("p");
38015
- paragraphs.forEach((p) => {
38016
- const innerHTML3 = p.innerHTML;
38017
- if (!innerHTML3.includes("<!--[if !supportLists]")) return;
38018
- const styleAttr = p.getAttribute("style") || "";
38019
- const msoListMatch = styleAttr.match(/mso-list:\s*l(\d+)\s+level(\d+)/);
38020
- if (msoListMatch) {
38021
- const [, abstractId, level] = msoListMatch;
38022
- const listNumId = getListNumIdFromAbstract(abstractId, editor);
38023
- if (!listNumId) return;
38024
- const abstractDefinition = getListAbstractDefinition(abstractId, editor);
38025
- const { lvlText, start: start2, numFmt } = getLevelDefinition(abstractDefinition, level - 1);
38026
- p.setAttribute("data-num-id", listNumId);
38027
- p.setAttribute("data-list-level", level - 1);
38028
- p.setAttribute("data-start", start2);
38029
- p.setAttribute("data-lvl-text", lvlText);
38030
- p.setAttribute("data-num-fmt", numFmt);
38031
- }
38032
- extractAndRemoveConditionalPrefix(p);
38033
- });
38034
- transformWordLists(tempDiv);
38035
- const doc2 = DOMParser$1.fromSchema(editor.schema).parse(tempDiv);
38036
- tempDiv.remove();
38037
- const { dispatch } = editor.view;
38038
- if (!dispatch) return false;
38039
- dispatch(view.state.tr.replaceSelectionWith(doc2, true));
38040
- return true;
38041
- };
38042
- const getLevelDefinition = (abstractDefinition, level) => {
38043
- if (!abstractDefinition || !abstractDefinition.elements) return null;
38044
- const levelElement = abstractDefinition.elements.find((el) => {
38045
- return el.name === "w:lvl" && el.attributes?.["w:ilvl"] == level;
38046
- });
38047
- if (!levelElement) return null;
38048
- const { elements } = levelElement;
38049
- const lvlText = elements.find((el) => el.name === "w:lvlText")?.attributes?.["w:val"];
38050
- const start2 = elements.find((el) => el.name === "w:start")?.attributes?.["w:val"];
38051
- const numFmt = elements.find((el) => el.name === "w:numFmt")?.attributes?.["w:val"];
38052
- return { lvlText, start: start2, numFmt, elements };
38053
- };
38054
- const getListNumIdFromAbstract = (abstractId, editor) => {
38055
- const { definitions } = editor?.converter?.numbering;
38056
- if (!definitions) return null;
38057
- const matchedDefinition = Object.values(definitions).find((def) => {
38058
- return def.elements.some((el) => el.name === "w:abstractNumId" && el.attributes?.["w:val"] == abstractId);
38059
- });
38060
- return matchedDefinition?.attributes?.["w:numId"];
38061
- };
38062
- const getListAbstractDefinition = (abstractId, editor) => {
38063
- const { abstracts = {} } = editor?.converter?.numbering;
38064
- return abstracts[abstractId] || null;
38065
- };
38066
- const transformWordLists = (container) => {
38067
- const paragraphs = Array.from(container.querySelectorAll("p[data-num-id]"));
38068
- const listMap = /* @__PURE__ */ new Map();
38069
- const listLevels = {};
38070
- for (const p of paragraphs) {
38071
- const listId = p.getAttribute("data-num-id");
38072
- const level = parseInt(p.getAttribute("data-list-level"));
38073
- const numFmt = p.getAttribute("data-num-fmt");
38074
- const start2 = p.getAttribute("data-start");
38075
- const lvlText = p.getAttribute("data-lvl-text");
38076
- if (!listMap.has(listId)) listMap.set(listId, []);
38077
- listMap.get(listId).push({ p, level, numFmt, start: start2, lvlText });
38078
- }
38079
- for (const [id, items] of listMap.entries()) {
38080
- if (!listLevels[id]) {
38081
- listLevels[id] = {
38082
- stack: [],
38083
- counts: {},
38084
- prevLevel: null
38085
- };
38086
- }
38087
- const parentStack = [];
38088
- items.forEach(({ p, level, numFmt, start: start2, lvlText }, index2) => {
38089
- const listLevel = generateListNestingPath(listLevels, id, level);
38090
- const li = document.createElement("li");
38091
- li.innerHTML = p.innerHTML;
38092
- li.setAttribute("data-list-level", JSON.stringify(listLevel));
38093
- li.setAttribute("data-num-id", id);
38094
- li.setAttribute("data-lvl-text", lvlText);
38095
- li.setAttribute("data-num-fmt", numFmt);
38096
- if (p.hasAttribute("data-font-family")) {
38097
- li.setAttribute("data-font-family", p.getAttribute("data-font-family"));
38098
- }
38099
- if (p.hasAttribute("data-font-size")) {
38100
- li.setAttribute("data-font-size", p.getAttribute("data-font-size"));
38101
- }
38102
- const parentNode2 = p.parentNode;
38103
- let listForLevel = parentStack[level];
38104
- if (!listForLevel) {
38105
- const newList = document.createElement("ol");
38106
- newList.setAttribute("data-list-id", id);
38107
- newList.level = level;
38108
- if (level > 0) {
38109
- const parentLi = parentStack[level - 1]?.querySelector("li:last-child");
38110
- if (parentLi) parentLi.appendChild(newList);
38111
- } else {
38112
- parentNode2.insertBefore(newList, p);
38113
- }
38114
- parentStack[level] = newList;
38115
- parentStack.length = level + 1;
38116
- listForLevel = newList;
38117
- }
38118
- listForLevel.appendChild(li);
38119
- p.remove();
38120
- });
38121
- }
38122
- };
38123
- function generateListNestingPath(listLevels, listId, currentLevel) {
38124
- const levelState = listLevels[listId];
38125
- if (!levelState.stack) levelState.stack = [];
38126
- if (levelState.prevLevel === void 0) levelState.prevLevel = null;
38127
- if (levelState.prevLevel === null) {
38128
- levelState.stack = Array(currentLevel).fill(1).concat(1);
38129
- } else {
38130
- if (currentLevel > levelState.prevLevel) {
38131
- levelState.stack.push(1);
38132
- } else if (currentLevel === levelState.prevLevel) {
38133
- levelState.stack[levelState.stack.length - 1]++;
38134
- } else {
38135
- levelState.stack = levelState.stack.slice(0, currentLevel + 1);
38136
- levelState.stack[currentLevel] = (levelState.stack[currentLevel] || 1) + 1;
38137
- }
38138
- }
38139
- levelState.prevLevel = currentLevel;
38140
- return [...levelState.stack];
38141
- }
38142
- function extractAndRemoveConditionalPrefix(p) {
38143
- const nodes = Array.from(p.childNodes);
38144
- let fontFamily2 = null;
38145
- let fontSize2 = null;
38146
- let start2 = -1, end2 = -1;
38147
- nodes.forEach((node2, index2) => {
38148
- if (node2.nodeType === Node.COMMENT_NODE && node2.nodeValue.includes("[if !supportLists]")) {
38149
- start2 = index2;
38150
- }
38151
- if (start2 !== -1 && node2.nodeType === Node.COMMENT_NODE && node2.nodeValue.includes("[endif]")) {
38152
- end2 = index2;
38153
- }
38154
- });
38155
- if (start2 !== -1 && end2 !== -1) {
38156
- for (let i = start2 + 1; i < end2; i++) {
38157
- const node2 = nodes[i];
38158
- if (node2.nodeType === Node.ELEMENT_NODE && node2.style) {
38159
- fontFamily2 = fontFamily2 || node2.style.fontFamily;
38160
- fontSize2 = fontSize2 || node2.style.fontSize;
38161
- }
38162
- }
38163
- for (let i = end2; i >= start2; i--) {
38164
- p.removeChild(p.childNodes[i]);
38165
- }
38166
- if (fontFamily2) p.setAttribute("data-font-family", fontFamily2);
38167
- if (fontSize2) p.setAttribute("data-font-size", fontSize2);
38168
- }
38169
- }
38170
- class InputRule {
38171
- constructor(config) {
38172
- __publicField$1(this, "match");
38173
- __publicField$1(this, "handler");
38174
- this.match = config.match;
38175
- this.handler = config.handler;
38176
- }
38177
- }
38178
- const inputRuleMatcherHandler = (text, match) => {
38179
- if (isRegExp(match)) {
38180
- return match.exec(text);
38181
- }
38182
- const inputRuleMatch = match(text);
38183
- if (!inputRuleMatch) {
38184
- return null;
38185
- }
38186
- const result = [inputRuleMatch.text];
38187
- result.index = inputRuleMatch.index;
38188
- result.input = text;
38189
- result.data = inputRuleMatch.data;
38190
- if (inputRuleMatch.replaceWith) {
38191
- if (!inputRuleMatch.text.includes(inputRuleMatch.replaceWith)) {
38192
- console.warn(
38193
- '[super-editor warn]: "inputRuleMatch.replaceWith" must be part of "inputRuleMatch.text".'
38194
- );
38195
- }
38196
- result.push(inputRuleMatch.replaceWith);
38197
- }
38198
- return result;
38199
- };
38200
- const run = (config) => {
38201
- const {
38202
- editor,
38203
- from: from2,
38204
- to,
38205
- text,
38206
- rules,
38207
- plugin: plugin2
38208
- } = config;
38209
- const { view } = editor;
38210
- if (view.composing) {
38211
- return false;
38212
- }
38213
- const $from = view.state.doc.resolve(from2);
38214
- if ($from.parent.type.spec.code || !!($from.nodeBefore || $from.nodeAfter)?.marks.find((mark) => mark.type.spec.code)) {
38215
- return false;
38216
- }
38217
- let matched = false;
38218
- const textBefore = getTextContentFromNodes($from) + text;
38219
- rules.forEach((rule) => {
38220
- if (matched) {
38221
- return;
38222
- }
38223
- const match = inputRuleMatcherHandler(textBefore, rule.match);
38224
- if (!match) {
38225
- return;
38226
- }
38227
- const tr = view.state.tr;
38228
- const state2 = chainableEditorState(tr, view.state);
38229
- const range2 = {
38230
- from: from2 - (match[0].length - text.length),
38231
- to
38232
- };
38233
- const { commands: commands2, chain, can } = new CommandService({
38234
- editor,
38235
- state: state2
38236
- });
38237
- const handler = rule.handler({
38238
- state: state2,
38239
- range: range2,
38240
- match,
38241
- commands: commands2,
38242
- chain,
38243
- can
38244
- });
38245
- if (handler === null || !tr.steps.length) {
38246
- return;
38247
- }
38248
- tr.setMeta(plugin2, {
38249
- transform: tr,
38250
- from: from2,
38251
- to,
38252
- text
38253
- });
38254
- view.dispatch(tr);
38255
- matched = true;
38256
- });
38257
- return matched;
38258
- };
38259
- const inputRulesPlugin = ({ editor, rules }) => {
38260
- const plugin2 = new Plugin({
38261
- key: new PluginKey("inputRulesPlugin"),
38262
- state: {
38263
- init() {
38264
- return null;
38265
- },
38266
- apply(tr, prev, state2) {
38267
- const stored = tr.getMeta(plugin2);
38268
- if (stored) {
38269
- return stored;
38270
- }
38271
- const simulatedInputMeta = tr.getMeta("applyInputRules");
38272
- const isSimulatedInput = !!simulatedInputMeta;
38273
- if (isSimulatedInput) {
38274
- setTimeout(() => {
38275
- let { text } = simulatedInputMeta;
38276
- if (typeof text !== "string") {
38277
- text = getHTMLFromFragment(Fragment.from(text), state2.schema);
38278
- }
38279
- const { from: from2 } = simulatedInputMeta;
38280
- const to = from2 + text.length;
38281
- run({
38282
- editor,
38283
- from: from2,
38284
- to,
38285
- text,
38286
- rules,
38287
- plugin: plugin2
38288
- });
38289
- });
38290
- }
38291
- return tr.selectionSet || tr.docChanged ? null : prev;
38292
- }
38293
- },
38294
- props: {
38295
- handleTextInput(view, from2, to, text) {
38296
- return run({
38297
- editor,
38298
- from: from2,
38299
- to,
38300
- text,
38301
- rules,
38302
- plugin: plugin2
38303
- });
38304
- },
38305
- // add support for input rules to trigger on enter
38306
- // this is useful for example for code blocks
38307
- handleKeyDown(view, event) {
38308
- if (event.key !== "Enter") {
38309
- return false;
38310
- }
38311
- const { $cursor } = view.state.selection;
38312
- if ($cursor) {
38313
- return run({
38314
- editor,
38315
- from: $cursor.pos,
38316
- to: $cursor.pos,
38317
- text: "\n",
38318
- rules,
38319
- plugin: plugin2
38320
- });
38321
- }
38322
- return false;
38323
- },
38324
- // Paste handler
38325
- handlePaste(view, event, slice2) {
38326
- const clipboard = event.clipboardData;
38327
- const html = clipboard.getData("text/html");
38328
- clipboard.getData("text/plain");
38329
- const fieldAnnotationContent = slice2.content.content.filter((item) => item.type.name === "fieldAnnotation");
38330
- if (fieldAnnotationContent.length) {
38331
- return false;
38332
- }
38333
- let source;
38334
- if (!html) {
38335
- source = "plain-text";
38336
- } else if (isWordHtml(html)) {
38337
- source = "word-html";
38338
- } else {
38339
- source = "browser-html";
38340
- }
38341
- switch (source) {
38342
- case "plain-text":
38343
- break;
38344
- case "word-html":
38345
- if (editor.options.mode === "docx") {
38346
- return handleDocxPaste(html, editor, view, plugin2);
38347
- }
38348
- case "browser-html":
38349
- return handleHtmlPaste$1(html, editor);
38350
- }
38351
- return false;
38352
- }
38353
- },
38354
- isInputRules: true
38355
- });
38356
- return plugin2;
38357
- };
38358
- function isWordHtml(html) {
38359
- return /class=["']?Mso|xmlns:o=["']?urn:schemas-microsoft-com|<!--\[if gte mso|<meta[^>]+name=["']?Generator["']?[^>]+Word/i.test(html);
38360
- }
38361
- const handleHtmlPaste$1 = (html, editor, plugin2) => {
38362
- const htmlWithPtSizing = convertEmToPt(html);
38363
- const cleanedHtml = sanitizeHtml(htmlWithPtSizing);
38364
- const doc2 = DOMParser$1.fromSchema(editor.schema).parse(cleanedHtml);
38365
- const { dispatch } = editor.view;
38366
- if (!dispatch) return false;
38367
- dispatch(editor.view.state.tr.replaceSelectionWith(doc2, true));
38368
- return true;
38369
- };
38370
- const convertEmToPt = (html) => {
38371
- return html.replace(
38372
- /font-size\s*:\s*([\d.]+)em/gi,
38373
- (_, emValue) => {
38374
- const em = parseFloat(emValue);
38375
- const pt = Math.round(em * 12 * 100) / 100;
38376
- return `font-size: ${pt}pt`;
38377
- }
38378
- );
38379
- };
38380
- function cleanHtmlUnnecessaryTags(html) {
38381
- return html.replace(/<o:p>.*?<\/o:p>/gi, "").replace(/&nbsp;/gi, " ").replace(/<span[^>]*>\s*<\/span>/gi, "").replace(/<p[^>]*>\s*<\/p>/gi, "").trim();
38382
- }
38383
- function sanitizeHtml(html, forbiddenTags = ["meta", "svg", "script", "style", "button"]) {
38384
- const container = document.createElement("div");
38385
- container.innerHTML = html;
38386
- const walkAndClean = (node2) => {
38387
- for (const child of [...node2.children]) {
38388
- if (forbiddenTags.includes(child.tagName.toLowerCase())) {
38389
- child.remove();
38390
- continue;
38391
- }
38392
- if (child.hasAttribute("linebreaktype")) {
38393
- child.removeAttribute("linebreaktype");
38394
- }
38395
- walkAndClean(child);
38396
- }
38397
- };
38398
- walkAndClean(container);
38399
- return container;
38400
- }
38401
38400
  const _ExtensionService = class _ExtensionService2 {
38402
38401
  constructor(extensions, userExtensions, editor) {
38403
38402
  __privateAdd$1(this, _ExtensionService_instances);
@@ -41285,7 +41284,7 @@ const _Editor = class _Editor2 extends EventEmitter$1 {
41285
41284
  * @returns {Object | void} Migration results
41286
41285
  */
41287
41286
  processCollaborationMigrations() {
41288
- console.debug("[checkVersionMigrations] Current editor version", "0.13.3-next.5");
41287
+ console.debug("[checkVersionMigrations] Current editor version", "0.13.3-next.7");
41289
41288
  if (!this.options.ydoc) return;
41290
41289
  const metaMap = this.options.ydoc.getMap("meta");
41291
41290
  let docVersion = metaMap.get("version");
@@ -55389,6 +55388,7 @@ const nodeResizer = (nodeNames = ["image"]) => {
55389
55388
  if (tr.getMeta(NodeResizerKey)) {
55390
55389
  return oldState;
55391
55390
  }
55391
+ if (typeof document === "undefined") return oldState;
55392
55392
  const decorations = [];
55393
55393
  const { selection } = newState;
55394
55394
  if (nodeNames.includes(selection.node?.type.name)) {