@harbour-enterprises/superdoc 0.22.0-next.9 → 0.22.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/chunks/{PdfViewer-HN-tp5RN.es.js → PdfViewer-BNWaI4WI.es.js} +1 -1
- package/dist/chunks/{PdfViewer-DyWe33pN.cjs → PdfViewer-DpkgwUPi.cjs} +1 -1
- package/dist/chunks/{index-BeVpZc19.cjs → index-BbGPYtNy.cjs} +2 -2
- package/dist/chunks/{index-ir6efMuz.es.js → index-DWKEKmiB.es.js} +2 -2
- package/dist/chunks/{super-editor.es-BwqYS285.es.js → super-editor.es-BVxfhpAJ.es.js} +1581 -1274
- package/dist/chunks/{super-editor.es-CKfdmK-8.cjs → super-editor.es-BoUJEZaF.cjs} +1581 -1274
- package/dist/core/types/index.d.ts.map +1 -1
- package/dist/style.css +1 -0
- package/dist/super-editor/ai-writer.es.js +2 -2
- package/dist/super-editor/chunks/{converter-BgedUNCW.js → converter-C-yWLpFM.js} +150 -105
- package/dist/super-editor/chunks/{docx-zipper-ByLK3trM.js → docx-zipper-CmGlSUQM.js} +1 -1
- package/dist/super-editor/chunks/{editor-CFqh_xBx.js → editor-BBnC1DzI.js} +1436 -1172
- package/dist/super-editor/chunks/{toolbar-DdfyWgZF.js → toolbar-QJANo61B.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/helpers/generateDocxRandomId.d.ts +5 -0
- package/dist/super-editor/src/extensions/index.d.ts +2 -1
- package/dist/super-editor/src/extensions/structured-content/index.d.ts +1 -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/style.css +1 -0
- package/dist/super-editor/super-editor.es.js +7 -7
- 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 +1581 -1274
- package/dist/superdoc.umd.js.map +1 -1
- package/package.json +1 -1
package/dist/superdoc.umd.js
CHANGED
|
@@ -22730,6 +22730,10 @@
|
|
|
22730
22730
|
}
|
|
22731
22731
|
return id.join("");
|
|
22732
22732
|
}
|
|
22733
|
+
function generateRandomSigned32BitIntStrId() {
|
|
22734
|
+
const val = Math.floor(Math.random() * 2147483647);
|
|
22735
|
+
return val.toString();
|
|
22736
|
+
}
|
|
22733
22737
|
function generateRandom32BitHex() {
|
|
22734
22738
|
const val = Math.floor(Math.random() * 2147483647);
|
|
22735
22739
|
return val.toString(16).toUpperCase().padStart(8, "0");
|
|
@@ -30308,6 +30312,7 @@ Please report this to https://github.com/markedjs/marked.`, e) {
|
|
|
30308
30312
|
generateDocxListAttributes,
|
|
30309
30313
|
generateDocxRandomId,
|
|
30310
30314
|
generateRandom32BitHex,
|
|
30315
|
+
generateRandomSigned32BitIntStrId,
|
|
30311
30316
|
getActiveFormatting,
|
|
30312
30317
|
getExtensionConfigField,
|
|
30313
30318
|
getMarkRange,
|
|
@@ -35902,6 +35907,9 @@ Please report this to https://github.com/markedjs/marked.`, e) {
|
|
|
35902
35907
|
const node = nodes[0];
|
|
35903
35908
|
const sdtPr = node.elements.find((el) => el.name === "w:sdtPr");
|
|
35904
35909
|
const sdtContent = node.elements.find((el) => el.name === "w:sdtContent");
|
|
35910
|
+
const id = sdtPr?.elements?.find((el) => el.name === "w:id");
|
|
35911
|
+
const tag = sdtPr?.elements?.find((el) => el.name === "w:tag");
|
|
35912
|
+
const alias = sdtPr?.elements?.find((el) => el.name === "w:alias");
|
|
35905
35913
|
if (!sdtContent) {
|
|
35906
35914
|
return null;
|
|
35907
35915
|
}
|
|
@@ -35913,15 +35921,16 @@ Please report this to https://github.com/markedjs/marked.`, e) {
|
|
|
35913
35921
|
nodes: sdtContent.elements,
|
|
35914
35922
|
path: [...params2.path || [], sdtContent]
|
|
35915
35923
|
});
|
|
35916
|
-
|
|
35917
|
-
|
|
35918
|
-
sdtContentType = "structuredContentBlock";
|
|
35919
|
-
}
|
|
35924
|
+
const isBlockNode2 = paragraph || table;
|
|
35925
|
+
const sdtContentType = isBlockNode2 ? "structuredContentBlock" : "structuredContent";
|
|
35920
35926
|
let result = {
|
|
35921
35927
|
type: sdtContentType,
|
|
35922
35928
|
content: translatedContent,
|
|
35923
35929
|
marks,
|
|
35924
35930
|
attrs: {
|
|
35931
|
+
id: id?.attributes?.["w:val"] || null,
|
|
35932
|
+
tag: tag?.attributes?.["w:val"] || null,
|
|
35933
|
+
alias: alias?.attributes?.["w:val"] || null,
|
|
35925
35934
|
sdtPr
|
|
35926
35935
|
}
|
|
35927
35936
|
};
|
|
@@ -38179,21 +38188,55 @@ Please report this to https://github.com/markedjs/marked.`, e) {
|
|
|
38179
38188
|
};
|
|
38180
38189
|
function translateStructuredContent(params2) {
|
|
38181
38190
|
const { node } = params2;
|
|
38182
|
-
const { attrs = {} } = node;
|
|
38183
38191
|
const childContent = translateChildNodes({ ...params2, nodes: node.content });
|
|
38184
|
-
const
|
|
38185
|
-
|
|
38186
|
-
|
|
38187
|
-
elements: childContent
|
|
38188
|
-
}
|
|
38189
|
-
];
|
|
38190
|
-
nodeElements.unshift(attrs.sdtPr);
|
|
38192
|
+
const sdtContent = { name: "w:sdtContent", elements: childContent };
|
|
38193
|
+
const sdtPr = generateSdtPrTagForStructuredContent({ node });
|
|
38194
|
+
const nodeElements = [sdtPr, sdtContent];
|
|
38191
38195
|
const result = {
|
|
38192
38196
|
name: "w:sdt",
|
|
38193
38197
|
elements: nodeElements
|
|
38194
38198
|
};
|
|
38195
38199
|
return result;
|
|
38196
38200
|
}
|
|
38201
|
+
function generateSdtPrTagForStructuredContent({ node }) {
|
|
38202
|
+
const { attrs = {} } = node;
|
|
38203
|
+
const id = {
|
|
38204
|
+
name: "w:id",
|
|
38205
|
+
type: "element",
|
|
38206
|
+
attributes: { "w:val": attrs.id }
|
|
38207
|
+
};
|
|
38208
|
+
const alias = {
|
|
38209
|
+
name: "w:alias",
|
|
38210
|
+
type: "element",
|
|
38211
|
+
attributes: { "w:val": attrs.alias }
|
|
38212
|
+
};
|
|
38213
|
+
const tag = {
|
|
38214
|
+
name: "w:tag",
|
|
38215
|
+
type: "element",
|
|
38216
|
+
attributes: { "w:val": attrs.tag }
|
|
38217
|
+
};
|
|
38218
|
+
const resultElements = [];
|
|
38219
|
+
if (attrs.id) resultElements.push(id);
|
|
38220
|
+
if (attrs.alias) resultElements.push(alias);
|
|
38221
|
+
if (attrs.tag) resultElements.push(tag);
|
|
38222
|
+
if (attrs.sdtPr) {
|
|
38223
|
+
const elements = attrs.sdtPr.elements || [];
|
|
38224
|
+
const elementsToExclude = ["w:id", "w:alias", "w:tag"];
|
|
38225
|
+
const restElements = elements.filter((el) => !elementsToExclude.includes(el.name));
|
|
38226
|
+
const result2 = {
|
|
38227
|
+
name: "w:sdtPr",
|
|
38228
|
+
type: "element",
|
|
38229
|
+
elements: [...resultElements, ...restElements]
|
|
38230
|
+
};
|
|
38231
|
+
return result2;
|
|
38232
|
+
}
|
|
38233
|
+
const result = {
|
|
38234
|
+
name: "w:sdtPr",
|
|
38235
|
+
type: "element",
|
|
38236
|
+
elements: resultElements
|
|
38237
|
+
};
|
|
38238
|
+
return result;
|
|
38239
|
+
}
|
|
38197
38240
|
const XML_NODE_NAME$3 = "w:sdt";
|
|
38198
38241
|
const SD_NODE_NAME$3 = ["fieldAnnotation", "structuredContent", "structuredContentBlock", "documentSection"];
|
|
38199
38242
|
const validXmlAttributes$3 = [];
|
|
@@ -39254,7 +39297,7 @@ Please report this to https://github.com/markedjs/marked.`, e) {
|
|
|
39254
39297
|
const pict = {
|
|
39255
39298
|
name: "w:pict",
|
|
39256
39299
|
attributes: {
|
|
39257
|
-
"w14:anchorId":
|
|
39300
|
+
"w14:anchorId": generateRandomSigned32BitIntStrId()
|
|
39258
39301
|
},
|
|
39259
39302
|
elements: [shape]
|
|
39260
39303
|
};
|
|
@@ -39321,7 +39364,7 @@ Please report this to https://github.com/markedjs/marked.`, e) {
|
|
|
39321
39364
|
const pict = {
|
|
39322
39365
|
name: "w:pict",
|
|
39323
39366
|
attributes: {
|
|
39324
|
-
"w14:anchorId":
|
|
39367
|
+
"w14:anchorId": generateRandomSigned32BitIntStrId()
|
|
39325
39368
|
},
|
|
39326
39369
|
elements: [rect]
|
|
39327
39370
|
};
|
|
@@ -40794,7 +40837,7 @@ Please report this to https://github.com/markedjs/marked.`, e) {
|
|
|
40794
40837
|
gutter: "0"
|
|
40795
40838
|
})
|
|
40796
40839
|
});
|
|
40797
|
-
function ensureSectionProperties(bodyNode
|
|
40840
|
+
function ensureSectionProperties(bodyNode) {
|
|
40798
40841
|
if (!bodyNode.elements) bodyNode.elements = [];
|
|
40799
40842
|
let sectPr = bodyNode.elements.find((el) => el.name === "w:sectPr");
|
|
40800
40843
|
if (!sectPr) {
|
|
@@ -44293,7 +44336,7 @@ Please report this to https://github.com/markedjs/marked.`, e) {
|
|
|
44293
44336
|
var __privateAdd$1 = (obj, member, value) => member.has(obj) ? __typeError$1("Cannot add the same private member more than once") : member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
|
|
44294
44337
|
var __privateSet = (obj, member, value, setter) => (__accessCheck$1(obj, member, "write to private field"), member.set(obj, value), value);
|
|
44295
44338
|
var __privateMethod$1 = (obj, member, method) => (__accessCheck$1(obj, member, "access private method"), method);
|
|
44296
|
-
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,
|
|
44339
|
+
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;
|
|
44297
44340
|
var GOOD_LEAF_SIZE = 200;
|
|
44298
44341
|
var RopeSequence = function RopeSequence2() {
|
|
44299
44342
|
};
|
|
@@ -56368,7 +56411,7 @@ Please report this to https://github.com/markedjs/marked.`, e) {
|
|
|
56368
56411
|
if (emitParams) editor.emit("commentsUpdate", emitParams);
|
|
56369
56412
|
return newTrackedChanges;
|
|
56370
56413
|
};
|
|
56371
|
-
const getTrackedChangeText = ({
|
|
56414
|
+
const getTrackedChangeText = ({ nodes, mark, trackedChangeType, isDeletionInsertion }) => {
|
|
56372
56415
|
let trackedChangeText = "";
|
|
56373
56416
|
let deletionText = "";
|
|
56374
56417
|
if (trackedChangeType === TrackInsertMarkName) {
|
|
@@ -56410,10 +56453,8 @@ Please report this to https://github.com/markedjs/marked.`, e) {
|
|
|
56410
56453
|
if (hasMatchingId) nodesWithMark.push(node2);
|
|
56411
56454
|
});
|
|
56412
56455
|
const { deletionText, trackedChangeText } = getTrackedChangeText({
|
|
56413
|
-
state: newEditorState,
|
|
56414
56456
|
nodes: nodesWithMark.length ? nodesWithMark : [node],
|
|
56415
56457
|
mark: trackedMark,
|
|
56416
|
-
marks,
|
|
56417
56458
|
trackedChangeType,
|
|
56418
56459
|
isDeletionInsertion
|
|
56419
56460
|
});
|
|
@@ -61068,228 +61109,1223 @@ Please report this to https://github.com/markedjs/marked.`, e) {
|
|
|
61068
61109
|
return this.editor.options.isHeadless ? [] : [slashMenuPlugin];
|
|
61069
61110
|
}
|
|
61070
61111
|
});
|
|
61071
|
-
|
|
61072
|
-
|
|
61073
|
-
|
|
61074
|
-
|
|
61075
|
-
|
|
61076
|
-
|
|
61077
|
-
|
|
61078
|
-
|
|
61079
|
-
|
|
61080
|
-
|
|
61081
|
-
|
|
61082
|
-
|
|
61083
|
-
|
|
61084
|
-
|
|
61085
|
-
|
|
61086
|
-
|
|
61087
|
-
|
|
61088
|
-
|
|
61089
|
-
|
|
61090
|
-
|
|
61091
|
-
|
|
61092
|
-
|
|
61093
|
-
|
|
61094
|
-
|
|
61095
|
-
|
|
61096
|
-
|
|
61097
|
-
|
|
61098
|
-
|
|
61099
|
-
|
|
61100
|
-
|
|
61101
|
-
|
|
61102
|
-
|
|
61103
|
-
|
|
61104
|
-
|
|
61105
|
-
|
|
61106
|
-
|
|
61107
|
-
|
|
61108
|
-
|
|
61109
|
-
|
|
61110
|
-
|
|
61111
|
-
|
|
61112
|
-
|
|
61113
|
-
|
|
61114
|
-
|
|
61115
|
-
|
|
61116
|
-
|
|
61117
|
-
|
|
61118
|
-
|
|
61119
|
-
|
|
61112
|
+
class StructuredContentViewBase {
|
|
61113
|
+
constructor(props) {
|
|
61114
|
+
__publicField$1(this, "node");
|
|
61115
|
+
__publicField$1(this, "view");
|
|
61116
|
+
__publicField$1(this, "getPos");
|
|
61117
|
+
__publicField$1(this, "decorations");
|
|
61118
|
+
__publicField$1(this, "innerDecorations");
|
|
61119
|
+
__publicField$1(this, "editor");
|
|
61120
|
+
__publicField$1(this, "extension");
|
|
61121
|
+
__publicField$1(this, "htmlAttributes");
|
|
61122
|
+
__publicField$1(this, "root");
|
|
61123
|
+
__publicField$1(this, "isDragging", false);
|
|
61124
|
+
this.node = props.node;
|
|
61125
|
+
this.view = props.editor.view;
|
|
61126
|
+
this.getPos = props.getPos;
|
|
61127
|
+
this.decorations = props.decorations;
|
|
61128
|
+
this.innerDecorations = props.innerDecorations;
|
|
61129
|
+
this.editor = props.editor;
|
|
61130
|
+
this.extension = props.extension;
|
|
61131
|
+
this.htmlAttributes = props.htmlAttributes;
|
|
61132
|
+
this.mount(props);
|
|
61133
|
+
}
|
|
61134
|
+
mount() {
|
|
61135
|
+
return;
|
|
61136
|
+
}
|
|
61137
|
+
get dom() {
|
|
61138
|
+
return this.root;
|
|
61139
|
+
}
|
|
61140
|
+
get contentDOM() {
|
|
61141
|
+
return null;
|
|
61142
|
+
}
|
|
61143
|
+
update(node, decorations, innerDecorations) {
|
|
61144
|
+
if (node.type !== this.node.type) {
|
|
61145
|
+
return false;
|
|
61146
|
+
}
|
|
61147
|
+
this.node = node;
|
|
61148
|
+
this.decorations = decorations;
|
|
61149
|
+
this.innerDecorations = innerDecorations;
|
|
61150
|
+
this.updateHTMLAttributes();
|
|
61151
|
+
return true;
|
|
61152
|
+
}
|
|
61153
|
+
stopEvent(event) {
|
|
61154
|
+
if (!this.dom) return false;
|
|
61155
|
+
const target = event.target;
|
|
61156
|
+
const isInElement = this.dom.contains(target) && !this.contentDOM?.contains(target);
|
|
61157
|
+
if (!isInElement) return false;
|
|
61158
|
+
const isDragEvent = event.type.startsWith("drag");
|
|
61159
|
+
const isDropEvent = event.type === "drop";
|
|
61160
|
+
const isInput = ["INPUT", "BUTTON", "SELECT", "TEXTAREA"].includes(target.tagName) || target.isContentEditable;
|
|
61161
|
+
if (isInput && !isDropEvent && !isDragEvent) return true;
|
|
61162
|
+
const { isEditable } = this.editor;
|
|
61163
|
+
const { isDragging } = this;
|
|
61164
|
+
const isDraggable = !!this.node.type.spec.draggable;
|
|
61165
|
+
const isSelectable = NodeSelection.isSelectable(this.node);
|
|
61166
|
+
const isCopyEvent = event.type === "copy";
|
|
61167
|
+
const isPasteEvent = event.type === "paste";
|
|
61168
|
+
const isCutEvent = event.type === "cut";
|
|
61169
|
+
const isClickEvent = event.type === "mousedown";
|
|
61170
|
+
if (!isDraggable && isSelectable && isDragEvent && event.target === this.dom) {
|
|
61171
|
+
event.preventDefault();
|
|
61172
|
+
}
|
|
61173
|
+
if (isDraggable && isDragEvent && !isDragging && event.target === this.dom) {
|
|
61174
|
+
event.preventDefault();
|
|
61175
|
+
return false;
|
|
61176
|
+
}
|
|
61177
|
+
if (isDraggable && isEditable && !isDragging && isClickEvent) {
|
|
61178
|
+
const dragHandle = target.closest("[data-drag-handle]");
|
|
61179
|
+
const isValidDragHandle = dragHandle && (this.dom === dragHandle || this.dom.contains(dragHandle));
|
|
61180
|
+
if (isValidDragHandle) {
|
|
61181
|
+
this.isDragging = true;
|
|
61182
|
+
document.addEventListener(
|
|
61183
|
+
"dragend",
|
|
61184
|
+
() => {
|
|
61185
|
+
this.isDragging = false;
|
|
61186
|
+
},
|
|
61187
|
+
{ once: true }
|
|
61188
|
+
);
|
|
61189
|
+
document.addEventListener(
|
|
61190
|
+
"drop",
|
|
61191
|
+
() => {
|
|
61192
|
+
this.isDragging = false;
|
|
61193
|
+
},
|
|
61194
|
+
{ once: true }
|
|
61195
|
+
);
|
|
61196
|
+
document.addEventListener(
|
|
61197
|
+
"mouseup",
|
|
61198
|
+
() => {
|
|
61199
|
+
this.isDragging = false;
|
|
61200
|
+
},
|
|
61201
|
+
{ once: true }
|
|
61202
|
+
);
|
|
61120
61203
|
}
|
|
61121
|
-
}
|
|
61204
|
+
}
|
|
61205
|
+
if (isDragging || isDropEvent || isCopyEvent || isPasteEvent || isCutEvent || isClickEvent && isSelectable) {
|
|
61206
|
+
return false;
|
|
61207
|
+
}
|
|
61208
|
+
return true;
|
|
61122
61209
|
}
|
|
61123
|
-
|
|
61124
|
-
|
|
61125
|
-
|
|
61126
|
-
|
|
61127
|
-
|
|
61128
|
-
|
|
61129
|
-
return
|
|
61210
|
+
ignoreMutation(mutation) {
|
|
61211
|
+
if (!this.dom || !this.contentDOM) return true;
|
|
61212
|
+
if (this.node.isLeaf || this.node.isAtom) return true;
|
|
61213
|
+
if (mutation.type === "selection") return false;
|
|
61214
|
+
if (this.contentDOM === mutation.target && mutation.type === "attributes") return true;
|
|
61215
|
+
if (this.contentDOM.contains(mutation.target)) return false;
|
|
61216
|
+
return true;
|
|
61130
61217
|
}
|
|
61131
|
-
|
|
61132
|
-
|
|
61133
|
-
|
|
61134
|
-
|
|
61135
|
-
|
|
61136
|
-
|
|
61137
|
-
|
|
61218
|
+
destroy() {
|
|
61219
|
+
this.dom.remove();
|
|
61220
|
+
this.contentDOM?.remove();
|
|
61221
|
+
}
|
|
61222
|
+
updateAttributes(attrs) {
|
|
61223
|
+
const pos = this.getPos();
|
|
61224
|
+
if (typeof pos !== "number") {
|
|
61225
|
+
return;
|
|
61226
|
+
}
|
|
61227
|
+
return this.view.dispatch(
|
|
61228
|
+
this.view.state.tr.setNodeMarkup(pos, void 0, {
|
|
61229
|
+
...this.node.attrs,
|
|
61230
|
+
...attrs
|
|
61231
|
+
})
|
|
61232
|
+
);
|
|
61233
|
+
}
|
|
61234
|
+
updateHTMLAttributes() {
|
|
61235
|
+
const { extensionService } = this.editor;
|
|
61236
|
+
const { attributes } = extensionService;
|
|
61237
|
+
const extensionAttrs = attributes.filter((i2) => i2.type === this.node.type.name);
|
|
61238
|
+
this.htmlAttributes = Attribute.getAttributesToRender(this.node, extensionAttrs);
|
|
61239
|
+
}
|
|
61240
|
+
createDragHandle() {
|
|
61241
|
+
const dragHandle = document.createElement("span");
|
|
61242
|
+
dragHandle.classList.add("sd-structured-content-draggable");
|
|
61243
|
+
dragHandle.draggable = true;
|
|
61244
|
+
dragHandle.contentEditable = "false";
|
|
61245
|
+
dragHandle.dataset.dragHandle = "";
|
|
61246
|
+
const textElement = document.createElement("span");
|
|
61247
|
+
textElement.textContent = this.node.attrs.alias || "Structured content";
|
|
61248
|
+
dragHandle.append(textElement);
|
|
61249
|
+
return dragHandle;
|
|
61250
|
+
}
|
|
61251
|
+
onDragStart(event) {
|
|
61252
|
+
const { view } = this.editor;
|
|
61253
|
+
const target = event.target;
|
|
61254
|
+
const dragHandle = target.nodeType === 3 ? target.parentElement?.closest("[data-drag-handle]") : target.closest("[data-drag-handle]");
|
|
61255
|
+
if (!this.dom || this.contentDOM?.contains(target) || !dragHandle) {
|
|
61256
|
+
return;
|
|
61257
|
+
}
|
|
61258
|
+
let x = 0;
|
|
61259
|
+
let y2 = 0;
|
|
61260
|
+
if (this.dom !== dragHandle) {
|
|
61261
|
+
const domBox = this.dom.getBoundingClientRect();
|
|
61262
|
+
const handleBox = dragHandle.getBoundingClientRect();
|
|
61263
|
+
const offsetX = event.offsetX ?? event.nativeEvent?.offsetX;
|
|
61264
|
+
const offsetY = event.offsetY ?? event.nativeEvent?.offsetY;
|
|
61265
|
+
x = handleBox.x - domBox.x + offsetX;
|
|
61266
|
+
y2 = handleBox.y - domBox.y + offsetY;
|
|
61267
|
+
}
|
|
61268
|
+
event.dataTransfer?.setDragImage(this.dom, x, y2);
|
|
61269
|
+
const pos = this.getPos();
|
|
61270
|
+
if (typeof pos !== "number") {
|
|
61271
|
+
return;
|
|
61272
|
+
}
|
|
61273
|
+
const selection = NodeSelection.create(view.state.doc, pos);
|
|
61274
|
+
const transaction = view.state.tr.setSelection(selection);
|
|
61138
61275
|
view.dispatch(transaction);
|
|
61139
|
-
});
|
|
61140
|
-
if (handled) {
|
|
61141
|
-
tr.setMeta("preventDispatch", true);
|
|
61142
61276
|
}
|
|
61143
|
-
|
|
61144
|
-
|
|
61145
|
-
|
|
61146
|
-
|
|
61147
|
-
|
|
61148
|
-
|
|
61277
|
+
}
|
|
61278
|
+
class StructuredContentInlineView extends StructuredContentViewBase {
|
|
61279
|
+
constructor(props) {
|
|
61280
|
+
super(props);
|
|
61281
|
+
}
|
|
61282
|
+
mount() {
|
|
61283
|
+
this.buildView();
|
|
61284
|
+
}
|
|
61285
|
+
get contentDOM() {
|
|
61286
|
+
const contentElement = this.dom?.querySelector(`.${structuredContentInnerClass$1}`);
|
|
61287
|
+
return contentElement || null;
|
|
61288
|
+
}
|
|
61289
|
+
createElement() {
|
|
61290
|
+
const element = document.createElement("span");
|
|
61291
|
+
element.classList.add(structuredContentClass$1);
|
|
61292
|
+
element.setAttribute("data-structured-content", "");
|
|
61293
|
+
const contentElement = document.createElement("span");
|
|
61294
|
+
contentElement.classList.add(structuredContentInnerClass$1);
|
|
61295
|
+
element.append(contentElement);
|
|
61296
|
+
const domAttrs = Attribute.mergeAttributes(this.htmlAttributes);
|
|
61297
|
+
updateDOMAttributes(element, { ...domAttrs });
|
|
61298
|
+
return { element, contentElement };
|
|
61299
|
+
}
|
|
61300
|
+
buildView() {
|
|
61301
|
+
const { element } = this.createElement();
|
|
61302
|
+
const dragHandle = this.createDragHandle();
|
|
61303
|
+
element.prepend(dragHandle);
|
|
61304
|
+
element.addEventListener("dragstart", (e) => this.onDragStart(e));
|
|
61305
|
+
this.root = element;
|
|
61306
|
+
}
|
|
61307
|
+
updateView() {
|
|
61308
|
+
const domAttrs = Attribute.mergeAttributes(this.htmlAttributes);
|
|
61309
|
+
updateDOMAttributes(this.dom, { ...domAttrs });
|
|
61310
|
+
}
|
|
61311
|
+
update(node, decorations, innerDecorations) {
|
|
61312
|
+
const result = super.update(node, decorations, innerDecorations);
|
|
61313
|
+
if (!result) return false;
|
|
61314
|
+
this.updateView();
|
|
61315
|
+
return true;
|
|
61316
|
+
}
|
|
61317
|
+
}
|
|
61318
|
+
const structuredContentClass$1 = "sd-structured-content";
|
|
61319
|
+
const structuredContentInnerClass$1 = "sd-structured-content__content";
|
|
61320
|
+
const StructuredContent = Node$1.create({
|
|
61321
|
+
name: "structuredContent",
|
|
61322
|
+
group: "inline structuredContent",
|
|
61149
61323
|
inline: true,
|
|
61150
61324
|
content: "inline*",
|
|
61151
|
-
|
|
61152
|
-
|
|
61325
|
+
isolating: true,
|
|
61326
|
+
atom: false,
|
|
61327
|
+
// false - has editable content.
|
|
61328
|
+
draggable: true,
|
|
61153
61329
|
addOptions() {
|
|
61154
61330
|
return {
|
|
61155
61331
|
htmlAttributes: {
|
|
61156
|
-
|
|
61332
|
+
class: structuredContentClass$1,
|
|
61333
|
+
"aria-label": "Structured content node"
|
|
61157
61334
|
}
|
|
61158
61335
|
};
|
|
61159
61336
|
},
|
|
61160
61337
|
addAttributes() {
|
|
61161
61338
|
return {
|
|
61162
|
-
|
|
61339
|
+
id: {
|
|
61163
61340
|
default: null,
|
|
61164
|
-
|
|
61165
|
-
|
|
61341
|
+
parseDOM: (elem) => elem.getAttribute("data-id"),
|
|
61342
|
+
renderDOM: (attrs) => {
|
|
61343
|
+
if (!attrs.id) return {};
|
|
61344
|
+
return { "data-id": attrs.id };
|
|
61345
|
+
}
|
|
61166
61346
|
},
|
|
61167
|
-
|
|
61347
|
+
tag: {
|
|
61168
61348
|
default: null,
|
|
61169
|
-
|
|
61170
|
-
|
|
61349
|
+
parseDOM: (elem) => elem.getAttribute("data-tag"),
|
|
61350
|
+
renderDOM: (attrs) => {
|
|
61351
|
+
if (!attrs.tag) return {};
|
|
61352
|
+
return { "data-tag": attrs.tag };
|
|
61353
|
+
}
|
|
61171
61354
|
},
|
|
61172
|
-
|
|
61355
|
+
alias: {
|
|
61173
61356
|
default: null,
|
|
61174
|
-
|
|
61175
|
-
|
|
61357
|
+
parseDOM: (elem) => elem.getAttribute("data-alias"),
|
|
61358
|
+
renderDOM: (attrs) => {
|
|
61359
|
+
if (!attrs.alias) return {};
|
|
61360
|
+
return { "data-alias": attrs.alias };
|
|
61361
|
+
}
|
|
61176
61362
|
},
|
|
61177
|
-
|
|
61178
|
-
|
|
61179
|
-
rendered: false,
|
|
61180
|
-
keepOnSplit: true
|
|
61363
|
+
sdtPr: {
|
|
61364
|
+
rendered: false
|
|
61181
61365
|
}
|
|
61182
61366
|
};
|
|
61183
61367
|
},
|
|
61184
|
-
addCommands() {
|
|
61185
|
-
return {
|
|
61186
|
-
splitRun
|
|
61187
|
-
};
|
|
61188
|
-
},
|
|
61189
61368
|
parseDOM() {
|
|
61190
|
-
return [{ tag: "span[data-
|
|
61369
|
+
return [{ tag: "span[data-structured-content]" }];
|
|
61191
61370
|
},
|
|
61192
61371
|
renderDOM({ htmlAttributes }) {
|
|
61193
|
-
|
|
61194
|
-
|
|
61372
|
+
return [
|
|
61373
|
+
"span",
|
|
61374
|
+
Attribute.mergeAttributes(this.options.htmlAttributes, htmlAttributes, {
|
|
61375
|
+
"data-structured-content": ""
|
|
61376
|
+
}),
|
|
61377
|
+
0
|
|
61378
|
+
];
|
|
61379
|
+
},
|
|
61380
|
+
addNodeView() {
|
|
61381
|
+
return (props) => {
|
|
61382
|
+
return new StructuredContentInlineView({ ...props });
|
|
61383
|
+
};
|
|
61195
61384
|
}
|
|
61196
61385
|
});
|
|
61197
|
-
|
|
61198
|
-
|
|
61199
|
-
|
|
61200
|
-
|
|
61201
|
-
|
|
61202
|
-
|
|
61203
|
-
|
|
61204
|
-
|
|
61386
|
+
class StructuredContentBlockView extends StructuredContentViewBase {
|
|
61387
|
+
constructor(props) {
|
|
61388
|
+
super(props);
|
|
61389
|
+
}
|
|
61390
|
+
mount() {
|
|
61391
|
+
this.buildView();
|
|
61392
|
+
}
|
|
61393
|
+
get contentDOM() {
|
|
61394
|
+
const contentElement = this.dom?.querySelector(`.${structuredContentInnerClass}`);
|
|
61395
|
+
return contentElement || null;
|
|
61396
|
+
}
|
|
61397
|
+
createElement() {
|
|
61398
|
+
const element = document.createElement("div");
|
|
61399
|
+
element.classList.add(structuredContentClass);
|
|
61400
|
+
element.setAttribute("data-structured-content-block", "");
|
|
61401
|
+
const contentElement = document.createElement("div");
|
|
61402
|
+
contentElement.classList.add(structuredContentInnerClass);
|
|
61403
|
+
element.append(contentElement);
|
|
61404
|
+
const domAttrs = Attribute.mergeAttributes(this.htmlAttributes);
|
|
61405
|
+
updateDOMAttributes(element, { ...domAttrs });
|
|
61406
|
+
return { element, contentElement };
|
|
61407
|
+
}
|
|
61408
|
+
buildView() {
|
|
61409
|
+
const { element } = this.createElement();
|
|
61410
|
+
const dragHandle = this.createDragHandle();
|
|
61411
|
+
element.prepend(dragHandle);
|
|
61412
|
+
element.addEventListener("dragstart", (e) => this.onDragStart(e));
|
|
61413
|
+
this.root = element;
|
|
61414
|
+
}
|
|
61415
|
+
updateView() {
|
|
61416
|
+
const domAttrs = Attribute.mergeAttributes(this.htmlAttributes);
|
|
61417
|
+
updateDOMAttributes(this.dom, { ...domAttrs });
|
|
61418
|
+
}
|
|
61419
|
+
update(node, decorations, innerDecorations) {
|
|
61420
|
+
const result = super.update(node, decorations, innerDecorations);
|
|
61421
|
+
if (!result) return false;
|
|
61422
|
+
this.updateView();
|
|
61423
|
+
return true;
|
|
61424
|
+
}
|
|
61425
|
+
}
|
|
61426
|
+
const structuredContentClass = "sd-structured-content-block";
|
|
61427
|
+
const structuredContentInnerClass = "sd-structured-content-block__content";
|
|
61428
|
+
const StructuredContentBlock = Node$1.create({
|
|
61429
|
+
name: "structuredContentBlock",
|
|
61430
|
+
group: "block structuredContent",
|
|
61431
|
+
content: "block*",
|
|
61432
|
+
isolating: true,
|
|
61433
|
+
atom: false,
|
|
61434
|
+
// false - has editable content.
|
|
61435
|
+
draggable: true,
|
|
61205
61436
|
addOptions() {
|
|
61206
61437
|
return {
|
|
61207
|
-
itemTypeName: "listItem",
|
|
61208
61438
|
htmlAttributes: {
|
|
61209
|
-
|
|
61210
|
-
|
|
61211
|
-
|
|
61212
|
-
keepAttributes: false
|
|
61439
|
+
class: structuredContentClass,
|
|
61440
|
+
"aria-label": "Structured content block node"
|
|
61441
|
+
}
|
|
61213
61442
|
};
|
|
61214
61443
|
},
|
|
61215
|
-
parseDOM() {
|
|
61216
|
-
return [{ tag: "ul" }];
|
|
61217
|
-
},
|
|
61218
|
-
renderDOM({ htmlAttributes }) {
|
|
61219
|
-
const attributes = Attribute.mergeAttributes(this.options.htmlAttributes, htmlAttributes);
|
|
61220
|
-
return ["ul", attributes, 0];
|
|
61221
|
-
},
|
|
61222
61444
|
addAttributes() {
|
|
61223
61445
|
return {
|
|
61224
|
-
|
|
61225
|
-
default:
|
|
61226
|
-
|
|
61446
|
+
id: {
|
|
61447
|
+
default: null,
|
|
61448
|
+
parseDOM: (elem) => elem.getAttribute("data-id"),
|
|
61449
|
+
renderDOM: (attrs) => {
|
|
61450
|
+
if (!attrs.id) return {};
|
|
61451
|
+
return { "data-id": attrs.id };
|
|
61452
|
+
}
|
|
61227
61453
|
},
|
|
61228
|
-
|
|
61229
|
-
|
|
61454
|
+
tag: {
|
|
61455
|
+
default: null,
|
|
61456
|
+
parseDOM: (elem) => elem.getAttribute("data-tag"),
|
|
61457
|
+
renderDOM: (attrs) => {
|
|
61458
|
+
if (!attrs.tag) return {};
|
|
61459
|
+
return { "data-tag": attrs.tag };
|
|
61460
|
+
}
|
|
61230
61461
|
},
|
|
61231
|
-
|
|
61462
|
+
alias: {
|
|
61232
61463
|
default: null,
|
|
61233
|
-
|
|
61234
|
-
parseDOM: (elem) => elem.getAttribute("data-sd-block-id"),
|
|
61464
|
+
parseDOM: (elem) => elem.getAttribute("data-alias"),
|
|
61235
61465
|
renderDOM: (attrs) => {
|
|
61236
|
-
|
|
61466
|
+
if (!attrs.alias) return {};
|
|
61467
|
+
return { "data-alias": attrs.alias };
|
|
61237
61468
|
}
|
|
61238
61469
|
},
|
|
61239
|
-
|
|
61240
|
-
rendered: false
|
|
61241
|
-
keepOnSplit: true
|
|
61242
|
-
}
|
|
61243
|
-
};
|
|
61244
|
-
},
|
|
61245
|
-
addCommands() {
|
|
61246
|
-
return {
|
|
61247
|
-
/**
|
|
61248
|
-
* Toggle a bullet list at the current selection
|
|
61249
|
-
* @category Command
|
|
61250
|
-
* @example
|
|
61251
|
-
* // Toggle bullet list on selected text
|
|
61252
|
-
* editor.commands.toggleBulletList()
|
|
61253
|
-
* @note Converts selected paragraphs to list items or removes list formatting
|
|
61254
|
-
*/
|
|
61255
|
-
toggleBulletList: () => (params2) => {
|
|
61256
|
-
return toggleList(this.type)(params2);
|
|
61470
|
+
sdtPr: {
|
|
61471
|
+
rendered: false
|
|
61257
61472
|
}
|
|
61258
61473
|
};
|
|
61259
61474
|
},
|
|
61260
|
-
|
|
61261
|
-
return {
|
|
61262
|
-
"Mod-Shift-8": () => {
|
|
61263
|
-
return this.editor.commands.toggleBulletList();
|
|
61264
|
-
}
|
|
61265
|
-
};
|
|
61475
|
+
parseDOM() {
|
|
61476
|
+
return [{ tag: "div[data-structured-content-block]" }];
|
|
61266
61477
|
},
|
|
61267
|
-
|
|
61478
|
+
renderDOM({ htmlAttributes }) {
|
|
61268
61479
|
return [
|
|
61269
|
-
|
|
61270
|
-
|
|
61271
|
-
|
|
61272
|
-
|
|
61273
|
-
|
|
61274
|
-
for (let depth = $pos.depth; depth >= 0; depth--) {
|
|
61275
|
-
if ($pos.node(depth).type === listItemType) {
|
|
61276
|
-
return null;
|
|
61277
|
-
}
|
|
61278
|
-
}
|
|
61279
|
-
const { tr } = state2;
|
|
61280
|
-
tr.delete(range2.from, range2.to);
|
|
61281
|
-
ListHelpers.createNewList({
|
|
61282
|
-
listType: this.type,
|
|
61283
|
-
tr,
|
|
61284
|
-
editor: this.editor
|
|
61285
|
-
});
|
|
61286
|
-
}
|
|
61287
|
-
})
|
|
61480
|
+
"div",
|
|
61481
|
+
Attribute.mergeAttributes(this.options.htmlAttributes, htmlAttributes, {
|
|
61482
|
+
"data-structured-content-block": ""
|
|
61483
|
+
}),
|
|
61484
|
+
0
|
|
61288
61485
|
];
|
|
61486
|
+
},
|
|
61487
|
+
addNodeView() {
|
|
61488
|
+
return (props) => {
|
|
61489
|
+
return new StructuredContentBlockView({ ...props });
|
|
61490
|
+
};
|
|
61289
61491
|
}
|
|
61290
61492
|
});
|
|
61291
|
-
|
|
61292
|
-
|
|
61493
|
+
function getStructuredContentTagsById(idOrIds, state2) {
|
|
61494
|
+
const result = findChildren$5(state2.doc, (node) => {
|
|
61495
|
+
const isStructuredContent = ["structuredContent", "structuredContentBlock"].includes(node.type.name);
|
|
61496
|
+
if (Array.isArray(idOrIds)) {
|
|
61497
|
+
return isStructuredContent && idOrIds.includes(node.attrs.id);
|
|
61498
|
+
} else {
|
|
61499
|
+
return isStructuredContent && node.attrs.id === idOrIds;
|
|
61500
|
+
}
|
|
61501
|
+
});
|
|
61502
|
+
return result;
|
|
61503
|
+
}
|
|
61504
|
+
function getStructuredContentTags(state2) {
|
|
61505
|
+
const result = findChildren$5(state2.doc, (node) => {
|
|
61506
|
+
return node.type.name === "structuredContent" || node.type.name === "structuredContentBlock";
|
|
61507
|
+
});
|
|
61508
|
+
return result;
|
|
61509
|
+
}
|
|
61510
|
+
function getStructuredContentInlineTags(state2) {
|
|
61511
|
+
const result = findChildren$5(state2.doc, (node) => node.type.name === "structuredContent");
|
|
61512
|
+
return result;
|
|
61513
|
+
}
|
|
61514
|
+
function getStructuredContentBlockTags(state2) {
|
|
61515
|
+
const result = findChildren$5(state2.doc, (node) => node.type.name === "structuredContentBlock");
|
|
61516
|
+
return result;
|
|
61517
|
+
}
|
|
61518
|
+
const structuredContentHelpers = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
61519
|
+
__proto__: null,
|
|
61520
|
+
getStructuredContentBlockTags,
|
|
61521
|
+
getStructuredContentInlineTags,
|
|
61522
|
+
getStructuredContentTags,
|
|
61523
|
+
getStructuredContentTagsById
|
|
61524
|
+
}, Symbol.toStringTag, { value: "Module" }));
|
|
61525
|
+
const STRUCTURED_CONTENT_NAMES = ["structuredContent", "structuredContentBlock"];
|
|
61526
|
+
const StructuredContentCommands = Extension.create({
|
|
61527
|
+
name: "structuredContentCommands",
|
|
61528
|
+
addCommands() {
|
|
61529
|
+
return {
|
|
61530
|
+
/**
|
|
61531
|
+
* Inserts a structured content inline at selection.
|
|
61532
|
+
* @category Command
|
|
61533
|
+
* @param {StructuredContentInlineInsert} options
|
|
61534
|
+
*/
|
|
61535
|
+
insertStructuredContentInline: (options = {}) => ({ editor, dispatch, state: state2, tr }) => {
|
|
61536
|
+
const { schema } = editor;
|
|
61537
|
+
let { from: from2, to } = state2.selection;
|
|
61538
|
+
if (dispatch) {
|
|
61539
|
+
const selectionText = state2.doc.textBetween(from2, to);
|
|
61540
|
+
let content = null;
|
|
61541
|
+
if (selectionText) {
|
|
61542
|
+
content = schema.text(selectionText);
|
|
61543
|
+
}
|
|
61544
|
+
if (options.text) {
|
|
61545
|
+
content = schema.text(options.text);
|
|
61546
|
+
}
|
|
61547
|
+
if (options.json) {
|
|
61548
|
+
content = schema.nodeFromJSON(options.json);
|
|
61549
|
+
}
|
|
61550
|
+
if (!content) {
|
|
61551
|
+
content = schema.text(" ");
|
|
61552
|
+
}
|
|
61553
|
+
const attrs = {
|
|
61554
|
+
...options.attrs,
|
|
61555
|
+
id: options.attrs?.id || generateRandomSigned32BitIntStrId(),
|
|
61556
|
+
tag: "inline_text_sdt",
|
|
61557
|
+
alias: options.attrs?.alias || "Structured content"
|
|
61558
|
+
};
|
|
61559
|
+
const node = schema.nodes.structuredContent.create(attrs, content, null);
|
|
61560
|
+
const parent = findParentNode((node2) => node2.type.name === "structuredContent")(state2.selection);
|
|
61561
|
+
if (parent) {
|
|
61562
|
+
const insertPos = parent.pos + parent.node.nodeSize;
|
|
61563
|
+
from2 = to = insertPos;
|
|
61564
|
+
}
|
|
61565
|
+
tr.replaceWith(from2, to, node);
|
|
61566
|
+
}
|
|
61567
|
+
return true;
|
|
61568
|
+
},
|
|
61569
|
+
/**
|
|
61570
|
+
* Inserts a structured content block at selection.
|
|
61571
|
+
* @category Command
|
|
61572
|
+
* @param {StructuredContentBlockInsert} options
|
|
61573
|
+
*/
|
|
61574
|
+
insertStructuredContentBlock: (options = {}) => ({ editor, dispatch, state: state2, tr }) => {
|
|
61575
|
+
const { schema } = editor;
|
|
61576
|
+
let { from: from2, to } = state2.selection;
|
|
61577
|
+
if (dispatch) {
|
|
61578
|
+
const selectionContent = state2.selection.content();
|
|
61579
|
+
let content = null;
|
|
61580
|
+
if (selectionContent.size) {
|
|
61581
|
+
content = selectionContent.content;
|
|
61582
|
+
}
|
|
61583
|
+
if (options.html) {
|
|
61584
|
+
const html = htmlHandler(options.html, editor);
|
|
61585
|
+
const doc2 = DOMParser$1.fromSchema(schema).parse(html);
|
|
61586
|
+
content = doc2.content;
|
|
61587
|
+
}
|
|
61588
|
+
if (options.json) {
|
|
61589
|
+
content = schema.nodeFromJSON(options.json);
|
|
61590
|
+
}
|
|
61591
|
+
if (!content) {
|
|
61592
|
+
content = schema.nodeFromJSON({ type: "paragraph", content: [] });
|
|
61593
|
+
}
|
|
61594
|
+
const attrs = {
|
|
61595
|
+
...options.attrs,
|
|
61596
|
+
id: options.attrs?.id || generateRandomSigned32BitIntStrId(),
|
|
61597
|
+
tag: "block_table_sdt",
|
|
61598
|
+
alias: options.attrs?.alias || "Structured content"
|
|
61599
|
+
};
|
|
61600
|
+
const node = schema.nodes.structuredContentBlock.create(attrs, content, null);
|
|
61601
|
+
const parent = findParentNode((node2) => node2.type.name === "structuredContentBlock")(state2.selection);
|
|
61602
|
+
if (parent) {
|
|
61603
|
+
const insertPos = parent.pos + parent.node.nodeSize;
|
|
61604
|
+
from2 = to = insertPos;
|
|
61605
|
+
}
|
|
61606
|
+
tr.replaceRangeWith(from2, to, node);
|
|
61607
|
+
}
|
|
61608
|
+
return true;
|
|
61609
|
+
},
|
|
61610
|
+
/**
|
|
61611
|
+
* Updates a structured content attributes or content.
|
|
61612
|
+
* If the updated node does not match the schema, it will not be updated.
|
|
61613
|
+
* @category Command
|
|
61614
|
+
* @param {string} id
|
|
61615
|
+
* @param {StructuredContentUpdate} options
|
|
61616
|
+
*/
|
|
61617
|
+
updateStructuredContentById: (id, options = {}) => ({ editor, dispatch, state: state2, tr }) => {
|
|
61618
|
+
const structuredContentTags = getStructuredContentTagsById(id, state2);
|
|
61619
|
+
if (!structuredContentTags.length) {
|
|
61620
|
+
return true;
|
|
61621
|
+
}
|
|
61622
|
+
const { schema } = editor;
|
|
61623
|
+
if (dispatch) {
|
|
61624
|
+
const structuredContent = structuredContentTags[0];
|
|
61625
|
+
const { pos, node } = structuredContent;
|
|
61626
|
+
const posFrom = pos;
|
|
61627
|
+
const posTo = pos + node.nodeSize;
|
|
61628
|
+
let content = null;
|
|
61629
|
+
if (options.text) {
|
|
61630
|
+
content = schema.text(options.text);
|
|
61631
|
+
}
|
|
61632
|
+
if (options.html) {
|
|
61633
|
+
const html = htmlHandler(options.html, editor);
|
|
61634
|
+
const doc2 = DOMParser$1.fromSchema(schema).parse(html);
|
|
61635
|
+
content = doc2.content;
|
|
61636
|
+
}
|
|
61637
|
+
if (options.json) {
|
|
61638
|
+
content = schema.nodeFromJSON(options.json);
|
|
61639
|
+
}
|
|
61640
|
+
if (!content) {
|
|
61641
|
+
content = node.content;
|
|
61642
|
+
}
|
|
61643
|
+
const updatedNode = node.type.create({ ...node.attrs, ...options.attrs }, content, node.marks);
|
|
61644
|
+
try {
|
|
61645
|
+
updatedNode.check();
|
|
61646
|
+
} catch {
|
|
61647
|
+
console.error("Updated node does not conform to the schema");
|
|
61648
|
+
return false;
|
|
61649
|
+
}
|
|
61650
|
+
tr.replaceWith(posFrom, posTo, updatedNode);
|
|
61651
|
+
}
|
|
61652
|
+
return true;
|
|
61653
|
+
},
|
|
61654
|
+
/**
|
|
61655
|
+
* Removes a structured content.
|
|
61656
|
+
* @category Command
|
|
61657
|
+
* @param {Array<{ node: Node, pos: number }>} structuredContentTags
|
|
61658
|
+
*/
|
|
61659
|
+
deleteStructuredContent: (structuredContentTags) => ({ dispatch, tr }) => {
|
|
61660
|
+
if (!structuredContentTags.length) {
|
|
61661
|
+
return true;
|
|
61662
|
+
}
|
|
61663
|
+
if (dispatch) {
|
|
61664
|
+
structuredContentTags.forEach((structuredContent) => {
|
|
61665
|
+
const { pos, node } = structuredContent;
|
|
61666
|
+
const posFrom = tr.mapping.map(pos);
|
|
61667
|
+
const posTo = tr.mapping.map(pos + node.nodeSize);
|
|
61668
|
+
const currentNode = tr.doc.nodeAt(posFrom);
|
|
61669
|
+
if (currentNode && node.eq(currentNode)) {
|
|
61670
|
+
tr.delete(posFrom, posTo);
|
|
61671
|
+
}
|
|
61672
|
+
});
|
|
61673
|
+
}
|
|
61674
|
+
return true;
|
|
61675
|
+
},
|
|
61676
|
+
/**
|
|
61677
|
+
* Removes a structured content by ID.
|
|
61678
|
+
* @category Command
|
|
61679
|
+
* @param {string | string[]} idOrIds
|
|
61680
|
+
*/
|
|
61681
|
+
deleteStructuredContentById: (idOrIds) => ({ dispatch, state: state2, tr }) => {
|
|
61682
|
+
const structuredContentTags = getStructuredContentTagsById(idOrIds, state2);
|
|
61683
|
+
if (!structuredContentTags.length) {
|
|
61684
|
+
return true;
|
|
61685
|
+
}
|
|
61686
|
+
if (dispatch) {
|
|
61687
|
+
structuredContentTags.forEach((structuredContent) => {
|
|
61688
|
+
const { pos, node } = structuredContent;
|
|
61689
|
+
const posFrom = tr.mapping.map(pos);
|
|
61690
|
+
const posTo = tr.mapping.map(pos + node.nodeSize);
|
|
61691
|
+
const currentNode = tr.doc.nodeAt(posFrom);
|
|
61692
|
+
if (currentNode && node.eq(currentNode)) {
|
|
61693
|
+
tr.delete(posFrom, posTo);
|
|
61694
|
+
}
|
|
61695
|
+
});
|
|
61696
|
+
}
|
|
61697
|
+
return true;
|
|
61698
|
+
},
|
|
61699
|
+
/**
|
|
61700
|
+
* Removes a structured content at cursor, preserving its content.
|
|
61701
|
+
* @category Command
|
|
61702
|
+
*/
|
|
61703
|
+
deleteStructuredContentAtSelection: () => ({ dispatch, state: state2, tr }) => {
|
|
61704
|
+
const predicate = (node) => STRUCTURED_CONTENT_NAMES.includes(node.type.name);
|
|
61705
|
+
const structuredContent = findParentNode(predicate)(state2.selection);
|
|
61706
|
+
if (!structuredContent) {
|
|
61707
|
+
return true;
|
|
61708
|
+
}
|
|
61709
|
+
if (dispatch) {
|
|
61710
|
+
const { node, pos } = structuredContent;
|
|
61711
|
+
const posFrom = pos;
|
|
61712
|
+
const posTo = posFrom + node.nodeSize;
|
|
61713
|
+
const content = node.content;
|
|
61714
|
+
tr.replaceWith(posFrom, posTo, content);
|
|
61715
|
+
}
|
|
61716
|
+
return true;
|
|
61717
|
+
}
|
|
61718
|
+
};
|
|
61719
|
+
},
|
|
61720
|
+
addHelpers() {
|
|
61721
|
+
return {
|
|
61722
|
+
...structuredContentHelpers
|
|
61723
|
+
};
|
|
61724
|
+
}
|
|
61725
|
+
});
|
|
61726
|
+
class DocumentSectionView {
|
|
61727
|
+
constructor(node, getPos, decorations, editor) {
|
|
61728
|
+
__privateAdd$1(this, _DocumentSectionView_instances);
|
|
61729
|
+
this.node = node;
|
|
61730
|
+
this.editor = editor;
|
|
61731
|
+
this.decorations = decorations;
|
|
61732
|
+
this.view = editor.view;
|
|
61733
|
+
this.getPos = getPos;
|
|
61734
|
+
__privateMethod$1(this, _DocumentSectionView_instances, init_fn2).call(this);
|
|
61735
|
+
}
|
|
61736
|
+
}
|
|
61737
|
+
_DocumentSectionView_instances = /* @__PURE__ */ new WeakSet();
|
|
61738
|
+
init_fn2 = function() {
|
|
61739
|
+
const { attrs } = this.node;
|
|
61740
|
+
const { id, title, description } = attrs;
|
|
61741
|
+
this.dom = document.createElement("div");
|
|
61742
|
+
this.dom.className = "sd-document-section-block";
|
|
61743
|
+
this.dom.setAttribute("data-id", id);
|
|
61744
|
+
this.dom.setAttribute("data-title", title);
|
|
61745
|
+
this.dom.setAttribute("data-description", description);
|
|
61746
|
+
this.dom.setAttribute("aria-label", "Document section");
|
|
61747
|
+
__privateMethod$1(this, _DocumentSectionView_instances, addToolTip_fn).call(this);
|
|
61748
|
+
this.contentDOM = document.createElement("div");
|
|
61749
|
+
this.contentDOM.className = "sd-document-section-block-content";
|
|
61750
|
+
this.contentDOM.setAttribute("contenteditable", "true");
|
|
61751
|
+
this.dom.appendChild(this.contentDOM);
|
|
61752
|
+
};
|
|
61753
|
+
addToolTip_fn = function() {
|
|
61754
|
+
const { title } = this.node.attrs;
|
|
61755
|
+
this.infoDiv = document.createElement("div");
|
|
61756
|
+
this.infoDiv.className = "sd-document-section-block-info";
|
|
61757
|
+
const textSpan = document.createElement("span");
|
|
61758
|
+
textSpan.textContent = title || "Document section";
|
|
61759
|
+
this.infoDiv.appendChild(textSpan);
|
|
61760
|
+
this.infoDiv.setAttribute("contenteditable", "false");
|
|
61761
|
+
this.dom.appendChild(this.infoDiv);
|
|
61762
|
+
};
|
|
61763
|
+
const getAllSections = (editor) => {
|
|
61764
|
+
if (!editor) return [];
|
|
61765
|
+
const type2 = editor.schema.nodes.documentSection;
|
|
61766
|
+
if (!type2) return [];
|
|
61767
|
+
const sections = [];
|
|
61768
|
+
const { state: state2 } = editor;
|
|
61769
|
+
state2.doc.descendants((node, pos) => {
|
|
61770
|
+
if (node.type.name === type2.name) {
|
|
61771
|
+
sections.push({ node, pos });
|
|
61772
|
+
}
|
|
61773
|
+
});
|
|
61774
|
+
return sections;
|
|
61775
|
+
};
|
|
61776
|
+
const exportSectionsToHTML = (editor) => {
|
|
61777
|
+
const sections = getAllSections(editor);
|
|
61778
|
+
const processedSections = /* @__PURE__ */ new Set();
|
|
61779
|
+
const result = [];
|
|
61780
|
+
sections.forEach(({ node }) => {
|
|
61781
|
+
const { attrs } = node;
|
|
61782
|
+
const { id, title, description } = attrs;
|
|
61783
|
+
if (processedSections.has(id)) return;
|
|
61784
|
+
processedSections.add(id);
|
|
61785
|
+
const html = getHTMLFromNode(node, editor);
|
|
61786
|
+
result.push({
|
|
61787
|
+
id,
|
|
61788
|
+
title,
|
|
61789
|
+
description,
|
|
61790
|
+
html
|
|
61791
|
+
});
|
|
61792
|
+
});
|
|
61793
|
+
return result;
|
|
61794
|
+
};
|
|
61795
|
+
const getHTMLFromNode = (node, editor) => {
|
|
61796
|
+
const tempDocument = document.implementation.createHTMLDocument();
|
|
61797
|
+
const container = tempDocument.createElement("div");
|
|
61798
|
+
const fragment = DOMSerializer.fromSchema(editor.schema).serializeFragment(node.content);
|
|
61799
|
+
container.appendChild(fragment);
|
|
61800
|
+
let html = container.innerHTML;
|
|
61801
|
+
return html;
|
|
61802
|
+
};
|
|
61803
|
+
const exportSectionsToJSON = (editor) => {
|
|
61804
|
+
const sections = getAllSections(editor);
|
|
61805
|
+
const processedSections = /* @__PURE__ */ new Set();
|
|
61806
|
+
const result = [];
|
|
61807
|
+
sections.forEach(({ node }) => {
|
|
61808
|
+
const { attrs } = node;
|
|
61809
|
+
const { id, title, description } = attrs;
|
|
61810
|
+
if (processedSections.has(id)) return;
|
|
61811
|
+
processedSections.add(id);
|
|
61812
|
+
result.push({
|
|
61813
|
+
id,
|
|
61814
|
+
title,
|
|
61815
|
+
description,
|
|
61816
|
+
content: node.toJSON()
|
|
61817
|
+
});
|
|
61818
|
+
});
|
|
61819
|
+
return result;
|
|
61820
|
+
};
|
|
61821
|
+
const getLinkedSectionEditor = (id, options, editor) => {
|
|
61822
|
+
const sections = getAllSections(editor);
|
|
61823
|
+
const section = sections.find((s) => s.node.attrs.id === id);
|
|
61824
|
+
if (!section) return null;
|
|
61825
|
+
const child = editor.createChildEditor({
|
|
61826
|
+
...options,
|
|
61827
|
+
onUpdate: ({ editor: childEditor, transaction }) => {
|
|
61828
|
+
const isFromtLinkedParent = transaction.getMeta("fromLinkedParent");
|
|
61829
|
+
if (isFromtLinkedParent) return;
|
|
61830
|
+
const updatedContent = childEditor.state.doc.content;
|
|
61831
|
+
const sectionNode = getAllSections(editor)?.find((s) => s.node.attrs.id === id);
|
|
61832
|
+
if (!sectionNode) return;
|
|
61833
|
+
const { pos, node } = sectionNode;
|
|
61834
|
+
const newNode = node.type.create(node.attrs, updatedContent, node.marks);
|
|
61835
|
+
const tr = editor.state.tr.replaceWith(pos, pos + node.nodeSize, newNode);
|
|
61836
|
+
tr.setMeta("fromLinkedChild", true);
|
|
61837
|
+
editor.view.dispatch(tr);
|
|
61838
|
+
}
|
|
61839
|
+
});
|
|
61840
|
+
editor.on("update", ({ transaction }) => {
|
|
61841
|
+
const isFromLinkedChild = transaction.getMeta("fromLinkedChild");
|
|
61842
|
+
if (isFromLinkedChild) return;
|
|
61843
|
+
const sectionNode = getAllSections(editor)?.find((s) => s.node.attrs.id === id);
|
|
61844
|
+
if (!sectionNode) return;
|
|
61845
|
+
const sectionContent = sectionNode.node.content;
|
|
61846
|
+
const json = {
|
|
61847
|
+
type: "doc",
|
|
61848
|
+
content: sectionContent.content.map((node) => node.toJSON())
|
|
61849
|
+
};
|
|
61850
|
+
const childTr = child.state.tr;
|
|
61851
|
+
childTr.setMeta("fromLinkedParent", true);
|
|
61852
|
+
childTr.replaceWith(0, child.state.doc.content.size, child.schema.nodeFromJSON(json));
|
|
61853
|
+
child.view.dispatch(childTr);
|
|
61854
|
+
});
|
|
61855
|
+
return child;
|
|
61856
|
+
};
|
|
61857
|
+
const SectionHelpers = {
|
|
61858
|
+
getAllSections,
|
|
61859
|
+
exportSectionsToHTML,
|
|
61860
|
+
exportSectionsToJSON,
|
|
61861
|
+
getLinkedSectionEditor
|
|
61862
|
+
};
|
|
61863
|
+
const DocumentSection = Node$1.create({
|
|
61864
|
+
name: "documentSection",
|
|
61865
|
+
group: "block",
|
|
61866
|
+
content: "block*",
|
|
61867
|
+
atom: true,
|
|
61868
|
+
isolating: true,
|
|
61869
|
+
addOptions() {
|
|
61870
|
+
return {
|
|
61871
|
+
htmlAttributes: {
|
|
61872
|
+
class: "sd-document-section-block",
|
|
61873
|
+
"aria-label": "Structured content block"
|
|
61874
|
+
}
|
|
61875
|
+
};
|
|
61876
|
+
},
|
|
61877
|
+
parseDOM() {
|
|
61878
|
+
return [
|
|
61879
|
+
{
|
|
61880
|
+
tag: "div.sd-document-section-block",
|
|
61881
|
+
priority: 60
|
|
61882
|
+
}
|
|
61883
|
+
];
|
|
61884
|
+
},
|
|
61885
|
+
renderDOM({ htmlAttributes }) {
|
|
61886
|
+
return ["div", Attribute.mergeAttributes(this.options.htmlAttributes, htmlAttributes), 0];
|
|
61887
|
+
},
|
|
61888
|
+
addAttributes() {
|
|
61889
|
+
return {
|
|
61890
|
+
id: {},
|
|
61891
|
+
sdBlockId: {
|
|
61892
|
+
default: null,
|
|
61893
|
+
keepOnSplit: false,
|
|
61894
|
+
parseDOM: (elem) => elem.getAttribute("data-sd-block-id"),
|
|
61895
|
+
renderDOM: (attrs) => {
|
|
61896
|
+
return attrs.sdBlockId ? { "data-sd-block-id": attrs.sdBlockId } : {};
|
|
61897
|
+
}
|
|
61898
|
+
},
|
|
61899
|
+
title: {},
|
|
61900
|
+
description: {},
|
|
61901
|
+
sectionType: {},
|
|
61902
|
+
isLocked: { default: false }
|
|
61903
|
+
};
|
|
61904
|
+
},
|
|
61905
|
+
addNodeView() {
|
|
61906
|
+
return ({ node, editor, getPos, decorations }) => {
|
|
61907
|
+
return new DocumentSectionView(node, getPos, decorations, editor);
|
|
61908
|
+
};
|
|
61909
|
+
},
|
|
61910
|
+
addCommands() {
|
|
61911
|
+
return {
|
|
61912
|
+
/**
|
|
61913
|
+
* Create a lockable content section
|
|
61914
|
+
* @category Command
|
|
61915
|
+
* @param {SectionCreate} [options={}] - Section configuration
|
|
61916
|
+
* @example
|
|
61917
|
+
* editor.commands.createDocumentSection({
|
|
61918
|
+
* id: 1,
|
|
61919
|
+
* title: 'Terms & Conditions',
|
|
61920
|
+
* isLocked: true,
|
|
61921
|
+
* html: '<p>Legal content...</p>'
|
|
61922
|
+
* })
|
|
61923
|
+
*/
|
|
61924
|
+
createDocumentSection: (options = {}) => ({ tr, state: state2, dispatch, editor }) => {
|
|
61925
|
+
const { selection } = state2;
|
|
61926
|
+
let { from: from2, to } = selection;
|
|
61927
|
+
let content = selection.content().content;
|
|
61928
|
+
const { html: optionsHTML, json: optionsJSON } = options;
|
|
61929
|
+
if (optionsHTML) {
|
|
61930
|
+
const html = htmlHandler(optionsHTML, this.editor);
|
|
61931
|
+
const doc2 = DOMParser$1.fromSchema(this.editor.schema).parse(html);
|
|
61932
|
+
content = doc2.content;
|
|
61933
|
+
}
|
|
61934
|
+
if (optionsJSON) {
|
|
61935
|
+
content = this.editor.schema.nodeFromJSON(optionsJSON);
|
|
61936
|
+
}
|
|
61937
|
+
if (!content?.content?.length) {
|
|
61938
|
+
content = this.editor.schema.nodeFromJSON({ type: "paragraph", content: [] });
|
|
61939
|
+
}
|
|
61940
|
+
if (!options.id) {
|
|
61941
|
+
const allSections = SectionHelpers.getAllSections(editor);
|
|
61942
|
+
options.id = allSections.length + 1;
|
|
61943
|
+
}
|
|
61944
|
+
if (!options.title) {
|
|
61945
|
+
options.title = "Document section";
|
|
61946
|
+
}
|
|
61947
|
+
const node = this.type.createAndFill(options, content);
|
|
61948
|
+
if (!node) return false;
|
|
61949
|
+
const isAlreadyInSdtBlock = findParentNode((node2) => node2.type.name === "documentSection")(selection);
|
|
61950
|
+
if (isAlreadyInSdtBlock && isAlreadyInSdtBlock.node) {
|
|
61951
|
+
const insertPos2 = isAlreadyInSdtBlock.pos + isAlreadyInSdtBlock.node.nodeSize;
|
|
61952
|
+
from2 = insertPos2;
|
|
61953
|
+
to = insertPos2;
|
|
61954
|
+
}
|
|
61955
|
+
tr.replaceRangeWith(from2, to, node);
|
|
61956
|
+
const nodeEnd = from2 + node.nodeSize;
|
|
61957
|
+
let shouldInsertParagraph = true;
|
|
61958
|
+
let insertPos = nodeEnd;
|
|
61959
|
+
if (nodeEnd >= tr.doc.content.size) {
|
|
61960
|
+
insertPos = tr.doc.content.size;
|
|
61961
|
+
if (insertPos > 0) {
|
|
61962
|
+
const $endPos = tr.doc.resolve(insertPos);
|
|
61963
|
+
if ($endPos.nodeBefore && $endPos.nodeBefore.type.name === "paragraph") {
|
|
61964
|
+
shouldInsertParagraph = false;
|
|
61965
|
+
}
|
|
61966
|
+
}
|
|
61967
|
+
}
|
|
61968
|
+
if (shouldInsertParagraph) {
|
|
61969
|
+
const emptyParagraph = tr.doc.type.schema.nodes.paragraph.create();
|
|
61970
|
+
tr.insert(insertPos, emptyParagraph);
|
|
61971
|
+
}
|
|
61972
|
+
if (dispatch) {
|
|
61973
|
+
tr.setMeta("documentSection", { action: "create" });
|
|
61974
|
+
dispatch(tr);
|
|
61975
|
+
setTimeout(() => {
|
|
61976
|
+
try {
|
|
61977
|
+
const currentState = editor.state;
|
|
61978
|
+
const docSize = currentState.doc.content.size;
|
|
61979
|
+
let targetPos = from2 + node.nodeSize;
|
|
61980
|
+
if (shouldInsertParagraph) {
|
|
61981
|
+
targetPos += 1;
|
|
61982
|
+
}
|
|
61983
|
+
targetPos = Math.min(targetPos, docSize);
|
|
61984
|
+
if (targetPos < docSize && targetPos > 0) {
|
|
61985
|
+
const newSelection = Selection.near(currentState.doc.resolve(targetPos));
|
|
61986
|
+
const newTr = currentState.tr.setSelection(newSelection);
|
|
61987
|
+
editor.view.dispatch(newTr);
|
|
61988
|
+
}
|
|
61989
|
+
} catch (e) {
|
|
61990
|
+
console.warn("Could not set delayed selection:", e);
|
|
61991
|
+
}
|
|
61992
|
+
}, 0);
|
|
61993
|
+
}
|
|
61994
|
+
return true;
|
|
61995
|
+
},
|
|
61996
|
+
/**
|
|
61997
|
+
* Remove section wrapper at cursor, preserving its content
|
|
61998
|
+
* @category Command
|
|
61999
|
+
* @example
|
|
62000
|
+
* editor.commands.removeSectionAtSelection()
|
|
62001
|
+
* @note Content stays in document, only section wrapper is removed
|
|
62002
|
+
*/
|
|
62003
|
+
removeSectionAtSelection: () => ({ tr, dispatch }) => {
|
|
62004
|
+
const sdtNode = findParentNode((node2) => node2.type.name === "documentSection")(tr.selection);
|
|
62005
|
+
if (!sdtNode) return false;
|
|
62006
|
+
const { node, pos } = sdtNode;
|
|
62007
|
+
const nodeStart = pos;
|
|
62008
|
+
const nodeEnd = nodeStart + node.nodeSize;
|
|
62009
|
+
const contentToPreserve = node.content;
|
|
62010
|
+
tr.delete(nodeStart, nodeEnd);
|
|
62011
|
+
if (contentToPreserve.size > 0) {
|
|
62012
|
+
tr.insert(nodeStart, contentToPreserve);
|
|
62013
|
+
}
|
|
62014
|
+
const newPos = Math.min(nodeStart, tr.doc.content.size);
|
|
62015
|
+
tr.setSelection(Selection.near(tr.doc.resolve(newPos)));
|
|
62016
|
+
if (dispatch) {
|
|
62017
|
+
tr.setMeta("documentSection", { action: "delete" });
|
|
62018
|
+
dispatch(tr);
|
|
62019
|
+
}
|
|
62020
|
+
return true;
|
|
62021
|
+
},
|
|
62022
|
+
/**
|
|
62023
|
+
* Delete section and all its content
|
|
62024
|
+
* @category Command
|
|
62025
|
+
* @param {number} id - Section to delete
|
|
62026
|
+
* @example
|
|
62027
|
+
* editor.commands.removeSectionById(123)
|
|
62028
|
+
*/
|
|
62029
|
+
removeSectionById: (id) => ({ tr, dispatch }) => {
|
|
62030
|
+
const sections = SectionHelpers.getAllSections(this.editor);
|
|
62031
|
+
const sectionToRemove = sections.find(({ node: node2 }) => node2.attrs.id === id);
|
|
62032
|
+
if (!sectionToRemove) return false;
|
|
62033
|
+
const { pos, node } = sectionToRemove;
|
|
62034
|
+
const nodeStart = pos;
|
|
62035
|
+
const nodeEnd = nodeStart + node.nodeSize;
|
|
62036
|
+
tr.delete(nodeStart, nodeEnd);
|
|
62037
|
+
if (dispatch) {
|
|
62038
|
+
tr.setMeta("documentSection", { action: "delete", id });
|
|
62039
|
+
dispatch(tr);
|
|
62040
|
+
}
|
|
62041
|
+
return true;
|
|
62042
|
+
},
|
|
62043
|
+
/**
|
|
62044
|
+
* Lock section against edits
|
|
62045
|
+
* @category Command
|
|
62046
|
+
* @param {number} id - Section to lock
|
|
62047
|
+
* @example
|
|
62048
|
+
* editor.commands.lockSectionById(123)
|
|
62049
|
+
*/
|
|
62050
|
+
lockSectionById: (id) => ({ tr, dispatch }) => {
|
|
62051
|
+
const sections = SectionHelpers.getAllSections(this.editor);
|
|
62052
|
+
const sectionToLock = sections.find(({ node }) => node.attrs.id === id);
|
|
62053
|
+
if (!sectionToLock) return false;
|
|
62054
|
+
tr.setNodeMarkup(sectionToLock.pos, null, { ...sectionToLock.node.attrs, isLocked: true });
|
|
62055
|
+
if (dispatch) {
|
|
62056
|
+
tr.setMeta("documentSection", { action: "lock", id });
|
|
62057
|
+
dispatch(tr);
|
|
62058
|
+
}
|
|
62059
|
+
return true;
|
|
62060
|
+
},
|
|
62061
|
+
/**
|
|
62062
|
+
* Modify section attributes or content
|
|
62063
|
+
* @category Command
|
|
62064
|
+
* @param {SectionUpdate} options - Changes to apply
|
|
62065
|
+
* @example
|
|
62066
|
+
* editor.commands.updateSectionById({ id: 123, attrs: { isLocked: false } })
|
|
62067
|
+
* editor.commands.updateSectionById({ id: 123, html: '<p>New content</p>' })
|
|
62068
|
+
* editor.commands.updateSectionById({
|
|
62069
|
+
* id: 123,
|
|
62070
|
+
* html: '<p>Updated</p>',
|
|
62071
|
+
* attrs: { title: 'New Title' }
|
|
62072
|
+
* })
|
|
62073
|
+
*/
|
|
62074
|
+
updateSectionById: ({ id, html, json, attrs }) => ({ tr, dispatch, editor }) => {
|
|
62075
|
+
const sections = SectionHelpers.getAllSections(editor || this.editor);
|
|
62076
|
+
const sectionToUpdate = sections.find(({ node: node2 }) => node2.attrs.id === id);
|
|
62077
|
+
if (!sectionToUpdate) return false;
|
|
62078
|
+
const { pos, node } = sectionToUpdate;
|
|
62079
|
+
let newContent = null;
|
|
62080
|
+
if (html) {
|
|
62081
|
+
const htmlDoc = htmlHandler(html, editor || this.editor);
|
|
62082
|
+
const doc2 = DOMParser$1.fromSchema((editor || this.editor).schema).parse(htmlDoc);
|
|
62083
|
+
newContent = doc2.content;
|
|
62084
|
+
}
|
|
62085
|
+
if (json) {
|
|
62086
|
+
newContent = (editor || this.editor).schema.nodeFromJSON(json);
|
|
62087
|
+
}
|
|
62088
|
+
if (!newContent) {
|
|
62089
|
+
newContent = node.content;
|
|
62090
|
+
}
|
|
62091
|
+
const updatedNode = node.type.create({ ...node.attrs, ...attrs }, newContent, node.marks);
|
|
62092
|
+
tr.replaceWith(pos, pos + node.nodeSize, updatedNode);
|
|
62093
|
+
if (dispatch) {
|
|
62094
|
+
tr.setMeta("documentSection", { action: "update", id, attrs });
|
|
62095
|
+
dispatch(tr);
|
|
62096
|
+
}
|
|
62097
|
+
return true;
|
|
62098
|
+
}
|
|
62099
|
+
};
|
|
62100
|
+
},
|
|
62101
|
+
addHelpers() {
|
|
62102
|
+
return {
|
|
62103
|
+
...SectionHelpers
|
|
62104
|
+
};
|
|
62105
|
+
}
|
|
62106
|
+
});
|
|
62107
|
+
const Document = Node$1.create({
|
|
62108
|
+
name: "doc",
|
|
62109
|
+
topNode: true,
|
|
62110
|
+
content: "block+",
|
|
62111
|
+
parseDOM() {
|
|
62112
|
+
return [{ tag: "doc" }];
|
|
62113
|
+
},
|
|
62114
|
+
renderDOM() {
|
|
62115
|
+
return ["doc", 0];
|
|
62116
|
+
},
|
|
62117
|
+
addAttributes() {
|
|
62118
|
+
return {
|
|
62119
|
+
attributes: {
|
|
62120
|
+
rendered: false,
|
|
62121
|
+
"aria-label": "Document node"
|
|
62122
|
+
}
|
|
62123
|
+
};
|
|
62124
|
+
},
|
|
62125
|
+
addCommands() {
|
|
62126
|
+
return {
|
|
62127
|
+
/**
|
|
62128
|
+
* Get document statistics
|
|
62129
|
+
* @category Command
|
|
62130
|
+
* @example
|
|
62131
|
+
* // Get word and character count
|
|
62132
|
+
* const stats = editor.commands.getDocumentStats()
|
|
62133
|
+
* console.log(`${stats.words} words, ${stats.characters} characters`)
|
|
62134
|
+
* @note Returns word count, character count, and paragraph count
|
|
62135
|
+
*/
|
|
62136
|
+
getDocumentStats: () => ({ editor }) => {
|
|
62137
|
+
const text = editor.getText();
|
|
62138
|
+
const words = text.split(/\s+/).filter((word) => word.length > 0).length;
|
|
62139
|
+
const characters = text.length;
|
|
62140
|
+
const paragraphs = editor.state.doc.content.childCount;
|
|
62141
|
+
return {
|
|
62142
|
+
words,
|
|
62143
|
+
characters,
|
|
62144
|
+
paragraphs
|
|
62145
|
+
};
|
|
62146
|
+
},
|
|
62147
|
+
/**
|
|
62148
|
+
* Clear entire document
|
|
62149
|
+
* @category Command
|
|
62150
|
+
* @example
|
|
62151
|
+
* editor.commands.clearDocument()
|
|
62152
|
+
* @note Replaces all content with an empty paragraph
|
|
62153
|
+
*/
|
|
62154
|
+
clearDocument: () => ({ commands: commands2 }) => {
|
|
62155
|
+
return commands2.setContent("<p></p>");
|
|
62156
|
+
}
|
|
62157
|
+
};
|
|
62158
|
+
}
|
|
62159
|
+
});
|
|
62160
|
+
const Text = Node$1.create({
|
|
62161
|
+
name: "text",
|
|
62162
|
+
group: "inline",
|
|
62163
|
+
inline: true,
|
|
62164
|
+
addOptions() {
|
|
62165
|
+
return {};
|
|
62166
|
+
}
|
|
62167
|
+
});
|
|
62168
|
+
const splitRun = () => (props) => {
|
|
62169
|
+
const { state: state2, view, tr } = props;
|
|
62170
|
+
const { $from, empty: empty2 } = state2.selection;
|
|
62171
|
+
if (!empty2) return false;
|
|
62172
|
+
if ($from.parent.type.name !== "run") return false;
|
|
62173
|
+
const handled = splitBlock(state2, (transaction) => {
|
|
62174
|
+
view.dispatch(transaction);
|
|
62175
|
+
});
|
|
62176
|
+
if (handled) {
|
|
62177
|
+
tr.setMeta("preventDispatch", true);
|
|
62178
|
+
}
|
|
62179
|
+
return handled;
|
|
62180
|
+
};
|
|
62181
|
+
const Run = OxmlNode.create({
|
|
62182
|
+
name: "run",
|
|
62183
|
+
oXmlName: "w:r",
|
|
62184
|
+
group: "inline",
|
|
62185
|
+
inline: true,
|
|
62186
|
+
content: "inline*",
|
|
62187
|
+
selectable: false,
|
|
62188
|
+
childToAttributes: ["runProperties"],
|
|
62189
|
+
addOptions() {
|
|
62190
|
+
return {
|
|
62191
|
+
htmlAttributes: {
|
|
62192
|
+
"data-run": "1"
|
|
62193
|
+
}
|
|
62194
|
+
};
|
|
62195
|
+
},
|
|
62196
|
+
addAttributes() {
|
|
62197
|
+
return {
|
|
62198
|
+
runProperties: {
|
|
62199
|
+
default: null,
|
|
62200
|
+
rendered: false,
|
|
62201
|
+
keepOnSplit: true
|
|
62202
|
+
},
|
|
62203
|
+
rsidR: {
|
|
62204
|
+
default: null,
|
|
62205
|
+
rendered: false,
|
|
62206
|
+
keepOnSplit: true
|
|
62207
|
+
},
|
|
62208
|
+
rsidRPr: {
|
|
62209
|
+
default: null,
|
|
62210
|
+
rendered: false,
|
|
62211
|
+
keepOnSplit: true
|
|
62212
|
+
},
|
|
62213
|
+
rsidDel: {
|
|
62214
|
+
default: null,
|
|
62215
|
+
rendered: false,
|
|
62216
|
+
keepOnSplit: true
|
|
62217
|
+
}
|
|
62218
|
+
};
|
|
62219
|
+
},
|
|
62220
|
+
addCommands() {
|
|
62221
|
+
return {
|
|
62222
|
+
splitRun
|
|
62223
|
+
};
|
|
62224
|
+
},
|
|
62225
|
+
parseDOM() {
|
|
62226
|
+
return [{ tag: "span[data-run]" }];
|
|
62227
|
+
},
|
|
62228
|
+
renderDOM({ htmlAttributes }) {
|
|
62229
|
+
const base2 = Attribute.mergeAttributes(this.options.htmlAttributes, htmlAttributes);
|
|
62230
|
+
return ["span", base2, 0];
|
|
62231
|
+
}
|
|
62232
|
+
});
|
|
62233
|
+
const inputRegex$1 = /^\s*([-+*])\s$/;
|
|
62234
|
+
const BulletList = Node$1.create({
|
|
62235
|
+
name: "bulletList",
|
|
62236
|
+
group: "block list",
|
|
62237
|
+
selectable: false,
|
|
62238
|
+
content() {
|
|
62239
|
+
return `${this.options.itemTypeName}+`;
|
|
62240
|
+
},
|
|
62241
|
+
addOptions() {
|
|
62242
|
+
return {
|
|
62243
|
+
itemTypeName: "listItem",
|
|
62244
|
+
htmlAttributes: {
|
|
62245
|
+
"aria-label": "Bullet list node"
|
|
62246
|
+
},
|
|
62247
|
+
keepMarks: true,
|
|
62248
|
+
keepAttributes: false
|
|
62249
|
+
};
|
|
62250
|
+
},
|
|
62251
|
+
parseDOM() {
|
|
62252
|
+
return [{ tag: "ul" }];
|
|
62253
|
+
},
|
|
62254
|
+
renderDOM({ htmlAttributes }) {
|
|
62255
|
+
const attributes = Attribute.mergeAttributes(this.options.htmlAttributes, htmlAttributes);
|
|
62256
|
+
return ["ul", attributes, 0];
|
|
62257
|
+
},
|
|
62258
|
+
addAttributes() {
|
|
62259
|
+
return {
|
|
62260
|
+
"list-style-type": {
|
|
62261
|
+
default: "bullet",
|
|
62262
|
+
rendered: false
|
|
62263
|
+
},
|
|
62264
|
+
listId: {
|
|
62265
|
+
rendered: false
|
|
62266
|
+
},
|
|
62267
|
+
sdBlockId: {
|
|
62268
|
+
default: null,
|
|
62269
|
+
keepOnSplit: false,
|
|
62270
|
+
parseDOM: (elem) => elem.getAttribute("data-sd-block-id"),
|
|
62271
|
+
renderDOM: (attrs) => {
|
|
62272
|
+
return attrs.sdBlockId ? { "data-sd-block-id": attrs.sdBlockId } : {};
|
|
62273
|
+
}
|
|
62274
|
+
},
|
|
62275
|
+
attributes: {
|
|
62276
|
+
rendered: false,
|
|
62277
|
+
keepOnSplit: true
|
|
62278
|
+
}
|
|
62279
|
+
};
|
|
62280
|
+
},
|
|
62281
|
+
addCommands() {
|
|
62282
|
+
return {
|
|
62283
|
+
/**
|
|
62284
|
+
* Toggle a bullet list at the current selection
|
|
62285
|
+
* @category Command
|
|
62286
|
+
* @example
|
|
62287
|
+
* // Toggle bullet list on selected text
|
|
62288
|
+
* editor.commands.toggleBulletList()
|
|
62289
|
+
* @note Converts selected paragraphs to list items or removes list formatting
|
|
62290
|
+
*/
|
|
62291
|
+
toggleBulletList: () => (params2) => {
|
|
62292
|
+
return toggleList(this.type)(params2);
|
|
62293
|
+
}
|
|
62294
|
+
};
|
|
62295
|
+
},
|
|
62296
|
+
addShortcuts() {
|
|
62297
|
+
return {
|
|
62298
|
+
"Mod-Shift-8": () => {
|
|
62299
|
+
return this.editor.commands.toggleBulletList();
|
|
62300
|
+
}
|
|
62301
|
+
};
|
|
62302
|
+
},
|
|
62303
|
+
addInputRules() {
|
|
62304
|
+
return [
|
|
62305
|
+
new InputRule({
|
|
62306
|
+
match: inputRegex$1,
|
|
62307
|
+
handler: ({ state: state2, range: range2 }) => {
|
|
62308
|
+
const $pos = state2.selection.$from;
|
|
62309
|
+
const listItemType = state2.schema.nodes.listItem;
|
|
62310
|
+
for (let depth = $pos.depth; depth >= 0; depth--) {
|
|
62311
|
+
if ($pos.node(depth).type === listItemType) {
|
|
62312
|
+
return null;
|
|
62313
|
+
}
|
|
62314
|
+
}
|
|
62315
|
+
const { tr } = state2;
|
|
62316
|
+
tr.delete(range2.from, range2.to);
|
|
62317
|
+
ListHelpers.createNewList({
|
|
62318
|
+
listType: this.type,
|
|
62319
|
+
tr,
|
|
62320
|
+
editor: this.editor
|
|
62321
|
+
});
|
|
62322
|
+
}
|
|
62323
|
+
})
|
|
62324
|
+
];
|
|
62325
|
+
}
|
|
62326
|
+
});
|
|
62327
|
+
const inputRegex = /^(\d+)\.\s$/;
|
|
62328
|
+
const OrderedList = Node$1.create({
|
|
61293
62329
|
name: "orderedList",
|
|
61294
62330
|
group: "block list",
|
|
61295
62331
|
selectable: false,
|
|
@@ -62650,7 +63686,7 @@ Please report this to https://github.com/markedjs/marked.`, e) {
|
|
|
62650
63686
|
this.decorations = decorations;
|
|
62651
63687
|
this.view = editor.view;
|
|
62652
63688
|
this.getPos = getPos;
|
|
62653
|
-
__privateMethod$1(this, _ListItemNodeView_instances,
|
|
63689
|
+
__privateMethod$1(this, _ListItemNodeView_instances, init_fn3).call(this);
|
|
62654
63690
|
activeListItemNodeViews.add(this);
|
|
62655
63691
|
}
|
|
62656
63692
|
refreshIndentStyling() {
|
|
@@ -62711,7 +63747,7 @@ Please report this to https://github.com/markedjs/marked.`, e) {
|
|
|
62711
63747
|
}
|
|
62712
63748
|
}
|
|
62713
63749
|
_ListItemNodeView_instances = /* @__PURE__ */ new WeakSet();
|
|
62714
|
-
|
|
63750
|
+
init_fn3 = function() {
|
|
62715
63751
|
const { attrs } = this.node;
|
|
62716
63752
|
const { listLevel, listNumberingType, lvlText, numId, level, customFormat } = attrs;
|
|
62717
63753
|
let orderMarker = "";
|
|
@@ -69820,984 +70856,335 @@ Please report this to https://github.com/markedjs/marked.`, e) {
|
|
|
69820
70856
|
}
|
|
69821
70857
|
};
|
|
69822
70858
|
},
|
|
69823
|
-
addAttributes() {
|
|
69824
|
-
return {
|
|
69825
|
-
marksAsAttrs: {
|
|
69826
|
-
default: null,
|
|
69827
|
-
rendered: false
|
|
69828
|
-
}
|
|
69829
|
-
};
|
|
69830
|
-
},
|
|
69831
|
-
addNodeView() {
|
|
69832
|
-
return ({ node, editor, getPos, decorations }) => {
|
|
69833
|
-
const htmlAttributes = this.options.htmlAttributes;
|
|
69834
|
-
return new AutoPageNumberNodeView(node, getPos, decorations, editor, htmlAttributes);
|
|
69835
|
-
};
|
|
69836
|
-
},
|
|
69837
|
-
parseDOM() {
|
|
69838
|
-
return [{ tag: 'span[data-id="auto-page-number"' }];
|
|
69839
|
-
},
|
|
69840
|
-
renderDOM({ htmlAttributes }) {
|
|
69841
|
-
return ["span", Attribute.mergeAttributes(this.options.htmlAttributes, htmlAttributes)];
|
|
69842
|
-
},
|
|
69843
|
-
addCommands() {
|
|
69844
|
-
return {
|
|
69845
|
-
/**
|
|
69846
|
-
* Insert an automatic page number
|
|
69847
|
-
* @category Command
|
|
69848
|
-
* @returns {Function} Command function
|
|
69849
|
-
* @example
|
|
69850
|
-
* editor.commands.addAutoPageNumber()
|
|
69851
|
-
* @note Only works in header/footer contexts
|
|
69852
|
-
*/
|
|
69853
|
-
addAutoPageNumber: () => ({ tr, dispatch, state: state2, editor }) => {
|
|
69854
|
-
const { options } = editor;
|
|
69855
|
-
if (!options.isHeaderOrFooter) return false;
|
|
69856
|
-
const { schema } = state2;
|
|
69857
|
-
const pageNumberType = schema?.nodes?.["page-number"];
|
|
69858
|
-
if (!pageNumberType) return false;
|
|
69859
|
-
const pageNumberNodeJSON = { type: "page-number" };
|
|
69860
|
-
const pageNumberNode = schema.nodeFromJSON(pageNumberNodeJSON);
|
|
69861
|
-
if (dispatch) {
|
|
69862
|
-
tr.replaceSelectionWith(pageNumberNode, false);
|
|
69863
|
-
tr.setMeta("forceUpdatePagination", true);
|
|
69864
|
-
}
|
|
69865
|
-
return true;
|
|
69866
|
-
}
|
|
69867
|
-
};
|
|
69868
|
-
},
|
|
69869
|
-
addShortcuts() {
|
|
69870
|
-
return {
|
|
69871
|
-
"Mod-Shift-alt-p": () => this.editor.commands.addAutoPageNumber()
|
|
69872
|
-
};
|
|
69873
|
-
}
|
|
69874
|
-
});
|
|
69875
|
-
const TotalPageCount = Node$1.create({
|
|
69876
|
-
name: "total-page-number",
|
|
69877
|
-
group: "inline",
|
|
69878
|
-
inline: true,
|
|
69879
|
-
atom: true,
|
|
69880
|
-
draggable: false,
|
|
69881
|
-
selectable: false,
|
|
69882
|
-
content: "text*",
|
|
69883
|
-
addOptions() {
|
|
69884
|
-
return {
|
|
69885
|
-
htmlAttributes: {
|
|
69886
|
-
contenteditable: false,
|
|
69887
|
-
"data-id": "auto-total-pages",
|
|
69888
|
-
"aria-label": "Total page count node",
|
|
69889
|
-
class: "sd-editor-auto-total-pages"
|
|
69890
|
-
}
|
|
69891
|
-
};
|
|
69892
|
-
},
|
|
69893
|
-
addAttributes() {
|
|
69894
|
-
return {
|
|
69895
|
-
marksAsAttrs: {
|
|
69896
|
-
default: null,
|
|
69897
|
-
rendered: false
|
|
69898
|
-
}
|
|
69899
|
-
};
|
|
69900
|
-
},
|
|
69901
|
-
addNodeView() {
|
|
69902
|
-
return ({ node, editor, getPos, decorations }) => {
|
|
69903
|
-
const htmlAttributes = this.options.htmlAttributes;
|
|
69904
|
-
return new AutoPageNumberNodeView(node, getPos, decorations, editor, htmlAttributes);
|
|
69905
|
-
};
|
|
69906
|
-
},
|
|
69907
|
-
parseDOM() {
|
|
69908
|
-
return [{ tag: 'span[data-id="auto-total-pages"' }];
|
|
69909
|
-
},
|
|
69910
|
-
renderDOM({ htmlAttributes }) {
|
|
69911
|
-
return ["span", Attribute.mergeAttributes(this.options.htmlAttributes, htmlAttributes), 0];
|
|
69912
|
-
},
|
|
69913
|
-
addCommands() {
|
|
69914
|
-
return {
|
|
69915
|
-
/**
|
|
69916
|
-
* Insert total page count
|
|
69917
|
-
* @category Command
|
|
69918
|
-
* @returns {Function} Command function
|
|
69919
|
-
* @example
|
|
69920
|
-
* editor.commands.addTotalPageCount()
|
|
69921
|
-
* @note Only works in header/footer contexts
|
|
69922
|
-
*/
|
|
69923
|
-
addTotalPageCount: () => ({ tr, dispatch, state: state2, editor }) => {
|
|
69924
|
-
const { options } = editor;
|
|
69925
|
-
if (!options.isHeaderOrFooter) return false;
|
|
69926
|
-
const { schema } = state2;
|
|
69927
|
-
const pageNumberType = schema.nodes?.["total-page-number"];
|
|
69928
|
-
if (!pageNumberType) return false;
|
|
69929
|
-
const currentPages = editor?.options?.parentEditor?.currentTotalPages || 1;
|
|
69930
|
-
const pageNumberNode = {
|
|
69931
|
-
type: "total-page-number",
|
|
69932
|
-
content: [{ type: "text", text: String(currentPages) }]
|
|
69933
|
-
};
|
|
69934
|
-
const pageNode = schema.nodeFromJSON(pageNumberNode);
|
|
69935
|
-
if (dispatch) {
|
|
69936
|
-
tr.replaceSelectionWith(pageNode, false);
|
|
69937
|
-
}
|
|
69938
|
-
return true;
|
|
69939
|
-
}
|
|
69940
|
-
};
|
|
69941
|
-
},
|
|
69942
|
-
addShortcuts() {
|
|
69943
|
-
return {
|
|
69944
|
-
"Mod-Shift-alt-c": () => this.editor.commands.addTotalPageCount()
|
|
69945
|
-
};
|
|
69946
|
-
}
|
|
69947
|
-
});
|
|
69948
|
-
const getNodeAttributes = (nodeName, editor) => {
|
|
69949
|
-
switch (nodeName) {
|
|
69950
|
-
case "page-number":
|
|
69951
|
-
return {
|
|
69952
|
-
text: editor.options.currentPageNumber || "1",
|
|
69953
|
-
className: "sd-editor-auto-page-number",
|
|
69954
|
-
dataId: "auto-page-number",
|
|
69955
|
-
ariaLabel: "Page number node"
|
|
69956
|
-
};
|
|
69957
|
-
case "total-page-number":
|
|
69958
|
-
return {
|
|
69959
|
-
text: editor.options.parentEditor?.currentTotalPages || "1",
|
|
69960
|
-
className: "sd-editor-auto-total-pages",
|
|
69961
|
-
dataId: "auto-total-pages",
|
|
69962
|
-
ariaLabel: "Total page count node"
|
|
69963
|
-
};
|
|
69964
|
-
default:
|
|
69965
|
-
return {};
|
|
69966
|
-
}
|
|
69967
|
-
};
|
|
69968
|
-
class AutoPageNumberNodeView {
|
|
69969
|
-
constructor(node, getPos, decorations, editor, htmlAttributes = {}) {
|
|
69970
|
-
__privateAdd$1(this, _AutoPageNumberNodeView_instances);
|
|
69971
|
-
this.node = node;
|
|
69972
|
-
this.editor = editor;
|
|
69973
|
-
this.view = editor.view;
|
|
69974
|
-
this.getPos = getPos;
|
|
69975
|
-
this.editor = editor;
|
|
69976
|
-
this.dom = __privateMethod$1(this, _AutoPageNumberNodeView_instances, renderDom_fn).call(this, node, htmlAttributes);
|
|
69977
|
-
}
|
|
69978
|
-
update(node) {
|
|
69979
|
-
const incomingType = node?.type?.name;
|
|
69980
|
-
const currentType = this.node?.type?.name;
|
|
69981
|
-
if (!incomingType || incomingType !== currentType) return false;
|
|
69982
|
-
this.node = node;
|
|
69983
|
-
return true;
|
|
69984
|
-
}
|
|
69985
|
-
}
|
|
69986
|
-
_AutoPageNumberNodeView_instances = /* @__PURE__ */ new WeakSet();
|
|
69987
|
-
renderDom_fn = function(node, htmlAttributes) {
|
|
69988
|
-
const attrs = getNodeAttributes(this.node.type.name, this.editor);
|
|
69989
|
-
const content = document.createTextNode(String(attrs.text));
|
|
69990
|
-
const nodeContent = document.createElement("span");
|
|
69991
|
-
nodeContent.className = attrs.className;
|
|
69992
|
-
nodeContent.setAttribute("data-id", attrs.dataId);
|
|
69993
|
-
nodeContent.setAttribute("aria-label", attrs.ariaLabel);
|
|
69994
|
-
const currentPos = this.getPos();
|
|
69995
|
-
const { styles, marks } = getMarksFromNeighbors(currentPos, this.view);
|
|
69996
|
-
__privateMethod$1(this, _AutoPageNumberNodeView_instances, scheduleUpdateNodeStyle_fn).call(this, currentPos, marks);
|
|
69997
|
-
Object.assign(nodeContent.style, styles);
|
|
69998
|
-
nodeContent.appendChild(content);
|
|
69999
|
-
Object.entries(htmlAttributes).forEach(([key2, value]) => {
|
|
70000
|
-
if (value) nodeContent.setAttribute(key2, value);
|
|
70001
|
-
});
|
|
70002
|
-
return nodeContent;
|
|
70003
|
-
};
|
|
70004
|
-
scheduleUpdateNodeStyle_fn = function(pos, marks) {
|
|
70005
|
-
setTimeout(() => {
|
|
70006
|
-
const { state: state2 } = this.editor;
|
|
70007
|
-
const { dispatch } = this.view;
|
|
70008
|
-
const node = state2.doc.nodeAt(pos);
|
|
70009
|
-
if (!node || node.isText) return;
|
|
70010
|
-
const currentMarks = node.attrs.marksAsAttrs || [];
|
|
70011
|
-
const newMarks = marks.map((m2) => ({ type: m2.type.name, attrs: m2.attrs }));
|
|
70012
|
-
const isEqual = JSON.stringify(currentMarks) === JSON.stringify(newMarks);
|
|
70013
|
-
if (isEqual) return;
|
|
70014
|
-
const newAttrs = {
|
|
70015
|
-
...node.attrs,
|
|
70016
|
-
marksAsAttrs: newMarks
|
|
70017
|
-
};
|
|
70018
|
-
const tr = state2.tr.setNodeMarkup(pos, void 0, newAttrs);
|
|
70019
|
-
dispatch(tr);
|
|
70020
|
-
}, 0);
|
|
70021
|
-
};
|
|
70022
|
-
const getMarksFromNeighbors = (currentPos, view) => {
|
|
70023
|
-
const $pos = view.state.doc.resolve(currentPos);
|
|
70024
|
-
const styles = {};
|
|
70025
|
-
const marks = [];
|
|
70026
|
-
const before = $pos.nodeBefore;
|
|
70027
|
-
if (before) {
|
|
70028
|
-
Object.assign(styles, processMarks(before.marks));
|
|
70029
|
-
marks.push(...before.marks);
|
|
70030
|
-
}
|
|
70031
|
-
const after = $pos.nodeAfter;
|
|
70032
|
-
if (after) {
|
|
70033
|
-
Object.assign(styles, { ...styles, ...processMarks(after.marks) });
|
|
70034
|
-
marks.push(...after.marks);
|
|
70035
|
-
}
|
|
70036
|
-
return {
|
|
70037
|
-
styles,
|
|
70038
|
-
marks
|
|
70039
|
-
};
|
|
70040
|
-
};
|
|
70041
|
-
const processMarks = (marks) => {
|
|
70042
|
-
const styles = {};
|
|
70043
|
-
marks.forEach((mark) => {
|
|
70044
|
-
const { type: type2, attrs } = mark;
|
|
70045
|
-
switch (type2.name) {
|
|
70046
|
-
case "textStyle":
|
|
70047
|
-
if (attrs.fontFamily) styles["font-family"] = attrs.fontFamily;
|
|
70048
|
-
if (attrs.fontSize) styles["font-size"] = attrs.fontSize;
|
|
70049
|
-
if (attrs.color) styles["color"] = attrs.color;
|
|
70050
|
-
if (attrs.backgroundColor) styles["background-color"] = attrs.backgroundColor;
|
|
70051
|
-
break;
|
|
70052
|
-
case "bold":
|
|
70053
|
-
styles["font-weight"] = "bold";
|
|
70054
|
-
break;
|
|
70055
|
-
case "italic":
|
|
70056
|
-
styles["font-style"] = "italic";
|
|
70057
|
-
break;
|
|
70058
|
-
case "underline":
|
|
70059
|
-
styles["text-decoration"] = (styles["text-decoration"] || "") + " underline";
|
|
70060
|
-
break;
|
|
70061
|
-
case "strike":
|
|
70062
|
-
styles["text-decoration"] = (styles["text-decoration"] || "") + " line-through";
|
|
70063
|
-
break;
|
|
70064
|
-
default:
|
|
70065
|
-
if (attrs?.style) {
|
|
70066
|
-
Object.entries(attrs.style).forEach(([key2, value]) => {
|
|
70067
|
-
styles[key2] = value;
|
|
70068
|
-
});
|
|
70069
|
-
}
|
|
70070
|
-
break;
|
|
70071
|
-
}
|
|
70072
|
-
});
|
|
70073
|
-
return styles;
|
|
70074
|
-
};
|
|
70075
|
-
const ShapeContainer = Node$1.create({
|
|
70076
|
-
name: "shapeContainer",
|
|
70077
|
-
group: "block",
|
|
70078
|
-
content: "block+",
|
|
70079
|
-
isolating: true,
|
|
70080
|
-
addOptions() {
|
|
70081
|
-
return {
|
|
70082
|
-
htmlAttributes: {
|
|
70083
|
-
class: "sd-editor-shape-container",
|
|
70084
|
-
"aria-label": "Shape container node"
|
|
70085
|
-
}
|
|
70086
|
-
};
|
|
70087
|
-
},
|
|
70088
|
-
addAttributes() {
|
|
70089
|
-
return {
|
|
70090
|
-
fillcolor: {
|
|
70091
|
-
renderDOM: (attrs) => {
|
|
70092
|
-
if (!attrs.fillcolor) return {};
|
|
70093
|
-
return {
|
|
70094
|
-
style: `background-color: ${attrs.fillcolor}`
|
|
70095
|
-
};
|
|
70096
|
-
}
|
|
70097
|
-
},
|
|
70098
|
-
sdBlockId: {
|
|
70099
|
-
default: null,
|
|
70100
|
-
keepOnSplit: false,
|
|
70101
|
-
parseDOM: (elem) => elem.getAttribute("data-sd-block-id"),
|
|
70102
|
-
renderDOM: (attrs) => {
|
|
70103
|
-
return attrs.sdBlockId ? { "data-sd-block-id": attrs.sdBlockId } : {};
|
|
70104
|
-
}
|
|
70105
|
-
},
|
|
70106
|
-
style: {
|
|
70107
|
-
renderDOM: (attrs) => {
|
|
70108
|
-
if (!attrs.style) return {};
|
|
70109
|
-
return {
|
|
70110
|
-
style: attrs.style
|
|
70111
|
-
};
|
|
70112
|
-
}
|
|
70113
|
-
},
|
|
70114
|
-
wrapAttributes: {
|
|
70115
|
-
rendered: false
|
|
70116
|
-
},
|
|
70117
|
-
attributes: {
|
|
70118
|
-
rendered: false
|
|
70119
|
-
}
|
|
70120
|
-
};
|
|
70121
|
-
},
|
|
70122
|
-
parseDOM() {
|
|
70123
|
-
return [
|
|
70124
|
-
{
|
|
70125
|
-
tag: `div[data-type="${this.name}"]`
|
|
70126
|
-
}
|
|
70127
|
-
];
|
|
70128
|
-
},
|
|
70129
|
-
renderDOM({ htmlAttributes }) {
|
|
70130
|
-
return [
|
|
70131
|
-
"div",
|
|
70132
|
-
Attribute.mergeAttributes(this.options.htmlAttributes, htmlAttributes, { "data-type": this.name }),
|
|
70133
|
-
0
|
|
70134
|
-
];
|
|
70135
|
-
}
|
|
70136
|
-
});
|
|
70137
|
-
const ShapeTextbox = Node$1.create({
|
|
70138
|
-
name: "shapeTextbox",
|
|
70139
|
-
group: "block",
|
|
70140
|
-
content: "paragraph* block*",
|
|
70141
|
-
isolating: true,
|
|
70142
|
-
addOptions() {
|
|
70143
|
-
return {
|
|
70144
|
-
htmlAttributes: {
|
|
70145
|
-
class: "sd-editor-shape-textbox",
|
|
70146
|
-
"aria-label": "Shape textbox node"
|
|
70147
|
-
}
|
|
70148
|
-
};
|
|
70149
|
-
},
|
|
70150
|
-
addAttributes() {
|
|
70151
|
-
return {
|
|
70152
|
-
sdBlockId: {
|
|
70153
|
-
default: null,
|
|
70154
|
-
keepOnSplit: false,
|
|
70155
|
-
parseDOM: (elem) => elem.getAttribute("data-sd-block-id"),
|
|
70156
|
-
renderDOM: (attrs) => {
|
|
70157
|
-
return attrs.sdBlockId ? { "data-sd-block-id": attrs.sdBlockId } : {};
|
|
70158
|
-
}
|
|
70159
|
-
},
|
|
70160
|
-
attributes: {
|
|
70161
|
-
rendered: false
|
|
70162
|
-
}
|
|
70163
|
-
};
|
|
70164
|
-
},
|
|
70165
|
-
parseDOM() {
|
|
70166
|
-
return [
|
|
70167
|
-
{
|
|
70168
|
-
tag: `div[data-type="${this.name}"]`
|
|
70169
|
-
}
|
|
70170
|
-
];
|
|
70171
|
-
},
|
|
70172
|
-
renderDOM({ htmlAttributes }) {
|
|
70173
|
-
return [
|
|
70174
|
-
"div",
|
|
70175
|
-
Attribute.mergeAttributes(this.options.htmlAttributes, htmlAttributes, { "data-type": this.name }),
|
|
70176
|
-
0
|
|
70177
|
-
];
|
|
70178
|
-
}
|
|
70179
|
-
});
|
|
70180
|
-
const ContentBlock = Node$1.create({
|
|
70181
|
-
name: "contentBlock",
|
|
70182
|
-
group: "inline",
|
|
70183
|
-
content: "",
|
|
70184
|
-
isolating: true,
|
|
70185
|
-
atom: true,
|
|
70186
|
-
inline: true,
|
|
70187
|
-
addOptions() {
|
|
70188
|
-
return {
|
|
70189
|
-
htmlAttributes: {
|
|
70190
|
-
contenteditable: false
|
|
70191
|
-
}
|
|
70192
|
-
};
|
|
70193
|
-
},
|
|
70194
|
-
addAttributes() {
|
|
70195
|
-
return {
|
|
70196
|
-
horizontalRule: {
|
|
70197
|
-
default: false,
|
|
70198
|
-
renderDOM: ({ horizontalRule }) => {
|
|
70199
|
-
if (!horizontalRule) return {};
|
|
70200
|
-
return { "data-horizontal-rule": "true" };
|
|
70201
|
-
}
|
|
70202
|
-
},
|
|
70203
|
-
size: {
|
|
70204
|
-
default: null,
|
|
70205
|
-
renderDOM: ({ size: size2 }) => {
|
|
70206
|
-
if (!size2) return {};
|
|
70207
|
-
let style2 = "";
|
|
70208
|
-
if (size2.top) style2 += `top: ${size2.top}px; `;
|
|
70209
|
-
if (size2.left) style2 += `left: ${size2.left}px; `;
|
|
70210
|
-
if (size2.width) style2 += `width: ${size2.width.toString().endsWith("%") ? size2.width : `${size2.width}px`}; `;
|
|
70211
|
-
if (size2.height)
|
|
70212
|
-
style2 += `height: ${size2.height.toString().endsWith("%") ? size2.height : `${size2.height}px`}; `;
|
|
70213
|
-
return { style: style2 };
|
|
70214
|
-
}
|
|
70215
|
-
},
|
|
70216
|
-
background: {
|
|
70217
|
-
default: null,
|
|
70218
|
-
renderDOM: (attrs) => {
|
|
70219
|
-
if (!attrs.background) return {};
|
|
70220
|
-
return {
|
|
70221
|
-
style: `background-color: ${attrs.background}`
|
|
70222
|
-
};
|
|
70223
|
-
}
|
|
70224
|
-
},
|
|
70225
|
-
drawingContent: {
|
|
70226
|
-
rendered: false
|
|
70227
|
-
},
|
|
70228
|
-
attributes: {
|
|
70859
|
+
addAttributes() {
|
|
70860
|
+
return {
|
|
70861
|
+
marksAsAttrs: {
|
|
70862
|
+
default: null,
|
|
70229
70863
|
rendered: false
|
|
70230
70864
|
}
|
|
70231
70865
|
};
|
|
70232
70866
|
},
|
|
70867
|
+
addNodeView() {
|
|
70868
|
+
return ({ node, editor, getPos, decorations }) => {
|
|
70869
|
+
const htmlAttributes = this.options.htmlAttributes;
|
|
70870
|
+
return new AutoPageNumberNodeView(node, getPos, decorations, editor, htmlAttributes);
|
|
70871
|
+
};
|
|
70872
|
+
},
|
|
70233
70873
|
parseDOM() {
|
|
70234
|
-
return [
|
|
70235
|
-
{
|
|
70236
|
-
tag: `div[data-type="${this.name}"]`
|
|
70237
|
-
}
|
|
70238
|
-
];
|
|
70874
|
+
return [{ tag: 'span[data-id="auto-page-number"' }];
|
|
70239
70875
|
},
|
|
70240
70876
|
renderDOM({ htmlAttributes }) {
|
|
70241
|
-
return ["
|
|
70877
|
+
return ["span", Attribute.mergeAttributes(this.options.htmlAttributes, htmlAttributes)];
|
|
70242
70878
|
},
|
|
70243
70879
|
addCommands() {
|
|
70244
70880
|
return {
|
|
70245
70881
|
/**
|
|
70246
|
-
* Insert
|
|
70247
|
-
* @category Command
|
|
70248
|
-
* @example
|
|
70249
|
-
* editor.commands.insertHorizontalRule()
|
|
70250
|
-
* @note Creates a visual separator between content sections
|
|
70251
|
-
*/
|
|
70252
|
-
insertHorizontalRule: () => ({ commands: commands2 }) => {
|
|
70253
|
-
return commands2.insertContent({
|
|
70254
|
-
type: this.name,
|
|
70255
|
-
attrs: {
|
|
70256
|
-
horizontalRule: true,
|
|
70257
|
-
size: { width: "100%", height: 2 },
|
|
70258
|
-
background: "#e5e7eb"
|
|
70259
|
-
}
|
|
70260
|
-
});
|
|
70261
|
-
},
|
|
70262
|
-
/**
|
|
70263
|
-
* Insert a content block
|
|
70882
|
+
* Insert an automatic page number
|
|
70264
70883
|
* @category Command
|
|
70265
|
-
* @
|
|
70266
|
-
* @example
|
|
70267
|
-
* // Insert a spacer block
|
|
70268
|
-
* editor.commands.insertContentBlock({ size: { height: 20 } })
|
|
70269
|
-
*
|
|
70884
|
+
* @returns {Function} Command function
|
|
70270
70885
|
* @example
|
|
70271
|
-
*
|
|
70272
|
-
*
|
|
70273
|
-
* size: { width: '50%', height: 3 },
|
|
70274
|
-
* background: '#3b82f6'
|
|
70275
|
-
* })
|
|
70276
|
-
* @note Used for spacing, dividers, and special inline content
|
|
70886
|
+
* editor.commands.addAutoPageNumber()
|
|
70887
|
+
* @note Only works in header/footer contexts
|
|
70277
70888
|
*/
|
|
70278
|
-
|
|
70279
|
-
|
|
70280
|
-
|
|
70281
|
-
|
|
70282
|
-
|
|
70889
|
+
addAutoPageNumber: () => ({ tr, dispatch, state: state2, editor }) => {
|
|
70890
|
+
const { options } = editor;
|
|
70891
|
+
if (!options.isHeaderOrFooter) return false;
|
|
70892
|
+
const { schema } = state2;
|
|
70893
|
+
const pageNumberType = schema?.nodes?.["page-number"];
|
|
70894
|
+
if (!pageNumberType) return false;
|
|
70895
|
+
const pageNumberNodeJSON = { type: "page-number" };
|
|
70896
|
+
const pageNumberNode = schema.nodeFromJSON(pageNumberNodeJSON);
|
|
70897
|
+
if (dispatch) {
|
|
70898
|
+
tr.replaceSelectionWith(pageNumberNode, false);
|
|
70899
|
+
tr.setMeta("forceUpdatePagination", true);
|
|
70900
|
+
}
|
|
70901
|
+
return true;
|
|
70283
70902
|
}
|
|
70284
70903
|
};
|
|
70904
|
+
},
|
|
70905
|
+
addShortcuts() {
|
|
70906
|
+
return {
|
|
70907
|
+
"Mod-Shift-alt-p": () => this.editor.commands.addAutoPageNumber()
|
|
70908
|
+
};
|
|
70285
70909
|
}
|
|
70286
70910
|
});
|
|
70287
|
-
|
|
70288
|
-
|
|
70289
|
-
|
|
70290
|
-
__publicField$1(this, "view");
|
|
70291
|
-
__publicField$1(this, "getPos");
|
|
70292
|
-
__publicField$1(this, "decorations");
|
|
70293
|
-
__publicField$1(this, "innerDecorations");
|
|
70294
|
-
__publicField$1(this, "editor");
|
|
70295
|
-
__publicField$1(this, "extension");
|
|
70296
|
-
__publicField$1(this, "htmlAttributes");
|
|
70297
|
-
__publicField$1(this, "root");
|
|
70298
|
-
__publicField$1(this, "isDragging", false);
|
|
70299
|
-
this.node = props.node;
|
|
70300
|
-
this.view = props.editor.view;
|
|
70301
|
-
this.getPos = props.getPos;
|
|
70302
|
-
this.decorations = props.decorations;
|
|
70303
|
-
this.innerDecorations = props.innerDecorations;
|
|
70304
|
-
this.editor = props.editor;
|
|
70305
|
-
this.extension = props.extension;
|
|
70306
|
-
this.htmlAttributes = props.htmlAttributes;
|
|
70307
|
-
this.mount(props);
|
|
70308
|
-
}
|
|
70309
|
-
mount() {
|
|
70310
|
-
return;
|
|
70311
|
-
}
|
|
70312
|
-
get dom() {
|
|
70313
|
-
return this.root;
|
|
70314
|
-
}
|
|
70315
|
-
get contentDOM() {
|
|
70316
|
-
return null;
|
|
70317
|
-
}
|
|
70318
|
-
update(node, decorations, innerDecorations) {
|
|
70319
|
-
if (node.type !== this.node.type) {
|
|
70320
|
-
return false;
|
|
70321
|
-
}
|
|
70322
|
-
this.node = node;
|
|
70323
|
-
this.decorations = decorations;
|
|
70324
|
-
this.innerDecorations = innerDecorations;
|
|
70325
|
-
this.updateHTMLAttributes();
|
|
70326
|
-
return true;
|
|
70327
|
-
}
|
|
70328
|
-
stopEvent(event) {
|
|
70329
|
-
if (!this.dom) return false;
|
|
70330
|
-
const target = event.target;
|
|
70331
|
-
const isInElement = this.dom.contains(target) && !this.contentDOM?.contains(target);
|
|
70332
|
-
if (!isInElement) return false;
|
|
70333
|
-
const isDragEvent = event.type.startsWith("drag");
|
|
70334
|
-
const isDropEvent = event.type === "drop";
|
|
70335
|
-
const isInput = ["INPUT", "BUTTON", "SELECT", "TEXTAREA"].includes(target.tagName) || target.isContentEditable;
|
|
70336
|
-
if (isInput && !isDropEvent && !isDragEvent) return true;
|
|
70337
|
-
const { isEditable } = this.editor;
|
|
70338
|
-
const { isDragging } = this;
|
|
70339
|
-
const isDraggable = !!this.node.type.spec.draggable;
|
|
70340
|
-
const isSelectable = NodeSelection.isSelectable(this.node);
|
|
70341
|
-
const isCopyEvent = event.type === "copy";
|
|
70342
|
-
const isPasteEvent = event.type === "paste";
|
|
70343
|
-
const isCutEvent = event.type === "cut";
|
|
70344
|
-
const isClickEvent = event.type === "mousedown";
|
|
70345
|
-
if (!isDraggable && isSelectable && isDragEvent && event.target === this.dom) {
|
|
70346
|
-
event.preventDefault();
|
|
70347
|
-
}
|
|
70348
|
-
if (isDraggable && isDragEvent && !isDragging && event.target === this.dom) {
|
|
70349
|
-
event.preventDefault();
|
|
70350
|
-
return false;
|
|
70351
|
-
}
|
|
70352
|
-
if (isDraggable && isEditable && !isDragging && isClickEvent) {
|
|
70353
|
-
const dragHandle = target.closest("[data-drag-handle]");
|
|
70354
|
-
const isValidDragHandle = dragHandle && (this.dom === dragHandle || this.dom.contains(dragHandle));
|
|
70355
|
-
if (isValidDragHandle) {
|
|
70356
|
-
this.isDragging = true;
|
|
70357
|
-
document.addEventListener(
|
|
70358
|
-
"dragend",
|
|
70359
|
-
() => {
|
|
70360
|
-
this.isDragging = false;
|
|
70361
|
-
},
|
|
70362
|
-
{ once: true }
|
|
70363
|
-
);
|
|
70364
|
-
document.addEventListener(
|
|
70365
|
-
"drop",
|
|
70366
|
-
() => {
|
|
70367
|
-
this.isDragging = false;
|
|
70368
|
-
},
|
|
70369
|
-
{ once: true }
|
|
70370
|
-
);
|
|
70371
|
-
document.addEventListener(
|
|
70372
|
-
"mouseup",
|
|
70373
|
-
() => {
|
|
70374
|
-
this.isDragging = false;
|
|
70375
|
-
},
|
|
70376
|
-
{ once: true }
|
|
70377
|
-
);
|
|
70378
|
-
}
|
|
70379
|
-
}
|
|
70380
|
-
if (isDragging || isDropEvent || isCopyEvent || isPasteEvent || isCutEvent || isClickEvent && isSelectable) {
|
|
70381
|
-
return false;
|
|
70382
|
-
}
|
|
70383
|
-
return true;
|
|
70384
|
-
}
|
|
70385
|
-
ignoreMutation(mutation) {
|
|
70386
|
-
if (!this.dom || !this.contentDOM) return true;
|
|
70387
|
-
if (this.node.isLeaf || this.node.isAtom) return true;
|
|
70388
|
-
if (mutation.type === "selection") return false;
|
|
70389
|
-
if (this.contentDOM === mutation.target && mutation.type === "attributes") return true;
|
|
70390
|
-
if (this.contentDOM.contains(mutation.target)) return false;
|
|
70391
|
-
return true;
|
|
70392
|
-
}
|
|
70393
|
-
destroy() {
|
|
70394
|
-
this.dom.remove();
|
|
70395
|
-
this.contentDOM?.remove();
|
|
70396
|
-
}
|
|
70397
|
-
updateAttributes(attrs) {
|
|
70398
|
-
const pos = this.getPos();
|
|
70399
|
-
if (typeof pos !== "number") {
|
|
70400
|
-
return;
|
|
70401
|
-
}
|
|
70402
|
-
return this.view.dispatch(
|
|
70403
|
-
this.view.state.tr.setNodeMarkup(pos, void 0, {
|
|
70404
|
-
...this.node.attrs,
|
|
70405
|
-
...attrs
|
|
70406
|
-
})
|
|
70407
|
-
);
|
|
70408
|
-
}
|
|
70409
|
-
updateHTMLAttributes() {
|
|
70410
|
-
const { extensionService } = this.editor;
|
|
70411
|
-
const { attributes } = extensionService;
|
|
70412
|
-
const extensionAttrs = attributes.filter((i2) => i2.type === this.node.type.name);
|
|
70413
|
-
this.htmlAttributes = Attribute.getAttributesToRender(this.node, extensionAttrs);
|
|
70414
|
-
}
|
|
70415
|
-
createDragHandle() {
|
|
70416
|
-
const dragHandle = document.createElement("span");
|
|
70417
|
-
dragHandle.classList.add("sd-structured-content-draggable");
|
|
70418
|
-
dragHandle.draggable = true;
|
|
70419
|
-
dragHandle.contentEditable = "false";
|
|
70420
|
-
dragHandle.dataset.dragHandle = "";
|
|
70421
|
-
const textElement = document.createElement("span");
|
|
70422
|
-
textElement.textContent = "Structured content";
|
|
70423
|
-
dragHandle.append(textElement);
|
|
70424
|
-
return dragHandle;
|
|
70425
|
-
}
|
|
70426
|
-
onDragStart(event) {
|
|
70427
|
-
const { view } = this.editor;
|
|
70428
|
-
const target = event.target;
|
|
70429
|
-
const dragHandle = target.nodeType === 3 ? target.parentElement?.closest("[data-drag-handle]") : target.closest("[data-drag-handle]");
|
|
70430
|
-
if (!this.dom || this.contentDOM?.contains(target) || !dragHandle) {
|
|
70431
|
-
return;
|
|
70432
|
-
}
|
|
70433
|
-
let x = 0;
|
|
70434
|
-
let y2 = 0;
|
|
70435
|
-
if (this.dom !== dragHandle) {
|
|
70436
|
-
const domBox = this.dom.getBoundingClientRect();
|
|
70437
|
-
const handleBox = dragHandle.getBoundingClientRect();
|
|
70438
|
-
const offsetX = event.offsetX ?? event.nativeEvent?.offsetX;
|
|
70439
|
-
const offsetY = event.offsetY ?? event.nativeEvent?.offsetY;
|
|
70440
|
-
x = handleBox.x - domBox.x + offsetX;
|
|
70441
|
-
y2 = handleBox.y - domBox.y + offsetY;
|
|
70442
|
-
}
|
|
70443
|
-
event.dataTransfer?.setDragImage(this.dom, x, y2);
|
|
70444
|
-
const pos = this.getPos();
|
|
70445
|
-
if (typeof pos !== "number") {
|
|
70446
|
-
return;
|
|
70447
|
-
}
|
|
70448
|
-
const selection = NodeSelection.create(view.state.doc, pos);
|
|
70449
|
-
const transaction = view.state.tr.setSelection(selection);
|
|
70450
|
-
view.dispatch(transaction);
|
|
70451
|
-
}
|
|
70452
|
-
}
|
|
70453
|
-
class StructuredContentInlineView extends StructuredContentViewBase {
|
|
70454
|
-
constructor(props) {
|
|
70455
|
-
super(props);
|
|
70456
|
-
}
|
|
70457
|
-
mount() {
|
|
70458
|
-
this.buildView();
|
|
70459
|
-
}
|
|
70460
|
-
get contentDOM() {
|
|
70461
|
-
const contentElement = this.dom?.querySelector(`.${structuredContentInnerClass$1}`);
|
|
70462
|
-
return contentElement || null;
|
|
70463
|
-
}
|
|
70464
|
-
createElement() {
|
|
70465
|
-
const element = document.createElement("span");
|
|
70466
|
-
element.classList.add(structuredContentClass$1);
|
|
70467
|
-
element.setAttribute("data-structured-content", "");
|
|
70468
|
-
const contentElement = document.createElement("span");
|
|
70469
|
-
contentElement.classList.add(structuredContentInnerClass$1);
|
|
70470
|
-
element.append(contentElement);
|
|
70471
|
-
const domAttrs = Attribute.mergeAttributes(this.htmlAttributes);
|
|
70472
|
-
updateDOMAttributes(element, { ...domAttrs });
|
|
70473
|
-
return { element, contentElement };
|
|
70474
|
-
}
|
|
70475
|
-
buildView() {
|
|
70476
|
-
const { element } = this.createElement();
|
|
70477
|
-
const dragHandle = this.createDragHandle();
|
|
70478
|
-
element.prepend(dragHandle);
|
|
70479
|
-
element.addEventListener("dragstart", (e) => this.onDragStart(e));
|
|
70480
|
-
this.root = element;
|
|
70481
|
-
}
|
|
70482
|
-
updateView() {
|
|
70483
|
-
const domAttrs = Attribute.mergeAttributes(this.htmlAttributes);
|
|
70484
|
-
updateDOMAttributes(this.dom, { ...domAttrs });
|
|
70485
|
-
}
|
|
70486
|
-
update(node, decorations, innerDecorations) {
|
|
70487
|
-
const result = super.update(node, decorations, innerDecorations);
|
|
70488
|
-
if (!result) return false;
|
|
70489
|
-
this.updateView();
|
|
70490
|
-
return true;
|
|
70491
|
-
}
|
|
70492
|
-
}
|
|
70493
|
-
const structuredContentClass$1 = "sd-structured-content";
|
|
70494
|
-
const structuredContentInnerClass$1 = "sd-structured-content__content";
|
|
70495
|
-
const StructuredContent = Node$1.create({
|
|
70496
|
-
name: "structuredContent",
|
|
70497
|
-
group: "inline structuredContent",
|
|
70911
|
+
const TotalPageCount = Node$1.create({
|
|
70912
|
+
name: "total-page-number",
|
|
70913
|
+
group: "inline",
|
|
70498
70914
|
inline: true,
|
|
70499
|
-
|
|
70500
|
-
|
|
70501
|
-
|
|
70502
|
-
|
|
70503
|
-
draggable: true,
|
|
70915
|
+
atom: true,
|
|
70916
|
+
draggable: false,
|
|
70917
|
+
selectable: false,
|
|
70918
|
+
content: "text*",
|
|
70504
70919
|
addOptions() {
|
|
70505
70920
|
return {
|
|
70506
70921
|
htmlAttributes: {
|
|
70507
|
-
|
|
70508
|
-
"
|
|
70922
|
+
contenteditable: false,
|
|
70923
|
+
"data-id": "auto-total-pages",
|
|
70924
|
+
"aria-label": "Total page count node",
|
|
70925
|
+
class: "sd-editor-auto-total-pages"
|
|
70509
70926
|
}
|
|
70510
70927
|
};
|
|
70511
70928
|
},
|
|
70512
70929
|
addAttributes() {
|
|
70513
70930
|
return {
|
|
70514
|
-
|
|
70931
|
+
marksAsAttrs: {
|
|
70515
70932
|
default: null,
|
|
70516
|
-
parseDOM: (elem) => elem.getAttribute("data-id"),
|
|
70517
|
-
renderDOM: (attrs) => {
|
|
70518
|
-
if (!attrs.id) return {};
|
|
70519
|
-
return { "data-id": attrs.id };
|
|
70520
|
-
}
|
|
70521
|
-
},
|
|
70522
|
-
sdtPr: {
|
|
70523
70933
|
rendered: false
|
|
70524
70934
|
}
|
|
70525
70935
|
};
|
|
70526
70936
|
},
|
|
70937
|
+
addNodeView() {
|
|
70938
|
+
return ({ node, editor, getPos, decorations }) => {
|
|
70939
|
+
const htmlAttributes = this.options.htmlAttributes;
|
|
70940
|
+
return new AutoPageNumberNodeView(node, getPos, decorations, editor, htmlAttributes);
|
|
70941
|
+
};
|
|
70942
|
+
},
|
|
70527
70943
|
parseDOM() {
|
|
70528
|
-
return [{ tag:
|
|
70944
|
+
return [{ tag: 'span[data-id="auto-total-pages"' }];
|
|
70529
70945
|
},
|
|
70530
70946
|
renderDOM({ htmlAttributes }) {
|
|
70531
|
-
return [
|
|
70532
|
-
"span",
|
|
70533
|
-
Attribute.mergeAttributes(this.options.htmlAttributes, htmlAttributes, {
|
|
70534
|
-
"data-structured-content": ""
|
|
70535
|
-
}),
|
|
70536
|
-
0
|
|
70537
|
-
];
|
|
70947
|
+
return ["span", Attribute.mergeAttributes(this.options.htmlAttributes, htmlAttributes), 0];
|
|
70538
70948
|
},
|
|
70539
|
-
|
|
70540
|
-
return
|
|
70541
|
-
|
|
70949
|
+
addCommands() {
|
|
70950
|
+
return {
|
|
70951
|
+
/**
|
|
70952
|
+
* Insert total page count
|
|
70953
|
+
* @category Command
|
|
70954
|
+
* @returns {Function} Command function
|
|
70955
|
+
* @example
|
|
70956
|
+
* editor.commands.addTotalPageCount()
|
|
70957
|
+
* @note Only works in header/footer contexts
|
|
70958
|
+
*/
|
|
70959
|
+
addTotalPageCount: () => ({ tr, dispatch, state: state2, editor }) => {
|
|
70960
|
+
const { options } = editor;
|
|
70961
|
+
if (!options.isHeaderOrFooter) return false;
|
|
70962
|
+
const { schema } = state2;
|
|
70963
|
+
const pageNumberType = schema.nodes?.["total-page-number"];
|
|
70964
|
+
if (!pageNumberType) return false;
|
|
70965
|
+
const currentPages = editor?.options?.parentEditor?.currentTotalPages || 1;
|
|
70966
|
+
const pageNumberNode = {
|
|
70967
|
+
type: "total-page-number",
|
|
70968
|
+
content: [{ type: "text", text: String(currentPages) }]
|
|
70969
|
+
};
|
|
70970
|
+
const pageNode = schema.nodeFromJSON(pageNumberNode);
|
|
70971
|
+
if (dispatch) {
|
|
70972
|
+
tr.replaceSelectionWith(pageNode, false);
|
|
70973
|
+
}
|
|
70974
|
+
return true;
|
|
70975
|
+
}
|
|
70976
|
+
};
|
|
70977
|
+
},
|
|
70978
|
+
addShortcuts() {
|
|
70979
|
+
return {
|
|
70980
|
+
"Mod-Shift-alt-c": () => this.editor.commands.addTotalPageCount()
|
|
70542
70981
|
};
|
|
70543
70982
|
}
|
|
70544
70983
|
});
|
|
70545
|
-
|
|
70546
|
-
|
|
70547
|
-
|
|
70548
|
-
|
|
70549
|
-
|
|
70550
|
-
|
|
70551
|
-
|
|
70552
|
-
|
|
70553
|
-
|
|
70554
|
-
|
|
70555
|
-
|
|
70556
|
-
|
|
70557
|
-
|
|
70558
|
-
|
|
70559
|
-
|
|
70560
|
-
|
|
70561
|
-
|
|
70562
|
-
|
|
70563
|
-
const domAttrs = Attribute.mergeAttributes(this.htmlAttributes);
|
|
70564
|
-
updateDOMAttributes(element, { ...domAttrs });
|
|
70565
|
-
return { element, contentElement };
|
|
70566
|
-
}
|
|
70567
|
-
buildView() {
|
|
70568
|
-
const { element } = this.createElement();
|
|
70569
|
-
const dragHandle = this.createDragHandle();
|
|
70570
|
-
element.prepend(dragHandle);
|
|
70571
|
-
element.addEventListener("dragstart", (e) => this.onDragStart(e));
|
|
70572
|
-
this.root = element;
|
|
70984
|
+
const getNodeAttributes = (nodeName, editor) => {
|
|
70985
|
+
switch (nodeName) {
|
|
70986
|
+
case "page-number":
|
|
70987
|
+
return {
|
|
70988
|
+
text: editor.options.currentPageNumber || "1",
|
|
70989
|
+
className: "sd-editor-auto-page-number",
|
|
70990
|
+
dataId: "auto-page-number",
|
|
70991
|
+
ariaLabel: "Page number node"
|
|
70992
|
+
};
|
|
70993
|
+
case "total-page-number":
|
|
70994
|
+
return {
|
|
70995
|
+
text: editor.options.parentEditor?.currentTotalPages || "1",
|
|
70996
|
+
className: "sd-editor-auto-total-pages",
|
|
70997
|
+
dataId: "auto-total-pages",
|
|
70998
|
+
ariaLabel: "Total page count node"
|
|
70999
|
+
};
|
|
71000
|
+
default:
|
|
71001
|
+
return {};
|
|
70573
71002
|
}
|
|
70574
|
-
|
|
70575
|
-
|
|
70576
|
-
|
|
71003
|
+
};
|
|
71004
|
+
class AutoPageNumberNodeView {
|
|
71005
|
+
constructor(node, getPos, decorations, editor, htmlAttributes = {}) {
|
|
71006
|
+
__privateAdd$1(this, _AutoPageNumberNodeView_instances);
|
|
71007
|
+
this.node = node;
|
|
71008
|
+
this.editor = editor;
|
|
71009
|
+
this.view = editor.view;
|
|
71010
|
+
this.getPos = getPos;
|
|
71011
|
+
this.editor = editor;
|
|
71012
|
+
this.dom = __privateMethod$1(this, _AutoPageNumberNodeView_instances, renderDom_fn).call(this, node, htmlAttributes);
|
|
70577
71013
|
}
|
|
70578
|
-
update(node
|
|
70579
|
-
const
|
|
70580
|
-
|
|
70581
|
-
|
|
71014
|
+
update(node) {
|
|
71015
|
+
const incomingType = node?.type?.name;
|
|
71016
|
+
const currentType = this.node?.type?.name;
|
|
71017
|
+
if (!incomingType || incomingType !== currentType) return false;
|
|
71018
|
+
this.node = node;
|
|
70582
71019
|
return true;
|
|
70583
71020
|
}
|
|
70584
71021
|
}
|
|
70585
|
-
|
|
70586
|
-
|
|
70587
|
-
|
|
70588
|
-
|
|
70589
|
-
|
|
70590
|
-
|
|
71022
|
+
_AutoPageNumberNodeView_instances = /* @__PURE__ */ new WeakSet();
|
|
71023
|
+
renderDom_fn = function(node, htmlAttributes) {
|
|
71024
|
+
const attrs = getNodeAttributes(this.node.type.name, this.editor);
|
|
71025
|
+
const content = document.createTextNode(String(attrs.text));
|
|
71026
|
+
const nodeContent = document.createElement("span");
|
|
71027
|
+
nodeContent.className = attrs.className;
|
|
71028
|
+
nodeContent.setAttribute("data-id", attrs.dataId);
|
|
71029
|
+
nodeContent.setAttribute("aria-label", attrs.ariaLabel);
|
|
71030
|
+
const currentPos = this.getPos();
|
|
71031
|
+
const { styles, marks } = getMarksFromNeighbors(currentPos, this.view);
|
|
71032
|
+
__privateMethod$1(this, _AutoPageNumberNodeView_instances, scheduleUpdateNodeStyle_fn).call(this, currentPos, marks);
|
|
71033
|
+
Object.assign(nodeContent.style, styles);
|
|
71034
|
+
nodeContent.appendChild(content);
|
|
71035
|
+
Object.entries(htmlAttributes).forEach(([key2, value]) => {
|
|
71036
|
+
if (value) nodeContent.setAttribute(key2, value);
|
|
71037
|
+
});
|
|
71038
|
+
return nodeContent;
|
|
71039
|
+
};
|
|
71040
|
+
scheduleUpdateNodeStyle_fn = function(pos, marks) {
|
|
71041
|
+
setTimeout(() => {
|
|
71042
|
+
const { state: state2 } = this.editor;
|
|
71043
|
+
const { dispatch } = this.view;
|
|
71044
|
+
const node = state2.doc.nodeAt(pos);
|
|
71045
|
+
if (!node || node.isText) return;
|
|
71046
|
+
const currentMarks = node.attrs.marksAsAttrs || [];
|
|
71047
|
+
const newMarks = marks.map((m2) => ({ type: m2.type.name, attrs: m2.attrs }));
|
|
71048
|
+
const isEqual = JSON.stringify(currentMarks) === JSON.stringify(newMarks);
|
|
71049
|
+
if (isEqual) return;
|
|
71050
|
+
const newAttrs = {
|
|
71051
|
+
...node.attrs,
|
|
71052
|
+
marksAsAttrs: newMarks
|
|
71053
|
+
};
|
|
71054
|
+
const tr = state2.tr.setNodeMarkup(pos, void 0, newAttrs);
|
|
71055
|
+
dispatch(tr);
|
|
71056
|
+
}, 0);
|
|
71057
|
+
};
|
|
71058
|
+
const getMarksFromNeighbors = (currentPos, view) => {
|
|
71059
|
+
const $pos = view.state.doc.resolve(currentPos);
|
|
71060
|
+
const styles = {};
|
|
71061
|
+
const marks = [];
|
|
71062
|
+
const before = $pos.nodeBefore;
|
|
71063
|
+
if (before) {
|
|
71064
|
+
Object.assign(styles, processMarks(before.marks));
|
|
71065
|
+
marks.push(...before.marks);
|
|
71066
|
+
}
|
|
71067
|
+
const after = $pos.nodeAfter;
|
|
71068
|
+
if (after) {
|
|
71069
|
+
Object.assign(styles, { ...styles, ...processMarks(after.marks) });
|
|
71070
|
+
marks.push(...after.marks);
|
|
71071
|
+
}
|
|
71072
|
+
return {
|
|
71073
|
+
styles,
|
|
71074
|
+
marks
|
|
71075
|
+
};
|
|
71076
|
+
};
|
|
71077
|
+
const processMarks = (marks) => {
|
|
71078
|
+
const styles = {};
|
|
71079
|
+
marks.forEach((mark) => {
|
|
71080
|
+
const { type: type2, attrs } = mark;
|
|
71081
|
+
switch (type2.name) {
|
|
71082
|
+
case "textStyle":
|
|
71083
|
+
if (attrs.fontFamily) styles["font-family"] = attrs.fontFamily;
|
|
71084
|
+
if (attrs.fontSize) styles["font-size"] = attrs.fontSize;
|
|
71085
|
+
if (attrs.color) styles["color"] = attrs.color;
|
|
71086
|
+
if (attrs.backgroundColor) styles["background-color"] = attrs.backgroundColor;
|
|
71087
|
+
break;
|
|
71088
|
+
case "bold":
|
|
71089
|
+
styles["font-weight"] = "bold";
|
|
71090
|
+
break;
|
|
71091
|
+
case "italic":
|
|
71092
|
+
styles["font-style"] = "italic";
|
|
71093
|
+
break;
|
|
71094
|
+
case "underline":
|
|
71095
|
+
styles["text-decoration"] = (styles["text-decoration"] || "") + " underline";
|
|
71096
|
+
break;
|
|
71097
|
+
case "strike":
|
|
71098
|
+
styles["text-decoration"] = (styles["text-decoration"] || "") + " line-through";
|
|
71099
|
+
break;
|
|
71100
|
+
default:
|
|
71101
|
+
if (attrs?.style) {
|
|
71102
|
+
Object.entries(attrs.style).forEach(([key2, value]) => {
|
|
71103
|
+
styles[key2] = value;
|
|
71104
|
+
});
|
|
71105
|
+
}
|
|
71106
|
+
break;
|
|
71107
|
+
}
|
|
71108
|
+
});
|
|
71109
|
+
return styles;
|
|
71110
|
+
};
|
|
71111
|
+
const ShapeContainer = Node$1.create({
|
|
71112
|
+
name: "shapeContainer",
|
|
71113
|
+
group: "block",
|
|
71114
|
+
content: "block+",
|
|
70591
71115
|
isolating: true,
|
|
70592
|
-
atom: false,
|
|
70593
|
-
// false - has editable content.
|
|
70594
|
-
draggable: true,
|
|
70595
71116
|
addOptions() {
|
|
70596
71117
|
return {
|
|
70597
71118
|
htmlAttributes: {
|
|
70598
|
-
class:
|
|
70599
|
-
"aria-label": "
|
|
71119
|
+
class: "sd-editor-shape-container",
|
|
71120
|
+
"aria-label": "Shape container node"
|
|
70600
71121
|
}
|
|
70601
71122
|
};
|
|
70602
71123
|
},
|
|
70603
71124
|
addAttributes() {
|
|
70604
71125
|
return {
|
|
70605
|
-
|
|
71126
|
+
fillcolor: {
|
|
71127
|
+
renderDOM: (attrs) => {
|
|
71128
|
+
if (!attrs.fillcolor) return {};
|
|
71129
|
+
return {
|
|
71130
|
+
style: `background-color: ${attrs.fillcolor}`
|
|
71131
|
+
};
|
|
71132
|
+
}
|
|
71133
|
+
},
|
|
71134
|
+
sdBlockId: {
|
|
70606
71135
|
default: null,
|
|
70607
|
-
|
|
71136
|
+
keepOnSplit: false,
|
|
71137
|
+
parseDOM: (elem) => elem.getAttribute("data-sd-block-id"),
|
|
70608
71138
|
renderDOM: (attrs) => {
|
|
70609
|
-
|
|
70610
|
-
return { "data-id": attrs.id };
|
|
71139
|
+
return attrs.sdBlockId ? { "data-sd-block-id": attrs.sdBlockId } : {};
|
|
70611
71140
|
}
|
|
70612
71141
|
},
|
|
70613
|
-
|
|
71142
|
+
style: {
|
|
71143
|
+
renderDOM: (attrs) => {
|
|
71144
|
+
if (!attrs.style) return {};
|
|
71145
|
+
return {
|
|
71146
|
+
style: attrs.style
|
|
71147
|
+
};
|
|
71148
|
+
}
|
|
71149
|
+
},
|
|
71150
|
+
wrapAttributes: {
|
|
71151
|
+
rendered: false
|
|
71152
|
+
},
|
|
71153
|
+
attributes: {
|
|
70614
71154
|
rendered: false
|
|
70615
71155
|
}
|
|
70616
71156
|
};
|
|
70617
71157
|
},
|
|
70618
71158
|
parseDOM() {
|
|
70619
|
-
return [
|
|
71159
|
+
return [
|
|
71160
|
+
{
|
|
71161
|
+
tag: `div[data-type="${this.name}"]`
|
|
71162
|
+
}
|
|
71163
|
+
];
|
|
70620
71164
|
},
|
|
70621
71165
|
renderDOM({ htmlAttributes }) {
|
|
70622
71166
|
return [
|
|
70623
71167
|
"div",
|
|
70624
|
-
Attribute.mergeAttributes(this.options.htmlAttributes, htmlAttributes, {
|
|
70625
|
-
"data-structured-content-block": ""
|
|
70626
|
-
}),
|
|
71168
|
+
Attribute.mergeAttributes(this.options.htmlAttributes, htmlAttributes, { "data-type": this.name }),
|
|
70627
71169
|
0
|
|
70628
71170
|
];
|
|
70629
|
-
},
|
|
70630
|
-
addNodeView() {
|
|
70631
|
-
return (props) => {
|
|
70632
|
-
return new StructuredContentBlockView({ ...props });
|
|
70633
|
-
};
|
|
70634
71171
|
}
|
|
70635
71172
|
});
|
|
70636
|
-
|
|
70637
|
-
|
|
70638
|
-
__privateAdd$1(this, _DocumentSectionView_instances);
|
|
70639
|
-
this.node = node;
|
|
70640
|
-
this.editor = editor;
|
|
70641
|
-
this.decorations = decorations;
|
|
70642
|
-
this.view = editor.view;
|
|
70643
|
-
this.getPos = getPos;
|
|
70644
|
-
__privateMethod$1(this, _DocumentSectionView_instances, init_fn3).call(this);
|
|
70645
|
-
}
|
|
70646
|
-
}
|
|
70647
|
-
_DocumentSectionView_instances = /* @__PURE__ */ new WeakSet();
|
|
70648
|
-
init_fn3 = function() {
|
|
70649
|
-
const { attrs } = this.node;
|
|
70650
|
-
const { id, title, description } = attrs;
|
|
70651
|
-
this.dom = document.createElement("div");
|
|
70652
|
-
this.dom.className = "sd-document-section-block";
|
|
70653
|
-
this.dom.setAttribute("data-id", id);
|
|
70654
|
-
this.dom.setAttribute("data-title", title);
|
|
70655
|
-
this.dom.setAttribute("data-description", description);
|
|
70656
|
-
this.dom.setAttribute("aria-label", "Document section");
|
|
70657
|
-
__privateMethod$1(this, _DocumentSectionView_instances, addToolTip_fn).call(this);
|
|
70658
|
-
this.contentDOM = document.createElement("div");
|
|
70659
|
-
this.contentDOM.className = "sd-document-section-block-content";
|
|
70660
|
-
this.contentDOM.setAttribute("contenteditable", "true");
|
|
70661
|
-
this.dom.appendChild(this.contentDOM);
|
|
70662
|
-
};
|
|
70663
|
-
addToolTip_fn = function() {
|
|
70664
|
-
const { title } = this.node.attrs;
|
|
70665
|
-
this.infoDiv = document.createElement("div");
|
|
70666
|
-
this.infoDiv.className = "sd-document-section-block-info";
|
|
70667
|
-
const textSpan = document.createElement("span");
|
|
70668
|
-
textSpan.textContent = title || "Document section";
|
|
70669
|
-
this.infoDiv.appendChild(textSpan);
|
|
70670
|
-
this.infoDiv.setAttribute("contenteditable", "false");
|
|
70671
|
-
this.dom.appendChild(this.infoDiv);
|
|
70672
|
-
};
|
|
70673
|
-
const getAllSections = (editor) => {
|
|
70674
|
-
if (!editor) return [];
|
|
70675
|
-
const type2 = editor.schema.nodes.documentSection;
|
|
70676
|
-
if (!type2) return [];
|
|
70677
|
-
const sections = [];
|
|
70678
|
-
const { state: state2 } = editor;
|
|
70679
|
-
state2.doc.descendants((node, pos) => {
|
|
70680
|
-
if (node.type.name === type2.name) {
|
|
70681
|
-
sections.push({ node, pos });
|
|
70682
|
-
}
|
|
70683
|
-
});
|
|
70684
|
-
return sections;
|
|
70685
|
-
};
|
|
70686
|
-
const exportSectionsToHTML = (editor) => {
|
|
70687
|
-
const sections = getAllSections(editor);
|
|
70688
|
-
const processedSections = /* @__PURE__ */ new Set();
|
|
70689
|
-
const result = [];
|
|
70690
|
-
sections.forEach(({ node }) => {
|
|
70691
|
-
const { attrs } = node;
|
|
70692
|
-
const { id, title, description } = attrs;
|
|
70693
|
-
if (processedSections.has(id)) return;
|
|
70694
|
-
processedSections.add(id);
|
|
70695
|
-
const html = getHTMLFromNode(node, editor);
|
|
70696
|
-
result.push({
|
|
70697
|
-
id,
|
|
70698
|
-
title,
|
|
70699
|
-
description,
|
|
70700
|
-
html
|
|
70701
|
-
});
|
|
70702
|
-
});
|
|
70703
|
-
return result;
|
|
70704
|
-
};
|
|
70705
|
-
const getHTMLFromNode = (node, editor) => {
|
|
70706
|
-
const tempDocument = document.implementation.createHTMLDocument();
|
|
70707
|
-
const container = tempDocument.createElement("div");
|
|
70708
|
-
const fragment = DOMSerializer.fromSchema(editor.schema).serializeFragment(node.content);
|
|
70709
|
-
container.appendChild(fragment);
|
|
70710
|
-
let html = container.innerHTML;
|
|
70711
|
-
return html;
|
|
70712
|
-
};
|
|
70713
|
-
const exportSectionsToJSON = (editor) => {
|
|
70714
|
-
const sections = getAllSections(editor);
|
|
70715
|
-
const processedSections = /* @__PURE__ */ new Set();
|
|
70716
|
-
const result = [];
|
|
70717
|
-
sections.forEach(({ node }) => {
|
|
70718
|
-
const { attrs } = node;
|
|
70719
|
-
const { id, title, description } = attrs;
|
|
70720
|
-
if (processedSections.has(id)) return;
|
|
70721
|
-
processedSections.add(id);
|
|
70722
|
-
result.push({
|
|
70723
|
-
id,
|
|
70724
|
-
title,
|
|
70725
|
-
description,
|
|
70726
|
-
content: node.toJSON()
|
|
70727
|
-
});
|
|
70728
|
-
});
|
|
70729
|
-
return result;
|
|
70730
|
-
};
|
|
70731
|
-
const getLinkedSectionEditor = (id, options, editor) => {
|
|
70732
|
-
const sections = getAllSections(editor);
|
|
70733
|
-
const section = sections.find((s) => s.node.attrs.id === id);
|
|
70734
|
-
if (!section) return null;
|
|
70735
|
-
const child = editor.createChildEditor({
|
|
70736
|
-
...options,
|
|
70737
|
-
onUpdate: ({ editor: childEditor, transaction }) => {
|
|
70738
|
-
const isFromtLinkedParent = transaction.getMeta("fromLinkedParent");
|
|
70739
|
-
if (isFromtLinkedParent) return;
|
|
70740
|
-
const updatedContent = childEditor.state.doc.content;
|
|
70741
|
-
const sectionNode = getAllSections(editor)?.find((s) => s.node.attrs.id === id);
|
|
70742
|
-
if (!sectionNode) return;
|
|
70743
|
-
const { pos, node } = sectionNode;
|
|
70744
|
-
const newNode = node.type.create(node.attrs, updatedContent, node.marks);
|
|
70745
|
-
const tr = editor.state.tr.replaceWith(pos, pos + node.nodeSize, newNode);
|
|
70746
|
-
tr.setMeta("fromLinkedChild", true);
|
|
70747
|
-
editor.view.dispatch(tr);
|
|
70748
|
-
}
|
|
70749
|
-
});
|
|
70750
|
-
editor.on("update", ({ transaction }) => {
|
|
70751
|
-
const isFromLinkedChild = transaction.getMeta("fromLinkedChild");
|
|
70752
|
-
if (isFromLinkedChild) return;
|
|
70753
|
-
const sectionNode = getAllSections(editor)?.find((s) => s.node.attrs.id === id);
|
|
70754
|
-
if (!sectionNode) return;
|
|
70755
|
-
const sectionContent = sectionNode.node.content;
|
|
70756
|
-
const json = {
|
|
70757
|
-
type: "doc",
|
|
70758
|
-
content: sectionContent.content.map((node) => node.toJSON())
|
|
70759
|
-
};
|
|
70760
|
-
const childTr = child.state.tr;
|
|
70761
|
-
childTr.setMeta("fromLinkedParent", true);
|
|
70762
|
-
childTr.replaceWith(0, child.state.doc.content.size, child.schema.nodeFromJSON(json));
|
|
70763
|
-
child.view.dispatch(childTr);
|
|
70764
|
-
});
|
|
70765
|
-
return child;
|
|
70766
|
-
};
|
|
70767
|
-
const SectionHelpers = {
|
|
70768
|
-
getAllSections,
|
|
70769
|
-
exportSectionsToHTML,
|
|
70770
|
-
exportSectionsToJSON,
|
|
70771
|
-
getLinkedSectionEditor
|
|
70772
|
-
};
|
|
70773
|
-
const DocumentSection = Node$1.create({
|
|
70774
|
-
name: "documentSection",
|
|
71173
|
+
const ShapeTextbox = Node$1.create({
|
|
71174
|
+
name: "shapeTextbox",
|
|
70775
71175
|
group: "block",
|
|
70776
|
-
content: "block*",
|
|
70777
|
-
atom: true,
|
|
71176
|
+
content: "paragraph* block*",
|
|
70778
71177
|
isolating: true,
|
|
70779
71178
|
addOptions() {
|
|
70780
71179
|
return {
|
|
70781
71180
|
htmlAttributes: {
|
|
70782
|
-
class: "sd-
|
|
70783
|
-
"aria-label": "
|
|
71181
|
+
class: "sd-editor-shape-textbox",
|
|
71182
|
+
"aria-label": "Shape textbox node"
|
|
70784
71183
|
}
|
|
70785
71184
|
};
|
|
70786
71185
|
},
|
|
70787
|
-
parseDOM() {
|
|
70788
|
-
return [
|
|
70789
|
-
{
|
|
70790
|
-
tag: "div.sd-document-section-block",
|
|
70791
|
-
priority: 60
|
|
70792
|
-
}
|
|
70793
|
-
];
|
|
70794
|
-
},
|
|
70795
|
-
renderDOM({ htmlAttributes }) {
|
|
70796
|
-
return ["div", Attribute.mergeAttributes(this.options.htmlAttributes, htmlAttributes), 0];
|
|
70797
|
-
},
|
|
70798
71186
|
addAttributes() {
|
|
70799
71187
|
return {
|
|
70800
|
-
id: {},
|
|
70801
71188
|
sdBlockId: {
|
|
70802
71189
|
default: null,
|
|
70803
71190
|
keepOnSplit: false,
|
|
@@ -70806,212 +71193,131 @@ Please report this to https://github.com/markedjs/marked.`, e) {
|
|
|
70806
71193
|
return attrs.sdBlockId ? { "data-sd-block-id": attrs.sdBlockId } : {};
|
|
70807
71194
|
}
|
|
70808
71195
|
},
|
|
70809
|
-
|
|
70810
|
-
|
|
70811
|
-
|
|
70812
|
-
isLocked: { default: false }
|
|
71196
|
+
attributes: {
|
|
71197
|
+
rendered: false
|
|
71198
|
+
}
|
|
70813
71199
|
};
|
|
70814
71200
|
},
|
|
70815
|
-
|
|
70816
|
-
return
|
|
70817
|
-
|
|
71201
|
+
parseDOM() {
|
|
71202
|
+
return [
|
|
71203
|
+
{
|
|
71204
|
+
tag: `div[data-type="${this.name}"]`
|
|
71205
|
+
}
|
|
71206
|
+
];
|
|
71207
|
+
},
|
|
71208
|
+
renderDOM({ htmlAttributes }) {
|
|
71209
|
+
return [
|
|
71210
|
+
"div",
|
|
71211
|
+
Attribute.mergeAttributes(this.options.htmlAttributes, htmlAttributes, { "data-type": this.name }),
|
|
71212
|
+
0
|
|
71213
|
+
];
|
|
71214
|
+
}
|
|
71215
|
+
});
|
|
71216
|
+
const ContentBlock = Node$1.create({
|
|
71217
|
+
name: "contentBlock",
|
|
71218
|
+
group: "inline",
|
|
71219
|
+
content: "",
|
|
71220
|
+
isolating: true,
|
|
71221
|
+
atom: true,
|
|
71222
|
+
inline: true,
|
|
71223
|
+
addOptions() {
|
|
71224
|
+
return {
|
|
71225
|
+
htmlAttributes: {
|
|
71226
|
+
contenteditable: false
|
|
71227
|
+
}
|
|
70818
71228
|
};
|
|
70819
71229
|
},
|
|
70820
|
-
|
|
71230
|
+
addAttributes() {
|
|
70821
71231
|
return {
|
|
70822
|
-
|
|
70823
|
-
|
|
70824
|
-
|
|
70825
|
-
|
|
70826
|
-
|
|
70827
|
-
* editor.commands.createDocumentSection({
|
|
70828
|
-
* id: 1,
|
|
70829
|
-
* title: 'Terms & Conditions',
|
|
70830
|
-
* isLocked: true,
|
|
70831
|
-
* html: '<p>Legal content...</p>'
|
|
70832
|
-
* })
|
|
70833
|
-
*/
|
|
70834
|
-
createDocumentSection: (options = {}) => ({ tr, state: state2, dispatch, editor }) => {
|
|
70835
|
-
const { selection } = state2;
|
|
70836
|
-
let { from: from2, to } = selection;
|
|
70837
|
-
let content = selection.content().content;
|
|
70838
|
-
const { html: optionsHTML, json: optionsJSON } = options;
|
|
70839
|
-
if (optionsHTML) {
|
|
70840
|
-
const html = htmlHandler(optionsHTML, this.editor);
|
|
70841
|
-
const doc2 = DOMParser$1.fromSchema(this.editor.schema).parse(html);
|
|
70842
|
-
content = doc2.content;
|
|
70843
|
-
}
|
|
70844
|
-
if (optionsJSON) {
|
|
70845
|
-
content = this.editor.schema.nodeFromJSON(optionsJSON);
|
|
70846
|
-
}
|
|
70847
|
-
if (!content?.content?.length) {
|
|
70848
|
-
content = this.editor.schema.nodeFromJSON({ type: "paragraph", content: [] });
|
|
70849
|
-
}
|
|
70850
|
-
if (!options.id) {
|
|
70851
|
-
const allSections = SectionHelpers.getAllSections(editor);
|
|
70852
|
-
options.id = allSections.length + 1;
|
|
70853
|
-
}
|
|
70854
|
-
if (!options.title) {
|
|
70855
|
-
options.title = "Document section";
|
|
70856
|
-
}
|
|
70857
|
-
const node = this.type.createAndFill(options, content);
|
|
70858
|
-
if (!node) return false;
|
|
70859
|
-
const isAlreadyInSdtBlock = findParentNode((node2) => node2.type.name === "documentSection")(selection);
|
|
70860
|
-
if (isAlreadyInSdtBlock && isAlreadyInSdtBlock.node) {
|
|
70861
|
-
const insertPos2 = isAlreadyInSdtBlock.pos + isAlreadyInSdtBlock.node.nodeSize;
|
|
70862
|
-
from2 = insertPos2;
|
|
70863
|
-
to = insertPos2;
|
|
70864
|
-
}
|
|
70865
|
-
tr.replaceRangeWith(from2, to, node);
|
|
70866
|
-
const nodeEnd = from2 + node.nodeSize;
|
|
70867
|
-
let shouldInsertParagraph = true;
|
|
70868
|
-
let insertPos = nodeEnd;
|
|
70869
|
-
if (nodeEnd >= tr.doc.content.size) {
|
|
70870
|
-
insertPos = tr.doc.content.size;
|
|
70871
|
-
if (insertPos > 0) {
|
|
70872
|
-
const $endPos = tr.doc.resolve(insertPos);
|
|
70873
|
-
if ($endPos.nodeBefore && $endPos.nodeBefore.type.name === "paragraph") {
|
|
70874
|
-
shouldInsertParagraph = false;
|
|
70875
|
-
}
|
|
70876
|
-
}
|
|
70877
|
-
}
|
|
70878
|
-
if (shouldInsertParagraph) {
|
|
70879
|
-
const emptyParagraph = tr.doc.type.schema.nodes.paragraph.create();
|
|
70880
|
-
tr.insert(insertPos, emptyParagraph);
|
|
70881
|
-
}
|
|
70882
|
-
if (dispatch) {
|
|
70883
|
-
tr.setMeta("documentSection", { action: "create" });
|
|
70884
|
-
dispatch(tr);
|
|
70885
|
-
setTimeout(() => {
|
|
70886
|
-
try {
|
|
70887
|
-
const currentState = editor.state;
|
|
70888
|
-
const docSize = currentState.doc.content.size;
|
|
70889
|
-
let targetPos = from2 + node.nodeSize;
|
|
70890
|
-
if (shouldInsertParagraph) {
|
|
70891
|
-
targetPos += 1;
|
|
70892
|
-
}
|
|
70893
|
-
targetPos = Math.min(targetPos, docSize);
|
|
70894
|
-
if (targetPos < docSize && targetPos > 0) {
|
|
70895
|
-
const newSelection = Selection.near(currentState.doc.resolve(targetPos));
|
|
70896
|
-
const newTr = currentState.tr.setSelection(newSelection);
|
|
70897
|
-
editor.view.dispatch(newTr);
|
|
70898
|
-
}
|
|
70899
|
-
} catch (e) {
|
|
70900
|
-
console.warn("Could not set delayed selection:", e);
|
|
70901
|
-
}
|
|
70902
|
-
}, 0);
|
|
71232
|
+
horizontalRule: {
|
|
71233
|
+
default: false,
|
|
71234
|
+
renderDOM: ({ horizontalRule }) => {
|
|
71235
|
+
if (!horizontalRule) return {};
|
|
71236
|
+
return { "data-horizontal-rule": "true" };
|
|
70903
71237
|
}
|
|
70904
|
-
return true;
|
|
70905
71238
|
},
|
|
70906
|
-
|
|
70907
|
-
|
|
70908
|
-
|
|
70909
|
-
|
|
70910
|
-
|
|
70911
|
-
|
|
70912
|
-
|
|
70913
|
-
|
|
70914
|
-
|
|
70915
|
-
|
|
70916
|
-
|
|
70917
|
-
const nodeStart = pos;
|
|
70918
|
-
const nodeEnd = nodeStart + node.nodeSize;
|
|
70919
|
-
const contentToPreserve = node.content;
|
|
70920
|
-
tr.delete(nodeStart, nodeEnd);
|
|
70921
|
-
if (contentToPreserve.size > 0) {
|
|
70922
|
-
tr.insert(nodeStart, contentToPreserve);
|
|
70923
|
-
}
|
|
70924
|
-
const newPos = Math.min(nodeStart, tr.doc.content.size);
|
|
70925
|
-
tr.setSelection(Selection.near(tr.doc.resolve(newPos)));
|
|
70926
|
-
if (dispatch) {
|
|
70927
|
-
tr.setMeta("documentSection", { action: "delete" });
|
|
70928
|
-
dispatch(tr);
|
|
71239
|
+
size: {
|
|
71240
|
+
default: null,
|
|
71241
|
+
renderDOM: ({ size: size2 }) => {
|
|
71242
|
+
if (!size2) return {};
|
|
71243
|
+
let style2 = "";
|
|
71244
|
+
if (size2.top) style2 += `top: ${size2.top}px; `;
|
|
71245
|
+
if (size2.left) style2 += `left: ${size2.left}px; `;
|
|
71246
|
+
if (size2.width) style2 += `width: ${size2.width.toString().endsWith("%") ? size2.width : `${size2.width}px`}; `;
|
|
71247
|
+
if (size2.height)
|
|
71248
|
+
style2 += `height: ${size2.height.toString().endsWith("%") ? size2.height : `${size2.height}px`}; `;
|
|
71249
|
+
return { style: style2 };
|
|
70929
71250
|
}
|
|
70930
|
-
return true;
|
|
70931
71251
|
},
|
|
70932
|
-
|
|
70933
|
-
|
|
70934
|
-
|
|
70935
|
-
|
|
70936
|
-
|
|
70937
|
-
|
|
70938
|
-
|
|
70939
|
-
removeSectionById: (id) => ({ tr, dispatch }) => {
|
|
70940
|
-
const sections = SectionHelpers.getAllSections(this.editor);
|
|
70941
|
-
const sectionToRemove = sections.find(({ node: node2 }) => node2.attrs.id === id);
|
|
70942
|
-
if (!sectionToRemove) return false;
|
|
70943
|
-
const { pos, node } = sectionToRemove;
|
|
70944
|
-
const nodeStart = pos;
|
|
70945
|
-
const nodeEnd = nodeStart + node.nodeSize;
|
|
70946
|
-
tr.delete(nodeStart, nodeEnd);
|
|
70947
|
-
if (dispatch) {
|
|
70948
|
-
tr.setMeta("documentSection", { action: "delete", id });
|
|
70949
|
-
dispatch(tr);
|
|
71252
|
+
background: {
|
|
71253
|
+
default: null,
|
|
71254
|
+
renderDOM: (attrs) => {
|
|
71255
|
+
if (!attrs.background) return {};
|
|
71256
|
+
return {
|
|
71257
|
+
style: `background-color: ${attrs.background}`
|
|
71258
|
+
};
|
|
70950
71259
|
}
|
|
70951
|
-
return true;
|
|
70952
71260
|
},
|
|
71261
|
+
drawingContent: {
|
|
71262
|
+
rendered: false
|
|
71263
|
+
},
|
|
71264
|
+
attributes: {
|
|
71265
|
+
rendered: false
|
|
71266
|
+
}
|
|
71267
|
+
};
|
|
71268
|
+
},
|
|
71269
|
+
parseDOM() {
|
|
71270
|
+
return [
|
|
71271
|
+
{
|
|
71272
|
+
tag: `div[data-type="${this.name}"]`
|
|
71273
|
+
}
|
|
71274
|
+
];
|
|
71275
|
+
},
|
|
71276
|
+
renderDOM({ htmlAttributes }) {
|
|
71277
|
+
return ["div", Attribute.mergeAttributes(this.options.htmlAttributes, htmlAttributes, { "data-type": this.name })];
|
|
71278
|
+
},
|
|
71279
|
+
addCommands() {
|
|
71280
|
+
return {
|
|
70953
71281
|
/**
|
|
70954
|
-
*
|
|
71282
|
+
* Insert a horizontal rule
|
|
70955
71283
|
* @category Command
|
|
70956
|
-
* @param {number} id - Section to lock
|
|
70957
71284
|
* @example
|
|
70958
|
-
* editor.commands.
|
|
71285
|
+
* editor.commands.insertHorizontalRule()
|
|
71286
|
+
* @note Creates a visual separator between content sections
|
|
70959
71287
|
*/
|
|
70960
|
-
|
|
70961
|
-
|
|
70962
|
-
|
|
70963
|
-
|
|
70964
|
-
|
|
70965
|
-
|
|
70966
|
-
|
|
70967
|
-
|
|
70968
|
-
}
|
|
70969
|
-
return true;
|
|
71288
|
+
insertHorizontalRule: () => ({ commands: commands2 }) => {
|
|
71289
|
+
return commands2.insertContent({
|
|
71290
|
+
type: this.name,
|
|
71291
|
+
attrs: {
|
|
71292
|
+
horizontalRule: true,
|
|
71293
|
+
size: { width: "100%", height: 2 },
|
|
71294
|
+
background: "#e5e7eb"
|
|
71295
|
+
}
|
|
71296
|
+
});
|
|
70970
71297
|
},
|
|
70971
71298
|
/**
|
|
70972
|
-
*
|
|
71299
|
+
* Insert a content block
|
|
70973
71300
|
* @category Command
|
|
70974
|
-
* @param {
|
|
71301
|
+
* @param {ContentBlockConfig} config - Block configuration
|
|
70975
71302
|
* @example
|
|
70976
|
-
*
|
|
70977
|
-
* editor.commands.
|
|
70978
|
-
*
|
|
70979
|
-
*
|
|
70980
|
-
*
|
|
70981
|
-
*
|
|
71303
|
+
* // Insert a spacer block
|
|
71304
|
+
* editor.commands.insertContentBlock({ size: { height: 20 } })
|
|
71305
|
+
*
|
|
71306
|
+
* @example
|
|
71307
|
+
* // Insert a colored divider
|
|
71308
|
+
* editor.commands.insertContentBlock({
|
|
71309
|
+
* size: { width: '50%', height: 3 },
|
|
71310
|
+
* background: '#3b82f6'
|
|
70982
71311
|
* })
|
|
71312
|
+
* @note Used for spacing, dividers, and special inline content
|
|
70983
71313
|
*/
|
|
70984
|
-
|
|
70985
|
-
|
|
70986
|
-
|
|
70987
|
-
|
|
70988
|
-
|
|
70989
|
-
let newContent = null;
|
|
70990
|
-
if (html) {
|
|
70991
|
-
const htmlDoc = htmlHandler(html, editor || this.editor);
|
|
70992
|
-
const doc2 = DOMParser$1.fromSchema((editor || this.editor).schema).parse(htmlDoc);
|
|
70993
|
-
newContent = doc2.content;
|
|
70994
|
-
}
|
|
70995
|
-
if (json) {
|
|
70996
|
-
newContent = (editor || this.editor).schema.nodeFromJSON(json);
|
|
70997
|
-
}
|
|
70998
|
-
if (!newContent) {
|
|
70999
|
-
newContent = node.content;
|
|
71000
|
-
}
|
|
71001
|
-
const updatedNode = node.type.create({ ...node.attrs, ...attrs }, newContent, node.marks);
|
|
71002
|
-
tr.replaceWith(pos, pos + node.nodeSize, updatedNode);
|
|
71003
|
-
if (dispatch) {
|
|
71004
|
-
tr.setMeta("documentSection", { action: "update", id, attrs });
|
|
71005
|
-
dispatch(tr);
|
|
71006
|
-
}
|
|
71007
|
-
return true;
|
|
71314
|
+
insertContentBlock: (config2) => ({ commands: commands2 }) => {
|
|
71315
|
+
return commands2.insertContent({
|
|
71316
|
+
type: this.name,
|
|
71317
|
+
attrs: config2
|
|
71318
|
+
});
|
|
71008
71319
|
}
|
|
71009
71320
|
};
|
|
71010
|
-
},
|
|
71011
|
-
addHelpers() {
|
|
71012
|
-
return {
|
|
71013
|
-
...SectionHelpers
|
|
71014
|
-
};
|
|
71015
71321
|
}
|
|
71016
71322
|
});
|
|
71017
71323
|
const { findChildren } = helpers;
|
|
@@ -77861,6 +78167,7 @@ Please report this to https://github.com/markedjs/marked.`, e) {
|
|
|
77861
78167
|
Search,
|
|
77862
78168
|
StructuredContent,
|
|
77863
78169
|
StructuredContentBlock,
|
|
78170
|
+
StructuredContentCommands,
|
|
77864
78171
|
DocumentSection,
|
|
77865
78172
|
NodeResizer,
|
|
77866
78173
|
CustomSelection,
|