@harbour-enterprises/superdoc 0.22.0-next.1 → 0.22.0-next.11
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/chunks/{PdfViewer-BpwMPbUj.es.js → PdfViewer-CS3pY_UR.es.js} +1 -1
- package/dist/chunks/{PdfViewer-B3KmcDup.cjs → PdfViewer-Cz3fT1qt.cjs} +1 -1
- package/dist/chunks/{index-Cw4YywoD.es.js → index-Bbqhu9ev.es.js} +53 -26
- package/dist/chunks/{index-BOf6E2I4.cjs → index-p73XAt11.cjs} +53 -26
- package/dist/chunks/{super-editor.es-DHDx2fsy.cjs → super-editor.es-CFD0lcOY.cjs} +3201 -2009
- package/dist/chunks/{super-editor.es-vfoWxyZL.es.js → super-editor.es-DK3l03fz.es.js} +3201 -2009
- package/dist/core/SuperDoc.d.ts +5 -0
- package/dist/core/SuperDoc.d.ts.map +1 -1
- package/dist/core/types/index.d.ts +4 -4
- package/dist/core/types/index.d.ts.map +1 -1
- package/dist/stores/comments-store.d.ts +4 -1
- package/dist/stores/comments-store.d.ts.map +1 -1
- package/dist/style.css +51 -44
- package/dist/super-editor/ai-writer.es.js +2 -2
- package/dist/super-editor/chunks/{converter-BcqEfCTg.js → converter-DFDRdFEB.js} +1880 -1169
- package/dist/super-editor/chunks/{docx-zipper-DZ9ph0iQ.js → docx-zipper-CplUdgI9.js} +73 -12
- package/dist/super-editor/chunks/{editor-BC2sSIVa.js → editor-BnpIdTLI.js} +1492 -1061
- package/dist/super-editor/chunks/{toolbar-DNTo5DDf.js → toolbar-5h-ljJ_h.js} +2 -2
- package/dist/super-editor/converter.es.js +1 -1
- package/dist/super-editor/docx-zipper.es.js +2 -2
- package/dist/super-editor/editor.es.js +3 -3
- package/dist/super-editor/file-zipper.es.js +1 -1
- package/dist/super-editor/src/core/DocxZipper.d.ts +1 -1
- package/dist/super-editor/src/core/helpers/generateDocxRandomId.d.ts +5 -0
- package/dist/super-editor/src/core/super-converter/SuperConverter.d.ts +1 -13
- package/dist/super-editor/src/core/super-converter/exporter.d.ts +5 -4
- package/dist/super-editor/src/core/super-converter/field-references/fld-preprocessors/hyperlink-preprocessor.d.ts +9 -0
- package/dist/super-editor/src/core/super-converter/field-references/fld-preprocessors/index.d.ts +2 -0
- package/dist/super-editor/src/core/super-converter/field-references/fld-preprocessors/num-pages-preprocessor.d.ts +9 -0
- package/dist/super-editor/src/core/super-converter/field-references/fld-preprocessors/page-preprocessor.d.ts +9 -0
- package/dist/super-editor/src/core/super-converter/field-references/fld-preprocessors/page-ref-preprocessor.d.ts +9 -0
- package/dist/super-editor/src/core/super-converter/field-references/fld-preprocessors/toc-preprocessor.d.ts +8 -0
- package/dist/super-editor/src/core/super-converter/field-references/index.d.ts +1 -0
- package/dist/super-editor/src/core/super-converter/field-references/preProcessNodesForFldChar.d.ts +21 -0
- package/dist/super-editor/src/core/super-converter/helpers/tableFallbackHelpers.d.ts +24 -0
- package/dist/super-editor/src/core/super-converter/v2/exporter/helpers/translateChildNodes.d.ts +3 -3
- package/dist/super-editor/src/core/super-converter/v2/importer/pageReferenceImporter.d.ts +4 -0
- package/dist/super-editor/src/core/super-converter/v2/importer/tableOfContentsImporter.d.ts +4 -0
- package/dist/super-editor/src/core/super-converter/v2/types/index.d.ts +7 -1
- package/dist/super-editor/src/core/super-converter/v3/handlers/sd/pageReference/index.d.ts +1 -0
- package/dist/super-editor/src/core/super-converter/v3/handlers/sd/pageReference/pageReference-translator.d.ts +7 -0
- package/dist/super-editor/src/core/super-converter/v3/handlers/sd/tableOfContents/index.d.ts +1 -0
- package/dist/super-editor/src/core/super-converter/v3/handlers/sd/tableOfContents/tableOfContents-translator.d.ts +10 -0
- package/dist/super-editor/src/core/super-converter/v3/handlers/w/caps/caps-translator.d.ts +7 -0
- package/dist/super-editor/src/core/super-converter/v3/handlers/w/p/helpers/w-p-helpers.d.ts +0 -2
- package/dist/super-editor/src/core/super-converter/v3/handlers/w/sdt/helpers/handle-doc-part-obj.d.ts +9 -1
- package/dist/super-editor/src/core/super-converter/v3/handlers/w/sdt/helpers/translate-document-part-obj.d.ts +6 -0
- package/dist/super-editor/src/core/super-converter/v3/node-translator/node-translator.d.ts +2 -2
- package/dist/super-editor/src/extensions/custom-selection/custom-selection.d.ts +5 -1
- package/dist/super-editor/src/extensions/index.d.ts +2 -1
- package/dist/super-editor/src/extensions/page-reference/index.d.ts +1 -0
- package/dist/super-editor/src/extensions/page-reference/page-reference.d.ts +2 -0
- package/dist/super-editor/src/extensions/structured-content/document-part-object.d.ts +2 -0
- package/dist/super-editor/src/extensions/structured-content/index.d.ts +2 -0
- package/dist/super-editor/src/extensions/structured-content/structured-content-commands.d.ts +67 -0
- package/dist/super-editor/src/extensions/structured-content/structuredContentHelpers/getStructuredContentBlockTags.d.ts +6 -0
- package/dist/super-editor/src/extensions/structured-content/structuredContentHelpers/getStructuredContentInlineTags.d.ts +6 -0
- package/dist/super-editor/src/extensions/structured-content/structuredContentHelpers/getStructuredContentTags.d.ts +6 -0
- package/dist/super-editor/src/extensions/structured-content/structuredContentHelpers/getStructuredContentTagsById.d.ts +7 -0
- package/dist/super-editor/src/extensions/structured-content/structuredContentHelpers/index.d.ts +4 -0
- package/dist/super-editor/src/extensions/tab/helpers/tabDecorations.d.ts +2 -2
- package/dist/super-editor/src/extensions/table-of-contents/index.d.ts +1 -0
- package/dist/super-editor/src/extensions/table-of-contents/table-of-contents.d.ts +2 -0
- package/dist/super-editor/src/utils/contextmenu-helpers.d.ts +24 -0
- package/dist/super-editor/style.css +7 -0
- package/dist/super-editor/super-editor.es.js +11 -17
- package/dist/super-editor/toolbar.es.js +2 -2
- package/dist/super-editor.cjs +1 -1
- package/dist/super-editor.es.js +1 -1
- package/dist/superdoc.cjs +2 -2
- package/dist/superdoc.es.js +2 -2
- package/dist/superdoc.umd.js +3245 -2026
- package/dist/superdoc.umd.js.map +1 -1
- package/package.json +1 -1
- package/dist/super-editor/src/components/slash-menu/contextmenu-helpers.d.ts +0 -1
|
@@ -9,12 +9,12 @@ var __privateGet = (obj, member, getter) => (__accessCheck(obj, member, "read fr
|
|
|
9
9
|
var __privateAdd = (obj, member, value) => member.has(obj) ? __typeError("Cannot add the same private member more than once") : member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
|
|
10
10
|
var __privateSet = (obj, member, value, setter) => (__accessCheck(obj, member, "write to private field"), setter ? setter.call(obj, value) : member.set(obj, value), value);
|
|
11
11
|
var __privateMethod = (obj, member, method) => (__accessCheck(obj, member, "access private method"), method);
|
|
12
|
-
var _Attribute_static, getGlobalAttributes_fn, getNodeAndMarksAttributes_fn, _Schema_static, createNodesSchema_fn, createMarksSchema_fn, _events, _ExtensionService_instances, setupExtensions_fn, attachEditorEvents_fn, _editor, _stateValidators, _xmlValidators, _requiredNodeTypes, _requiredMarkTypes, _SuperValidator_instances, initializeValidators_fn, collectValidatorRequirements_fn, analyzeDocument_fn, _commandService, _Editor_instances, initContainerElement_fn, init_fn, initRichText_fn, onFocus_fn, checkHeadless_fn, registerCopyHandler_fn, insertNewFileData_fn, registerPluginByNameIfNotExists_fn, createExtensionService_fn, createCommandService_fn, createConverter_fn, initMedia_fn, initFonts_fn, createSchema_fn, generatePmData_fn, createView_fn, onCollaborationReady_fn, initComments_fn, initPagination_fn, dispatchTransaction_fn, handleNodeSelection_fn, prepareDocumentForImport_fn, prepareDocumentForExport_fn, endCollaboration_fn, validateDocumentInit_fn, validateDocumentExport_fn, initDevTools_fn,
|
|
12
|
+
var _Attribute_static, getGlobalAttributes_fn, getNodeAndMarksAttributes_fn, _Schema_static, createNodesSchema_fn, createMarksSchema_fn, _events, _ExtensionService_instances, setupExtensions_fn, attachEditorEvents_fn, _editor, _stateValidators, _xmlValidators, _requiredNodeTypes, _requiredMarkTypes, _SuperValidator_instances, initializeValidators_fn, collectValidatorRequirements_fn, analyzeDocument_fn, _commandService, _Editor_instances, initContainerElement_fn, init_fn, initRichText_fn, onFocus_fn, checkHeadless_fn, registerCopyHandler_fn, insertNewFileData_fn, registerPluginByNameIfNotExists_fn, createExtensionService_fn, createCommandService_fn, createConverter_fn, initMedia_fn, initFonts_fn, createSchema_fn, generatePmData_fn, createView_fn, onCollaborationReady_fn, initComments_fn, initPagination_fn, dispatchTransaction_fn, handleNodeSelection_fn, prepareDocumentForImport_fn, prepareDocumentForExport_fn, endCollaboration_fn, validateDocumentInit_fn, validateDocumentExport_fn, initDevTools_fn, _DocumentSectionView_instances, init_fn2, addToolTip_fn, _ListItemNodeView_instances, init_fn3, _FieldAnnotationView_instances, createAnnotation_fn, _AutoPageNumberNodeView_instances, renderDom_fn, scheduleUpdateNodeStyle_fn;
|
|
13
13
|
import * as Y from "yjs";
|
|
14
14
|
import { UndoManager, Item as Item$1, ContentType, Text as Text$1, XmlElement, encodeStateAsUpdate } from "yjs";
|
|
15
|
-
import { P as PluginKey, a as Plugin, M as Mapping, N as NodeSelection, S as Selection, T as TextSelection, b as Slice, D as DOMSerializer, F as Fragment, c as DOMParser$1, d as Mark$1, e as dropPoint, A as AllSelection, p as process$1, B as Buffer2, f as callOrGet, g as getExtensionConfigField, h as getMarkType, i as getMarksFromSelection, j as getNodeType, k as getSchemaTypeNameByName, l as Schema$1, m as cleanSchemaItem, n as canSplit, o as defaultBlockAt$1, q as liftTarget, r as canJoin, s as joinPoint, t as replaceStep$1, R as ReplaceAroundStep$1, u as isTextSelection, v as getMarkRange, w as isMarkActive, x as isNodeActive, y as deleteProps, z as processContent, C as ReplaceStep, E as NodeRange, G as findWrapping, L as ListHelpers, H as findParentNode, I as isMacOS, J as isIOS, K as getSchemaTypeByName, O as inputRulesPlugin, Q as TrackDeleteMarkName, U as TrackInsertMarkName, V as v4, W as TrackFormatMarkName, X as comments_module_events, Y as findMark, Z as objectIncludes, _ as AddMarkStep, $ as RemoveMarkStep, a0 as twipsToLines, a1 as pixelsToTwips, a2 as helpers, a3 as posToDOMRect, a4 as CommandService, a5 as SuperConverter, a6 as createDocument, a7 as createDocFromMarkdown, a8 as createDocFromHTML, a9 as EditorState, aa as hasSomeParentWithClass, ab as isActive, ac as unflattenListsInHtml, ad as parseSizeUnit, ae as minMax, af as getLineHeightValueString, ag as
|
|
15
|
+
import { P as PluginKey, a as Plugin, M as Mapping, N as NodeSelection, S as Selection, T as TextSelection, b as Slice, D as DOMSerializer, F as Fragment, c as DOMParser$1, d as Mark$1, e as dropPoint, A as AllSelection, p as process$1, B as Buffer2, f as callOrGet, g as getExtensionConfigField, h as getMarkType, i as getMarksFromSelection, j as getNodeType, k as getSchemaTypeNameByName, l as Schema$1, m as cleanSchemaItem, n as canSplit, o as defaultBlockAt$1, q as liftTarget, r as canJoin, s as joinPoint, t as replaceStep$1, R as ReplaceAroundStep$1, u as isTextSelection, v as getMarkRange, w as isMarkActive, x as isNodeActive, y as deleteProps, z as processContent, C as ReplaceStep, E as NodeRange, G as findWrapping, L as ListHelpers, H as findParentNode, I as isMacOS, J as isIOS, K as getSchemaTypeByName, O as inputRulesPlugin, Q as TrackDeleteMarkName, U as TrackInsertMarkName, V as v4, W as TrackFormatMarkName, X as comments_module_events, Y as findMark, Z as objectIncludes, _ as AddMarkStep, $ as RemoveMarkStep, a0 as twipsToLines, a1 as pixelsToTwips, a2 as helpers, a3 as posToDOMRect, a4 as CommandService, a5 as SuperConverter, a6 as createDocument, a7 as createDocFromMarkdown, a8 as createDocFromHTML, a9 as EditorState, aa as hasSomeParentWithClass, ab as isActive, ac as unflattenListsInHtml, ad as parseSizeUnit, ae as minMax, af as getLineHeightValueString, ag as updateDOMAttributes, ah as findChildren$5, ai as htmlHandler, aj as generateRandomSigned32BitIntStrId, ak as InputRule, al as kebabCase, am as findParentNodeClosestToPos, an as getListItemStyleDefinitions, ao as docxNumberigHelpers, ap as parseIndentElement, aq as combineIndents, ar as SelectionRange, as as Transform, at as isInTable$1, au as generateDocxRandomId, av as insertNewRelationship } from "./converter-DFDRdFEB.js";
|
|
16
16
|
import { ref, computed, createElementBlock, openBlock, withModifiers, Fragment as Fragment$1, renderList, normalizeClass, createCommentVNode, toDisplayString, createElementVNode, createApp } from "vue";
|
|
17
|
-
import { D as DocxZipper } from "./docx-zipper-
|
|
17
|
+
import { D as DocxZipper } from "./docx-zipper-CplUdgI9.js";
|
|
18
18
|
var GOOD_LEAF_SIZE = 200;
|
|
19
19
|
var RopeSequence = function RopeSequence2() {
|
|
20
20
|
};
|
|
@@ -11675,9 +11675,11 @@ const toggleHeaderFooterEditMode = ({ editor, focusedSectionEditor, isEditMode,
|
|
|
11675
11675
|
item.editor.view.dom.setAttribute("documentmode", documentMode);
|
|
11676
11676
|
});
|
|
11677
11677
|
if (isEditMode) {
|
|
11678
|
-
const pm =
|
|
11679
|
-
pm
|
|
11680
|
-
|
|
11678
|
+
const pm = editor.view?.dom || editor.options.element?.querySelector?.(".ProseMirror");
|
|
11679
|
+
if (pm) {
|
|
11680
|
+
pm.classList.add("header-footer-edit");
|
|
11681
|
+
pm.setAttribute("aria-readonly", true);
|
|
11682
|
+
}
|
|
11681
11683
|
}
|
|
11682
11684
|
if (focusedSectionEditor) {
|
|
11683
11685
|
focusedSectionEditor.view.focus();
|
|
@@ -12105,28 +12107,25 @@ const handleTrackedChangeTransaction = (trackedChangeMeta, trackedChanges, newEd
|
|
|
12105
12107
|
if (emitParams) editor.emit("commentsUpdate", emitParams);
|
|
12106
12108
|
return newTrackedChanges;
|
|
12107
12109
|
};
|
|
12108
|
-
const getTrackedChangeText = ({
|
|
12110
|
+
const getTrackedChangeText = ({ nodes, mark, trackedChangeType, isDeletionInsertion }) => {
|
|
12109
12111
|
let trackedChangeText = "";
|
|
12110
12112
|
let deletionText = "";
|
|
12111
12113
|
if (trackedChangeType === TrackInsertMarkName) {
|
|
12112
|
-
trackedChangeText = node
|
|
12114
|
+
trackedChangeText = nodes.reduce((acc, node) => {
|
|
12115
|
+
if (!node.marks.find((nodeMark) => nodeMark.type.name === mark.type.name)) return acc;
|
|
12116
|
+
acc += node?.text || node?.textContent || "";
|
|
12117
|
+
return acc;
|
|
12118
|
+
}, "");
|
|
12113
12119
|
}
|
|
12114
12120
|
if (trackedChangeType === TrackFormatMarkName) {
|
|
12115
12121
|
trackedChangeText = translateFormatChangesToEnglish(mark.attrs);
|
|
12116
12122
|
}
|
|
12117
12123
|
if (trackedChangeType === TrackDeleteMarkName || isDeletionInsertion) {
|
|
12118
|
-
deletionText = node
|
|
12119
|
-
|
|
12120
|
-
|
|
12121
|
-
|
|
12122
|
-
|
|
12123
|
-
const changeMarks = marks2.filter((mark2) => TRACK_CHANGE_MARKS.includes(mark2.type.name));
|
|
12124
|
-
if (!changeMarks.length) return false;
|
|
12125
|
-
const hasMatchingId = changeMarks.find((mark2) => mark2.attrs.id === id);
|
|
12126
|
-
if (hasMatchingId) return true;
|
|
12127
|
-
});
|
|
12128
|
-
deletionText = deletionNode?.node.text ?? "";
|
|
12129
|
-
}
|
|
12124
|
+
deletionText = nodes.reduce((acc, node) => {
|
|
12125
|
+
if (!node.marks.find((nodeMark) => nodeMark.type.name === TrackDeleteMarkName)) return acc;
|
|
12126
|
+
acc += node?.text || node?.textContent || "";
|
|
12127
|
+
return acc;
|
|
12128
|
+
}, "");
|
|
12130
12129
|
}
|
|
12131
12130
|
return {
|
|
12132
12131
|
deletionText,
|
|
@@ -12141,20 +12140,17 @@ const createOrUpdateTrackedChangeComment = ({ event, marks, deletionNodes, nodes
|
|
|
12141
12140
|
const id = attrs.id;
|
|
12142
12141
|
const node = nodes[0];
|
|
12143
12142
|
const isDeletionInsertion = !!(marks.insertedMark && marks.deletionMark);
|
|
12144
|
-
let
|
|
12143
|
+
let nodesWithMark = [];
|
|
12145
12144
|
newEditorState.doc.descendants((node2) => {
|
|
12146
12145
|
const { marks: marks2 = [] } = node2;
|
|
12147
12146
|
const changeMarks = marks2.filter((mark) => TRACK_CHANGE_MARKS.includes(mark.type.name));
|
|
12148
12147
|
if (!changeMarks.length) return;
|
|
12149
12148
|
const hasMatchingId = changeMarks.find((mark) => mark.attrs.id === id);
|
|
12150
|
-
if (hasMatchingId)
|
|
12151
|
-
if (existingNode) return false;
|
|
12149
|
+
if (hasMatchingId) nodesWithMark.push(node2);
|
|
12152
12150
|
});
|
|
12153
12151
|
const { deletionText, trackedChangeText } = getTrackedChangeText({
|
|
12154
|
-
|
|
12155
|
-
node: existingNode || node,
|
|
12152
|
+
nodes: nodesWithMark.length ? nodesWithMark : [node],
|
|
12156
12153
|
mark: trackedMark,
|
|
12157
|
-
marks,
|
|
12158
12154
|
trackedChangeType,
|
|
12159
12155
|
isDeletionInsertion
|
|
12160
12156
|
});
|
|
@@ -12182,14 +12178,6 @@ const createOrUpdateTrackedChangeComment = ({ event, marks, deletionNodes, nodes
|
|
|
12182
12178
|
else if (event === "update") params2.event = comments_module_events.UPDATE;
|
|
12183
12179
|
return params2;
|
|
12184
12180
|
};
|
|
12185
|
-
function findNode$1(node, predicate) {
|
|
12186
|
-
let found = null;
|
|
12187
|
-
node.descendants((node2, pos) => {
|
|
12188
|
-
if (predicate(node2)) found = { node: node2, pos };
|
|
12189
|
-
if (found) return false;
|
|
12190
|
-
});
|
|
12191
|
-
return found;
|
|
12192
|
-
}
|
|
12193
12181
|
function findRangeById(doc2, id) {
|
|
12194
12182
|
let from2 = null, to = null;
|
|
12195
12183
|
doc2.descendants((node, pos) => {
|
|
@@ -12707,6 +12695,7 @@ const generateTableIfNecessary = ({ tableNode, annotationValues, tr, state }) =>
|
|
|
12707
12695
|
const mappedRowStart = tr.mapping.map(absoluteRowStart);
|
|
12708
12696
|
const rowEnd = mappedRowStart + rowNode.nodeSize;
|
|
12709
12697
|
tr.replaceWith(mappedRowStart, rowEnd, Fragment.from(newRows));
|
|
12698
|
+
tr.setMeta("tableGeneration", true);
|
|
12710
12699
|
} catch (error) {
|
|
12711
12700
|
console.error("Error during row generation:", error);
|
|
12712
12701
|
throw error;
|
|
@@ -13111,7 +13100,7 @@ function findFieldAnnotationsBetween(from2, to, doc2) {
|
|
|
13111
13100
|
}
|
|
13112
13101
|
function findRemovedFieldAnnotations(tr) {
|
|
13113
13102
|
let removedNodes = [];
|
|
13114
|
-
if (!tr.steps.length || tr.meta && !Object.keys(tr.meta).every((meta) => ["inputType", "uiEvent", "paste"].includes(meta)) || ["historyUndo", "historyRedo"].includes(tr.getMeta("inputType")) || ["drop"].includes(tr.getMeta("uiEvent")) || tr.getMeta("fieldAnnotationUpdate") === true) {
|
|
13103
|
+
if (!tr.steps.length || tr.meta && !Object.keys(tr.meta).every((meta) => ["inputType", "uiEvent", "paste"].includes(meta)) || ["historyUndo", "historyRedo"].includes(tr.getMeta("inputType")) || ["drop"].includes(tr.getMeta("uiEvent")) || tr.getMeta("fieldAnnotationUpdate") === true || tr.getMeta("tableGeneration") === true) {
|
|
13115
13104
|
return removedNodes;
|
|
13116
13105
|
}
|
|
13117
13106
|
const hasDeletion = transactionDeletedAnything(tr);
|
|
@@ -14332,7 +14321,7 @@ const _Editor = class _Editor extends EventEmitter {
|
|
|
14332
14321
|
setDocumentMode(documentMode) {
|
|
14333
14322
|
let cleanedMode = documentMode?.toLowerCase() || "editing";
|
|
14334
14323
|
if (!this.extensionService || !this.state) return;
|
|
14335
|
-
const pm =
|
|
14324
|
+
const pm = this.view?.dom || this.options.element?.querySelector?.(".ProseMirror");
|
|
14336
14325
|
if (this.options.role === "viewer") cleanedMode = "viewing";
|
|
14337
14326
|
if (this.options.role === "suggester" && cleanedMode === "editing") cleanedMode = "suggesting";
|
|
14338
14327
|
if (cleanedMode === "viewing") {
|
|
@@ -14820,7 +14809,8 @@ const _Editor = class _Editor extends EventEmitter {
|
|
|
14820
14809
|
files: this.options.content
|
|
14821
14810
|
},
|
|
14822
14811
|
media,
|
|
14823
|
-
true
|
|
14812
|
+
true,
|
|
14813
|
+
updatedDocs
|
|
14824
14814
|
);
|
|
14825
14815
|
return updatedDocs;
|
|
14826
14816
|
}
|
|
@@ -15380,9 +15370,11 @@ createView_fn = function(element) {
|
|
|
15380
15370
|
isEditMode: false,
|
|
15381
15371
|
documentMode: this.options.documentMode
|
|
15382
15372
|
});
|
|
15383
|
-
const pm =
|
|
15384
|
-
pm
|
|
15385
|
-
|
|
15373
|
+
const pm = this.view?.dom || this.options.element?.querySelector?.(".ProseMirror");
|
|
15374
|
+
if (pm) {
|
|
15375
|
+
pm.classList.remove("header-footer-edit");
|
|
15376
|
+
pm.setAttribute("aria-readonly", false);
|
|
15377
|
+
}
|
|
15386
15378
|
}
|
|
15387
15379
|
setWordSelection(view, pos);
|
|
15388
15380
|
}
|
|
@@ -16973,221 +16965,1258 @@ const SlashMenu = Extension.create({
|
|
|
16973
16965
|
return this.editor.options.isHeadless ? [] : [slashMenuPlugin];
|
|
16974
16966
|
}
|
|
16975
16967
|
});
|
|
16976
|
-
|
|
16977
|
-
|
|
16978
|
-
|
|
16979
|
-
|
|
16980
|
-
|
|
16981
|
-
|
|
16982
|
-
|
|
16983
|
-
|
|
16984
|
-
|
|
16985
|
-
|
|
16986
|
-
|
|
16987
|
-
|
|
16988
|
-
|
|
16989
|
-
|
|
16990
|
-
|
|
16991
|
-
|
|
16992
|
-
|
|
16993
|
-
|
|
16994
|
-
|
|
16995
|
-
|
|
16996
|
-
|
|
16997
|
-
|
|
16998
|
-
|
|
16999
|
-
|
|
17000
|
-
|
|
17001
|
-
|
|
17002
|
-
|
|
17003
|
-
|
|
17004
|
-
|
|
17005
|
-
|
|
17006
|
-
|
|
17007
|
-
|
|
17008
|
-
|
|
17009
|
-
|
|
17010
|
-
|
|
17011
|
-
|
|
17012
|
-
|
|
17013
|
-
|
|
17014
|
-
|
|
17015
|
-
|
|
17016
|
-
|
|
17017
|
-
|
|
17018
|
-
|
|
17019
|
-
|
|
17020
|
-
|
|
17021
|
-
|
|
17022
|
-
|
|
17023
|
-
|
|
17024
|
-
|
|
16968
|
+
class StructuredContentViewBase {
|
|
16969
|
+
constructor(props) {
|
|
16970
|
+
__publicField(this, "node");
|
|
16971
|
+
__publicField(this, "view");
|
|
16972
|
+
__publicField(this, "getPos");
|
|
16973
|
+
__publicField(this, "decorations");
|
|
16974
|
+
__publicField(this, "innerDecorations");
|
|
16975
|
+
__publicField(this, "editor");
|
|
16976
|
+
__publicField(this, "extension");
|
|
16977
|
+
__publicField(this, "htmlAttributes");
|
|
16978
|
+
__publicField(this, "root");
|
|
16979
|
+
__publicField(this, "isDragging", false);
|
|
16980
|
+
this.node = props.node;
|
|
16981
|
+
this.view = props.editor.view;
|
|
16982
|
+
this.getPos = props.getPos;
|
|
16983
|
+
this.decorations = props.decorations;
|
|
16984
|
+
this.innerDecorations = props.innerDecorations;
|
|
16985
|
+
this.editor = props.editor;
|
|
16986
|
+
this.extension = props.extension;
|
|
16987
|
+
this.htmlAttributes = props.htmlAttributes;
|
|
16988
|
+
this.mount(props);
|
|
16989
|
+
}
|
|
16990
|
+
mount() {
|
|
16991
|
+
return;
|
|
16992
|
+
}
|
|
16993
|
+
get dom() {
|
|
16994
|
+
return this.root;
|
|
16995
|
+
}
|
|
16996
|
+
get contentDOM() {
|
|
16997
|
+
return null;
|
|
16998
|
+
}
|
|
16999
|
+
update(node, decorations, innerDecorations) {
|
|
17000
|
+
if (node.type !== this.node.type) {
|
|
17001
|
+
return false;
|
|
17002
|
+
}
|
|
17003
|
+
this.node = node;
|
|
17004
|
+
this.decorations = decorations;
|
|
17005
|
+
this.innerDecorations = innerDecorations;
|
|
17006
|
+
this.updateHTMLAttributes();
|
|
17007
|
+
return true;
|
|
17008
|
+
}
|
|
17009
|
+
stopEvent(event) {
|
|
17010
|
+
if (!this.dom) return false;
|
|
17011
|
+
const target = event.target;
|
|
17012
|
+
const isInElement = this.dom.contains(target) && !this.contentDOM?.contains(target);
|
|
17013
|
+
if (!isInElement) return false;
|
|
17014
|
+
const isDragEvent = event.type.startsWith("drag");
|
|
17015
|
+
const isDropEvent = event.type === "drop";
|
|
17016
|
+
const isInput = ["INPUT", "BUTTON", "SELECT", "TEXTAREA"].includes(target.tagName) || target.isContentEditable;
|
|
17017
|
+
if (isInput && !isDropEvent && !isDragEvent) return true;
|
|
17018
|
+
const { isEditable } = this.editor;
|
|
17019
|
+
const { isDragging } = this;
|
|
17020
|
+
const isDraggable = !!this.node.type.spec.draggable;
|
|
17021
|
+
const isSelectable = NodeSelection.isSelectable(this.node);
|
|
17022
|
+
const isCopyEvent = event.type === "copy";
|
|
17023
|
+
const isPasteEvent = event.type === "paste";
|
|
17024
|
+
const isCutEvent = event.type === "cut";
|
|
17025
|
+
const isClickEvent = event.type === "mousedown";
|
|
17026
|
+
if (!isDraggable && isSelectable && isDragEvent && event.target === this.dom) {
|
|
17027
|
+
event.preventDefault();
|
|
17028
|
+
}
|
|
17029
|
+
if (isDraggable && isDragEvent && !isDragging && event.target === this.dom) {
|
|
17030
|
+
event.preventDefault();
|
|
17031
|
+
return false;
|
|
17032
|
+
}
|
|
17033
|
+
if (isDraggable && isEditable && !isDragging && isClickEvent) {
|
|
17034
|
+
const dragHandle = target.closest("[data-drag-handle]");
|
|
17035
|
+
const isValidDragHandle = dragHandle && (this.dom === dragHandle || this.dom.contains(dragHandle));
|
|
17036
|
+
if (isValidDragHandle) {
|
|
17037
|
+
this.isDragging = true;
|
|
17038
|
+
document.addEventListener(
|
|
17039
|
+
"dragend",
|
|
17040
|
+
() => {
|
|
17041
|
+
this.isDragging = false;
|
|
17042
|
+
},
|
|
17043
|
+
{ once: true }
|
|
17044
|
+
);
|
|
17045
|
+
document.addEventListener(
|
|
17046
|
+
"drop",
|
|
17047
|
+
() => {
|
|
17048
|
+
this.isDragging = false;
|
|
17049
|
+
},
|
|
17050
|
+
{ once: true }
|
|
17051
|
+
);
|
|
17052
|
+
document.addEventListener(
|
|
17053
|
+
"mouseup",
|
|
17054
|
+
() => {
|
|
17055
|
+
this.isDragging = false;
|
|
17056
|
+
},
|
|
17057
|
+
{ once: true }
|
|
17058
|
+
);
|
|
17025
17059
|
}
|
|
17026
|
-
}
|
|
17060
|
+
}
|
|
17061
|
+
if (isDragging || isDropEvent || isCopyEvent || isPasteEvent || isCutEvent || isClickEvent && isSelectable) {
|
|
17062
|
+
return false;
|
|
17063
|
+
}
|
|
17064
|
+
return true;
|
|
17027
17065
|
}
|
|
17028
|
-
|
|
17029
|
-
|
|
17030
|
-
|
|
17031
|
-
|
|
17032
|
-
|
|
17033
|
-
|
|
17034
|
-
return
|
|
17066
|
+
ignoreMutation(mutation) {
|
|
17067
|
+
if (!this.dom || !this.contentDOM) return true;
|
|
17068
|
+
if (this.node.isLeaf || this.node.isAtom) return true;
|
|
17069
|
+
if (mutation.type === "selection") return false;
|
|
17070
|
+
if (this.contentDOM === mutation.target && mutation.type === "attributes") return true;
|
|
17071
|
+
if (this.contentDOM.contains(mutation.target)) return false;
|
|
17072
|
+
return true;
|
|
17035
17073
|
}
|
|
17036
|
-
|
|
17037
|
-
|
|
17038
|
-
|
|
17039
|
-
|
|
17040
|
-
|
|
17041
|
-
|
|
17042
|
-
|
|
17074
|
+
destroy() {
|
|
17075
|
+
this.dom.remove();
|
|
17076
|
+
this.contentDOM?.remove();
|
|
17077
|
+
}
|
|
17078
|
+
updateAttributes(attrs) {
|
|
17079
|
+
const pos = this.getPos();
|
|
17080
|
+
if (typeof pos !== "number") {
|
|
17081
|
+
return;
|
|
17082
|
+
}
|
|
17083
|
+
return this.view.dispatch(
|
|
17084
|
+
this.view.state.tr.setNodeMarkup(pos, void 0, {
|
|
17085
|
+
...this.node.attrs,
|
|
17086
|
+
...attrs
|
|
17087
|
+
})
|
|
17088
|
+
);
|
|
17089
|
+
}
|
|
17090
|
+
updateHTMLAttributes() {
|
|
17091
|
+
const { extensionService } = this.editor;
|
|
17092
|
+
const { attributes } = extensionService;
|
|
17093
|
+
const extensionAttrs = attributes.filter((i) => i.type === this.node.type.name);
|
|
17094
|
+
this.htmlAttributes = Attribute.getAttributesToRender(this.node, extensionAttrs);
|
|
17095
|
+
}
|
|
17096
|
+
createDragHandle() {
|
|
17097
|
+
const dragHandle = document.createElement("span");
|
|
17098
|
+
dragHandle.classList.add("sd-structured-content-draggable");
|
|
17099
|
+
dragHandle.draggable = true;
|
|
17100
|
+
dragHandle.contentEditable = "false";
|
|
17101
|
+
dragHandle.dataset.dragHandle = "";
|
|
17102
|
+
const textElement = document.createElement("span");
|
|
17103
|
+
textElement.textContent = this.node.attrs.alias || "Structured content";
|
|
17104
|
+
dragHandle.append(textElement);
|
|
17105
|
+
return dragHandle;
|
|
17106
|
+
}
|
|
17107
|
+
onDragStart(event) {
|
|
17108
|
+
const { view } = this.editor;
|
|
17109
|
+
const target = event.target;
|
|
17110
|
+
const dragHandle = target.nodeType === 3 ? target.parentElement?.closest("[data-drag-handle]") : target.closest("[data-drag-handle]");
|
|
17111
|
+
if (!this.dom || this.contentDOM?.contains(target) || !dragHandle) {
|
|
17112
|
+
return;
|
|
17113
|
+
}
|
|
17114
|
+
let x = 0;
|
|
17115
|
+
let y = 0;
|
|
17116
|
+
if (this.dom !== dragHandle) {
|
|
17117
|
+
const domBox = this.dom.getBoundingClientRect();
|
|
17118
|
+
const handleBox = dragHandle.getBoundingClientRect();
|
|
17119
|
+
const offsetX = event.offsetX ?? event.nativeEvent?.offsetX;
|
|
17120
|
+
const offsetY = event.offsetY ?? event.nativeEvent?.offsetY;
|
|
17121
|
+
x = handleBox.x - domBox.x + offsetX;
|
|
17122
|
+
y = handleBox.y - domBox.y + offsetY;
|
|
17123
|
+
}
|
|
17124
|
+
event.dataTransfer?.setDragImage(this.dom, x, y);
|
|
17125
|
+
const pos = this.getPos();
|
|
17126
|
+
if (typeof pos !== "number") {
|
|
17127
|
+
return;
|
|
17128
|
+
}
|
|
17129
|
+
const selection = NodeSelection.create(view.state.doc, pos);
|
|
17130
|
+
const transaction = view.state.tr.setSelection(selection);
|
|
17043
17131
|
view.dispatch(transaction);
|
|
17044
|
-
});
|
|
17045
|
-
if (handled) {
|
|
17046
|
-
tr.setMeta("preventDispatch", true);
|
|
17047
17132
|
}
|
|
17048
|
-
|
|
17049
|
-
|
|
17050
|
-
|
|
17051
|
-
|
|
17052
|
-
|
|
17053
|
-
|
|
17133
|
+
}
|
|
17134
|
+
class StructuredContentInlineView extends StructuredContentViewBase {
|
|
17135
|
+
constructor(props) {
|
|
17136
|
+
super(props);
|
|
17137
|
+
}
|
|
17138
|
+
mount() {
|
|
17139
|
+
this.buildView();
|
|
17140
|
+
}
|
|
17141
|
+
get contentDOM() {
|
|
17142
|
+
const contentElement = this.dom?.querySelector(`.${structuredContentInnerClass$1}`);
|
|
17143
|
+
return contentElement || null;
|
|
17144
|
+
}
|
|
17145
|
+
createElement() {
|
|
17146
|
+
const element = document.createElement("span");
|
|
17147
|
+
element.classList.add(structuredContentClass$1);
|
|
17148
|
+
element.setAttribute("data-structured-content", "");
|
|
17149
|
+
const contentElement = document.createElement("span");
|
|
17150
|
+
contentElement.classList.add(structuredContentInnerClass$1);
|
|
17151
|
+
element.append(contentElement);
|
|
17152
|
+
const domAttrs = Attribute.mergeAttributes(this.htmlAttributes);
|
|
17153
|
+
updateDOMAttributes(element, { ...domAttrs });
|
|
17154
|
+
return { element, contentElement };
|
|
17155
|
+
}
|
|
17156
|
+
buildView() {
|
|
17157
|
+
const { element } = this.createElement();
|
|
17158
|
+
const dragHandle = this.createDragHandle();
|
|
17159
|
+
element.prepend(dragHandle);
|
|
17160
|
+
element.addEventListener("dragstart", (e) => this.onDragStart(e));
|
|
17161
|
+
this.root = element;
|
|
17162
|
+
}
|
|
17163
|
+
updateView() {
|
|
17164
|
+
const domAttrs = Attribute.mergeAttributes(this.htmlAttributes);
|
|
17165
|
+
updateDOMAttributes(this.dom, { ...domAttrs });
|
|
17166
|
+
}
|
|
17167
|
+
update(node, decorations, innerDecorations) {
|
|
17168
|
+
const result = super.update(node, decorations, innerDecorations);
|
|
17169
|
+
if (!result) return false;
|
|
17170
|
+
this.updateView();
|
|
17171
|
+
return true;
|
|
17172
|
+
}
|
|
17173
|
+
}
|
|
17174
|
+
const structuredContentClass$1 = "sd-structured-content";
|
|
17175
|
+
const structuredContentInnerClass$1 = "sd-structured-content__content";
|
|
17176
|
+
const StructuredContent = Node$1.create({
|
|
17177
|
+
name: "structuredContent",
|
|
17178
|
+
group: "inline structuredContent",
|
|
17054
17179
|
inline: true,
|
|
17055
17180
|
content: "inline*",
|
|
17056
|
-
|
|
17057
|
-
|
|
17181
|
+
isolating: true,
|
|
17182
|
+
atom: false,
|
|
17183
|
+
// false - has editable content.
|
|
17184
|
+
draggable: true,
|
|
17058
17185
|
addOptions() {
|
|
17059
17186
|
return {
|
|
17060
17187
|
htmlAttributes: {
|
|
17061
|
-
|
|
17188
|
+
class: structuredContentClass$1,
|
|
17189
|
+
"aria-label": "Structured content node"
|
|
17062
17190
|
}
|
|
17063
17191
|
};
|
|
17064
17192
|
},
|
|
17065
17193
|
addAttributes() {
|
|
17066
17194
|
return {
|
|
17067
|
-
|
|
17195
|
+
id: {
|
|
17068
17196
|
default: null,
|
|
17069
|
-
|
|
17070
|
-
|
|
17197
|
+
parseDOM: (elem) => elem.getAttribute("data-id"),
|
|
17198
|
+
renderDOM: (attrs) => {
|
|
17199
|
+
if (!attrs.id) return {};
|
|
17200
|
+
return { "data-id": attrs.id };
|
|
17201
|
+
}
|
|
17071
17202
|
},
|
|
17072
|
-
|
|
17203
|
+
tag: {
|
|
17073
17204
|
default: null,
|
|
17074
|
-
|
|
17075
|
-
|
|
17205
|
+
parseDOM: (elem) => elem.getAttribute("data-tag"),
|
|
17206
|
+
renderDOM: (attrs) => {
|
|
17207
|
+
if (!attrs.tag) return {};
|
|
17208
|
+
return { "data-tag": attrs.tag };
|
|
17209
|
+
}
|
|
17076
17210
|
},
|
|
17077
|
-
|
|
17211
|
+
alias: {
|
|
17078
17212
|
default: null,
|
|
17079
|
-
|
|
17080
|
-
|
|
17213
|
+
parseDOM: (elem) => elem.getAttribute("data-alias"),
|
|
17214
|
+
renderDOM: (attrs) => {
|
|
17215
|
+
if (!attrs.alias) return {};
|
|
17216
|
+
return { "data-alias": attrs.alias };
|
|
17217
|
+
}
|
|
17081
17218
|
},
|
|
17082
|
-
|
|
17083
|
-
|
|
17084
|
-
rendered: false,
|
|
17085
|
-
keepOnSplit: true
|
|
17219
|
+
sdtPr: {
|
|
17220
|
+
rendered: false
|
|
17086
17221
|
}
|
|
17087
17222
|
};
|
|
17088
17223
|
},
|
|
17089
|
-
addCommands() {
|
|
17090
|
-
return {
|
|
17091
|
-
splitRun
|
|
17092
|
-
};
|
|
17093
|
-
},
|
|
17094
17224
|
parseDOM() {
|
|
17095
|
-
return [{ tag: "span[data-
|
|
17225
|
+
return [{ tag: "span[data-structured-content]" }];
|
|
17096
17226
|
},
|
|
17097
17227
|
renderDOM({ htmlAttributes }) {
|
|
17098
|
-
|
|
17099
|
-
|
|
17228
|
+
return [
|
|
17229
|
+
"span",
|
|
17230
|
+
Attribute.mergeAttributes(this.options.htmlAttributes, htmlAttributes, {
|
|
17231
|
+
"data-structured-content": ""
|
|
17232
|
+
}),
|
|
17233
|
+
0
|
|
17234
|
+
];
|
|
17235
|
+
},
|
|
17236
|
+
addNodeView() {
|
|
17237
|
+
return (props) => {
|
|
17238
|
+
return new StructuredContentInlineView({ ...props });
|
|
17239
|
+
};
|
|
17100
17240
|
}
|
|
17101
17241
|
});
|
|
17102
|
-
|
|
17103
|
-
|
|
17104
|
-
|
|
17105
|
-
|
|
17106
|
-
|
|
17107
|
-
|
|
17108
|
-
|
|
17109
|
-
|
|
17242
|
+
class StructuredContentBlockView extends StructuredContentViewBase {
|
|
17243
|
+
constructor(props) {
|
|
17244
|
+
super(props);
|
|
17245
|
+
}
|
|
17246
|
+
mount() {
|
|
17247
|
+
this.buildView();
|
|
17248
|
+
}
|
|
17249
|
+
get contentDOM() {
|
|
17250
|
+
const contentElement = this.dom?.querySelector(`.${structuredContentInnerClass}`);
|
|
17251
|
+
return contentElement || null;
|
|
17252
|
+
}
|
|
17253
|
+
createElement() {
|
|
17254
|
+
const element = document.createElement("div");
|
|
17255
|
+
element.classList.add(structuredContentClass);
|
|
17256
|
+
element.setAttribute("data-structured-content-block", "");
|
|
17257
|
+
const contentElement = document.createElement("div");
|
|
17258
|
+
contentElement.classList.add(structuredContentInnerClass);
|
|
17259
|
+
element.append(contentElement);
|
|
17260
|
+
const domAttrs = Attribute.mergeAttributes(this.htmlAttributes);
|
|
17261
|
+
updateDOMAttributes(element, { ...domAttrs });
|
|
17262
|
+
return { element, contentElement };
|
|
17263
|
+
}
|
|
17264
|
+
buildView() {
|
|
17265
|
+
const { element } = this.createElement();
|
|
17266
|
+
const dragHandle = this.createDragHandle();
|
|
17267
|
+
element.prepend(dragHandle);
|
|
17268
|
+
element.addEventListener("dragstart", (e) => this.onDragStart(e));
|
|
17269
|
+
this.root = element;
|
|
17270
|
+
}
|
|
17271
|
+
updateView() {
|
|
17272
|
+
const domAttrs = Attribute.mergeAttributes(this.htmlAttributes);
|
|
17273
|
+
updateDOMAttributes(this.dom, { ...domAttrs });
|
|
17274
|
+
}
|
|
17275
|
+
update(node, decorations, innerDecorations) {
|
|
17276
|
+
const result = super.update(node, decorations, innerDecorations);
|
|
17277
|
+
if (!result) return false;
|
|
17278
|
+
this.updateView();
|
|
17279
|
+
return true;
|
|
17280
|
+
}
|
|
17281
|
+
}
|
|
17282
|
+
const structuredContentClass = "sd-structured-content-block";
|
|
17283
|
+
const structuredContentInnerClass = "sd-structured-content-block__content";
|
|
17284
|
+
const StructuredContentBlock = Node$1.create({
|
|
17285
|
+
name: "structuredContentBlock",
|
|
17286
|
+
group: "block structuredContent",
|
|
17287
|
+
content: "block*",
|
|
17288
|
+
isolating: true,
|
|
17289
|
+
atom: false,
|
|
17290
|
+
// false - has editable content.
|
|
17291
|
+
draggable: true,
|
|
17110
17292
|
addOptions() {
|
|
17111
17293
|
return {
|
|
17112
|
-
itemTypeName: "listItem",
|
|
17113
17294
|
htmlAttributes: {
|
|
17114
|
-
|
|
17115
|
-
|
|
17116
|
-
|
|
17117
|
-
keepAttributes: false
|
|
17295
|
+
class: structuredContentClass,
|
|
17296
|
+
"aria-label": "Structured content block node"
|
|
17297
|
+
}
|
|
17118
17298
|
};
|
|
17119
17299
|
},
|
|
17120
|
-
parseDOM() {
|
|
17121
|
-
return [{ tag: "ul" }];
|
|
17122
|
-
},
|
|
17123
|
-
renderDOM({ htmlAttributes }) {
|
|
17124
|
-
const attributes = Attribute.mergeAttributes(this.options.htmlAttributes, htmlAttributes);
|
|
17125
|
-
return ["ul", attributes, 0];
|
|
17126
|
-
},
|
|
17127
17300
|
addAttributes() {
|
|
17128
17301
|
return {
|
|
17129
|
-
|
|
17130
|
-
default:
|
|
17131
|
-
|
|
17302
|
+
id: {
|
|
17303
|
+
default: null,
|
|
17304
|
+
parseDOM: (elem) => elem.getAttribute("data-id"),
|
|
17305
|
+
renderDOM: (attrs) => {
|
|
17306
|
+
if (!attrs.id) return {};
|
|
17307
|
+
return { "data-id": attrs.id };
|
|
17308
|
+
}
|
|
17132
17309
|
},
|
|
17133
|
-
|
|
17134
|
-
|
|
17310
|
+
tag: {
|
|
17311
|
+
default: null,
|
|
17312
|
+
parseDOM: (elem) => elem.getAttribute("data-tag"),
|
|
17313
|
+
renderDOM: (attrs) => {
|
|
17314
|
+
if (!attrs.tag) return {};
|
|
17315
|
+
return { "data-tag": attrs.tag };
|
|
17316
|
+
}
|
|
17135
17317
|
},
|
|
17136
|
-
|
|
17318
|
+
alias: {
|
|
17137
17319
|
default: null,
|
|
17138
|
-
|
|
17139
|
-
parseDOM: (elem) => elem.getAttribute("data-sd-block-id"),
|
|
17320
|
+
parseDOM: (elem) => elem.getAttribute("data-alias"),
|
|
17140
17321
|
renderDOM: (attrs) => {
|
|
17141
|
-
|
|
17322
|
+
if (!attrs.alias) return {};
|
|
17323
|
+
return { "data-alias": attrs.alias };
|
|
17142
17324
|
}
|
|
17143
17325
|
},
|
|
17144
|
-
|
|
17145
|
-
rendered: false
|
|
17146
|
-
keepOnSplit: true
|
|
17326
|
+
sdtPr: {
|
|
17327
|
+
rendered: false
|
|
17147
17328
|
}
|
|
17148
17329
|
};
|
|
17149
17330
|
},
|
|
17331
|
+
parseDOM() {
|
|
17332
|
+
return [{ tag: "div[data-structured-content-block]" }];
|
|
17333
|
+
},
|
|
17334
|
+
renderDOM({ htmlAttributes }) {
|
|
17335
|
+
return [
|
|
17336
|
+
"div",
|
|
17337
|
+
Attribute.mergeAttributes(this.options.htmlAttributes, htmlAttributes, {
|
|
17338
|
+
"data-structured-content-block": ""
|
|
17339
|
+
}),
|
|
17340
|
+
0
|
|
17341
|
+
];
|
|
17342
|
+
},
|
|
17343
|
+
addNodeView() {
|
|
17344
|
+
return (props) => {
|
|
17345
|
+
return new StructuredContentBlockView({ ...props });
|
|
17346
|
+
};
|
|
17347
|
+
}
|
|
17348
|
+
});
|
|
17349
|
+
function getStructuredContentTagsById(idOrIds, state) {
|
|
17350
|
+
const result = findChildren$5(state.doc, (node) => {
|
|
17351
|
+
const isStructuredContent = ["structuredContent", "structuredContentBlock"].includes(node.type.name);
|
|
17352
|
+
if (Array.isArray(idOrIds)) {
|
|
17353
|
+
return isStructuredContent && idOrIds.includes(node.attrs.id);
|
|
17354
|
+
} else {
|
|
17355
|
+
return isStructuredContent && node.attrs.id === idOrIds;
|
|
17356
|
+
}
|
|
17357
|
+
});
|
|
17358
|
+
return result;
|
|
17359
|
+
}
|
|
17360
|
+
function getStructuredContentTags(state) {
|
|
17361
|
+
const result = findChildren$5(state.doc, (node) => {
|
|
17362
|
+
return node.type.name === "structuredContent" || node.type.name === "structuredContentBlock";
|
|
17363
|
+
});
|
|
17364
|
+
return result;
|
|
17365
|
+
}
|
|
17366
|
+
function getStructuredContentInlineTags(state) {
|
|
17367
|
+
const result = findChildren$5(state.doc, (node) => node.type.name === "structuredContent");
|
|
17368
|
+
return result;
|
|
17369
|
+
}
|
|
17370
|
+
function getStructuredContentBlockTags(state) {
|
|
17371
|
+
const result = findChildren$5(state.doc, (node) => node.type.name === "structuredContentBlock");
|
|
17372
|
+
return result;
|
|
17373
|
+
}
|
|
17374
|
+
const structuredContentHelpers = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
17375
|
+
__proto__: null,
|
|
17376
|
+
getStructuredContentBlockTags,
|
|
17377
|
+
getStructuredContentInlineTags,
|
|
17378
|
+
getStructuredContentTags,
|
|
17379
|
+
getStructuredContentTagsById
|
|
17380
|
+
}, Symbol.toStringTag, { value: "Module" }));
|
|
17381
|
+
const STRUCTURED_CONTENT_NAMES = ["structuredContent", "structuredContentBlock"];
|
|
17382
|
+
const StructuredContentCommands = Extension.create({
|
|
17383
|
+
name: "structuredContentCommands",
|
|
17150
17384
|
addCommands() {
|
|
17151
17385
|
return {
|
|
17152
17386
|
/**
|
|
17153
|
-
*
|
|
17387
|
+
* Inserts a structured content inline at selection.
|
|
17154
17388
|
* @category Command
|
|
17155
|
-
* @
|
|
17156
|
-
* // Toggle bullet list on selected text
|
|
17157
|
-
* editor.commands.toggleBulletList()
|
|
17158
|
-
* @note Converts selected paragraphs to list items or removes list formatting
|
|
17389
|
+
* @param {StructuredContentInlineInsert} options
|
|
17159
17390
|
*/
|
|
17160
|
-
|
|
17161
|
-
|
|
17162
|
-
|
|
17163
|
-
|
|
17164
|
-
|
|
17165
|
-
|
|
17166
|
-
|
|
17167
|
-
|
|
17168
|
-
return this.editor.commands.toggleBulletList();
|
|
17169
|
-
}
|
|
17170
|
-
};
|
|
17171
|
-
},
|
|
17172
|
-
addInputRules() {
|
|
17173
|
-
return [
|
|
17174
|
-
new InputRule({
|
|
17175
|
-
match: inputRegex$1,
|
|
17176
|
-
handler: ({ state, range }) => {
|
|
17177
|
-
const $pos = state.selection.$from;
|
|
17178
|
-
const listItemType = state.schema.nodes.listItem;
|
|
17179
|
-
for (let depth = $pos.depth; depth >= 0; depth--) {
|
|
17180
|
-
if ($pos.node(depth).type === listItemType) {
|
|
17181
|
-
return null;
|
|
17182
|
-
}
|
|
17391
|
+
insertStructuredContentInline: (options = {}) => ({ editor, dispatch, state, tr }) => {
|
|
17392
|
+
const { schema } = editor;
|
|
17393
|
+
let { from: from2, to } = state.selection;
|
|
17394
|
+
if (dispatch) {
|
|
17395
|
+
const selectionText = state.doc.textBetween(from2, to);
|
|
17396
|
+
let content = null;
|
|
17397
|
+
if (selectionText) {
|
|
17398
|
+
content = schema.text(selectionText);
|
|
17183
17399
|
}
|
|
17184
|
-
|
|
17185
|
-
|
|
17186
|
-
|
|
17187
|
-
|
|
17188
|
-
|
|
17189
|
-
|
|
17190
|
-
|
|
17400
|
+
if (options.text) {
|
|
17401
|
+
content = schema.text(options.text);
|
|
17402
|
+
}
|
|
17403
|
+
if (options.json) {
|
|
17404
|
+
content = schema.nodeFromJSON(options.json);
|
|
17405
|
+
}
|
|
17406
|
+
if (!content) {
|
|
17407
|
+
content = schema.text(" ");
|
|
17408
|
+
}
|
|
17409
|
+
const attrs = {
|
|
17410
|
+
...options.attrs,
|
|
17411
|
+
id: options.attrs?.id || generateRandomSigned32BitIntStrId(),
|
|
17412
|
+
tag: "inline_text_sdt",
|
|
17413
|
+
alias: options.attrs?.alias || "Structured content"
|
|
17414
|
+
};
|
|
17415
|
+
const node = schema.nodes.structuredContent.create(attrs, content, null);
|
|
17416
|
+
const parent = findParentNode((node2) => node2.type.name === "structuredContent")(state.selection);
|
|
17417
|
+
if (parent) {
|
|
17418
|
+
const insertPos = parent.pos + parent.node.nodeSize;
|
|
17419
|
+
from2 = to = insertPos;
|
|
17420
|
+
}
|
|
17421
|
+
tr.replaceWith(from2, to, node);
|
|
17422
|
+
}
|
|
17423
|
+
return true;
|
|
17424
|
+
},
|
|
17425
|
+
/**
|
|
17426
|
+
* Inserts a structured content block at selection.
|
|
17427
|
+
* @category Command
|
|
17428
|
+
* @param {StructuredContentBlockInsert} options
|
|
17429
|
+
*/
|
|
17430
|
+
insertStructuredContentBlock: (options = {}) => ({ editor, dispatch, state, tr }) => {
|
|
17431
|
+
const { schema } = editor;
|
|
17432
|
+
let { from: from2, to } = state.selection;
|
|
17433
|
+
if (dispatch) {
|
|
17434
|
+
const selectionContent = state.selection.content();
|
|
17435
|
+
let content = null;
|
|
17436
|
+
if (selectionContent.size) {
|
|
17437
|
+
content = selectionContent.content;
|
|
17438
|
+
}
|
|
17439
|
+
if (options.html) {
|
|
17440
|
+
const html = htmlHandler(options.html, editor);
|
|
17441
|
+
const doc2 = DOMParser$1.fromSchema(schema).parse(html);
|
|
17442
|
+
content = doc2.content;
|
|
17443
|
+
}
|
|
17444
|
+
if (options.json) {
|
|
17445
|
+
content = schema.nodeFromJSON(options.json);
|
|
17446
|
+
}
|
|
17447
|
+
if (!content) {
|
|
17448
|
+
content = schema.nodeFromJSON({ type: "paragraph", content: [] });
|
|
17449
|
+
}
|
|
17450
|
+
const attrs = {
|
|
17451
|
+
...options.attrs,
|
|
17452
|
+
id: options.attrs?.id || generateRandomSigned32BitIntStrId(),
|
|
17453
|
+
tag: "block_table_sdt",
|
|
17454
|
+
alias: options.attrs?.alias || "Structured content"
|
|
17455
|
+
};
|
|
17456
|
+
const node = schema.nodes.structuredContentBlock.create(attrs, content, null);
|
|
17457
|
+
const parent = findParentNode((node2) => node2.type.name === "structuredContentBlock")(state.selection);
|
|
17458
|
+
if (parent) {
|
|
17459
|
+
const insertPos = parent.pos + parent.node.nodeSize;
|
|
17460
|
+
from2 = to = insertPos;
|
|
17461
|
+
}
|
|
17462
|
+
tr.replaceRangeWith(from2, to, node);
|
|
17463
|
+
}
|
|
17464
|
+
return true;
|
|
17465
|
+
},
|
|
17466
|
+
/**
|
|
17467
|
+
* Updates a structured content attributes or content.
|
|
17468
|
+
* If the updated node does not match the schema, it will not be updated.
|
|
17469
|
+
* @category Command
|
|
17470
|
+
* @param {string} id
|
|
17471
|
+
* @param {StructuredContentUpdate} options
|
|
17472
|
+
*/
|
|
17473
|
+
updateStructuredContentById: (id, options = {}) => ({ editor, dispatch, state, tr }) => {
|
|
17474
|
+
const structuredContentTags = getStructuredContentTagsById(id, state);
|
|
17475
|
+
if (!structuredContentTags.length) {
|
|
17476
|
+
return true;
|
|
17477
|
+
}
|
|
17478
|
+
const { schema } = editor;
|
|
17479
|
+
if (dispatch) {
|
|
17480
|
+
const structuredContent = structuredContentTags[0];
|
|
17481
|
+
const { pos, node } = structuredContent;
|
|
17482
|
+
const posFrom = pos;
|
|
17483
|
+
const posTo = pos + node.nodeSize;
|
|
17484
|
+
let content = null;
|
|
17485
|
+
if (options.text) {
|
|
17486
|
+
content = schema.text(options.text);
|
|
17487
|
+
}
|
|
17488
|
+
if (options.html) {
|
|
17489
|
+
const html = htmlHandler(options.html, editor);
|
|
17490
|
+
const doc2 = DOMParser$1.fromSchema(schema).parse(html);
|
|
17491
|
+
content = doc2.content;
|
|
17492
|
+
}
|
|
17493
|
+
if (options.json) {
|
|
17494
|
+
content = schema.nodeFromJSON(options.json);
|
|
17495
|
+
}
|
|
17496
|
+
if (!content) {
|
|
17497
|
+
content = node.content;
|
|
17498
|
+
}
|
|
17499
|
+
const updatedNode = node.type.create({ ...node.attrs, ...options.attrs }, content, node.marks);
|
|
17500
|
+
try {
|
|
17501
|
+
updatedNode.check();
|
|
17502
|
+
} catch {
|
|
17503
|
+
console.error("Updated node does not conform to the schema");
|
|
17504
|
+
return false;
|
|
17505
|
+
}
|
|
17506
|
+
tr.replaceWith(posFrom, posTo, updatedNode);
|
|
17507
|
+
}
|
|
17508
|
+
return true;
|
|
17509
|
+
},
|
|
17510
|
+
/**
|
|
17511
|
+
* Removes a structured content.
|
|
17512
|
+
* @category Command
|
|
17513
|
+
* @param {Array<{ node: Node, pos: number }>} structuredContentTags
|
|
17514
|
+
*/
|
|
17515
|
+
deleteStructuredContent: (structuredContentTags) => ({ dispatch, tr }) => {
|
|
17516
|
+
if (!structuredContentTags.length) {
|
|
17517
|
+
return true;
|
|
17518
|
+
}
|
|
17519
|
+
if (dispatch) {
|
|
17520
|
+
structuredContentTags.forEach((structuredContent) => {
|
|
17521
|
+
const { pos, node } = structuredContent;
|
|
17522
|
+
const posFrom = tr.mapping.map(pos);
|
|
17523
|
+
const posTo = tr.mapping.map(pos + node.nodeSize);
|
|
17524
|
+
const currentNode = tr.doc.nodeAt(posFrom);
|
|
17525
|
+
if (currentNode && node.eq(currentNode)) {
|
|
17526
|
+
tr.delete(posFrom, posTo);
|
|
17527
|
+
}
|
|
17528
|
+
});
|
|
17529
|
+
}
|
|
17530
|
+
return true;
|
|
17531
|
+
},
|
|
17532
|
+
/**
|
|
17533
|
+
* Removes a structured content by ID.
|
|
17534
|
+
* @category Command
|
|
17535
|
+
* @param {string | string[]} idOrIds
|
|
17536
|
+
*/
|
|
17537
|
+
deleteStructuredContentById: (idOrIds) => ({ dispatch, state, tr }) => {
|
|
17538
|
+
const structuredContentTags = getStructuredContentTagsById(idOrIds, state);
|
|
17539
|
+
if (!structuredContentTags.length) {
|
|
17540
|
+
return true;
|
|
17541
|
+
}
|
|
17542
|
+
if (dispatch) {
|
|
17543
|
+
structuredContentTags.forEach((structuredContent) => {
|
|
17544
|
+
const { pos, node } = structuredContent;
|
|
17545
|
+
const posFrom = tr.mapping.map(pos);
|
|
17546
|
+
const posTo = tr.mapping.map(pos + node.nodeSize);
|
|
17547
|
+
const currentNode = tr.doc.nodeAt(posFrom);
|
|
17548
|
+
if (currentNode && node.eq(currentNode)) {
|
|
17549
|
+
tr.delete(posFrom, posTo);
|
|
17550
|
+
}
|
|
17551
|
+
});
|
|
17552
|
+
}
|
|
17553
|
+
return true;
|
|
17554
|
+
},
|
|
17555
|
+
/**
|
|
17556
|
+
* Removes a structured content at cursor, preserving its content.
|
|
17557
|
+
* @category Command
|
|
17558
|
+
*/
|
|
17559
|
+
deleteStructuredContentAtSelection: () => ({ dispatch, state, tr }) => {
|
|
17560
|
+
const predicate = (node) => STRUCTURED_CONTENT_NAMES.includes(node.type.name);
|
|
17561
|
+
const structuredContent = findParentNode(predicate)(state.selection);
|
|
17562
|
+
if (!structuredContent) {
|
|
17563
|
+
return true;
|
|
17564
|
+
}
|
|
17565
|
+
if (dispatch) {
|
|
17566
|
+
const { node, pos } = structuredContent;
|
|
17567
|
+
const posFrom = pos;
|
|
17568
|
+
const posTo = posFrom + node.nodeSize;
|
|
17569
|
+
const content = node.content;
|
|
17570
|
+
tr.replaceWith(posFrom, posTo, content);
|
|
17571
|
+
}
|
|
17572
|
+
return true;
|
|
17573
|
+
}
|
|
17574
|
+
};
|
|
17575
|
+
},
|
|
17576
|
+
addHelpers() {
|
|
17577
|
+
return {
|
|
17578
|
+
...structuredContentHelpers
|
|
17579
|
+
};
|
|
17580
|
+
}
|
|
17581
|
+
});
|
|
17582
|
+
class DocumentSectionView {
|
|
17583
|
+
constructor(node, getPos, decorations, editor) {
|
|
17584
|
+
__privateAdd(this, _DocumentSectionView_instances);
|
|
17585
|
+
this.node = node;
|
|
17586
|
+
this.editor = editor;
|
|
17587
|
+
this.decorations = decorations;
|
|
17588
|
+
this.view = editor.view;
|
|
17589
|
+
this.getPos = getPos;
|
|
17590
|
+
__privateMethod(this, _DocumentSectionView_instances, init_fn2).call(this);
|
|
17591
|
+
}
|
|
17592
|
+
}
|
|
17593
|
+
_DocumentSectionView_instances = new WeakSet();
|
|
17594
|
+
init_fn2 = function() {
|
|
17595
|
+
const { attrs } = this.node;
|
|
17596
|
+
const { id, title, description } = attrs;
|
|
17597
|
+
this.dom = document.createElement("div");
|
|
17598
|
+
this.dom.className = "sd-document-section-block";
|
|
17599
|
+
this.dom.setAttribute("data-id", id);
|
|
17600
|
+
this.dom.setAttribute("data-title", title);
|
|
17601
|
+
this.dom.setAttribute("data-description", description);
|
|
17602
|
+
this.dom.setAttribute("aria-label", "Document section");
|
|
17603
|
+
__privateMethod(this, _DocumentSectionView_instances, addToolTip_fn).call(this);
|
|
17604
|
+
this.contentDOM = document.createElement("div");
|
|
17605
|
+
this.contentDOM.className = "sd-document-section-block-content";
|
|
17606
|
+
this.contentDOM.setAttribute("contenteditable", "true");
|
|
17607
|
+
this.dom.appendChild(this.contentDOM);
|
|
17608
|
+
};
|
|
17609
|
+
addToolTip_fn = function() {
|
|
17610
|
+
const { title } = this.node.attrs;
|
|
17611
|
+
this.infoDiv = document.createElement("div");
|
|
17612
|
+
this.infoDiv.className = "sd-document-section-block-info";
|
|
17613
|
+
const textSpan = document.createElement("span");
|
|
17614
|
+
textSpan.textContent = title || "Document section";
|
|
17615
|
+
this.infoDiv.appendChild(textSpan);
|
|
17616
|
+
this.infoDiv.setAttribute("contenteditable", "false");
|
|
17617
|
+
this.dom.appendChild(this.infoDiv);
|
|
17618
|
+
};
|
|
17619
|
+
const getAllSections = (editor) => {
|
|
17620
|
+
if (!editor) return [];
|
|
17621
|
+
const type = editor.schema.nodes.documentSection;
|
|
17622
|
+
if (!type) return [];
|
|
17623
|
+
const sections = [];
|
|
17624
|
+
const { state } = editor;
|
|
17625
|
+
state.doc.descendants((node, pos) => {
|
|
17626
|
+
if (node.type.name === type.name) {
|
|
17627
|
+
sections.push({ node, pos });
|
|
17628
|
+
}
|
|
17629
|
+
});
|
|
17630
|
+
return sections;
|
|
17631
|
+
};
|
|
17632
|
+
const exportSectionsToHTML = (editor) => {
|
|
17633
|
+
const sections = getAllSections(editor);
|
|
17634
|
+
const processedSections = /* @__PURE__ */ new Set();
|
|
17635
|
+
const result = [];
|
|
17636
|
+
sections.forEach(({ node }) => {
|
|
17637
|
+
const { attrs } = node;
|
|
17638
|
+
const { id, title, description } = attrs;
|
|
17639
|
+
if (processedSections.has(id)) return;
|
|
17640
|
+
processedSections.add(id);
|
|
17641
|
+
const html = getHTMLFromNode(node, editor);
|
|
17642
|
+
result.push({
|
|
17643
|
+
id,
|
|
17644
|
+
title,
|
|
17645
|
+
description,
|
|
17646
|
+
html
|
|
17647
|
+
});
|
|
17648
|
+
});
|
|
17649
|
+
return result;
|
|
17650
|
+
};
|
|
17651
|
+
const getHTMLFromNode = (node, editor) => {
|
|
17652
|
+
const tempDocument = document.implementation.createHTMLDocument();
|
|
17653
|
+
const container = tempDocument.createElement("div");
|
|
17654
|
+
const fragment = DOMSerializer.fromSchema(editor.schema).serializeFragment(node.content);
|
|
17655
|
+
container.appendChild(fragment);
|
|
17656
|
+
let html = container.innerHTML;
|
|
17657
|
+
return html;
|
|
17658
|
+
};
|
|
17659
|
+
const exportSectionsToJSON = (editor) => {
|
|
17660
|
+
const sections = getAllSections(editor);
|
|
17661
|
+
const processedSections = /* @__PURE__ */ new Set();
|
|
17662
|
+
const result = [];
|
|
17663
|
+
sections.forEach(({ node }) => {
|
|
17664
|
+
const { attrs } = node;
|
|
17665
|
+
const { id, title, description } = attrs;
|
|
17666
|
+
if (processedSections.has(id)) return;
|
|
17667
|
+
processedSections.add(id);
|
|
17668
|
+
result.push({
|
|
17669
|
+
id,
|
|
17670
|
+
title,
|
|
17671
|
+
description,
|
|
17672
|
+
content: node.toJSON()
|
|
17673
|
+
});
|
|
17674
|
+
});
|
|
17675
|
+
return result;
|
|
17676
|
+
};
|
|
17677
|
+
const getLinkedSectionEditor = (id, options, editor) => {
|
|
17678
|
+
const sections = getAllSections(editor);
|
|
17679
|
+
const section = sections.find((s) => s.node.attrs.id === id);
|
|
17680
|
+
if (!section) return null;
|
|
17681
|
+
const child = editor.createChildEditor({
|
|
17682
|
+
...options,
|
|
17683
|
+
onUpdate: ({ editor: childEditor, transaction }) => {
|
|
17684
|
+
const isFromtLinkedParent = transaction.getMeta("fromLinkedParent");
|
|
17685
|
+
if (isFromtLinkedParent) return;
|
|
17686
|
+
const updatedContent = childEditor.state.doc.content;
|
|
17687
|
+
const sectionNode = getAllSections(editor)?.find((s) => s.node.attrs.id === id);
|
|
17688
|
+
if (!sectionNode) return;
|
|
17689
|
+
const { pos, node } = sectionNode;
|
|
17690
|
+
const newNode = node.type.create(node.attrs, updatedContent, node.marks);
|
|
17691
|
+
const tr = editor.state.tr.replaceWith(pos, pos + node.nodeSize, newNode);
|
|
17692
|
+
tr.setMeta("fromLinkedChild", true);
|
|
17693
|
+
editor.view.dispatch(tr);
|
|
17694
|
+
}
|
|
17695
|
+
});
|
|
17696
|
+
editor.on("update", ({ transaction }) => {
|
|
17697
|
+
const isFromLinkedChild = transaction.getMeta("fromLinkedChild");
|
|
17698
|
+
if (isFromLinkedChild) return;
|
|
17699
|
+
const sectionNode = getAllSections(editor)?.find((s) => s.node.attrs.id === id);
|
|
17700
|
+
if (!sectionNode) return;
|
|
17701
|
+
const sectionContent = sectionNode.node.content;
|
|
17702
|
+
const json = {
|
|
17703
|
+
type: "doc",
|
|
17704
|
+
content: sectionContent.content.map((node) => node.toJSON())
|
|
17705
|
+
};
|
|
17706
|
+
const childTr = child.state.tr;
|
|
17707
|
+
childTr.setMeta("fromLinkedParent", true);
|
|
17708
|
+
childTr.replaceWith(0, child.state.doc.content.size, child.schema.nodeFromJSON(json));
|
|
17709
|
+
child.view.dispatch(childTr);
|
|
17710
|
+
});
|
|
17711
|
+
return child;
|
|
17712
|
+
};
|
|
17713
|
+
const SectionHelpers = {
|
|
17714
|
+
getAllSections,
|
|
17715
|
+
exportSectionsToHTML,
|
|
17716
|
+
exportSectionsToJSON,
|
|
17717
|
+
getLinkedSectionEditor
|
|
17718
|
+
};
|
|
17719
|
+
const DocumentSection = Node$1.create({
|
|
17720
|
+
name: "documentSection",
|
|
17721
|
+
group: "block",
|
|
17722
|
+
content: "block*",
|
|
17723
|
+
atom: true,
|
|
17724
|
+
isolating: true,
|
|
17725
|
+
addOptions() {
|
|
17726
|
+
return {
|
|
17727
|
+
htmlAttributes: {
|
|
17728
|
+
class: "sd-document-section-block",
|
|
17729
|
+
"aria-label": "Structured content block"
|
|
17730
|
+
}
|
|
17731
|
+
};
|
|
17732
|
+
},
|
|
17733
|
+
parseDOM() {
|
|
17734
|
+
return [
|
|
17735
|
+
{
|
|
17736
|
+
tag: "div.sd-document-section-block",
|
|
17737
|
+
priority: 60
|
|
17738
|
+
}
|
|
17739
|
+
];
|
|
17740
|
+
},
|
|
17741
|
+
renderDOM({ htmlAttributes }) {
|
|
17742
|
+
return ["div", Attribute.mergeAttributes(this.options.htmlAttributes, htmlAttributes), 0];
|
|
17743
|
+
},
|
|
17744
|
+
addAttributes() {
|
|
17745
|
+
return {
|
|
17746
|
+
id: {},
|
|
17747
|
+
sdBlockId: {
|
|
17748
|
+
default: null,
|
|
17749
|
+
keepOnSplit: false,
|
|
17750
|
+
parseDOM: (elem) => elem.getAttribute("data-sd-block-id"),
|
|
17751
|
+
renderDOM: (attrs) => {
|
|
17752
|
+
return attrs.sdBlockId ? { "data-sd-block-id": attrs.sdBlockId } : {};
|
|
17753
|
+
}
|
|
17754
|
+
},
|
|
17755
|
+
title: {},
|
|
17756
|
+
description: {},
|
|
17757
|
+
sectionType: {},
|
|
17758
|
+
isLocked: { default: false }
|
|
17759
|
+
};
|
|
17760
|
+
},
|
|
17761
|
+
addNodeView() {
|
|
17762
|
+
return ({ node, editor, getPos, decorations }) => {
|
|
17763
|
+
return new DocumentSectionView(node, getPos, decorations, editor);
|
|
17764
|
+
};
|
|
17765
|
+
},
|
|
17766
|
+
addCommands() {
|
|
17767
|
+
return {
|
|
17768
|
+
/**
|
|
17769
|
+
* Create a lockable content section
|
|
17770
|
+
* @category Command
|
|
17771
|
+
* @param {SectionCreate} [options={}] - Section configuration
|
|
17772
|
+
* @example
|
|
17773
|
+
* editor.commands.createDocumentSection({
|
|
17774
|
+
* id: 1,
|
|
17775
|
+
* title: 'Terms & Conditions',
|
|
17776
|
+
* isLocked: true,
|
|
17777
|
+
* html: '<p>Legal content...</p>'
|
|
17778
|
+
* })
|
|
17779
|
+
*/
|
|
17780
|
+
createDocumentSection: (options = {}) => ({ tr, state, dispatch, editor }) => {
|
|
17781
|
+
const { selection } = state;
|
|
17782
|
+
let { from: from2, to } = selection;
|
|
17783
|
+
let content = selection.content().content;
|
|
17784
|
+
const { html: optionsHTML, json: optionsJSON } = options;
|
|
17785
|
+
if (optionsHTML) {
|
|
17786
|
+
const html = htmlHandler(optionsHTML, this.editor);
|
|
17787
|
+
const doc2 = DOMParser$1.fromSchema(this.editor.schema).parse(html);
|
|
17788
|
+
content = doc2.content;
|
|
17789
|
+
}
|
|
17790
|
+
if (optionsJSON) {
|
|
17791
|
+
content = this.editor.schema.nodeFromJSON(optionsJSON);
|
|
17792
|
+
}
|
|
17793
|
+
if (!content?.content?.length) {
|
|
17794
|
+
content = this.editor.schema.nodeFromJSON({ type: "paragraph", content: [] });
|
|
17795
|
+
}
|
|
17796
|
+
if (!options.id) {
|
|
17797
|
+
const allSections = SectionHelpers.getAllSections(editor);
|
|
17798
|
+
options.id = allSections.length + 1;
|
|
17799
|
+
}
|
|
17800
|
+
if (!options.title) {
|
|
17801
|
+
options.title = "Document section";
|
|
17802
|
+
}
|
|
17803
|
+
const node = this.type.createAndFill(options, content);
|
|
17804
|
+
if (!node) return false;
|
|
17805
|
+
const isAlreadyInSdtBlock = findParentNode((node2) => node2.type.name === "documentSection")(selection);
|
|
17806
|
+
if (isAlreadyInSdtBlock && isAlreadyInSdtBlock.node) {
|
|
17807
|
+
const insertPos2 = isAlreadyInSdtBlock.pos + isAlreadyInSdtBlock.node.nodeSize;
|
|
17808
|
+
from2 = insertPos2;
|
|
17809
|
+
to = insertPos2;
|
|
17810
|
+
}
|
|
17811
|
+
tr.replaceRangeWith(from2, to, node);
|
|
17812
|
+
const nodeEnd = from2 + node.nodeSize;
|
|
17813
|
+
let shouldInsertParagraph = true;
|
|
17814
|
+
let insertPos = nodeEnd;
|
|
17815
|
+
if (nodeEnd >= tr.doc.content.size) {
|
|
17816
|
+
insertPos = tr.doc.content.size;
|
|
17817
|
+
if (insertPos > 0) {
|
|
17818
|
+
const $endPos = tr.doc.resolve(insertPos);
|
|
17819
|
+
if ($endPos.nodeBefore && $endPos.nodeBefore.type.name === "paragraph") {
|
|
17820
|
+
shouldInsertParagraph = false;
|
|
17821
|
+
}
|
|
17822
|
+
}
|
|
17823
|
+
}
|
|
17824
|
+
if (shouldInsertParagraph) {
|
|
17825
|
+
const emptyParagraph = tr.doc.type.schema.nodes.paragraph.create();
|
|
17826
|
+
tr.insert(insertPos, emptyParagraph);
|
|
17827
|
+
}
|
|
17828
|
+
if (dispatch) {
|
|
17829
|
+
tr.setMeta("documentSection", { action: "create" });
|
|
17830
|
+
dispatch(tr);
|
|
17831
|
+
setTimeout(() => {
|
|
17832
|
+
try {
|
|
17833
|
+
const currentState = editor.state;
|
|
17834
|
+
const docSize = currentState.doc.content.size;
|
|
17835
|
+
let targetPos = from2 + node.nodeSize;
|
|
17836
|
+
if (shouldInsertParagraph) {
|
|
17837
|
+
targetPos += 1;
|
|
17838
|
+
}
|
|
17839
|
+
targetPos = Math.min(targetPos, docSize);
|
|
17840
|
+
if (targetPos < docSize && targetPos > 0) {
|
|
17841
|
+
const newSelection = Selection.near(currentState.doc.resolve(targetPos));
|
|
17842
|
+
const newTr = currentState.tr.setSelection(newSelection);
|
|
17843
|
+
editor.view.dispatch(newTr);
|
|
17844
|
+
}
|
|
17845
|
+
} catch (e) {
|
|
17846
|
+
console.warn("Could not set delayed selection:", e);
|
|
17847
|
+
}
|
|
17848
|
+
}, 0);
|
|
17849
|
+
}
|
|
17850
|
+
return true;
|
|
17851
|
+
},
|
|
17852
|
+
/**
|
|
17853
|
+
* Remove section wrapper at cursor, preserving its content
|
|
17854
|
+
* @category Command
|
|
17855
|
+
* @example
|
|
17856
|
+
* editor.commands.removeSectionAtSelection()
|
|
17857
|
+
* @note Content stays in document, only section wrapper is removed
|
|
17858
|
+
*/
|
|
17859
|
+
removeSectionAtSelection: () => ({ tr, dispatch }) => {
|
|
17860
|
+
const sdtNode = findParentNode((node2) => node2.type.name === "documentSection")(tr.selection);
|
|
17861
|
+
if (!sdtNode) return false;
|
|
17862
|
+
const { node, pos } = sdtNode;
|
|
17863
|
+
const nodeStart = pos;
|
|
17864
|
+
const nodeEnd = nodeStart + node.nodeSize;
|
|
17865
|
+
const contentToPreserve = node.content;
|
|
17866
|
+
tr.delete(nodeStart, nodeEnd);
|
|
17867
|
+
if (contentToPreserve.size > 0) {
|
|
17868
|
+
tr.insert(nodeStart, contentToPreserve);
|
|
17869
|
+
}
|
|
17870
|
+
const newPos = Math.min(nodeStart, tr.doc.content.size);
|
|
17871
|
+
tr.setSelection(Selection.near(tr.doc.resolve(newPos)));
|
|
17872
|
+
if (dispatch) {
|
|
17873
|
+
tr.setMeta("documentSection", { action: "delete" });
|
|
17874
|
+
dispatch(tr);
|
|
17875
|
+
}
|
|
17876
|
+
return true;
|
|
17877
|
+
},
|
|
17878
|
+
/**
|
|
17879
|
+
* Delete section and all its content
|
|
17880
|
+
* @category Command
|
|
17881
|
+
* @param {number} id - Section to delete
|
|
17882
|
+
* @example
|
|
17883
|
+
* editor.commands.removeSectionById(123)
|
|
17884
|
+
*/
|
|
17885
|
+
removeSectionById: (id) => ({ tr, dispatch }) => {
|
|
17886
|
+
const sections = SectionHelpers.getAllSections(this.editor);
|
|
17887
|
+
const sectionToRemove = sections.find(({ node: node2 }) => node2.attrs.id === id);
|
|
17888
|
+
if (!sectionToRemove) return false;
|
|
17889
|
+
const { pos, node } = sectionToRemove;
|
|
17890
|
+
const nodeStart = pos;
|
|
17891
|
+
const nodeEnd = nodeStart + node.nodeSize;
|
|
17892
|
+
tr.delete(nodeStart, nodeEnd);
|
|
17893
|
+
if (dispatch) {
|
|
17894
|
+
tr.setMeta("documentSection", { action: "delete", id });
|
|
17895
|
+
dispatch(tr);
|
|
17896
|
+
}
|
|
17897
|
+
return true;
|
|
17898
|
+
},
|
|
17899
|
+
/**
|
|
17900
|
+
* Lock section against edits
|
|
17901
|
+
* @category Command
|
|
17902
|
+
* @param {number} id - Section to lock
|
|
17903
|
+
* @example
|
|
17904
|
+
* editor.commands.lockSectionById(123)
|
|
17905
|
+
*/
|
|
17906
|
+
lockSectionById: (id) => ({ tr, dispatch }) => {
|
|
17907
|
+
const sections = SectionHelpers.getAllSections(this.editor);
|
|
17908
|
+
const sectionToLock = sections.find(({ node }) => node.attrs.id === id);
|
|
17909
|
+
if (!sectionToLock) return false;
|
|
17910
|
+
tr.setNodeMarkup(sectionToLock.pos, null, { ...sectionToLock.node.attrs, isLocked: true });
|
|
17911
|
+
if (dispatch) {
|
|
17912
|
+
tr.setMeta("documentSection", { action: "lock", id });
|
|
17913
|
+
dispatch(tr);
|
|
17914
|
+
}
|
|
17915
|
+
return true;
|
|
17916
|
+
},
|
|
17917
|
+
/**
|
|
17918
|
+
* Modify section attributes or content
|
|
17919
|
+
* @category Command
|
|
17920
|
+
* @param {SectionUpdate} options - Changes to apply
|
|
17921
|
+
* @example
|
|
17922
|
+
* editor.commands.updateSectionById({ id: 123, attrs: { isLocked: false } })
|
|
17923
|
+
* editor.commands.updateSectionById({ id: 123, html: '<p>New content</p>' })
|
|
17924
|
+
* editor.commands.updateSectionById({
|
|
17925
|
+
* id: 123,
|
|
17926
|
+
* html: '<p>Updated</p>',
|
|
17927
|
+
* attrs: { title: 'New Title' }
|
|
17928
|
+
* })
|
|
17929
|
+
*/
|
|
17930
|
+
updateSectionById: ({ id, html, json, attrs }) => ({ tr, dispatch, editor }) => {
|
|
17931
|
+
const sections = SectionHelpers.getAllSections(editor || this.editor);
|
|
17932
|
+
const sectionToUpdate = sections.find(({ node: node2 }) => node2.attrs.id === id);
|
|
17933
|
+
if (!sectionToUpdate) return false;
|
|
17934
|
+
const { pos, node } = sectionToUpdate;
|
|
17935
|
+
let newContent = null;
|
|
17936
|
+
if (html) {
|
|
17937
|
+
const htmlDoc = htmlHandler(html, editor || this.editor);
|
|
17938
|
+
const doc2 = DOMParser$1.fromSchema((editor || this.editor).schema).parse(htmlDoc);
|
|
17939
|
+
newContent = doc2.content;
|
|
17940
|
+
}
|
|
17941
|
+
if (json) {
|
|
17942
|
+
newContent = (editor || this.editor).schema.nodeFromJSON(json);
|
|
17943
|
+
}
|
|
17944
|
+
if (!newContent) {
|
|
17945
|
+
newContent = node.content;
|
|
17946
|
+
}
|
|
17947
|
+
const updatedNode = node.type.create({ ...node.attrs, ...attrs }, newContent, node.marks);
|
|
17948
|
+
tr.replaceWith(pos, pos + node.nodeSize, updatedNode);
|
|
17949
|
+
if (dispatch) {
|
|
17950
|
+
tr.setMeta("documentSection", { action: "update", id, attrs });
|
|
17951
|
+
dispatch(tr);
|
|
17952
|
+
}
|
|
17953
|
+
return true;
|
|
17954
|
+
}
|
|
17955
|
+
};
|
|
17956
|
+
},
|
|
17957
|
+
addHelpers() {
|
|
17958
|
+
return {
|
|
17959
|
+
...SectionHelpers
|
|
17960
|
+
};
|
|
17961
|
+
}
|
|
17962
|
+
});
|
|
17963
|
+
const DocumentPartObject = Node$1.create({
|
|
17964
|
+
name: "documentPartObject",
|
|
17965
|
+
group: "block",
|
|
17966
|
+
content: "block*",
|
|
17967
|
+
isolating: true,
|
|
17968
|
+
addOptions() {
|
|
17969
|
+
return {
|
|
17970
|
+
htmlAttributes: {
|
|
17971
|
+
class: "sd-document-part-object-block",
|
|
17972
|
+
"aria-label": "Structured document part block"
|
|
17973
|
+
}
|
|
17974
|
+
};
|
|
17975
|
+
},
|
|
17976
|
+
parseDOM() {
|
|
17977
|
+
return [
|
|
17978
|
+
{
|
|
17979
|
+
tag: "div.sd-document-part-object-block",
|
|
17980
|
+
priority: 60
|
|
17981
|
+
}
|
|
17982
|
+
];
|
|
17983
|
+
},
|
|
17984
|
+
renderDOM({ htmlAttributes }) {
|
|
17985
|
+
return ["div", Attribute.mergeAttributes(this.options.htmlAttributes, htmlAttributes), 0];
|
|
17986
|
+
},
|
|
17987
|
+
addAttributes() {
|
|
17988
|
+
return {
|
|
17989
|
+
sdBlockId: {
|
|
17990
|
+
default: null,
|
|
17991
|
+
keepOnSplit: false,
|
|
17992
|
+
parseDOM: (elem) => elem.getAttribute("data-sd-block-id"),
|
|
17993
|
+
renderDOM: (attrs) => {
|
|
17994
|
+
return attrs.sdBlockId ? { "data-sd-block-id": attrs.sdBlockId } : {};
|
|
17995
|
+
}
|
|
17996
|
+
},
|
|
17997
|
+
id: {},
|
|
17998
|
+
docPartGallery: {},
|
|
17999
|
+
docPartUnique: {
|
|
18000
|
+
default: true
|
|
18001
|
+
}
|
|
18002
|
+
};
|
|
18003
|
+
}
|
|
18004
|
+
});
|
|
18005
|
+
const Document = Node$1.create({
|
|
18006
|
+
name: "doc",
|
|
18007
|
+
topNode: true,
|
|
18008
|
+
content: "block+",
|
|
18009
|
+
parseDOM() {
|
|
18010
|
+
return [{ tag: "doc" }];
|
|
18011
|
+
},
|
|
18012
|
+
renderDOM() {
|
|
18013
|
+
return ["doc", 0];
|
|
18014
|
+
},
|
|
18015
|
+
addAttributes() {
|
|
18016
|
+
return {
|
|
18017
|
+
attributes: {
|
|
18018
|
+
rendered: false,
|
|
18019
|
+
"aria-label": "Document node"
|
|
18020
|
+
}
|
|
18021
|
+
};
|
|
18022
|
+
},
|
|
18023
|
+
addCommands() {
|
|
18024
|
+
return {
|
|
18025
|
+
/**
|
|
18026
|
+
* Get document statistics
|
|
18027
|
+
* @category Command
|
|
18028
|
+
* @example
|
|
18029
|
+
* // Get word and character count
|
|
18030
|
+
* const stats = editor.commands.getDocumentStats()
|
|
18031
|
+
* console.log(`${stats.words} words, ${stats.characters} characters`)
|
|
18032
|
+
* @note Returns word count, character count, and paragraph count
|
|
18033
|
+
*/
|
|
18034
|
+
getDocumentStats: () => ({ editor }) => {
|
|
18035
|
+
const text = editor.getText();
|
|
18036
|
+
const words = text.split(/\s+/).filter((word) => word.length > 0).length;
|
|
18037
|
+
const characters = text.length;
|
|
18038
|
+
const paragraphs = editor.state.doc.content.childCount;
|
|
18039
|
+
return {
|
|
18040
|
+
words,
|
|
18041
|
+
characters,
|
|
18042
|
+
paragraphs
|
|
18043
|
+
};
|
|
18044
|
+
},
|
|
18045
|
+
/**
|
|
18046
|
+
* Clear entire document
|
|
18047
|
+
* @category Command
|
|
18048
|
+
* @example
|
|
18049
|
+
* editor.commands.clearDocument()
|
|
18050
|
+
* @note Replaces all content with an empty paragraph
|
|
18051
|
+
*/
|
|
18052
|
+
clearDocument: () => ({ commands: commands2 }) => {
|
|
18053
|
+
return commands2.setContent("<p></p>");
|
|
18054
|
+
}
|
|
18055
|
+
};
|
|
18056
|
+
}
|
|
18057
|
+
});
|
|
18058
|
+
const Text = Node$1.create({
|
|
18059
|
+
name: "text",
|
|
18060
|
+
group: "inline",
|
|
18061
|
+
inline: true,
|
|
18062
|
+
addOptions() {
|
|
18063
|
+
return {};
|
|
18064
|
+
}
|
|
18065
|
+
});
|
|
18066
|
+
const splitRun = () => (props) => {
|
|
18067
|
+
const { state, view, tr } = props;
|
|
18068
|
+
const { $from, empty: empty2 } = state.selection;
|
|
18069
|
+
if (!empty2) return false;
|
|
18070
|
+
if ($from.parent.type.name !== "run") return false;
|
|
18071
|
+
const handled = splitBlock(state, (transaction) => {
|
|
18072
|
+
view.dispatch(transaction);
|
|
18073
|
+
});
|
|
18074
|
+
if (handled) {
|
|
18075
|
+
tr.setMeta("preventDispatch", true);
|
|
18076
|
+
}
|
|
18077
|
+
return handled;
|
|
18078
|
+
};
|
|
18079
|
+
const Run = OxmlNode.create({
|
|
18080
|
+
name: "run",
|
|
18081
|
+
oXmlName: "w:r",
|
|
18082
|
+
group: "inline",
|
|
18083
|
+
inline: true,
|
|
18084
|
+
content: "inline*",
|
|
18085
|
+
selectable: false,
|
|
18086
|
+
childToAttributes: ["runProperties"],
|
|
18087
|
+
addOptions() {
|
|
18088
|
+
return {
|
|
18089
|
+
htmlAttributes: {
|
|
18090
|
+
"data-run": "1"
|
|
18091
|
+
}
|
|
18092
|
+
};
|
|
18093
|
+
},
|
|
18094
|
+
addAttributes() {
|
|
18095
|
+
return {
|
|
18096
|
+
runProperties: {
|
|
18097
|
+
default: null,
|
|
18098
|
+
rendered: false,
|
|
18099
|
+
keepOnSplit: true
|
|
18100
|
+
},
|
|
18101
|
+
rsidR: {
|
|
18102
|
+
default: null,
|
|
18103
|
+
rendered: false,
|
|
18104
|
+
keepOnSplit: true
|
|
18105
|
+
},
|
|
18106
|
+
rsidRPr: {
|
|
18107
|
+
default: null,
|
|
18108
|
+
rendered: false,
|
|
18109
|
+
keepOnSplit: true
|
|
18110
|
+
},
|
|
18111
|
+
rsidDel: {
|
|
18112
|
+
default: null,
|
|
18113
|
+
rendered: false,
|
|
18114
|
+
keepOnSplit: true
|
|
18115
|
+
}
|
|
18116
|
+
};
|
|
18117
|
+
},
|
|
18118
|
+
addCommands() {
|
|
18119
|
+
return {
|
|
18120
|
+
splitRun
|
|
18121
|
+
};
|
|
18122
|
+
},
|
|
18123
|
+
parseDOM() {
|
|
18124
|
+
return [{ tag: "span[data-run]" }];
|
|
18125
|
+
},
|
|
18126
|
+
renderDOM({ htmlAttributes }) {
|
|
18127
|
+
const base2 = Attribute.mergeAttributes(this.options.htmlAttributes, htmlAttributes);
|
|
18128
|
+
return ["span", base2, 0];
|
|
18129
|
+
}
|
|
18130
|
+
});
|
|
18131
|
+
const inputRegex$1 = /^\s*([-+*])\s$/;
|
|
18132
|
+
const BulletList = Node$1.create({
|
|
18133
|
+
name: "bulletList",
|
|
18134
|
+
group: "block list",
|
|
18135
|
+
selectable: false,
|
|
18136
|
+
content() {
|
|
18137
|
+
return `${this.options.itemTypeName}+`;
|
|
18138
|
+
},
|
|
18139
|
+
addOptions() {
|
|
18140
|
+
return {
|
|
18141
|
+
itemTypeName: "listItem",
|
|
18142
|
+
htmlAttributes: {
|
|
18143
|
+
"aria-label": "Bullet list node"
|
|
18144
|
+
},
|
|
18145
|
+
keepMarks: true,
|
|
18146
|
+
keepAttributes: false
|
|
18147
|
+
};
|
|
18148
|
+
},
|
|
18149
|
+
parseDOM() {
|
|
18150
|
+
return [{ tag: "ul" }];
|
|
18151
|
+
},
|
|
18152
|
+
renderDOM({ htmlAttributes }) {
|
|
18153
|
+
const attributes = Attribute.mergeAttributes(this.options.htmlAttributes, htmlAttributes);
|
|
18154
|
+
return ["ul", attributes, 0];
|
|
18155
|
+
},
|
|
18156
|
+
addAttributes() {
|
|
18157
|
+
return {
|
|
18158
|
+
"list-style-type": {
|
|
18159
|
+
default: "bullet",
|
|
18160
|
+
rendered: false
|
|
18161
|
+
},
|
|
18162
|
+
listId: {
|
|
18163
|
+
rendered: false
|
|
18164
|
+
},
|
|
18165
|
+
sdBlockId: {
|
|
18166
|
+
default: null,
|
|
18167
|
+
keepOnSplit: false,
|
|
18168
|
+
parseDOM: (elem) => elem.getAttribute("data-sd-block-id"),
|
|
18169
|
+
renderDOM: (attrs) => {
|
|
18170
|
+
return attrs.sdBlockId ? { "data-sd-block-id": attrs.sdBlockId } : {};
|
|
18171
|
+
}
|
|
18172
|
+
},
|
|
18173
|
+
attributes: {
|
|
18174
|
+
rendered: false,
|
|
18175
|
+
keepOnSplit: true
|
|
18176
|
+
}
|
|
18177
|
+
};
|
|
18178
|
+
},
|
|
18179
|
+
addCommands() {
|
|
18180
|
+
return {
|
|
18181
|
+
/**
|
|
18182
|
+
* Toggle a bullet list at the current selection
|
|
18183
|
+
* @category Command
|
|
18184
|
+
* @example
|
|
18185
|
+
* // Toggle bullet list on selected text
|
|
18186
|
+
* editor.commands.toggleBulletList()
|
|
18187
|
+
* @note Converts selected paragraphs to list items or removes list formatting
|
|
18188
|
+
*/
|
|
18189
|
+
toggleBulletList: () => (params2) => {
|
|
18190
|
+
return toggleList(this.type)(params2);
|
|
18191
|
+
}
|
|
18192
|
+
};
|
|
18193
|
+
},
|
|
18194
|
+
addShortcuts() {
|
|
18195
|
+
return {
|
|
18196
|
+
"Mod-Shift-8": () => {
|
|
18197
|
+
return this.editor.commands.toggleBulletList();
|
|
18198
|
+
}
|
|
18199
|
+
};
|
|
18200
|
+
},
|
|
18201
|
+
addInputRules() {
|
|
18202
|
+
return [
|
|
18203
|
+
new InputRule({
|
|
18204
|
+
match: inputRegex$1,
|
|
18205
|
+
handler: ({ state, range }) => {
|
|
18206
|
+
const $pos = state.selection.$from;
|
|
18207
|
+
const listItemType = state.schema.nodes.listItem;
|
|
18208
|
+
for (let depth = $pos.depth; depth >= 0; depth--) {
|
|
18209
|
+
if ($pos.node(depth).type === listItemType) {
|
|
18210
|
+
return null;
|
|
18211
|
+
}
|
|
18212
|
+
}
|
|
18213
|
+
const { tr } = state;
|
|
18214
|
+
tr.delete(range.from, range.to);
|
|
18215
|
+
ListHelpers.createNewList({
|
|
18216
|
+
listType: this.type,
|
|
18217
|
+
tr,
|
|
18218
|
+
editor: this.editor
|
|
18219
|
+
});
|
|
17191
18220
|
}
|
|
17192
18221
|
})
|
|
17193
18222
|
];
|
|
@@ -17480,15 +18509,31 @@ const intToJapaneseCounting = (num) => {
|
|
|
17480
18509
|
}
|
|
17481
18510
|
return result;
|
|
17482
18511
|
};
|
|
17483
|
-
const
|
|
17484
|
-
|
|
18512
|
+
const isKeyboardInvocation = (event) => {
|
|
18513
|
+
return event.type === "contextmenu" && typeof event.detail === "number" && event.detail === 0 && (event.button === 0 || event.button === void 0) && event.clientX === 0 && event.clientY === 0;
|
|
18514
|
+
};
|
|
18515
|
+
const prefersNativeMenu = (event) => {
|
|
17485
18516
|
if (!event) return false;
|
|
17486
18517
|
if (event.ctrlKey || event.metaKey) {
|
|
17487
18518
|
return true;
|
|
17488
18519
|
}
|
|
17489
|
-
|
|
17490
|
-
return Boolean(isKeyboardInvocation);
|
|
18520
|
+
return isKeyboardInvocation(event);
|
|
17491
18521
|
};
|
|
18522
|
+
const shouldAllowNativeContextMenu = (event) => {
|
|
18523
|
+
return prefersNativeMenu(event);
|
|
18524
|
+
};
|
|
18525
|
+
const shouldBypassContextMenu = shouldAllowNativeContextMenu;
|
|
18526
|
+
const DEFAULT_SELECTION_STATE = Object.freeze({
|
|
18527
|
+
focused: false,
|
|
18528
|
+
preservedSelection: null,
|
|
18529
|
+
showVisualSelection: false,
|
|
18530
|
+
skipFocusReset: false
|
|
18531
|
+
});
|
|
18532
|
+
const normalizeSelectionState = (state = {}) => ({
|
|
18533
|
+
...DEFAULT_SELECTION_STATE,
|
|
18534
|
+
...state
|
|
18535
|
+
});
|
|
18536
|
+
const CustomSelectionPluginKey = new PluginKey("CustomSelection");
|
|
17492
18537
|
const handleClickOutside = (event, editor) => {
|
|
17493
18538
|
const editorElem = editor?.options?.element;
|
|
17494
18539
|
if (!editorElem) return;
|
|
@@ -17525,11 +18570,7 @@ const CustomSelection = Extension.create({
|
|
|
17525
18570
|
const customSelectionPlugin = new Plugin({
|
|
17526
18571
|
key: CustomSelectionPluginKey,
|
|
17527
18572
|
state: {
|
|
17528
|
-
init: () => ({
|
|
17529
|
-
focused: false,
|
|
17530
|
-
preservedSelection: null,
|
|
17531
|
-
showVisualSelection: false
|
|
17532
|
-
}),
|
|
18573
|
+
init: () => ({ ...DEFAULT_SELECTION_STATE }),
|
|
17533
18574
|
apply: (tr, value) => {
|
|
17534
18575
|
const meta = getFocusMeta(tr);
|
|
17535
18576
|
if (meta !== void 0) {
|
|
@@ -17560,7 +18601,8 @@ const CustomSelection = Extension.create({
|
|
|
17560
18601
|
setFocusMeta(view.state.tr, {
|
|
17561
18602
|
focused: true,
|
|
17562
18603
|
preservedSelection: selection,
|
|
17563
|
-
showVisualSelection: true
|
|
18604
|
+
showVisualSelection: true,
|
|
18605
|
+
skipFocusReset: true
|
|
17564
18606
|
})
|
|
17565
18607
|
);
|
|
17566
18608
|
}
|
|
@@ -17581,7 +18623,8 @@ const CustomSelection = Extension.create({
|
|
|
17581
18623
|
setFocusMeta(view.state.tr, {
|
|
17582
18624
|
focused: true,
|
|
17583
18625
|
preservedSelection: selection2,
|
|
17584
|
-
showVisualSelection: true
|
|
18626
|
+
showVisualSelection: true,
|
|
18627
|
+
skipFocusReset: true
|
|
17585
18628
|
})
|
|
17586
18629
|
);
|
|
17587
18630
|
this.editor.setOptions({
|
|
@@ -17604,7 +18647,8 @@ const CustomSelection = Extension.create({
|
|
|
17604
18647
|
setFocusMeta(view.state.tr, {
|
|
17605
18648
|
focused: true,
|
|
17606
18649
|
preservedSelection: selection,
|
|
17607
|
-
showVisualSelection: true
|
|
18650
|
+
showVisualSelection: true,
|
|
18651
|
+
skipFocusReset: false
|
|
17608
18652
|
})
|
|
17609
18653
|
);
|
|
17610
18654
|
this.editor.setOptions({
|
|
@@ -17622,7 +18666,8 @@ const CustomSelection = Extension.create({
|
|
|
17622
18666
|
setFocusMeta(view.state.tr, {
|
|
17623
18667
|
focused: true,
|
|
17624
18668
|
preservedSelection: selection,
|
|
17625
|
-
showVisualSelection: true
|
|
18669
|
+
showVisualSelection: true,
|
|
18670
|
+
skipFocusReset: false
|
|
17626
18671
|
})
|
|
17627
18672
|
);
|
|
17628
18673
|
}
|
|
@@ -17633,7 +18678,8 @@ const CustomSelection = Extension.create({
|
|
|
17633
18678
|
setFocusMeta(view.state.tr, {
|
|
17634
18679
|
focused: false,
|
|
17635
18680
|
preservedSelection: null,
|
|
17636
|
-
showVisualSelection: false
|
|
18681
|
+
showVisualSelection: false,
|
|
18682
|
+
skipFocusReset: false
|
|
17637
18683
|
})
|
|
17638
18684
|
);
|
|
17639
18685
|
if (!selection.empty && !this.editor.options.element?.contains(target)) {
|
|
@@ -17650,12 +18696,20 @@ const CustomSelection = Extension.create({
|
|
|
17650
18696
|
const isElement2 = target instanceof Element;
|
|
17651
18697
|
const isToolbarBtn = isElement2 && isToolbarButton(target);
|
|
17652
18698
|
const isToolbarInp = isElement2 && isToolbarInput(target);
|
|
18699
|
+
const focusState = getFocusState(view.state);
|
|
18700
|
+
if (focusState?.skipFocusReset) {
|
|
18701
|
+
view.dispatch(
|
|
18702
|
+
setFocusMeta(view.state.tr, normalizeSelectionState({ ...focusState, skipFocusReset: false }))
|
|
18703
|
+
);
|
|
18704
|
+
return false;
|
|
18705
|
+
}
|
|
17653
18706
|
if (!isToolbarBtn && !isToolbarInp) {
|
|
17654
18707
|
view.dispatch(
|
|
17655
18708
|
setFocusMeta(view.state.tr, {
|
|
17656
18709
|
focused: false,
|
|
17657
18710
|
preservedSelection: null,
|
|
17658
|
-
showVisualSelection: false
|
|
18711
|
+
showVisualSelection: false,
|
|
18712
|
+
skipFocusReset: false
|
|
17659
18713
|
})
|
|
17660
18714
|
);
|
|
17661
18715
|
}
|
|
@@ -17666,12 +18720,16 @@ const CustomSelection = Extension.create({
|
|
|
17666
18720
|
const isToolbarBtn = isElement2 && isToolbarButton(target);
|
|
17667
18721
|
const isToolbarInp = isElement2 && isToolbarInput(target);
|
|
17668
18722
|
const state = getFocusState(view.state);
|
|
18723
|
+
if (state?.skipFocusReset) {
|
|
18724
|
+
return false;
|
|
18725
|
+
}
|
|
17669
18726
|
if (isToolbarBtn || isToolbarInp) {
|
|
17670
18727
|
view.dispatch(
|
|
17671
18728
|
setFocusMeta(view.state.tr, {
|
|
17672
18729
|
focused: true,
|
|
17673
18730
|
preservedSelection: state.preservedSelection || view.state.selection,
|
|
17674
|
-
showVisualSelection: true
|
|
18731
|
+
showVisualSelection: true,
|
|
18732
|
+
skipFocusReset: false
|
|
17675
18733
|
})
|
|
17676
18734
|
);
|
|
17677
18735
|
} else {
|
|
@@ -17679,7 +18737,8 @@ const CustomSelection = Extension.create({
|
|
|
17679
18737
|
setFocusMeta(view.state.tr, {
|
|
17680
18738
|
focused: false,
|
|
17681
18739
|
preservedSelection: null,
|
|
17682
|
-
showVisualSelection: false
|
|
18740
|
+
showVisualSelection: false,
|
|
18741
|
+
skipFocusReset: false
|
|
17683
18742
|
})
|
|
17684
18743
|
);
|
|
17685
18744
|
}
|
|
@@ -18079,7 +19138,12 @@ const generateDecorations = (state, styles) => {
|
|
|
18079
19138
|
return { ...base2, ...linkedStyle.definition?.styles || {} };
|
|
18080
19139
|
};
|
|
18081
19140
|
const pMap = buildStyleMap(paragraphStyleId);
|
|
18082
|
-
|
|
19141
|
+
let tMap;
|
|
19142
|
+
if (paragraphStyleId?.startsWith("TOC")) {
|
|
19143
|
+
tMap = {};
|
|
19144
|
+
} else {
|
|
19145
|
+
tMap = buildStyleMap(inlineTextStyleId);
|
|
19146
|
+
}
|
|
18083
19147
|
const rMap = buildStyleMap(runStyleId);
|
|
18084
19148
|
const finalStyles = { ...pMap, ...tMap, ...rMap };
|
|
18085
19149
|
if (Object.keys(finalStyles).length === 0) return;
|
|
@@ -18525,7 +19589,7 @@ class ListItemNodeView {
|
|
|
18525
19589
|
this.decorations = decorations;
|
|
18526
19590
|
this.view = editor.view;
|
|
18527
19591
|
this.getPos = getPos;
|
|
18528
|
-
__privateMethod(this, _ListItemNodeView_instances,
|
|
19592
|
+
__privateMethod(this, _ListItemNodeView_instances, init_fn3).call(this);
|
|
18529
19593
|
activeListItemNodeViews.add(this);
|
|
18530
19594
|
}
|
|
18531
19595
|
refreshIndentStyling() {
|
|
@@ -18586,7 +19650,7 @@ class ListItemNodeView {
|
|
|
18586
19650
|
}
|
|
18587
19651
|
}
|
|
18588
19652
|
_ListItemNodeView_instances = new WeakSet();
|
|
18589
|
-
|
|
19653
|
+
init_fn3 = function() {
|
|
18590
19654
|
const { attrs } = this.node;
|
|
18591
19655
|
const { listLevel, listNumberingType, lvlText, numId, level, customFormat } = attrs;
|
|
18592
19656
|
let orderMarker = "";
|
|
@@ -19376,7 +20440,7 @@ const CommentsMark = Mark.create({
|
|
|
19376
20440
|
});
|
|
19377
20441
|
const defaultTabDistance = 48;
|
|
19378
20442
|
const defaultLineLength = 816;
|
|
19379
|
-
const getTabDecorations = (doc2, view, from2 = 0, to = null) => {
|
|
20443
|
+
const getTabDecorations = (doc2, view, helpers2, from2 = 0, to = null) => {
|
|
19380
20444
|
const decorations = [];
|
|
19381
20445
|
const paragraphCache = /* @__PURE__ */ new Map();
|
|
19382
20446
|
const end2 = to ?? doc2.content.size;
|
|
@@ -19384,7 +20448,7 @@ const getTabDecorations = (doc2, view, from2 = 0, to = null) => {
|
|
|
19384
20448
|
if (node.type.name !== "tab") return;
|
|
19385
20449
|
let extraStyles = "";
|
|
19386
20450
|
const $pos = doc2.resolve(pos);
|
|
19387
|
-
const paragraphContext = getParagraphContext($pos, paragraphCache);
|
|
20451
|
+
const paragraphContext = getParagraphContext($pos, paragraphCache, helpers2);
|
|
19388
20452
|
if (!paragraphContext) return;
|
|
19389
20453
|
try {
|
|
19390
20454
|
const { tabStops, flattened, startPos } = paragraphContext;
|
|
@@ -19439,18 +20503,27 @@ const getTabDecorations = (doc2, view, from2 = 0, to = null) => {
|
|
|
19439
20503
|
});
|
|
19440
20504
|
return decorations;
|
|
19441
20505
|
};
|
|
19442
|
-
function getParagraphContext($pos, cache) {
|
|
20506
|
+
function getParagraphContext($pos, cache, helpers2) {
|
|
19443
20507
|
for (let depth = $pos.depth; depth >= 0; depth--) {
|
|
19444
20508
|
const node = $pos.node(depth);
|
|
19445
20509
|
if (node?.type?.name === "paragraph") {
|
|
19446
20510
|
const startPos = $pos.start(depth);
|
|
19447
20511
|
if (!cache.has(startPos)) {
|
|
20512
|
+
let tabStops = [];
|
|
20513
|
+
if (Array.isArray(node.attrs?.tabStops)) {
|
|
20514
|
+
tabStops = node.attrs.tabStops;
|
|
20515
|
+
} else {
|
|
20516
|
+
const style = helpers2.linkedStyles.getStyleById(node.attrs?.styleId);
|
|
20517
|
+
if (Array.isArray(style?.definition?.styles?.tabStops)) {
|
|
20518
|
+
tabStops = style.definition.styles.tabStops;
|
|
20519
|
+
}
|
|
20520
|
+
}
|
|
19448
20521
|
cache.set(startPos, {
|
|
19449
20522
|
paragraph: node,
|
|
19450
20523
|
paragraphDepth: depth,
|
|
19451
20524
|
startPos,
|
|
19452
20525
|
indent: node.attrs?.indent || {},
|
|
19453
|
-
tabStops
|
|
20526
|
+
tabStops,
|
|
19454
20527
|
flattened: flattenParagraph(node, startPos),
|
|
19455
20528
|
accumulatedTabWidth: 0
|
|
19456
20529
|
});
|
|
@@ -19616,7 +20689,7 @@ const TabNode = Node$1.create({
|
|
|
19616
20689
|
};
|
|
19617
20690
|
},
|
|
19618
20691
|
addPmPlugins() {
|
|
19619
|
-
const { view } = this.editor;
|
|
20692
|
+
const { view, helpers: helpers2 } = this.editor;
|
|
19620
20693
|
const tabPlugin = new Plugin({
|
|
19621
20694
|
name: "tabPlugin",
|
|
19622
20695
|
key: new PluginKey("tabPlugin"),
|
|
@@ -19626,7 +20699,7 @@ const TabNode = Node$1.create({
|
|
|
19626
20699
|
},
|
|
19627
20700
|
apply(tr, { decorations }, _oldState, newState) {
|
|
19628
20701
|
if (!decorations) {
|
|
19629
|
-
decorations = DecorationSet.create(newState.doc, getTabDecorations(newState.doc, view));
|
|
20702
|
+
decorations = DecorationSet.create(newState.doc, getTabDecorations(newState.doc, view, helpers2));
|
|
19630
20703
|
}
|
|
19631
20704
|
if (!tr.docChanged) {
|
|
19632
20705
|
return { decorations };
|
|
@@ -19666,7 +20739,7 @@ const TabNode = Node$1.create({
|
|
|
19666
20739
|
rangesToRecalculate.forEach(([start2, end2]) => {
|
|
19667
20740
|
const oldDecorations = decorations.find(start2, end2);
|
|
19668
20741
|
decorations = decorations.remove(oldDecorations);
|
|
19669
|
-
const newDecorations = getTabDecorations(newState.doc, view, start2, end2);
|
|
20742
|
+
const newDecorations = getTabDecorations(newState.doc, view, helpers2, start2, end2);
|
|
19670
20743
|
decorations = decorations.add(newState.doc, newDecorations);
|
|
19671
20744
|
});
|
|
19672
20745
|
return { decorations };
|
|
@@ -25947,83 +27020,66 @@ const processMarks = (marks) => {
|
|
|
25947
27020
|
});
|
|
25948
27021
|
return styles;
|
|
25949
27022
|
};
|
|
25950
|
-
const
|
|
25951
|
-
name: "
|
|
25952
|
-
group: "
|
|
25953
|
-
|
|
25954
|
-
|
|
27023
|
+
const PageReference = Node$1.create({
|
|
27024
|
+
name: "pageReference",
|
|
27025
|
+
group: "inline",
|
|
27026
|
+
inline: true,
|
|
27027
|
+
atom: true,
|
|
27028
|
+
draggable: false,
|
|
27029
|
+
selectable: false,
|
|
27030
|
+
content: "inline*",
|
|
25955
27031
|
addOptions() {
|
|
25956
27032
|
return {
|
|
25957
27033
|
htmlAttributes: {
|
|
25958
|
-
|
|
25959
|
-
"
|
|
27034
|
+
contenteditable: false,
|
|
27035
|
+
"data-id": "auto-page-reference",
|
|
27036
|
+
"aria-label": "Page reference node",
|
|
27037
|
+
class: "sd-editor-page-reference"
|
|
25960
27038
|
}
|
|
25961
27039
|
};
|
|
25962
27040
|
},
|
|
25963
27041
|
addAttributes() {
|
|
25964
27042
|
return {
|
|
25965
|
-
|
|
25966
|
-
renderDOM: (attrs) => {
|
|
25967
|
-
if (!attrs.fillcolor) return {};
|
|
25968
|
-
return {
|
|
25969
|
-
style: `background-color: ${attrs.fillcolor}`
|
|
25970
|
-
};
|
|
25971
|
-
}
|
|
25972
|
-
},
|
|
25973
|
-
sdBlockId: {
|
|
27043
|
+
marksAsAttrs: {
|
|
25974
27044
|
default: null,
|
|
25975
|
-
keepOnSplit: false,
|
|
25976
|
-
parseDOM: (elem) => elem.getAttribute("data-sd-block-id"),
|
|
25977
|
-
renderDOM: (attrs) => {
|
|
25978
|
-
return attrs.sdBlockId ? { "data-sd-block-id": attrs.sdBlockId } : {};
|
|
25979
|
-
}
|
|
25980
|
-
},
|
|
25981
|
-
style: {
|
|
25982
|
-
renderDOM: (attrs) => {
|
|
25983
|
-
if (!attrs.style) return {};
|
|
25984
|
-
return {
|
|
25985
|
-
style: attrs.style
|
|
25986
|
-
};
|
|
25987
|
-
}
|
|
25988
|
-
},
|
|
25989
|
-
wrapAttributes: {
|
|
25990
27045
|
rendered: false
|
|
25991
27046
|
},
|
|
25992
|
-
|
|
27047
|
+
instruction: {
|
|
27048
|
+
default: "",
|
|
25993
27049
|
rendered: false
|
|
25994
27050
|
}
|
|
25995
27051
|
};
|
|
25996
27052
|
},
|
|
25997
27053
|
parseDOM() {
|
|
25998
|
-
return [
|
|
25999
|
-
{
|
|
26000
|
-
tag: `div[data-type="${this.name}"]`
|
|
26001
|
-
}
|
|
26002
|
-
];
|
|
27054
|
+
return [{ tag: 'span[data-id="auto-page-reference"]' }];
|
|
26003
27055
|
},
|
|
26004
27056
|
renderDOM({ htmlAttributes }) {
|
|
26005
|
-
return [
|
|
26006
|
-
"div",
|
|
26007
|
-
Attribute.mergeAttributes(this.options.htmlAttributes, htmlAttributes, { "data-type": this.name }),
|
|
26008
|
-
0
|
|
26009
|
-
];
|
|
27057
|
+
return ["span", Attribute.mergeAttributes(this.options.htmlAttributes, htmlAttributes), 0];
|
|
26010
27058
|
}
|
|
26011
27059
|
});
|
|
26012
|
-
const
|
|
26013
|
-
name: "
|
|
27060
|
+
const ShapeContainer = Node$1.create({
|
|
27061
|
+
name: "shapeContainer",
|
|
26014
27062
|
group: "block",
|
|
26015
|
-
content: "
|
|
27063
|
+
content: "block+",
|
|
26016
27064
|
isolating: true,
|
|
26017
27065
|
addOptions() {
|
|
26018
27066
|
return {
|
|
26019
27067
|
htmlAttributes: {
|
|
26020
|
-
class: "sd-editor-shape-
|
|
26021
|
-
"aria-label": "Shape
|
|
27068
|
+
class: "sd-editor-shape-container",
|
|
27069
|
+
"aria-label": "Shape container node"
|
|
26022
27070
|
}
|
|
26023
27071
|
};
|
|
26024
27072
|
},
|
|
26025
27073
|
addAttributes() {
|
|
26026
27074
|
return {
|
|
27075
|
+
fillcolor: {
|
|
27076
|
+
renderDOM: (attrs) => {
|
|
27077
|
+
if (!attrs.fillcolor) return {};
|
|
27078
|
+
return {
|
|
27079
|
+
style: `background-color: ${attrs.fillcolor}`
|
|
27080
|
+
};
|
|
27081
|
+
}
|
|
27082
|
+
},
|
|
26027
27083
|
sdBlockId: {
|
|
26028
27084
|
default: null,
|
|
26029
27085
|
keepOnSplit: false,
|
|
@@ -26032,72 +27088,15 @@ const ShapeTextbox = Node$1.create({
|
|
|
26032
27088
|
return attrs.sdBlockId ? { "data-sd-block-id": attrs.sdBlockId } : {};
|
|
26033
27089
|
}
|
|
26034
27090
|
},
|
|
26035
|
-
|
|
26036
|
-
rendered: false
|
|
26037
|
-
}
|
|
26038
|
-
};
|
|
26039
|
-
},
|
|
26040
|
-
parseDOM() {
|
|
26041
|
-
return [
|
|
26042
|
-
{
|
|
26043
|
-
tag: `div[data-type="${this.name}"]`
|
|
26044
|
-
}
|
|
26045
|
-
];
|
|
26046
|
-
},
|
|
26047
|
-
renderDOM({ htmlAttributes }) {
|
|
26048
|
-
return [
|
|
26049
|
-
"div",
|
|
26050
|
-
Attribute.mergeAttributes(this.options.htmlAttributes, htmlAttributes, { "data-type": this.name }),
|
|
26051
|
-
0
|
|
26052
|
-
];
|
|
26053
|
-
}
|
|
26054
|
-
});
|
|
26055
|
-
const ContentBlock = Node$1.create({
|
|
26056
|
-
name: "contentBlock",
|
|
26057
|
-
group: "inline",
|
|
26058
|
-
content: "",
|
|
26059
|
-
isolating: true,
|
|
26060
|
-
atom: true,
|
|
26061
|
-
inline: true,
|
|
26062
|
-
addOptions() {
|
|
26063
|
-
return {
|
|
26064
|
-
htmlAttributes: {
|
|
26065
|
-
contenteditable: false
|
|
26066
|
-
}
|
|
26067
|
-
};
|
|
26068
|
-
},
|
|
26069
|
-
addAttributes() {
|
|
26070
|
-
return {
|
|
26071
|
-
horizontalRule: {
|
|
26072
|
-
default: false,
|
|
26073
|
-
renderDOM: ({ horizontalRule }) => {
|
|
26074
|
-
if (!horizontalRule) return {};
|
|
26075
|
-
return { "data-horizontal-rule": "true" };
|
|
26076
|
-
}
|
|
26077
|
-
},
|
|
26078
|
-
size: {
|
|
26079
|
-
default: null,
|
|
26080
|
-
renderDOM: ({ size }) => {
|
|
26081
|
-
if (!size) return {};
|
|
26082
|
-
let style = "";
|
|
26083
|
-
if (size.top) style += `top: ${size.top}px; `;
|
|
26084
|
-
if (size.left) style += `left: ${size.left}px; `;
|
|
26085
|
-
if (size.width) style += `width: ${size.width.toString().endsWith("%") ? size.width : `${size.width}px`}; `;
|
|
26086
|
-
if (size.height)
|
|
26087
|
-
style += `height: ${size.height.toString().endsWith("%") ? size.height : `${size.height}px`}; `;
|
|
26088
|
-
return { style };
|
|
26089
|
-
}
|
|
26090
|
-
},
|
|
26091
|
-
background: {
|
|
26092
|
-
default: null,
|
|
27091
|
+
style: {
|
|
26093
27092
|
renderDOM: (attrs) => {
|
|
26094
|
-
if (!attrs.
|
|
27093
|
+
if (!attrs.style) return {};
|
|
26095
27094
|
return {
|
|
26096
|
-
style:
|
|
27095
|
+
style: attrs.style
|
|
26097
27096
|
};
|
|
26098
27097
|
}
|
|
26099
27098
|
},
|
|
26100
|
-
|
|
27099
|
+
wrapAttributes: {
|
|
26101
27100
|
rendered: false
|
|
26102
27101
|
},
|
|
26103
27102
|
attributes: {
|
|
@@ -26107,786 +27106,167 @@ const ContentBlock = Node$1.create({
|
|
|
26107
27106
|
},
|
|
26108
27107
|
parseDOM() {
|
|
26109
27108
|
return [
|
|
26110
|
-
{
|
|
26111
|
-
tag: `div[data-type="${this.name}"]`
|
|
26112
|
-
}
|
|
26113
|
-
];
|
|
26114
|
-
},
|
|
26115
|
-
renderDOM({ htmlAttributes }) {
|
|
26116
|
-
return [
|
|
26117
|
-
|
|
26118
|
-
|
|
26119
|
-
|
|
26120
|
-
|
|
26121
|
-
* Insert a horizontal rule
|
|
26122
|
-
* @category Command
|
|
26123
|
-
* @example
|
|
26124
|
-
* editor.commands.insertHorizontalRule()
|
|
26125
|
-
* @note Creates a visual separator between content sections
|
|
26126
|
-
*/
|
|
26127
|
-
insertHorizontalRule: () => ({ commands: commands2 }) => {
|
|
26128
|
-
return commands2.insertContent({
|
|
26129
|
-
type: this.name,
|
|
26130
|
-
attrs: {
|
|
26131
|
-
horizontalRule: true,
|
|
26132
|
-
size: { width: "100%", height: 2 },
|
|
26133
|
-
background: "#e5e7eb"
|
|
26134
|
-
}
|
|
26135
|
-
});
|
|
26136
|
-
},
|
|
26137
|
-
/**
|
|
26138
|
-
* Insert a content block
|
|
26139
|
-
* @category Command
|
|
26140
|
-
* @param {ContentBlockConfig} config - Block configuration
|
|
26141
|
-
* @example
|
|
26142
|
-
* // Insert a spacer block
|
|
26143
|
-
* editor.commands.insertContentBlock({ size: { height: 20 } })
|
|
26144
|
-
*
|
|
26145
|
-
* @example
|
|
26146
|
-
* // Insert a colored divider
|
|
26147
|
-
* editor.commands.insertContentBlock({
|
|
26148
|
-
* size: { width: '50%', height: 3 },
|
|
26149
|
-
* background: '#3b82f6'
|
|
26150
|
-
* })
|
|
26151
|
-
* @note Used for spacing, dividers, and special inline content
|
|
26152
|
-
*/
|
|
26153
|
-
insertContentBlock: (config) => ({ commands: commands2 }) => {
|
|
26154
|
-
return commands2.insertContent({
|
|
26155
|
-
type: this.name,
|
|
26156
|
-
attrs: config
|
|
26157
|
-
});
|
|
26158
|
-
}
|
|
26159
|
-
};
|
|
26160
|
-
}
|
|
26161
|
-
});
|
|
26162
|
-
class StructuredContentViewBase {
|
|
26163
|
-
constructor(props) {
|
|
26164
|
-
__publicField(this, "node");
|
|
26165
|
-
__publicField(this, "view");
|
|
26166
|
-
__publicField(this, "getPos");
|
|
26167
|
-
__publicField(this, "decorations");
|
|
26168
|
-
__publicField(this, "innerDecorations");
|
|
26169
|
-
__publicField(this, "editor");
|
|
26170
|
-
__publicField(this, "extension");
|
|
26171
|
-
__publicField(this, "htmlAttributes");
|
|
26172
|
-
__publicField(this, "root");
|
|
26173
|
-
__publicField(this, "isDragging", false);
|
|
26174
|
-
this.node = props.node;
|
|
26175
|
-
this.view = props.editor.view;
|
|
26176
|
-
this.getPos = props.getPos;
|
|
26177
|
-
this.decorations = props.decorations;
|
|
26178
|
-
this.innerDecorations = props.innerDecorations;
|
|
26179
|
-
this.editor = props.editor;
|
|
26180
|
-
this.extension = props.extension;
|
|
26181
|
-
this.htmlAttributes = props.htmlAttributes;
|
|
26182
|
-
this.mount(props);
|
|
26183
|
-
}
|
|
26184
|
-
mount() {
|
|
26185
|
-
return;
|
|
26186
|
-
}
|
|
26187
|
-
get dom() {
|
|
26188
|
-
return this.root;
|
|
26189
|
-
}
|
|
26190
|
-
get contentDOM() {
|
|
26191
|
-
return null;
|
|
26192
|
-
}
|
|
26193
|
-
update(node, decorations, innerDecorations) {
|
|
26194
|
-
if (node.type !== this.node.type) {
|
|
26195
|
-
return false;
|
|
26196
|
-
}
|
|
26197
|
-
this.node = node;
|
|
26198
|
-
this.decorations = decorations;
|
|
26199
|
-
this.innerDecorations = innerDecorations;
|
|
26200
|
-
this.updateHTMLAttributes();
|
|
26201
|
-
return true;
|
|
26202
|
-
}
|
|
26203
|
-
stopEvent(event) {
|
|
26204
|
-
if (!this.dom) return false;
|
|
26205
|
-
const target = event.target;
|
|
26206
|
-
const isInElement = this.dom.contains(target) && !this.contentDOM?.contains(target);
|
|
26207
|
-
if (!isInElement) return false;
|
|
26208
|
-
const isDragEvent = event.type.startsWith("drag");
|
|
26209
|
-
const isDropEvent = event.type === "drop";
|
|
26210
|
-
const isInput = ["INPUT", "BUTTON", "SELECT", "TEXTAREA"].includes(target.tagName) || target.isContentEditable;
|
|
26211
|
-
if (isInput && !isDropEvent && !isDragEvent) return true;
|
|
26212
|
-
const { isEditable } = this.editor;
|
|
26213
|
-
const { isDragging } = this;
|
|
26214
|
-
const isDraggable = !!this.node.type.spec.draggable;
|
|
26215
|
-
const isSelectable = NodeSelection.isSelectable(this.node);
|
|
26216
|
-
const isCopyEvent = event.type === "copy";
|
|
26217
|
-
const isPasteEvent = event.type === "paste";
|
|
26218
|
-
const isCutEvent = event.type === "cut";
|
|
26219
|
-
const isClickEvent = event.type === "mousedown";
|
|
26220
|
-
if (!isDraggable && isSelectable && isDragEvent && event.target === this.dom) {
|
|
26221
|
-
event.preventDefault();
|
|
26222
|
-
}
|
|
26223
|
-
if (isDraggable && isDragEvent && !isDragging && event.target === this.dom) {
|
|
26224
|
-
event.preventDefault();
|
|
26225
|
-
return false;
|
|
26226
|
-
}
|
|
26227
|
-
if (isDraggable && isEditable && !isDragging && isClickEvent) {
|
|
26228
|
-
const dragHandle = target.closest("[data-drag-handle]");
|
|
26229
|
-
const isValidDragHandle = dragHandle && (this.dom === dragHandle || this.dom.contains(dragHandle));
|
|
26230
|
-
if (isValidDragHandle) {
|
|
26231
|
-
this.isDragging = true;
|
|
26232
|
-
document.addEventListener(
|
|
26233
|
-
"dragend",
|
|
26234
|
-
() => {
|
|
26235
|
-
this.isDragging = false;
|
|
26236
|
-
},
|
|
26237
|
-
{ once: true }
|
|
26238
|
-
);
|
|
26239
|
-
document.addEventListener(
|
|
26240
|
-
"drop",
|
|
26241
|
-
() => {
|
|
26242
|
-
this.isDragging = false;
|
|
26243
|
-
},
|
|
26244
|
-
{ once: true }
|
|
26245
|
-
);
|
|
26246
|
-
document.addEventListener(
|
|
26247
|
-
"mouseup",
|
|
26248
|
-
() => {
|
|
26249
|
-
this.isDragging = false;
|
|
26250
|
-
},
|
|
26251
|
-
{ once: true }
|
|
26252
|
-
);
|
|
26253
|
-
}
|
|
26254
|
-
}
|
|
26255
|
-
if (isDragging || isDropEvent || isCopyEvent || isPasteEvent || isCutEvent || isClickEvent && isSelectable) {
|
|
26256
|
-
return false;
|
|
26257
|
-
}
|
|
26258
|
-
return true;
|
|
26259
|
-
}
|
|
26260
|
-
ignoreMutation(mutation) {
|
|
26261
|
-
if (!this.dom || !this.contentDOM) return true;
|
|
26262
|
-
if (this.node.isLeaf || this.node.isAtom) return true;
|
|
26263
|
-
if (mutation.type === "selection") return false;
|
|
26264
|
-
if (this.contentDOM === mutation.target && mutation.type === "attributes") return true;
|
|
26265
|
-
if (this.contentDOM.contains(mutation.target)) return false;
|
|
26266
|
-
return true;
|
|
26267
|
-
}
|
|
26268
|
-
destroy() {
|
|
26269
|
-
this.dom.remove();
|
|
26270
|
-
this.contentDOM?.remove();
|
|
26271
|
-
}
|
|
26272
|
-
updateAttributes(attrs) {
|
|
26273
|
-
const pos = this.getPos();
|
|
26274
|
-
if (typeof pos !== "number") {
|
|
26275
|
-
return;
|
|
26276
|
-
}
|
|
26277
|
-
return this.view.dispatch(
|
|
26278
|
-
this.view.state.tr.setNodeMarkup(pos, void 0, {
|
|
26279
|
-
...this.node.attrs,
|
|
26280
|
-
...attrs
|
|
26281
|
-
})
|
|
26282
|
-
);
|
|
26283
|
-
}
|
|
26284
|
-
updateHTMLAttributes() {
|
|
26285
|
-
const { extensionService } = this.editor;
|
|
26286
|
-
const { attributes } = extensionService;
|
|
26287
|
-
const extensionAttrs = attributes.filter((i) => i.type === this.node.type.name);
|
|
26288
|
-
this.htmlAttributes = Attribute.getAttributesToRender(this.node, extensionAttrs);
|
|
26289
|
-
}
|
|
26290
|
-
createDragHandle() {
|
|
26291
|
-
const dragHandle = document.createElement("span");
|
|
26292
|
-
dragHandle.classList.add("sd-structured-content-draggable");
|
|
26293
|
-
dragHandle.draggable = true;
|
|
26294
|
-
dragHandle.contentEditable = "false";
|
|
26295
|
-
dragHandle.dataset.dragHandle = "";
|
|
26296
|
-
const textElement = document.createElement("span");
|
|
26297
|
-
textElement.textContent = "Structured content";
|
|
26298
|
-
dragHandle.append(textElement);
|
|
26299
|
-
return dragHandle;
|
|
26300
|
-
}
|
|
26301
|
-
onDragStart(event) {
|
|
26302
|
-
const { view } = this.editor;
|
|
26303
|
-
const target = event.target;
|
|
26304
|
-
const dragHandle = target.nodeType === 3 ? target.parentElement?.closest("[data-drag-handle]") : target.closest("[data-drag-handle]");
|
|
26305
|
-
if (!this.dom || this.contentDOM?.contains(target) || !dragHandle) {
|
|
26306
|
-
return;
|
|
26307
|
-
}
|
|
26308
|
-
let x = 0;
|
|
26309
|
-
let y = 0;
|
|
26310
|
-
if (this.dom !== dragHandle) {
|
|
26311
|
-
const domBox = this.dom.getBoundingClientRect();
|
|
26312
|
-
const handleBox = dragHandle.getBoundingClientRect();
|
|
26313
|
-
const offsetX = event.offsetX ?? event.nativeEvent?.offsetX;
|
|
26314
|
-
const offsetY = event.offsetY ?? event.nativeEvent?.offsetY;
|
|
26315
|
-
x = handleBox.x - domBox.x + offsetX;
|
|
26316
|
-
y = handleBox.y - domBox.y + offsetY;
|
|
26317
|
-
}
|
|
26318
|
-
event.dataTransfer?.setDragImage(this.dom, x, y);
|
|
26319
|
-
const pos = this.getPos();
|
|
26320
|
-
if (typeof pos !== "number") {
|
|
26321
|
-
return;
|
|
26322
|
-
}
|
|
26323
|
-
const selection = NodeSelection.create(view.state.doc, pos);
|
|
26324
|
-
const transaction = view.state.tr.setSelection(selection);
|
|
26325
|
-
view.dispatch(transaction);
|
|
26326
|
-
}
|
|
26327
|
-
}
|
|
26328
|
-
class StructuredContentInlineView extends StructuredContentViewBase {
|
|
26329
|
-
constructor(props) {
|
|
26330
|
-
super(props);
|
|
26331
|
-
}
|
|
26332
|
-
mount() {
|
|
26333
|
-
this.buildView();
|
|
26334
|
-
}
|
|
26335
|
-
get contentDOM() {
|
|
26336
|
-
const contentElement = this.dom?.querySelector(`.${structuredContentInnerClass$1}`);
|
|
26337
|
-
return contentElement || null;
|
|
26338
|
-
}
|
|
26339
|
-
createElement() {
|
|
26340
|
-
const element = document.createElement("span");
|
|
26341
|
-
element.classList.add(structuredContentClass$1);
|
|
26342
|
-
element.setAttribute("data-structured-content", "");
|
|
26343
|
-
const contentElement = document.createElement("span");
|
|
26344
|
-
contentElement.classList.add(structuredContentInnerClass$1);
|
|
26345
|
-
element.append(contentElement);
|
|
26346
|
-
const domAttrs = Attribute.mergeAttributes(this.htmlAttributes);
|
|
26347
|
-
updateDOMAttributes(element, { ...domAttrs });
|
|
26348
|
-
return { element, contentElement };
|
|
26349
|
-
}
|
|
26350
|
-
buildView() {
|
|
26351
|
-
const { element } = this.createElement();
|
|
26352
|
-
const dragHandle = this.createDragHandle();
|
|
26353
|
-
element.prepend(dragHandle);
|
|
26354
|
-
element.addEventListener("dragstart", (e) => this.onDragStart(e));
|
|
26355
|
-
this.root = element;
|
|
26356
|
-
}
|
|
26357
|
-
updateView() {
|
|
26358
|
-
const domAttrs = Attribute.mergeAttributes(this.htmlAttributes);
|
|
26359
|
-
updateDOMAttributes(this.dom, { ...domAttrs });
|
|
26360
|
-
}
|
|
26361
|
-
update(node, decorations, innerDecorations) {
|
|
26362
|
-
const result = super.update(node, decorations, innerDecorations);
|
|
26363
|
-
if (!result) return false;
|
|
26364
|
-
this.updateView();
|
|
26365
|
-
return true;
|
|
26366
|
-
}
|
|
26367
|
-
}
|
|
26368
|
-
const structuredContentClass$1 = "sd-structured-content";
|
|
26369
|
-
const structuredContentInnerClass$1 = "sd-structured-content__content";
|
|
26370
|
-
const StructuredContent = Node$1.create({
|
|
26371
|
-
name: "structuredContent",
|
|
26372
|
-
group: "inline structuredContent",
|
|
26373
|
-
inline: true,
|
|
26374
|
-
content: "inline*",
|
|
26375
|
-
isolating: true,
|
|
26376
|
-
atom: false,
|
|
26377
|
-
// false - has editable content.
|
|
26378
|
-
draggable: true,
|
|
26379
|
-
addOptions() {
|
|
26380
|
-
return {
|
|
26381
|
-
htmlAttributes: {
|
|
26382
|
-
class: structuredContentClass$1,
|
|
26383
|
-
"aria-label": "Structured content node"
|
|
26384
|
-
}
|
|
26385
|
-
};
|
|
26386
|
-
},
|
|
26387
|
-
addAttributes() {
|
|
26388
|
-
return {
|
|
26389
|
-
id: {
|
|
26390
|
-
default: null,
|
|
26391
|
-
parseDOM: (elem) => elem.getAttribute("data-id"),
|
|
26392
|
-
renderDOM: (attrs) => {
|
|
26393
|
-
if (!attrs.id) return {};
|
|
26394
|
-
return { "data-id": attrs.id };
|
|
26395
|
-
}
|
|
26396
|
-
},
|
|
26397
|
-
sdtPr: {
|
|
26398
|
-
rendered: false
|
|
26399
|
-
}
|
|
26400
|
-
};
|
|
26401
|
-
},
|
|
26402
|
-
parseDOM() {
|
|
26403
|
-
return [{ tag: "span[data-structured-content]" }];
|
|
26404
|
-
},
|
|
26405
|
-
renderDOM({ htmlAttributes }) {
|
|
26406
|
-
return [
|
|
26407
|
-
"span",
|
|
26408
|
-
Attribute.mergeAttributes(this.options.htmlAttributes, htmlAttributes, {
|
|
26409
|
-
"data-structured-content": ""
|
|
26410
|
-
}),
|
|
26411
|
-
0
|
|
26412
|
-
];
|
|
26413
|
-
},
|
|
26414
|
-
addNodeView() {
|
|
26415
|
-
return (props) => {
|
|
26416
|
-
return new StructuredContentInlineView({ ...props });
|
|
26417
|
-
};
|
|
26418
|
-
}
|
|
26419
|
-
});
|
|
26420
|
-
class StructuredContentBlockView extends StructuredContentViewBase {
|
|
26421
|
-
constructor(props) {
|
|
26422
|
-
super(props);
|
|
26423
|
-
}
|
|
26424
|
-
mount() {
|
|
26425
|
-
this.buildView();
|
|
26426
|
-
}
|
|
26427
|
-
get contentDOM() {
|
|
26428
|
-
const contentElement = this.dom?.querySelector(`.${structuredContentInnerClass}`);
|
|
26429
|
-
return contentElement || null;
|
|
26430
|
-
}
|
|
26431
|
-
createElement() {
|
|
26432
|
-
const element = document.createElement("div");
|
|
26433
|
-
element.classList.add(structuredContentClass);
|
|
26434
|
-
element.setAttribute("data-structured-content-block", "");
|
|
26435
|
-
const contentElement = document.createElement("div");
|
|
26436
|
-
contentElement.classList.add(structuredContentInnerClass);
|
|
26437
|
-
element.append(contentElement);
|
|
26438
|
-
const domAttrs = Attribute.mergeAttributes(this.htmlAttributes);
|
|
26439
|
-
updateDOMAttributes(element, { ...domAttrs });
|
|
26440
|
-
return { element, contentElement };
|
|
26441
|
-
}
|
|
26442
|
-
buildView() {
|
|
26443
|
-
const { element } = this.createElement();
|
|
26444
|
-
const dragHandle = this.createDragHandle();
|
|
26445
|
-
element.prepend(dragHandle);
|
|
26446
|
-
element.addEventListener("dragstart", (e) => this.onDragStart(e));
|
|
26447
|
-
this.root = element;
|
|
26448
|
-
}
|
|
26449
|
-
updateView() {
|
|
26450
|
-
const domAttrs = Attribute.mergeAttributes(this.htmlAttributes);
|
|
26451
|
-
updateDOMAttributes(this.dom, { ...domAttrs });
|
|
26452
|
-
}
|
|
26453
|
-
update(node, decorations, innerDecorations) {
|
|
26454
|
-
const result = super.update(node, decorations, innerDecorations);
|
|
26455
|
-
if (!result) return false;
|
|
26456
|
-
this.updateView();
|
|
26457
|
-
return true;
|
|
27109
|
+
{
|
|
27110
|
+
tag: `div[data-type="${this.name}"]`
|
|
27111
|
+
}
|
|
27112
|
+
];
|
|
27113
|
+
},
|
|
27114
|
+
renderDOM({ htmlAttributes }) {
|
|
27115
|
+
return [
|
|
27116
|
+
"div",
|
|
27117
|
+
Attribute.mergeAttributes(this.options.htmlAttributes, htmlAttributes, { "data-type": this.name }),
|
|
27118
|
+
0
|
|
27119
|
+
];
|
|
26458
27120
|
}
|
|
26459
|
-
}
|
|
26460
|
-
const
|
|
26461
|
-
|
|
26462
|
-
|
|
26463
|
-
|
|
26464
|
-
group: "block structuredContent",
|
|
26465
|
-
content: "block*",
|
|
27121
|
+
});
|
|
27122
|
+
const ShapeTextbox = Node$1.create({
|
|
27123
|
+
name: "shapeTextbox",
|
|
27124
|
+
group: "block",
|
|
27125
|
+
content: "paragraph* block*",
|
|
26466
27126
|
isolating: true,
|
|
26467
|
-
atom: false,
|
|
26468
|
-
// false - has editable content.
|
|
26469
|
-
draggable: true,
|
|
26470
27127
|
addOptions() {
|
|
26471
27128
|
return {
|
|
26472
27129
|
htmlAttributes: {
|
|
26473
|
-
class:
|
|
26474
|
-
"aria-label": "
|
|
27130
|
+
class: "sd-editor-shape-textbox",
|
|
27131
|
+
"aria-label": "Shape textbox node"
|
|
26475
27132
|
}
|
|
26476
27133
|
};
|
|
26477
27134
|
},
|
|
26478
27135
|
addAttributes() {
|
|
26479
27136
|
return {
|
|
26480
|
-
|
|
27137
|
+
sdBlockId: {
|
|
26481
27138
|
default: null,
|
|
26482
|
-
|
|
27139
|
+
keepOnSplit: false,
|
|
27140
|
+
parseDOM: (elem) => elem.getAttribute("data-sd-block-id"),
|
|
26483
27141
|
renderDOM: (attrs) => {
|
|
26484
|
-
|
|
26485
|
-
return { "data-id": attrs.id };
|
|
27142
|
+
return attrs.sdBlockId ? { "data-sd-block-id": attrs.sdBlockId } : {};
|
|
26486
27143
|
}
|
|
26487
27144
|
},
|
|
26488
|
-
|
|
27145
|
+
attributes: {
|
|
26489
27146
|
rendered: false
|
|
26490
27147
|
}
|
|
26491
27148
|
};
|
|
26492
27149
|
},
|
|
26493
27150
|
parseDOM() {
|
|
26494
|
-
return [
|
|
27151
|
+
return [
|
|
27152
|
+
{
|
|
27153
|
+
tag: `div[data-type="${this.name}"]`
|
|
27154
|
+
}
|
|
27155
|
+
];
|
|
26495
27156
|
},
|
|
26496
27157
|
renderDOM({ htmlAttributes }) {
|
|
26497
27158
|
return [
|
|
26498
27159
|
"div",
|
|
26499
|
-
Attribute.mergeAttributes(this.options.htmlAttributes, htmlAttributes, {
|
|
26500
|
-
"data-structured-content-block": ""
|
|
26501
|
-
}),
|
|
27160
|
+
Attribute.mergeAttributes(this.options.htmlAttributes, htmlAttributes, { "data-type": this.name }),
|
|
26502
27161
|
0
|
|
26503
27162
|
];
|
|
26504
|
-
},
|
|
26505
|
-
addNodeView() {
|
|
26506
|
-
return (props) => {
|
|
26507
|
-
return new StructuredContentBlockView({ ...props });
|
|
26508
|
-
};
|
|
26509
27163
|
}
|
|
26510
27164
|
});
|
|
26511
|
-
|
|
26512
|
-
|
|
26513
|
-
|
|
26514
|
-
|
|
26515
|
-
this.editor = editor;
|
|
26516
|
-
this.decorations = decorations;
|
|
26517
|
-
this.view = editor.view;
|
|
26518
|
-
this.getPos = getPos;
|
|
26519
|
-
__privateMethod(this, _DocumentSectionView_instances, init_fn3).call(this);
|
|
26520
|
-
}
|
|
26521
|
-
}
|
|
26522
|
-
_DocumentSectionView_instances = new WeakSet();
|
|
26523
|
-
init_fn3 = function() {
|
|
26524
|
-
const { attrs } = this.node;
|
|
26525
|
-
const { id, title, description } = attrs;
|
|
26526
|
-
this.dom = document.createElement("div");
|
|
26527
|
-
this.dom.className = "sd-document-section-block";
|
|
26528
|
-
this.dom.setAttribute("data-id", id);
|
|
26529
|
-
this.dom.setAttribute("data-title", title);
|
|
26530
|
-
this.dom.setAttribute("data-description", description);
|
|
26531
|
-
this.dom.setAttribute("aria-label", "Document section");
|
|
26532
|
-
__privateMethod(this, _DocumentSectionView_instances, addToolTip_fn).call(this);
|
|
26533
|
-
this.contentDOM = document.createElement("div");
|
|
26534
|
-
this.contentDOM.className = "sd-document-section-block-content";
|
|
26535
|
-
this.contentDOM.setAttribute("contenteditable", "true");
|
|
26536
|
-
this.dom.appendChild(this.contentDOM);
|
|
26537
|
-
};
|
|
26538
|
-
addToolTip_fn = function() {
|
|
26539
|
-
const { title } = this.node.attrs;
|
|
26540
|
-
this.infoDiv = document.createElement("div");
|
|
26541
|
-
this.infoDiv.className = "sd-document-section-block-info";
|
|
26542
|
-
const textSpan = document.createElement("span");
|
|
26543
|
-
textSpan.textContent = title || "Document section";
|
|
26544
|
-
this.infoDiv.appendChild(textSpan);
|
|
26545
|
-
this.infoDiv.setAttribute("contenteditable", "false");
|
|
26546
|
-
this.dom.appendChild(this.infoDiv);
|
|
26547
|
-
};
|
|
26548
|
-
const getAllSections = (editor) => {
|
|
26549
|
-
if (!editor) return [];
|
|
26550
|
-
const type = editor.schema.nodes.documentSection;
|
|
26551
|
-
if (!type) return [];
|
|
26552
|
-
const sections = [];
|
|
26553
|
-
const { state } = editor;
|
|
26554
|
-
state.doc.descendants((node, pos) => {
|
|
26555
|
-
if (node.type.name === type.name) {
|
|
26556
|
-
sections.push({ node, pos });
|
|
26557
|
-
}
|
|
26558
|
-
});
|
|
26559
|
-
return sections;
|
|
26560
|
-
};
|
|
26561
|
-
const exportSectionsToHTML = (editor) => {
|
|
26562
|
-
const sections = getAllSections(editor);
|
|
26563
|
-
const processedSections = /* @__PURE__ */ new Set();
|
|
26564
|
-
const result = [];
|
|
26565
|
-
sections.forEach(({ node }) => {
|
|
26566
|
-
const { attrs } = node;
|
|
26567
|
-
const { id, title, description } = attrs;
|
|
26568
|
-
if (processedSections.has(id)) return;
|
|
26569
|
-
processedSections.add(id);
|
|
26570
|
-
const html = getHTMLFromNode(node, editor);
|
|
26571
|
-
result.push({
|
|
26572
|
-
id,
|
|
26573
|
-
title,
|
|
26574
|
-
description,
|
|
26575
|
-
html
|
|
26576
|
-
});
|
|
26577
|
-
});
|
|
26578
|
-
return result;
|
|
26579
|
-
};
|
|
26580
|
-
const getHTMLFromNode = (node, editor) => {
|
|
26581
|
-
const tempDocument = document.implementation.createHTMLDocument();
|
|
26582
|
-
const container = tempDocument.createElement("div");
|
|
26583
|
-
const fragment = DOMSerializer.fromSchema(editor.schema).serializeFragment(node.content);
|
|
26584
|
-
container.appendChild(fragment);
|
|
26585
|
-
let html = container.innerHTML;
|
|
26586
|
-
return html;
|
|
26587
|
-
};
|
|
26588
|
-
const exportSectionsToJSON = (editor) => {
|
|
26589
|
-
const sections = getAllSections(editor);
|
|
26590
|
-
const processedSections = /* @__PURE__ */ new Set();
|
|
26591
|
-
const result = [];
|
|
26592
|
-
sections.forEach(({ node }) => {
|
|
26593
|
-
const { attrs } = node;
|
|
26594
|
-
const { id, title, description } = attrs;
|
|
26595
|
-
if (processedSections.has(id)) return;
|
|
26596
|
-
processedSections.add(id);
|
|
26597
|
-
result.push({
|
|
26598
|
-
id,
|
|
26599
|
-
title,
|
|
26600
|
-
description,
|
|
26601
|
-
content: node.toJSON()
|
|
26602
|
-
});
|
|
26603
|
-
});
|
|
26604
|
-
return result;
|
|
26605
|
-
};
|
|
26606
|
-
const getLinkedSectionEditor = (id, options, editor) => {
|
|
26607
|
-
const sections = getAllSections(editor);
|
|
26608
|
-
const section = sections.find((s) => s.node.attrs.id === id);
|
|
26609
|
-
if (!section) return null;
|
|
26610
|
-
const child = editor.createChildEditor({
|
|
26611
|
-
...options,
|
|
26612
|
-
onUpdate: ({ editor: childEditor, transaction }) => {
|
|
26613
|
-
const isFromtLinkedParent = transaction.getMeta("fromLinkedParent");
|
|
26614
|
-
if (isFromtLinkedParent) return;
|
|
26615
|
-
const updatedContent = childEditor.state.doc.content;
|
|
26616
|
-
const sectionNode = getAllSections(editor)?.find((s) => s.node.attrs.id === id);
|
|
26617
|
-
if (!sectionNode) return;
|
|
26618
|
-
const { pos, node } = sectionNode;
|
|
26619
|
-
const newNode = node.type.create(node.attrs, updatedContent, node.marks);
|
|
26620
|
-
const tr = editor.state.tr.replaceWith(pos, pos + node.nodeSize, newNode);
|
|
26621
|
-
tr.setMeta("fromLinkedChild", true);
|
|
26622
|
-
editor.view.dispatch(tr);
|
|
26623
|
-
}
|
|
26624
|
-
});
|
|
26625
|
-
editor.on("update", ({ transaction }) => {
|
|
26626
|
-
const isFromLinkedChild = transaction.getMeta("fromLinkedChild");
|
|
26627
|
-
if (isFromLinkedChild) return;
|
|
26628
|
-
const sectionNode = getAllSections(editor)?.find((s) => s.node.attrs.id === id);
|
|
26629
|
-
if (!sectionNode) return;
|
|
26630
|
-
const sectionContent = sectionNode.node.content;
|
|
26631
|
-
const json = {
|
|
26632
|
-
type: "doc",
|
|
26633
|
-
content: sectionContent.content.map((node) => node.toJSON())
|
|
26634
|
-
};
|
|
26635
|
-
const childTr = child.state.tr;
|
|
26636
|
-
childTr.setMeta("fromLinkedParent", true);
|
|
26637
|
-
childTr.replaceWith(0, child.state.doc.content.size, child.schema.nodeFromJSON(json));
|
|
26638
|
-
child.view.dispatch(childTr);
|
|
26639
|
-
});
|
|
26640
|
-
return child;
|
|
26641
|
-
};
|
|
26642
|
-
const SectionHelpers = {
|
|
26643
|
-
getAllSections,
|
|
26644
|
-
exportSectionsToHTML,
|
|
26645
|
-
exportSectionsToJSON,
|
|
26646
|
-
getLinkedSectionEditor
|
|
26647
|
-
};
|
|
26648
|
-
const DocumentSection = Node$1.create({
|
|
26649
|
-
name: "documentSection",
|
|
26650
|
-
group: "block",
|
|
26651
|
-
content: "block*",
|
|
26652
|
-
atom: true,
|
|
27165
|
+
const ContentBlock = Node$1.create({
|
|
27166
|
+
name: "contentBlock",
|
|
27167
|
+
group: "inline",
|
|
27168
|
+
content: "",
|
|
26653
27169
|
isolating: true,
|
|
27170
|
+
atom: true,
|
|
27171
|
+
inline: true,
|
|
26654
27172
|
addOptions() {
|
|
26655
27173
|
return {
|
|
26656
27174
|
htmlAttributes: {
|
|
26657
|
-
|
|
26658
|
-
"aria-label": "Structured content block"
|
|
27175
|
+
contenteditable: false
|
|
26659
27176
|
}
|
|
26660
27177
|
};
|
|
26661
27178
|
},
|
|
26662
|
-
parseDOM() {
|
|
26663
|
-
return [
|
|
26664
|
-
{
|
|
26665
|
-
tag: "div.sd-document-section-block",
|
|
26666
|
-
priority: 60
|
|
26667
|
-
}
|
|
26668
|
-
];
|
|
26669
|
-
},
|
|
26670
|
-
renderDOM({ htmlAttributes }) {
|
|
26671
|
-
return ["div", Attribute.mergeAttributes(this.options.htmlAttributes, htmlAttributes), 0];
|
|
26672
|
-
},
|
|
26673
27179
|
addAttributes() {
|
|
26674
27180
|
return {
|
|
26675
|
-
|
|
26676
|
-
|
|
27181
|
+
horizontalRule: {
|
|
27182
|
+
default: false,
|
|
27183
|
+
renderDOM: ({ horizontalRule }) => {
|
|
27184
|
+
if (!horizontalRule) return {};
|
|
27185
|
+
return { "data-horizontal-rule": "true" };
|
|
27186
|
+
}
|
|
27187
|
+
},
|
|
27188
|
+
size: {
|
|
27189
|
+
default: null,
|
|
27190
|
+
renderDOM: ({ size }) => {
|
|
27191
|
+
if (!size) return {};
|
|
27192
|
+
let style = "";
|
|
27193
|
+
if (size.top) style += `top: ${size.top}px; `;
|
|
27194
|
+
if (size.left) style += `left: ${size.left}px; `;
|
|
27195
|
+
if (size.width) style += `width: ${size.width.toString().endsWith("%") ? size.width : `${size.width}px`}; `;
|
|
27196
|
+
if (size.height)
|
|
27197
|
+
style += `height: ${size.height.toString().endsWith("%") ? size.height : `${size.height}px`}; `;
|
|
27198
|
+
return { style };
|
|
27199
|
+
}
|
|
27200
|
+
},
|
|
27201
|
+
background: {
|
|
26677
27202
|
default: null,
|
|
26678
|
-
keepOnSplit: false,
|
|
26679
|
-
parseDOM: (elem) => elem.getAttribute("data-sd-block-id"),
|
|
26680
27203
|
renderDOM: (attrs) => {
|
|
26681
|
-
|
|
27204
|
+
if (!attrs.background) return {};
|
|
27205
|
+
return {
|
|
27206
|
+
style: `background-color: ${attrs.background}`
|
|
27207
|
+
};
|
|
26682
27208
|
}
|
|
26683
27209
|
},
|
|
26684
|
-
|
|
26685
|
-
|
|
26686
|
-
|
|
26687
|
-
|
|
27210
|
+
drawingContent: {
|
|
27211
|
+
rendered: false
|
|
27212
|
+
},
|
|
27213
|
+
attributes: {
|
|
27214
|
+
rendered: false
|
|
27215
|
+
}
|
|
26688
27216
|
};
|
|
26689
27217
|
},
|
|
26690
|
-
|
|
26691
|
-
return
|
|
26692
|
-
|
|
26693
|
-
|
|
27218
|
+
parseDOM() {
|
|
27219
|
+
return [
|
|
27220
|
+
{
|
|
27221
|
+
tag: `div[data-type="${this.name}"]`
|
|
27222
|
+
}
|
|
27223
|
+
];
|
|
27224
|
+
},
|
|
27225
|
+
renderDOM({ htmlAttributes }) {
|
|
27226
|
+
return ["div", Attribute.mergeAttributes(this.options.htmlAttributes, htmlAttributes, { "data-type": this.name })];
|
|
26694
27227
|
},
|
|
26695
27228
|
addCommands() {
|
|
26696
27229
|
return {
|
|
26697
27230
|
/**
|
|
26698
|
-
*
|
|
27231
|
+
* Insert a horizontal rule
|
|
26699
27232
|
* @category Command
|
|
26700
|
-
* @param {SectionCreate} [options={}] - Section configuration
|
|
26701
27233
|
* @example
|
|
26702
|
-
* editor.commands.
|
|
26703
|
-
*
|
|
26704
|
-
* title: 'Terms & Conditions',
|
|
26705
|
-
* isLocked: true,
|
|
26706
|
-
* html: '<p>Legal content...</p>'
|
|
26707
|
-
* })
|
|
27234
|
+
* editor.commands.insertHorizontalRule()
|
|
27235
|
+
* @note Creates a visual separator between content sections
|
|
26708
27236
|
*/
|
|
26709
|
-
|
|
26710
|
-
|
|
26711
|
-
|
|
26712
|
-
|
|
26713
|
-
|
|
26714
|
-
|
|
26715
|
-
|
|
26716
|
-
const doc2 = DOMParser$1.fromSchema(this.editor.schema).parse(html);
|
|
26717
|
-
content = doc2.content;
|
|
26718
|
-
}
|
|
26719
|
-
if (optionsJSON) {
|
|
26720
|
-
content = this.editor.schema.nodeFromJSON(optionsJSON);
|
|
26721
|
-
}
|
|
26722
|
-
if (!content?.content?.length) {
|
|
26723
|
-
content = this.editor.schema.nodeFromJSON({ type: "paragraph", content: [] });
|
|
26724
|
-
}
|
|
26725
|
-
if (!options.id) {
|
|
26726
|
-
const allSections = SectionHelpers.getAllSections(editor);
|
|
26727
|
-
options.id = allSections.length + 1;
|
|
26728
|
-
}
|
|
26729
|
-
if (!options.title) {
|
|
26730
|
-
options.title = "Document section";
|
|
26731
|
-
}
|
|
26732
|
-
const node = this.type.createAndFill(options, content);
|
|
26733
|
-
if (!node) return false;
|
|
26734
|
-
const isAlreadyInSdtBlock = findParentNode((node2) => node2.type.name === "documentSection")(selection);
|
|
26735
|
-
if (isAlreadyInSdtBlock && isAlreadyInSdtBlock.node) {
|
|
26736
|
-
const insertPos2 = isAlreadyInSdtBlock.pos + isAlreadyInSdtBlock.node.nodeSize;
|
|
26737
|
-
from2 = insertPos2;
|
|
26738
|
-
to = insertPos2;
|
|
26739
|
-
}
|
|
26740
|
-
tr.replaceRangeWith(from2, to, node);
|
|
26741
|
-
const nodeEnd = from2 + node.nodeSize;
|
|
26742
|
-
let shouldInsertParagraph = true;
|
|
26743
|
-
let insertPos = nodeEnd;
|
|
26744
|
-
if (nodeEnd >= tr.doc.content.size) {
|
|
26745
|
-
insertPos = tr.doc.content.size;
|
|
26746
|
-
if (insertPos > 0) {
|
|
26747
|
-
const $endPos = tr.doc.resolve(insertPos);
|
|
26748
|
-
if ($endPos.nodeBefore && $endPos.nodeBefore.type.name === "paragraph") {
|
|
26749
|
-
shouldInsertParagraph = false;
|
|
26750
|
-
}
|
|
27237
|
+
insertHorizontalRule: () => ({ commands: commands2 }) => {
|
|
27238
|
+
return commands2.insertContent({
|
|
27239
|
+
type: this.name,
|
|
27240
|
+
attrs: {
|
|
27241
|
+
horizontalRule: true,
|
|
27242
|
+
size: { width: "100%", height: 2 },
|
|
27243
|
+
background: "#e5e7eb"
|
|
26751
27244
|
}
|
|
26752
|
-
}
|
|
26753
|
-
if (shouldInsertParagraph) {
|
|
26754
|
-
const emptyParagraph = tr.doc.type.schema.nodes.paragraph.create();
|
|
26755
|
-
tr.insert(insertPos, emptyParagraph);
|
|
26756
|
-
}
|
|
26757
|
-
if (dispatch) {
|
|
26758
|
-
tr.setMeta("documentSection", { action: "create" });
|
|
26759
|
-
dispatch(tr);
|
|
26760
|
-
setTimeout(() => {
|
|
26761
|
-
try {
|
|
26762
|
-
const currentState = editor.state;
|
|
26763
|
-
const docSize = currentState.doc.content.size;
|
|
26764
|
-
let targetPos = from2 + node.nodeSize;
|
|
26765
|
-
if (shouldInsertParagraph) {
|
|
26766
|
-
targetPos += 1;
|
|
26767
|
-
}
|
|
26768
|
-
targetPos = Math.min(targetPos, docSize);
|
|
26769
|
-
if (targetPos < docSize && targetPos > 0) {
|
|
26770
|
-
const newSelection = Selection.near(currentState.doc.resolve(targetPos));
|
|
26771
|
-
const newTr = currentState.tr.setSelection(newSelection);
|
|
26772
|
-
editor.view.dispatch(newTr);
|
|
26773
|
-
}
|
|
26774
|
-
} catch (e) {
|
|
26775
|
-
console.warn("Could not set delayed selection:", e);
|
|
26776
|
-
}
|
|
26777
|
-
}, 0);
|
|
26778
|
-
}
|
|
26779
|
-
return true;
|
|
26780
|
-
},
|
|
26781
|
-
/**
|
|
26782
|
-
* Remove section wrapper at cursor, preserving its content
|
|
26783
|
-
* @category Command
|
|
26784
|
-
* @example
|
|
26785
|
-
* editor.commands.removeSectionAtSelection()
|
|
26786
|
-
* @note Content stays in document, only section wrapper is removed
|
|
26787
|
-
*/
|
|
26788
|
-
removeSectionAtSelection: () => ({ tr, dispatch }) => {
|
|
26789
|
-
const sdtNode = findParentNode((node2) => node2.type.name === "documentSection")(tr.selection);
|
|
26790
|
-
if (!sdtNode) return false;
|
|
26791
|
-
const { node, pos } = sdtNode;
|
|
26792
|
-
const nodeStart = pos;
|
|
26793
|
-
const nodeEnd = nodeStart + node.nodeSize;
|
|
26794
|
-
const contentToPreserve = node.content;
|
|
26795
|
-
tr.delete(nodeStart, nodeEnd);
|
|
26796
|
-
if (contentToPreserve.size > 0) {
|
|
26797
|
-
tr.insert(nodeStart, contentToPreserve);
|
|
26798
|
-
}
|
|
26799
|
-
const newPos = Math.min(nodeStart, tr.doc.content.size);
|
|
26800
|
-
tr.setSelection(Selection.near(tr.doc.resolve(newPos)));
|
|
26801
|
-
if (dispatch) {
|
|
26802
|
-
tr.setMeta("documentSection", { action: "delete" });
|
|
26803
|
-
dispatch(tr);
|
|
26804
|
-
}
|
|
26805
|
-
return true;
|
|
26806
|
-
},
|
|
26807
|
-
/**
|
|
26808
|
-
* Delete section and all its content
|
|
26809
|
-
* @category Command
|
|
26810
|
-
* @param {number} id - Section to delete
|
|
26811
|
-
* @example
|
|
26812
|
-
* editor.commands.removeSectionById(123)
|
|
26813
|
-
*/
|
|
26814
|
-
removeSectionById: (id) => ({ tr, dispatch }) => {
|
|
26815
|
-
const sections = SectionHelpers.getAllSections(this.editor);
|
|
26816
|
-
const sectionToRemove = sections.find(({ node: node2 }) => node2.attrs.id === id);
|
|
26817
|
-
if (!sectionToRemove) return false;
|
|
26818
|
-
const { pos, node } = sectionToRemove;
|
|
26819
|
-
const nodeStart = pos;
|
|
26820
|
-
const nodeEnd = nodeStart + node.nodeSize;
|
|
26821
|
-
tr.delete(nodeStart, nodeEnd);
|
|
26822
|
-
if (dispatch) {
|
|
26823
|
-
tr.setMeta("documentSection", { action: "delete", id });
|
|
26824
|
-
dispatch(tr);
|
|
26825
|
-
}
|
|
26826
|
-
return true;
|
|
27245
|
+
});
|
|
26827
27246
|
},
|
|
26828
27247
|
/**
|
|
26829
|
-
*
|
|
27248
|
+
* Insert a content block
|
|
26830
27249
|
* @category Command
|
|
26831
|
-
* @param {
|
|
27250
|
+
* @param {ContentBlockConfig} config - Block configuration
|
|
26832
27251
|
* @example
|
|
26833
|
-
*
|
|
26834
|
-
|
|
26835
|
-
|
|
26836
|
-
const sections = SectionHelpers.getAllSections(this.editor);
|
|
26837
|
-
const sectionToLock = sections.find(({ node }) => node.attrs.id === id);
|
|
26838
|
-
if (!sectionToLock) return false;
|
|
26839
|
-
tr.setNodeMarkup(sectionToLock.pos, null, { ...sectionToLock.node.attrs, isLocked: true });
|
|
26840
|
-
if (dispatch) {
|
|
26841
|
-
tr.setMeta("documentSection", { action: "lock", id });
|
|
26842
|
-
dispatch(tr);
|
|
26843
|
-
}
|
|
26844
|
-
return true;
|
|
26845
|
-
},
|
|
26846
|
-
/**
|
|
26847
|
-
* Modify section attributes or content
|
|
26848
|
-
* @category Command
|
|
26849
|
-
* @param {SectionUpdate} options - Changes to apply
|
|
27252
|
+
* // Insert a spacer block
|
|
27253
|
+
* editor.commands.insertContentBlock({ size: { height: 20 } })
|
|
27254
|
+
*
|
|
26850
27255
|
* @example
|
|
26851
|
-
*
|
|
26852
|
-
* editor.commands.
|
|
26853
|
-
*
|
|
26854
|
-
*
|
|
26855
|
-
* html: '<p>Updated</p>',
|
|
26856
|
-
* attrs: { title: 'New Title' }
|
|
27256
|
+
* // Insert a colored divider
|
|
27257
|
+
* editor.commands.insertContentBlock({
|
|
27258
|
+
* size: { width: '50%', height: 3 },
|
|
27259
|
+
* background: '#3b82f6'
|
|
26857
27260
|
* })
|
|
27261
|
+
* @note Used for spacing, dividers, and special inline content
|
|
26858
27262
|
*/
|
|
26859
|
-
|
|
26860
|
-
|
|
26861
|
-
|
|
26862
|
-
|
|
26863
|
-
|
|
26864
|
-
let newContent = null;
|
|
26865
|
-
if (html) {
|
|
26866
|
-
const htmlDoc = htmlHandler(html, editor || this.editor);
|
|
26867
|
-
const doc2 = DOMParser$1.fromSchema((editor || this.editor).schema).parse(htmlDoc);
|
|
26868
|
-
newContent = doc2.content;
|
|
26869
|
-
}
|
|
26870
|
-
if (json) {
|
|
26871
|
-
newContent = (editor || this.editor).schema.nodeFromJSON(json);
|
|
26872
|
-
}
|
|
26873
|
-
if (!newContent) {
|
|
26874
|
-
newContent = node.content;
|
|
26875
|
-
}
|
|
26876
|
-
const updatedNode = node.type.create({ ...node.attrs, ...attrs }, newContent, node.marks);
|
|
26877
|
-
tr.replaceWith(pos, pos + node.nodeSize, updatedNode);
|
|
26878
|
-
if (dispatch) {
|
|
26879
|
-
tr.setMeta("documentSection", { action: "update", id, attrs });
|
|
26880
|
-
dispatch(tr);
|
|
26881
|
-
}
|
|
26882
|
-
return true;
|
|
27263
|
+
insertContentBlock: (config) => ({ commands: commands2 }) => {
|
|
27264
|
+
return commands2.insertContent({
|
|
27265
|
+
type: this.name,
|
|
27266
|
+
attrs: config
|
|
27267
|
+
});
|
|
26883
27268
|
}
|
|
26884
27269
|
};
|
|
26885
|
-
},
|
|
26886
|
-
addHelpers() {
|
|
26887
|
-
return {
|
|
26888
|
-
...SectionHelpers
|
|
26889
|
-
};
|
|
26890
27270
|
}
|
|
26891
27271
|
});
|
|
26892
27272
|
const { findChildren } = helpers;
|
|
@@ -27090,6 +27470,51 @@ const checkForNewBlockNodesInTrs = (transactions) => {
|
|
|
27090
27470
|
});
|
|
27091
27471
|
});
|
|
27092
27472
|
};
|
|
27473
|
+
const TableOfContents = Node$1.create({
|
|
27474
|
+
name: "tableOfContents",
|
|
27475
|
+
group: "block",
|
|
27476
|
+
content: "paragraph+",
|
|
27477
|
+
inline: false,
|
|
27478
|
+
addOptions() {
|
|
27479
|
+
return {
|
|
27480
|
+
htmlAttributes: {
|
|
27481
|
+
"data-id": "table-of-contents",
|
|
27482
|
+
"aria-label": "Table of Contents"
|
|
27483
|
+
}
|
|
27484
|
+
};
|
|
27485
|
+
},
|
|
27486
|
+
parseDOM() {
|
|
27487
|
+
return [
|
|
27488
|
+
{
|
|
27489
|
+
tag: 'div[data-id="table-of-contents"]'
|
|
27490
|
+
}
|
|
27491
|
+
];
|
|
27492
|
+
},
|
|
27493
|
+
renderDOM({ htmlAttributes }) {
|
|
27494
|
+
return ["div", Attribute.mergeAttributes(this.options.htmlAttributes, htmlAttributes), 0];
|
|
27495
|
+
},
|
|
27496
|
+
addAttributes() {
|
|
27497
|
+
return {
|
|
27498
|
+
instruction: {
|
|
27499
|
+
default: null,
|
|
27500
|
+
rendered: false
|
|
27501
|
+
},
|
|
27502
|
+
/**
|
|
27503
|
+
* @private
|
|
27504
|
+
* @category Attribute
|
|
27505
|
+
* @param {string} [sdBlockId] - Internal block tracking ID (not user-configurable)
|
|
27506
|
+
*/
|
|
27507
|
+
sdBlockId: {
|
|
27508
|
+
default: null,
|
|
27509
|
+
keepOnSplit: false,
|
|
27510
|
+
parseDOM: (elem) => elem.getAttribute("data-sd-block-id"),
|
|
27511
|
+
renderDOM: (attrs) => {
|
|
27512
|
+
return attrs.sdBlockId ? { "data-sd-block-id": attrs.sdBlockId } : {};
|
|
27513
|
+
}
|
|
27514
|
+
}
|
|
27515
|
+
};
|
|
27516
|
+
}
|
|
27517
|
+
});
|
|
27093
27518
|
const TextStyle = Mark.create({
|
|
27094
27519
|
name: "textStyle",
|
|
27095
27520
|
addOptions() {
|
|
@@ -33454,7 +33879,8 @@ const nodeResizer = (nodeNames = ["image"], editor) => {
|
|
|
33454
33879
|
const prevSelection = prevState.selection;
|
|
33455
33880
|
if (selection.from !== prevSelection.from || selection.to !== prevSelection.to) {
|
|
33456
33881
|
setTimeout(() => {
|
|
33457
|
-
const
|
|
33882
|
+
const searchRoot = editorView?.dom;
|
|
33883
|
+
const selectedResizableWrapper = searchRoot?.querySelector(".sd-editor-resizable-wrapper");
|
|
33458
33884
|
if (selectedResizableWrapper) {
|
|
33459
33885
|
showResizeHandles(view2, selectedResizableWrapper);
|
|
33460
33886
|
} else {
|
|
@@ -33695,6 +34121,7 @@ const getStarterExtensions = () => {
|
|
|
33695
34121
|
SlashMenu,
|
|
33696
34122
|
Strike,
|
|
33697
34123
|
TabNode,
|
|
34124
|
+
TableOfContents,
|
|
33698
34125
|
Text,
|
|
33699
34126
|
TextAlign,
|
|
33700
34127
|
TextIndent,
|
|
@@ -33729,13 +34156,16 @@ const getStarterExtensions = () => {
|
|
|
33729
34156
|
AiLoaderNode,
|
|
33730
34157
|
PageNumber,
|
|
33731
34158
|
TotalPageCount,
|
|
34159
|
+
PageReference,
|
|
33732
34160
|
ShapeContainer,
|
|
33733
34161
|
ShapeTextbox,
|
|
33734
34162
|
ContentBlock,
|
|
33735
34163
|
Search,
|
|
33736
34164
|
StructuredContent,
|
|
33737
34165
|
StructuredContentBlock,
|
|
34166
|
+
StructuredContentCommands,
|
|
33738
34167
|
DocumentSection,
|
|
34168
|
+
DocumentPartObject,
|
|
33739
34169
|
NodeResizer,
|
|
33740
34170
|
CustomSelection,
|
|
33741
34171
|
TextTransform
|
|
@@ -33768,6 +34198,7 @@ export {
|
|
|
33768
34198
|
SectionHelpers as o,
|
|
33769
34199
|
getAllowedImageDimensions as p,
|
|
33770
34200
|
replaceSelectionWithImagePlaceholder as r,
|
|
34201
|
+
shouldBypassContextMenu as s,
|
|
33771
34202
|
useHighContrastMode as u,
|
|
33772
34203
|
yUndoPluginKey as y
|
|
33773
34204
|
};
|