@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
|
@@ -14988,6 +14988,10 @@ function generateDocxRandomId(length2 = 8) {
|
|
|
14988
14988
|
}
|
|
14989
14989
|
return id.join("");
|
|
14990
14990
|
}
|
|
14991
|
+
function generateRandomSigned32BitIntStrId() {
|
|
14992
|
+
const val = Math.floor(Math.random() * 2147483647);
|
|
14993
|
+
return val.toString();
|
|
14994
|
+
}
|
|
14991
14995
|
function generateRandom32BitHex() {
|
|
14992
14996
|
const val = Math.floor(Math.random() * 2147483647);
|
|
14993
14997
|
return val.toString(16).toUpperCase().padStart(8, "0");
|
|
@@ -22566,6 +22570,7 @@ const helpers = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.definePrope
|
|
|
22566
22570
|
generateDocxListAttributes,
|
|
22567
22571
|
generateDocxRandomId,
|
|
22568
22572
|
generateRandom32BitHex,
|
|
22573
|
+
generateRandomSigned32BitIntStrId,
|
|
22569
22574
|
getActiveFormatting,
|
|
22570
22575
|
getExtensionConfigField,
|
|
22571
22576
|
getMarkRange,
|
|
@@ -28160,6 +28165,9 @@ function handleStructuredContentNode(params2) {
|
|
|
28160
28165
|
const node = nodes[0];
|
|
28161
28166
|
const sdtPr = node.elements.find((el) => el.name === "w:sdtPr");
|
|
28162
28167
|
const sdtContent = node.elements.find((el) => el.name === "w:sdtContent");
|
|
28168
|
+
const id = sdtPr?.elements?.find((el) => el.name === "w:id");
|
|
28169
|
+
const tag = sdtPr?.elements?.find((el) => el.name === "w:tag");
|
|
28170
|
+
const alias = sdtPr?.elements?.find((el) => el.name === "w:alias");
|
|
28163
28171
|
if (!sdtContent) {
|
|
28164
28172
|
return null;
|
|
28165
28173
|
}
|
|
@@ -28171,15 +28179,16 @@ function handleStructuredContentNode(params2) {
|
|
|
28171
28179
|
nodes: sdtContent.elements,
|
|
28172
28180
|
path: [...params2.path || [], sdtContent]
|
|
28173
28181
|
});
|
|
28174
|
-
|
|
28175
|
-
|
|
28176
|
-
sdtContentType = "structuredContentBlock";
|
|
28177
|
-
}
|
|
28182
|
+
const isBlockNode2 = paragraph || table;
|
|
28183
|
+
const sdtContentType = isBlockNode2 ? "structuredContentBlock" : "structuredContent";
|
|
28178
28184
|
let result = {
|
|
28179
28185
|
type: sdtContentType,
|
|
28180
28186
|
content: translatedContent,
|
|
28181
28187
|
marks,
|
|
28182
28188
|
attrs: {
|
|
28189
|
+
id: id?.attributes?.["w:val"] || null,
|
|
28190
|
+
tag: tag?.attributes?.["w:val"] || null,
|
|
28191
|
+
alias: alias?.attributes?.["w:val"] || null,
|
|
28183
28192
|
sdtPr
|
|
28184
28193
|
}
|
|
28185
28194
|
};
|
|
@@ -30437,21 +30446,55 @@ const generateSdtPrTagForDocumentSection = (id, title, tag) => {
|
|
|
30437
30446
|
};
|
|
30438
30447
|
function translateStructuredContent(params2) {
|
|
30439
30448
|
const { node } = params2;
|
|
30440
|
-
const { attrs = {} } = node;
|
|
30441
30449
|
const childContent = translateChildNodes({ ...params2, nodes: node.content });
|
|
30442
|
-
const
|
|
30443
|
-
|
|
30444
|
-
|
|
30445
|
-
elements: childContent
|
|
30446
|
-
}
|
|
30447
|
-
];
|
|
30448
|
-
nodeElements.unshift(attrs.sdtPr);
|
|
30450
|
+
const sdtContent = { name: "w:sdtContent", elements: childContent };
|
|
30451
|
+
const sdtPr = generateSdtPrTagForStructuredContent({ node });
|
|
30452
|
+
const nodeElements = [sdtPr, sdtContent];
|
|
30449
30453
|
const result = {
|
|
30450
30454
|
name: "w:sdt",
|
|
30451
30455
|
elements: nodeElements
|
|
30452
30456
|
};
|
|
30453
30457
|
return result;
|
|
30454
30458
|
}
|
|
30459
|
+
function generateSdtPrTagForStructuredContent({ node }) {
|
|
30460
|
+
const { attrs = {} } = node;
|
|
30461
|
+
const id = {
|
|
30462
|
+
name: "w:id",
|
|
30463
|
+
type: "element",
|
|
30464
|
+
attributes: { "w:val": attrs.id }
|
|
30465
|
+
};
|
|
30466
|
+
const alias = {
|
|
30467
|
+
name: "w:alias",
|
|
30468
|
+
type: "element",
|
|
30469
|
+
attributes: { "w:val": attrs.alias }
|
|
30470
|
+
};
|
|
30471
|
+
const tag = {
|
|
30472
|
+
name: "w:tag",
|
|
30473
|
+
type: "element",
|
|
30474
|
+
attributes: { "w:val": attrs.tag }
|
|
30475
|
+
};
|
|
30476
|
+
const resultElements = [];
|
|
30477
|
+
if (attrs.id) resultElements.push(id);
|
|
30478
|
+
if (attrs.alias) resultElements.push(alias);
|
|
30479
|
+
if (attrs.tag) resultElements.push(tag);
|
|
30480
|
+
if (attrs.sdtPr) {
|
|
30481
|
+
const elements = attrs.sdtPr.elements || [];
|
|
30482
|
+
const elementsToExclude = ["w:id", "w:alias", "w:tag"];
|
|
30483
|
+
const restElements = elements.filter((el) => !elementsToExclude.includes(el.name));
|
|
30484
|
+
const result2 = {
|
|
30485
|
+
name: "w:sdtPr",
|
|
30486
|
+
type: "element",
|
|
30487
|
+
elements: [...resultElements, ...restElements]
|
|
30488
|
+
};
|
|
30489
|
+
return result2;
|
|
30490
|
+
}
|
|
30491
|
+
const result = {
|
|
30492
|
+
name: "w:sdtPr",
|
|
30493
|
+
type: "element",
|
|
30494
|
+
elements: resultElements
|
|
30495
|
+
};
|
|
30496
|
+
return result;
|
|
30497
|
+
}
|
|
30455
30498
|
const XML_NODE_NAME$3 = "w:sdt";
|
|
30456
30499
|
const SD_NODE_NAME$3 = ["fieldAnnotation", "structuredContent", "structuredContentBlock", "documentSection"];
|
|
30457
30500
|
const validXmlAttributes$3 = [];
|
|
@@ -31512,7 +31555,7 @@ function translateShapeContainer(params2) {
|
|
|
31512
31555
|
const pict = {
|
|
31513
31556
|
name: "w:pict",
|
|
31514
31557
|
attributes: {
|
|
31515
|
-
"w14:anchorId":
|
|
31558
|
+
"w14:anchorId": generateRandomSigned32BitIntStrId()
|
|
31516
31559
|
},
|
|
31517
31560
|
elements: [shape]
|
|
31518
31561
|
};
|
|
@@ -31579,7 +31622,7 @@ function translateVRectContentBlock(params2) {
|
|
|
31579
31622
|
const pict = {
|
|
31580
31623
|
name: "w:pict",
|
|
31581
31624
|
attributes: {
|
|
31582
|
-
"w14:anchorId":
|
|
31625
|
+
"w14:anchorId": generateRandomSigned32BitIntStrId()
|
|
31583
31626
|
},
|
|
31584
31627
|
elements: [rect]
|
|
31585
31628
|
};
|
|
@@ -33079,7 +33122,7 @@ const DEFAULT_SECTION_PROPS = Object.freeze({
|
|
|
33079
33122
|
gutter: "0"
|
|
33080
33123
|
})
|
|
33081
33124
|
});
|
|
33082
|
-
function ensureSectionProperties(bodyNode
|
|
33125
|
+
function ensureSectionProperties(bodyNode) {
|
|
33083
33126
|
if (!bodyNode.elements) bodyNode.elements = [];
|
|
33084
33127
|
let sectPr = bodyNode.elements.find((el) => el.name === "w:sectPr");
|
|
33085
33128
|
if (!sectPr) {
|
|
@@ -36578,7 +36621,7 @@ var __privateGet$1 = (obj, member, getter) => (__accessCheck$1(obj, member, "rea
|
|
|
36578
36621
|
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);
|
|
36579
36622
|
var __privateSet = (obj, member, value, setter) => (__accessCheck$1(obj, member, "write to private field"), member.set(obj, value), value);
|
|
36580
36623
|
var __privateMethod$1 = (obj, member, method) => (__accessCheck$1(obj, member, "access private method"), method);
|
|
36581
|
-
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,
|
|
36624
|
+
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;
|
|
36582
36625
|
var GOOD_LEAF_SIZE = 200;
|
|
36583
36626
|
var RopeSequence = function RopeSequence2() {
|
|
36584
36627
|
};
|
|
@@ -48653,7 +48696,7 @@ const handleTrackedChangeTransaction = (trackedChangeMeta, trackedChanges, newEd
|
|
|
48653
48696
|
if (emitParams) editor.emit("commentsUpdate", emitParams);
|
|
48654
48697
|
return newTrackedChanges;
|
|
48655
48698
|
};
|
|
48656
|
-
const getTrackedChangeText = ({
|
|
48699
|
+
const getTrackedChangeText = ({ nodes, mark, trackedChangeType, isDeletionInsertion }) => {
|
|
48657
48700
|
let trackedChangeText = "";
|
|
48658
48701
|
let deletionText = "";
|
|
48659
48702
|
if (trackedChangeType === TrackInsertMarkName) {
|
|
@@ -48695,10 +48738,8 @@ const createOrUpdateTrackedChangeComment = ({ event, marks, deletionNodes, nodes
|
|
|
48695
48738
|
if (hasMatchingId) nodesWithMark.push(node2);
|
|
48696
48739
|
});
|
|
48697
48740
|
const { deletionText, trackedChangeText } = getTrackedChangeText({
|
|
48698
|
-
state: newEditorState,
|
|
48699
48741
|
nodes: nodesWithMark.length ? nodesWithMark : [node],
|
|
48700
48742
|
mark: trackedMark,
|
|
48701
|
-
marks,
|
|
48702
48743
|
trackedChangeType,
|
|
48703
48744
|
isDeletionInsertion
|
|
48704
48745
|
});
|
|
@@ -53353,228 +53394,1223 @@ const SlashMenu = Extension.create({
|
|
|
53353
53394
|
return this.editor.options.isHeadless ? [] : [slashMenuPlugin];
|
|
53354
53395
|
}
|
|
53355
53396
|
});
|
|
53356
|
-
|
|
53357
|
-
|
|
53358
|
-
|
|
53359
|
-
|
|
53360
|
-
|
|
53361
|
-
|
|
53362
|
-
|
|
53363
|
-
|
|
53364
|
-
|
|
53365
|
-
|
|
53366
|
-
|
|
53367
|
-
|
|
53368
|
-
|
|
53369
|
-
|
|
53370
|
-
|
|
53371
|
-
|
|
53372
|
-
|
|
53373
|
-
|
|
53374
|
-
|
|
53375
|
-
|
|
53376
|
-
|
|
53377
|
-
|
|
53378
|
-
|
|
53379
|
-
|
|
53380
|
-
|
|
53381
|
-
|
|
53382
|
-
|
|
53383
|
-
|
|
53384
|
-
|
|
53385
|
-
|
|
53386
|
-
|
|
53387
|
-
|
|
53388
|
-
|
|
53389
|
-
|
|
53390
|
-
|
|
53391
|
-
|
|
53392
|
-
|
|
53393
|
-
|
|
53394
|
-
|
|
53395
|
-
|
|
53396
|
-
|
|
53397
|
-
|
|
53398
|
-
|
|
53399
|
-
|
|
53400
|
-
|
|
53401
|
-
|
|
53402
|
-
|
|
53403
|
-
|
|
53404
|
-
|
|
53397
|
+
class StructuredContentViewBase {
|
|
53398
|
+
constructor(props) {
|
|
53399
|
+
__publicField$1(this, "node");
|
|
53400
|
+
__publicField$1(this, "view");
|
|
53401
|
+
__publicField$1(this, "getPos");
|
|
53402
|
+
__publicField$1(this, "decorations");
|
|
53403
|
+
__publicField$1(this, "innerDecorations");
|
|
53404
|
+
__publicField$1(this, "editor");
|
|
53405
|
+
__publicField$1(this, "extension");
|
|
53406
|
+
__publicField$1(this, "htmlAttributes");
|
|
53407
|
+
__publicField$1(this, "root");
|
|
53408
|
+
__publicField$1(this, "isDragging", false);
|
|
53409
|
+
this.node = props.node;
|
|
53410
|
+
this.view = props.editor.view;
|
|
53411
|
+
this.getPos = props.getPos;
|
|
53412
|
+
this.decorations = props.decorations;
|
|
53413
|
+
this.innerDecorations = props.innerDecorations;
|
|
53414
|
+
this.editor = props.editor;
|
|
53415
|
+
this.extension = props.extension;
|
|
53416
|
+
this.htmlAttributes = props.htmlAttributes;
|
|
53417
|
+
this.mount(props);
|
|
53418
|
+
}
|
|
53419
|
+
mount() {
|
|
53420
|
+
return;
|
|
53421
|
+
}
|
|
53422
|
+
get dom() {
|
|
53423
|
+
return this.root;
|
|
53424
|
+
}
|
|
53425
|
+
get contentDOM() {
|
|
53426
|
+
return null;
|
|
53427
|
+
}
|
|
53428
|
+
update(node, decorations, innerDecorations) {
|
|
53429
|
+
if (node.type !== this.node.type) {
|
|
53430
|
+
return false;
|
|
53431
|
+
}
|
|
53432
|
+
this.node = node;
|
|
53433
|
+
this.decorations = decorations;
|
|
53434
|
+
this.innerDecorations = innerDecorations;
|
|
53435
|
+
this.updateHTMLAttributes();
|
|
53436
|
+
return true;
|
|
53437
|
+
}
|
|
53438
|
+
stopEvent(event) {
|
|
53439
|
+
if (!this.dom) return false;
|
|
53440
|
+
const target = event.target;
|
|
53441
|
+
const isInElement = this.dom.contains(target) && !this.contentDOM?.contains(target);
|
|
53442
|
+
if (!isInElement) return false;
|
|
53443
|
+
const isDragEvent = event.type.startsWith("drag");
|
|
53444
|
+
const isDropEvent = event.type === "drop";
|
|
53445
|
+
const isInput = ["INPUT", "BUTTON", "SELECT", "TEXTAREA"].includes(target.tagName) || target.isContentEditable;
|
|
53446
|
+
if (isInput && !isDropEvent && !isDragEvent) return true;
|
|
53447
|
+
const { isEditable } = this.editor;
|
|
53448
|
+
const { isDragging } = this;
|
|
53449
|
+
const isDraggable = !!this.node.type.spec.draggable;
|
|
53450
|
+
const isSelectable = NodeSelection.isSelectable(this.node);
|
|
53451
|
+
const isCopyEvent = event.type === "copy";
|
|
53452
|
+
const isPasteEvent = event.type === "paste";
|
|
53453
|
+
const isCutEvent = event.type === "cut";
|
|
53454
|
+
const isClickEvent = event.type === "mousedown";
|
|
53455
|
+
if (!isDraggable && isSelectable && isDragEvent && event.target === this.dom) {
|
|
53456
|
+
event.preventDefault();
|
|
53457
|
+
}
|
|
53458
|
+
if (isDraggable && isDragEvent && !isDragging && event.target === this.dom) {
|
|
53459
|
+
event.preventDefault();
|
|
53460
|
+
return false;
|
|
53461
|
+
}
|
|
53462
|
+
if (isDraggable && isEditable && !isDragging && isClickEvent) {
|
|
53463
|
+
const dragHandle = target.closest("[data-drag-handle]");
|
|
53464
|
+
const isValidDragHandle = dragHandle && (this.dom === dragHandle || this.dom.contains(dragHandle));
|
|
53465
|
+
if (isValidDragHandle) {
|
|
53466
|
+
this.isDragging = true;
|
|
53467
|
+
document.addEventListener(
|
|
53468
|
+
"dragend",
|
|
53469
|
+
() => {
|
|
53470
|
+
this.isDragging = false;
|
|
53471
|
+
},
|
|
53472
|
+
{ once: true }
|
|
53473
|
+
);
|
|
53474
|
+
document.addEventListener(
|
|
53475
|
+
"drop",
|
|
53476
|
+
() => {
|
|
53477
|
+
this.isDragging = false;
|
|
53478
|
+
},
|
|
53479
|
+
{ once: true }
|
|
53480
|
+
);
|
|
53481
|
+
document.addEventListener(
|
|
53482
|
+
"mouseup",
|
|
53483
|
+
() => {
|
|
53484
|
+
this.isDragging = false;
|
|
53485
|
+
},
|
|
53486
|
+
{ once: true }
|
|
53487
|
+
);
|
|
53405
53488
|
}
|
|
53406
|
-
}
|
|
53489
|
+
}
|
|
53490
|
+
if (isDragging || isDropEvent || isCopyEvent || isPasteEvent || isCutEvent || isClickEvent && isSelectable) {
|
|
53491
|
+
return false;
|
|
53492
|
+
}
|
|
53493
|
+
return true;
|
|
53407
53494
|
}
|
|
53408
|
-
|
|
53409
|
-
|
|
53410
|
-
|
|
53411
|
-
|
|
53412
|
-
|
|
53413
|
-
|
|
53414
|
-
return
|
|
53495
|
+
ignoreMutation(mutation) {
|
|
53496
|
+
if (!this.dom || !this.contentDOM) return true;
|
|
53497
|
+
if (this.node.isLeaf || this.node.isAtom) return true;
|
|
53498
|
+
if (mutation.type === "selection") return false;
|
|
53499
|
+
if (this.contentDOM === mutation.target && mutation.type === "attributes") return true;
|
|
53500
|
+
if (this.contentDOM.contains(mutation.target)) return false;
|
|
53501
|
+
return true;
|
|
53415
53502
|
}
|
|
53416
|
-
|
|
53417
|
-
|
|
53418
|
-
|
|
53419
|
-
|
|
53420
|
-
|
|
53421
|
-
|
|
53422
|
-
|
|
53503
|
+
destroy() {
|
|
53504
|
+
this.dom.remove();
|
|
53505
|
+
this.contentDOM?.remove();
|
|
53506
|
+
}
|
|
53507
|
+
updateAttributes(attrs) {
|
|
53508
|
+
const pos = this.getPos();
|
|
53509
|
+
if (typeof pos !== "number") {
|
|
53510
|
+
return;
|
|
53511
|
+
}
|
|
53512
|
+
return this.view.dispatch(
|
|
53513
|
+
this.view.state.tr.setNodeMarkup(pos, void 0, {
|
|
53514
|
+
...this.node.attrs,
|
|
53515
|
+
...attrs
|
|
53516
|
+
})
|
|
53517
|
+
);
|
|
53518
|
+
}
|
|
53519
|
+
updateHTMLAttributes() {
|
|
53520
|
+
const { extensionService } = this.editor;
|
|
53521
|
+
const { attributes } = extensionService;
|
|
53522
|
+
const extensionAttrs = attributes.filter((i) => i.type === this.node.type.name);
|
|
53523
|
+
this.htmlAttributes = Attribute2.getAttributesToRender(this.node, extensionAttrs);
|
|
53524
|
+
}
|
|
53525
|
+
createDragHandle() {
|
|
53526
|
+
const dragHandle = document.createElement("span");
|
|
53527
|
+
dragHandle.classList.add("sd-structured-content-draggable");
|
|
53528
|
+
dragHandle.draggable = true;
|
|
53529
|
+
dragHandle.contentEditable = "false";
|
|
53530
|
+
dragHandle.dataset.dragHandle = "";
|
|
53531
|
+
const textElement = document.createElement("span");
|
|
53532
|
+
textElement.textContent = this.node.attrs.alias || "Structured content";
|
|
53533
|
+
dragHandle.append(textElement);
|
|
53534
|
+
return dragHandle;
|
|
53535
|
+
}
|
|
53536
|
+
onDragStart(event) {
|
|
53537
|
+
const { view } = this.editor;
|
|
53538
|
+
const target = event.target;
|
|
53539
|
+
const dragHandle = target.nodeType === 3 ? target.parentElement?.closest("[data-drag-handle]") : target.closest("[data-drag-handle]");
|
|
53540
|
+
if (!this.dom || this.contentDOM?.contains(target) || !dragHandle) {
|
|
53541
|
+
return;
|
|
53542
|
+
}
|
|
53543
|
+
let x = 0;
|
|
53544
|
+
let y2 = 0;
|
|
53545
|
+
if (this.dom !== dragHandle) {
|
|
53546
|
+
const domBox = this.dom.getBoundingClientRect();
|
|
53547
|
+
const handleBox = dragHandle.getBoundingClientRect();
|
|
53548
|
+
const offsetX = event.offsetX ?? event.nativeEvent?.offsetX;
|
|
53549
|
+
const offsetY = event.offsetY ?? event.nativeEvent?.offsetY;
|
|
53550
|
+
x = handleBox.x - domBox.x + offsetX;
|
|
53551
|
+
y2 = handleBox.y - domBox.y + offsetY;
|
|
53552
|
+
}
|
|
53553
|
+
event.dataTransfer?.setDragImage(this.dom, x, y2);
|
|
53554
|
+
const pos = this.getPos();
|
|
53555
|
+
if (typeof pos !== "number") {
|
|
53556
|
+
return;
|
|
53557
|
+
}
|
|
53558
|
+
const selection = NodeSelection.create(view.state.doc, pos);
|
|
53559
|
+
const transaction = view.state.tr.setSelection(selection);
|
|
53423
53560
|
view.dispatch(transaction);
|
|
53424
|
-
});
|
|
53425
|
-
if (handled) {
|
|
53426
|
-
tr.setMeta("preventDispatch", true);
|
|
53427
53561
|
}
|
|
53428
|
-
|
|
53429
|
-
|
|
53430
|
-
|
|
53431
|
-
|
|
53432
|
-
|
|
53433
|
-
|
|
53562
|
+
}
|
|
53563
|
+
class StructuredContentInlineView extends StructuredContentViewBase {
|
|
53564
|
+
constructor(props) {
|
|
53565
|
+
super(props);
|
|
53566
|
+
}
|
|
53567
|
+
mount() {
|
|
53568
|
+
this.buildView();
|
|
53569
|
+
}
|
|
53570
|
+
get contentDOM() {
|
|
53571
|
+
const contentElement = this.dom?.querySelector(`.${structuredContentInnerClass$1}`);
|
|
53572
|
+
return contentElement || null;
|
|
53573
|
+
}
|
|
53574
|
+
createElement() {
|
|
53575
|
+
const element = document.createElement("span");
|
|
53576
|
+
element.classList.add(structuredContentClass$1);
|
|
53577
|
+
element.setAttribute("data-structured-content", "");
|
|
53578
|
+
const contentElement = document.createElement("span");
|
|
53579
|
+
contentElement.classList.add(structuredContentInnerClass$1);
|
|
53580
|
+
element.append(contentElement);
|
|
53581
|
+
const domAttrs = Attribute2.mergeAttributes(this.htmlAttributes);
|
|
53582
|
+
updateDOMAttributes(element, { ...domAttrs });
|
|
53583
|
+
return { element, contentElement };
|
|
53584
|
+
}
|
|
53585
|
+
buildView() {
|
|
53586
|
+
const { element } = this.createElement();
|
|
53587
|
+
const dragHandle = this.createDragHandle();
|
|
53588
|
+
element.prepend(dragHandle);
|
|
53589
|
+
element.addEventListener("dragstart", (e) => this.onDragStart(e));
|
|
53590
|
+
this.root = element;
|
|
53591
|
+
}
|
|
53592
|
+
updateView() {
|
|
53593
|
+
const domAttrs = Attribute2.mergeAttributes(this.htmlAttributes);
|
|
53594
|
+
updateDOMAttributes(this.dom, { ...domAttrs });
|
|
53595
|
+
}
|
|
53596
|
+
update(node, decorations, innerDecorations) {
|
|
53597
|
+
const result = super.update(node, decorations, innerDecorations);
|
|
53598
|
+
if (!result) return false;
|
|
53599
|
+
this.updateView();
|
|
53600
|
+
return true;
|
|
53601
|
+
}
|
|
53602
|
+
}
|
|
53603
|
+
const structuredContentClass$1 = "sd-structured-content";
|
|
53604
|
+
const structuredContentInnerClass$1 = "sd-structured-content__content";
|
|
53605
|
+
const StructuredContent = Node$1.create({
|
|
53606
|
+
name: "structuredContent",
|
|
53607
|
+
group: "inline structuredContent",
|
|
53434
53608
|
inline: true,
|
|
53435
53609
|
content: "inline*",
|
|
53436
|
-
|
|
53437
|
-
|
|
53610
|
+
isolating: true,
|
|
53611
|
+
atom: false,
|
|
53612
|
+
// false - has editable content.
|
|
53613
|
+
draggable: true,
|
|
53438
53614
|
addOptions() {
|
|
53439
53615
|
return {
|
|
53440
53616
|
htmlAttributes: {
|
|
53441
|
-
|
|
53617
|
+
class: structuredContentClass$1,
|
|
53618
|
+
"aria-label": "Structured content node"
|
|
53442
53619
|
}
|
|
53443
53620
|
};
|
|
53444
53621
|
},
|
|
53445
53622
|
addAttributes() {
|
|
53446
53623
|
return {
|
|
53447
|
-
|
|
53624
|
+
id: {
|
|
53448
53625
|
default: null,
|
|
53449
|
-
|
|
53450
|
-
|
|
53626
|
+
parseDOM: (elem) => elem.getAttribute("data-id"),
|
|
53627
|
+
renderDOM: (attrs) => {
|
|
53628
|
+
if (!attrs.id) return {};
|
|
53629
|
+
return { "data-id": attrs.id };
|
|
53630
|
+
}
|
|
53451
53631
|
},
|
|
53452
|
-
|
|
53632
|
+
tag: {
|
|
53453
53633
|
default: null,
|
|
53454
|
-
|
|
53455
|
-
|
|
53634
|
+
parseDOM: (elem) => elem.getAttribute("data-tag"),
|
|
53635
|
+
renderDOM: (attrs) => {
|
|
53636
|
+
if (!attrs.tag) return {};
|
|
53637
|
+
return { "data-tag": attrs.tag };
|
|
53638
|
+
}
|
|
53456
53639
|
},
|
|
53457
|
-
|
|
53640
|
+
alias: {
|
|
53458
53641
|
default: null,
|
|
53459
|
-
|
|
53460
|
-
|
|
53642
|
+
parseDOM: (elem) => elem.getAttribute("data-alias"),
|
|
53643
|
+
renderDOM: (attrs) => {
|
|
53644
|
+
if (!attrs.alias) return {};
|
|
53645
|
+
return { "data-alias": attrs.alias };
|
|
53646
|
+
}
|
|
53461
53647
|
},
|
|
53462
|
-
|
|
53463
|
-
|
|
53464
|
-
rendered: false,
|
|
53465
|
-
keepOnSplit: true
|
|
53648
|
+
sdtPr: {
|
|
53649
|
+
rendered: false
|
|
53466
53650
|
}
|
|
53467
53651
|
};
|
|
53468
53652
|
},
|
|
53469
|
-
addCommands() {
|
|
53470
|
-
return {
|
|
53471
|
-
splitRun
|
|
53472
|
-
};
|
|
53473
|
-
},
|
|
53474
53653
|
parseDOM() {
|
|
53475
|
-
return [{ tag: "span[data-
|
|
53654
|
+
return [{ tag: "span[data-structured-content]" }];
|
|
53476
53655
|
},
|
|
53477
53656
|
renderDOM({ htmlAttributes }) {
|
|
53478
|
-
|
|
53479
|
-
|
|
53657
|
+
return [
|
|
53658
|
+
"span",
|
|
53659
|
+
Attribute2.mergeAttributes(this.options.htmlAttributes, htmlAttributes, {
|
|
53660
|
+
"data-structured-content": ""
|
|
53661
|
+
}),
|
|
53662
|
+
0
|
|
53663
|
+
];
|
|
53664
|
+
},
|
|
53665
|
+
addNodeView() {
|
|
53666
|
+
return (props) => {
|
|
53667
|
+
return new StructuredContentInlineView({ ...props });
|
|
53668
|
+
};
|
|
53480
53669
|
}
|
|
53481
53670
|
});
|
|
53482
|
-
|
|
53483
|
-
|
|
53484
|
-
|
|
53485
|
-
|
|
53486
|
-
|
|
53487
|
-
|
|
53488
|
-
|
|
53489
|
-
|
|
53671
|
+
class StructuredContentBlockView extends StructuredContentViewBase {
|
|
53672
|
+
constructor(props) {
|
|
53673
|
+
super(props);
|
|
53674
|
+
}
|
|
53675
|
+
mount() {
|
|
53676
|
+
this.buildView();
|
|
53677
|
+
}
|
|
53678
|
+
get contentDOM() {
|
|
53679
|
+
const contentElement = this.dom?.querySelector(`.${structuredContentInnerClass}`);
|
|
53680
|
+
return contentElement || null;
|
|
53681
|
+
}
|
|
53682
|
+
createElement() {
|
|
53683
|
+
const element = document.createElement("div");
|
|
53684
|
+
element.classList.add(structuredContentClass);
|
|
53685
|
+
element.setAttribute("data-structured-content-block", "");
|
|
53686
|
+
const contentElement = document.createElement("div");
|
|
53687
|
+
contentElement.classList.add(structuredContentInnerClass);
|
|
53688
|
+
element.append(contentElement);
|
|
53689
|
+
const domAttrs = Attribute2.mergeAttributes(this.htmlAttributes);
|
|
53690
|
+
updateDOMAttributes(element, { ...domAttrs });
|
|
53691
|
+
return { element, contentElement };
|
|
53692
|
+
}
|
|
53693
|
+
buildView() {
|
|
53694
|
+
const { element } = this.createElement();
|
|
53695
|
+
const dragHandle = this.createDragHandle();
|
|
53696
|
+
element.prepend(dragHandle);
|
|
53697
|
+
element.addEventListener("dragstart", (e) => this.onDragStart(e));
|
|
53698
|
+
this.root = element;
|
|
53699
|
+
}
|
|
53700
|
+
updateView() {
|
|
53701
|
+
const domAttrs = Attribute2.mergeAttributes(this.htmlAttributes);
|
|
53702
|
+
updateDOMAttributes(this.dom, { ...domAttrs });
|
|
53703
|
+
}
|
|
53704
|
+
update(node, decorations, innerDecorations) {
|
|
53705
|
+
const result = super.update(node, decorations, innerDecorations);
|
|
53706
|
+
if (!result) return false;
|
|
53707
|
+
this.updateView();
|
|
53708
|
+
return true;
|
|
53709
|
+
}
|
|
53710
|
+
}
|
|
53711
|
+
const structuredContentClass = "sd-structured-content-block";
|
|
53712
|
+
const structuredContentInnerClass = "sd-structured-content-block__content";
|
|
53713
|
+
const StructuredContentBlock = Node$1.create({
|
|
53714
|
+
name: "structuredContentBlock",
|
|
53715
|
+
group: "block structuredContent",
|
|
53716
|
+
content: "block*",
|
|
53717
|
+
isolating: true,
|
|
53718
|
+
atom: false,
|
|
53719
|
+
// false - has editable content.
|
|
53720
|
+
draggable: true,
|
|
53490
53721
|
addOptions() {
|
|
53491
53722
|
return {
|
|
53492
|
-
itemTypeName: "listItem",
|
|
53493
53723
|
htmlAttributes: {
|
|
53494
|
-
|
|
53495
|
-
|
|
53496
|
-
|
|
53497
|
-
keepAttributes: false
|
|
53724
|
+
class: structuredContentClass,
|
|
53725
|
+
"aria-label": "Structured content block node"
|
|
53726
|
+
}
|
|
53498
53727
|
};
|
|
53499
53728
|
},
|
|
53500
|
-
parseDOM() {
|
|
53501
|
-
return [{ tag: "ul" }];
|
|
53502
|
-
},
|
|
53503
|
-
renderDOM({ htmlAttributes }) {
|
|
53504
|
-
const attributes = Attribute2.mergeAttributes(this.options.htmlAttributes, htmlAttributes);
|
|
53505
|
-
return ["ul", attributes, 0];
|
|
53506
|
-
},
|
|
53507
53729
|
addAttributes() {
|
|
53508
53730
|
return {
|
|
53509
|
-
|
|
53510
|
-
default:
|
|
53511
|
-
|
|
53731
|
+
id: {
|
|
53732
|
+
default: null,
|
|
53733
|
+
parseDOM: (elem) => elem.getAttribute("data-id"),
|
|
53734
|
+
renderDOM: (attrs) => {
|
|
53735
|
+
if (!attrs.id) return {};
|
|
53736
|
+
return { "data-id": attrs.id };
|
|
53737
|
+
}
|
|
53512
53738
|
},
|
|
53513
|
-
|
|
53514
|
-
|
|
53739
|
+
tag: {
|
|
53740
|
+
default: null,
|
|
53741
|
+
parseDOM: (elem) => elem.getAttribute("data-tag"),
|
|
53742
|
+
renderDOM: (attrs) => {
|
|
53743
|
+
if (!attrs.tag) return {};
|
|
53744
|
+
return { "data-tag": attrs.tag };
|
|
53745
|
+
}
|
|
53515
53746
|
},
|
|
53516
|
-
|
|
53747
|
+
alias: {
|
|
53517
53748
|
default: null,
|
|
53518
|
-
|
|
53519
|
-
parseDOM: (elem) => elem.getAttribute("data-sd-block-id"),
|
|
53749
|
+
parseDOM: (elem) => elem.getAttribute("data-alias"),
|
|
53520
53750
|
renderDOM: (attrs) => {
|
|
53521
|
-
|
|
53751
|
+
if (!attrs.alias) return {};
|
|
53752
|
+
return { "data-alias": attrs.alias };
|
|
53522
53753
|
}
|
|
53523
53754
|
},
|
|
53524
|
-
|
|
53525
|
-
rendered: false
|
|
53526
|
-
keepOnSplit: true
|
|
53527
|
-
}
|
|
53528
|
-
};
|
|
53529
|
-
},
|
|
53530
|
-
addCommands() {
|
|
53531
|
-
return {
|
|
53532
|
-
/**
|
|
53533
|
-
* Toggle a bullet list at the current selection
|
|
53534
|
-
* @category Command
|
|
53535
|
-
* @example
|
|
53536
|
-
* // Toggle bullet list on selected text
|
|
53537
|
-
* editor.commands.toggleBulletList()
|
|
53538
|
-
* @note Converts selected paragraphs to list items or removes list formatting
|
|
53539
|
-
*/
|
|
53540
|
-
toggleBulletList: () => (params2) => {
|
|
53541
|
-
return toggleList(this.type)(params2);
|
|
53755
|
+
sdtPr: {
|
|
53756
|
+
rendered: false
|
|
53542
53757
|
}
|
|
53543
53758
|
};
|
|
53544
53759
|
},
|
|
53545
|
-
|
|
53546
|
-
return {
|
|
53547
|
-
"Mod-Shift-8": () => {
|
|
53548
|
-
return this.editor.commands.toggleBulletList();
|
|
53549
|
-
}
|
|
53550
|
-
};
|
|
53760
|
+
parseDOM() {
|
|
53761
|
+
return [{ tag: "div[data-structured-content-block]" }];
|
|
53551
53762
|
},
|
|
53552
|
-
|
|
53763
|
+
renderDOM({ htmlAttributes }) {
|
|
53553
53764
|
return [
|
|
53554
|
-
|
|
53555
|
-
|
|
53556
|
-
|
|
53557
|
-
|
|
53558
|
-
|
|
53559
|
-
for (let depth = $pos.depth; depth >= 0; depth--) {
|
|
53560
|
-
if ($pos.node(depth).type === listItemType) {
|
|
53561
|
-
return null;
|
|
53562
|
-
}
|
|
53563
|
-
}
|
|
53564
|
-
const { tr } = state2;
|
|
53565
|
-
tr.delete(range2.from, range2.to);
|
|
53566
|
-
ListHelpers.createNewList({
|
|
53567
|
-
listType: this.type,
|
|
53568
|
-
tr,
|
|
53569
|
-
editor: this.editor
|
|
53570
|
-
});
|
|
53571
|
-
}
|
|
53572
|
-
})
|
|
53765
|
+
"div",
|
|
53766
|
+
Attribute2.mergeAttributes(this.options.htmlAttributes, htmlAttributes, {
|
|
53767
|
+
"data-structured-content-block": ""
|
|
53768
|
+
}),
|
|
53769
|
+
0
|
|
53573
53770
|
];
|
|
53771
|
+
},
|
|
53772
|
+
addNodeView() {
|
|
53773
|
+
return (props) => {
|
|
53774
|
+
return new StructuredContentBlockView({ ...props });
|
|
53775
|
+
};
|
|
53574
53776
|
}
|
|
53575
53777
|
});
|
|
53576
|
-
|
|
53577
|
-
const
|
|
53778
|
+
function getStructuredContentTagsById(idOrIds, state2) {
|
|
53779
|
+
const result = findChildren$5(state2.doc, (node) => {
|
|
53780
|
+
const isStructuredContent = ["structuredContent", "structuredContentBlock"].includes(node.type.name);
|
|
53781
|
+
if (Array.isArray(idOrIds)) {
|
|
53782
|
+
return isStructuredContent && idOrIds.includes(node.attrs.id);
|
|
53783
|
+
} else {
|
|
53784
|
+
return isStructuredContent && node.attrs.id === idOrIds;
|
|
53785
|
+
}
|
|
53786
|
+
});
|
|
53787
|
+
return result;
|
|
53788
|
+
}
|
|
53789
|
+
function getStructuredContentTags(state2) {
|
|
53790
|
+
const result = findChildren$5(state2.doc, (node) => {
|
|
53791
|
+
return node.type.name === "structuredContent" || node.type.name === "structuredContentBlock";
|
|
53792
|
+
});
|
|
53793
|
+
return result;
|
|
53794
|
+
}
|
|
53795
|
+
function getStructuredContentInlineTags(state2) {
|
|
53796
|
+
const result = findChildren$5(state2.doc, (node) => node.type.name === "structuredContent");
|
|
53797
|
+
return result;
|
|
53798
|
+
}
|
|
53799
|
+
function getStructuredContentBlockTags(state2) {
|
|
53800
|
+
const result = findChildren$5(state2.doc, (node) => node.type.name === "structuredContentBlock");
|
|
53801
|
+
return result;
|
|
53802
|
+
}
|
|
53803
|
+
const structuredContentHelpers = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
53804
|
+
__proto__: null,
|
|
53805
|
+
getStructuredContentBlockTags,
|
|
53806
|
+
getStructuredContentInlineTags,
|
|
53807
|
+
getStructuredContentTags,
|
|
53808
|
+
getStructuredContentTagsById
|
|
53809
|
+
}, Symbol.toStringTag, { value: "Module" }));
|
|
53810
|
+
const STRUCTURED_CONTENT_NAMES = ["structuredContent", "structuredContentBlock"];
|
|
53811
|
+
const StructuredContentCommands = Extension.create({
|
|
53812
|
+
name: "structuredContentCommands",
|
|
53813
|
+
addCommands() {
|
|
53814
|
+
return {
|
|
53815
|
+
/**
|
|
53816
|
+
* Inserts a structured content inline at selection.
|
|
53817
|
+
* @category Command
|
|
53818
|
+
* @param {StructuredContentInlineInsert} options
|
|
53819
|
+
*/
|
|
53820
|
+
insertStructuredContentInline: (options = {}) => ({ editor, dispatch, state: state2, tr }) => {
|
|
53821
|
+
const { schema } = editor;
|
|
53822
|
+
let { from: from2, to } = state2.selection;
|
|
53823
|
+
if (dispatch) {
|
|
53824
|
+
const selectionText = state2.doc.textBetween(from2, to);
|
|
53825
|
+
let content = null;
|
|
53826
|
+
if (selectionText) {
|
|
53827
|
+
content = schema.text(selectionText);
|
|
53828
|
+
}
|
|
53829
|
+
if (options.text) {
|
|
53830
|
+
content = schema.text(options.text);
|
|
53831
|
+
}
|
|
53832
|
+
if (options.json) {
|
|
53833
|
+
content = schema.nodeFromJSON(options.json);
|
|
53834
|
+
}
|
|
53835
|
+
if (!content) {
|
|
53836
|
+
content = schema.text(" ");
|
|
53837
|
+
}
|
|
53838
|
+
const attrs = {
|
|
53839
|
+
...options.attrs,
|
|
53840
|
+
id: options.attrs?.id || generateRandomSigned32BitIntStrId(),
|
|
53841
|
+
tag: "inline_text_sdt",
|
|
53842
|
+
alias: options.attrs?.alias || "Structured content"
|
|
53843
|
+
};
|
|
53844
|
+
const node = schema.nodes.structuredContent.create(attrs, content, null);
|
|
53845
|
+
const parent = findParentNode((node2) => node2.type.name === "structuredContent")(state2.selection);
|
|
53846
|
+
if (parent) {
|
|
53847
|
+
const insertPos = parent.pos + parent.node.nodeSize;
|
|
53848
|
+
from2 = to = insertPos;
|
|
53849
|
+
}
|
|
53850
|
+
tr.replaceWith(from2, to, node);
|
|
53851
|
+
}
|
|
53852
|
+
return true;
|
|
53853
|
+
},
|
|
53854
|
+
/**
|
|
53855
|
+
* Inserts a structured content block at selection.
|
|
53856
|
+
* @category Command
|
|
53857
|
+
* @param {StructuredContentBlockInsert} options
|
|
53858
|
+
*/
|
|
53859
|
+
insertStructuredContentBlock: (options = {}) => ({ editor, dispatch, state: state2, tr }) => {
|
|
53860
|
+
const { schema } = editor;
|
|
53861
|
+
let { from: from2, to } = state2.selection;
|
|
53862
|
+
if (dispatch) {
|
|
53863
|
+
const selectionContent = state2.selection.content();
|
|
53864
|
+
let content = null;
|
|
53865
|
+
if (selectionContent.size) {
|
|
53866
|
+
content = selectionContent.content;
|
|
53867
|
+
}
|
|
53868
|
+
if (options.html) {
|
|
53869
|
+
const html = htmlHandler(options.html, editor);
|
|
53870
|
+
const doc2 = DOMParser$1.fromSchema(schema).parse(html);
|
|
53871
|
+
content = doc2.content;
|
|
53872
|
+
}
|
|
53873
|
+
if (options.json) {
|
|
53874
|
+
content = schema.nodeFromJSON(options.json);
|
|
53875
|
+
}
|
|
53876
|
+
if (!content) {
|
|
53877
|
+
content = schema.nodeFromJSON({ type: "paragraph", content: [] });
|
|
53878
|
+
}
|
|
53879
|
+
const attrs = {
|
|
53880
|
+
...options.attrs,
|
|
53881
|
+
id: options.attrs?.id || generateRandomSigned32BitIntStrId(),
|
|
53882
|
+
tag: "block_table_sdt",
|
|
53883
|
+
alias: options.attrs?.alias || "Structured content"
|
|
53884
|
+
};
|
|
53885
|
+
const node = schema.nodes.structuredContentBlock.create(attrs, content, null);
|
|
53886
|
+
const parent = findParentNode((node2) => node2.type.name === "structuredContentBlock")(state2.selection);
|
|
53887
|
+
if (parent) {
|
|
53888
|
+
const insertPos = parent.pos + parent.node.nodeSize;
|
|
53889
|
+
from2 = to = insertPos;
|
|
53890
|
+
}
|
|
53891
|
+
tr.replaceRangeWith(from2, to, node);
|
|
53892
|
+
}
|
|
53893
|
+
return true;
|
|
53894
|
+
},
|
|
53895
|
+
/**
|
|
53896
|
+
* Updates a structured content attributes or content.
|
|
53897
|
+
* If the updated node does not match the schema, it will not be updated.
|
|
53898
|
+
* @category Command
|
|
53899
|
+
* @param {string} id
|
|
53900
|
+
* @param {StructuredContentUpdate} options
|
|
53901
|
+
*/
|
|
53902
|
+
updateStructuredContentById: (id, options = {}) => ({ editor, dispatch, state: state2, tr }) => {
|
|
53903
|
+
const structuredContentTags = getStructuredContentTagsById(id, state2);
|
|
53904
|
+
if (!structuredContentTags.length) {
|
|
53905
|
+
return true;
|
|
53906
|
+
}
|
|
53907
|
+
const { schema } = editor;
|
|
53908
|
+
if (dispatch) {
|
|
53909
|
+
const structuredContent = structuredContentTags[0];
|
|
53910
|
+
const { pos, node } = structuredContent;
|
|
53911
|
+
const posFrom = pos;
|
|
53912
|
+
const posTo = pos + node.nodeSize;
|
|
53913
|
+
let content = null;
|
|
53914
|
+
if (options.text) {
|
|
53915
|
+
content = schema.text(options.text);
|
|
53916
|
+
}
|
|
53917
|
+
if (options.html) {
|
|
53918
|
+
const html = htmlHandler(options.html, editor);
|
|
53919
|
+
const doc2 = DOMParser$1.fromSchema(schema).parse(html);
|
|
53920
|
+
content = doc2.content;
|
|
53921
|
+
}
|
|
53922
|
+
if (options.json) {
|
|
53923
|
+
content = schema.nodeFromJSON(options.json);
|
|
53924
|
+
}
|
|
53925
|
+
if (!content) {
|
|
53926
|
+
content = node.content;
|
|
53927
|
+
}
|
|
53928
|
+
const updatedNode = node.type.create({ ...node.attrs, ...options.attrs }, content, node.marks);
|
|
53929
|
+
try {
|
|
53930
|
+
updatedNode.check();
|
|
53931
|
+
} catch {
|
|
53932
|
+
console.error("Updated node does not conform to the schema");
|
|
53933
|
+
return false;
|
|
53934
|
+
}
|
|
53935
|
+
tr.replaceWith(posFrom, posTo, updatedNode);
|
|
53936
|
+
}
|
|
53937
|
+
return true;
|
|
53938
|
+
},
|
|
53939
|
+
/**
|
|
53940
|
+
* Removes a structured content.
|
|
53941
|
+
* @category Command
|
|
53942
|
+
* @param {Array<{ node: Node, pos: number }>} structuredContentTags
|
|
53943
|
+
*/
|
|
53944
|
+
deleteStructuredContent: (structuredContentTags) => ({ dispatch, tr }) => {
|
|
53945
|
+
if (!structuredContentTags.length) {
|
|
53946
|
+
return true;
|
|
53947
|
+
}
|
|
53948
|
+
if (dispatch) {
|
|
53949
|
+
structuredContentTags.forEach((structuredContent) => {
|
|
53950
|
+
const { pos, node } = structuredContent;
|
|
53951
|
+
const posFrom = tr.mapping.map(pos);
|
|
53952
|
+
const posTo = tr.mapping.map(pos + node.nodeSize);
|
|
53953
|
+
const currentNode = tr.doc.nodeAt(posFrom);
|
|
53954
|
+
if (currentNode && node.eq(currentNode)) {
|
|
53955
|
+
tr.delete(posFrom, posTo);
|
|
53956
|
+
}
|
|
53957
|
+
});
|
|
53958
|
+
}
|
|
53959
|
+
return true;
|
|
53960
|
+
},
|
|
53961
|
+
/**
|
|
53962
|
+
* Removes a structured content by ID.
|
|
53963
|
+
* @category Command
|
|
53964
|
+
* @param {string | string[]} idOrIds
|
|
53965
|
+
*/
|
|
53966
|
+
deleteStructuredContentById: (idOrIds) => ({ dispatch, state: state2, tr }) => {
|
|
53967
|
+
const structuredContentTags = getStructuredContentTagsById(idOrIds, state2);
|
|
53968
|
+
if (!structuredContentTags.length) {
|
|
53969
|
+
return true;
|
|
53970
|
+
}
|
|
53971
|
+
if (dispatch) {
|
|
53972
|
+
structuredContentTags.forEach((structuredContent) => {
|
|
53973
|
+
const { pos, node } = structuredContent;
|
|
53974
|
+
const posFrom = tr.mapping.map(pos);
|
|
53975
|
+
const posTo = tr.mapping.map(pos + node.nodeSize);
|
|
53976
|
+
const currentNode = tr.doc.nodeAt(posFrom);
|
|
53977
|
+
if (currentNode && node.eq(currentNode)) {
|
|
53978
|
+
tr.delete(posFrom, posTo);
|
|
53979
|
+
}
|
|
53980
|
+
});
|
|
53981
|
+
}
|
|
53982
|
+
return true;
|
|
53983
|
+
},
|
|
53984
|
+
/**
|
|
53985
|
+
* Removes a structured content at cursor, preserving its content.
|
|
53986
|
+
* @category Command
|
|
53987
|
+
*/
|
|
53988
|
+
deleteStructuredContentAtSelection: () => ({ dispatch, state: state2, tr }) => {
|
|
53989
|
+
const predicate = (node) => STRUCTURED_CONTENT_NAMES.includes(node.type.name);
|
|
53990
|
+
const structuredContent = findParentNode(predicate)(state2.selection);
|
|
53991
|
+
if (!structuredContent) {
|
|
53992
|
+
return true;
|
|
53993
|
+
}
|
|
53994
|
+
if (dispatch) {
|
|
53995
|
+
const { node, pos } = structuredContent;
|
|
53996
|
+
const posFrom = pos;
|
|
53997
|
+
const posTo = posFrom + node.nodeSize;
|
|
53998
|
+
const content = node.content;
|
|
53999
|
+
tr.replaceWith(posFrom, posTo, content);
|
|
54000
|
+
}
|
|
54001
|
+
return true;
|
|
54002
|
+
}
|
|
54003
|
+
};
|
|
54004
|
+
},
|
|
54005
|
+
addHelpers() {
|
|
54006
|
+
return {
|
|
54007
|
+
...structuredContentHelpers
|
|
54008
|
+
};
|
|
54009
|
+
}
|
|
54010
|
+
});
|
|
54011
|
+
class DocumentSectionView {
|
|
54012
|
+
constructor(node, getPos, decorations, editor) {
|
|
54013
|
+
__privateAdd$1(this, _DocumentSectionView_instances);
|
|
54014
|
+
this.node = node;
|
|
54015
|
+
this.editor = editor;
|
|
54016
|
+
this.decorations = decorations;
|
|
54017
|
+
this.view = editor.view;
|
|
54018
|
+
this.getPos = getPos;
|
|
54019
|
+
__privateMethod$1(this, _DocumentSectionView_instances, init_fn2).call(this);
|
|
54020
|
+
}
|
|
54021
|
+
}
|
|
54022
|
+
_DocumentSectionView_instances = /* @__PURE__ */ new WeakSet();
|
|
54023
|
+
init_fn2 = function() {
|
|
54024
|
+
const { attrs } = this.node;
|
|
54025
|
+
const { id, title, description } = attrs;
|
|
54026
|
+
this.dom = document.createElement("div");
|
|
54027
|
+
this.dom.className = "sd-document-section-block";
|
|
54028
|
+
this.dom.setAttribute("data-id", id);
|
|
54029
|
+
this.dom.setAttribute("data-title", title);
|
|
54030
|
+
this.dom.setAttribute("data-description", description);
|
|
54031
|
+
this.dom.setAttribute("aria-label", "Document section");
|
|
54032
|
+
__privateMethod$1(this, _DocumentSectionView_instances, addToolTip_fn).call(this);
|
|
54033
|
+
this.contentDOM = document.createElement("div");
|
|
54034
|
+
this.contentDOM.className = "sd-document-section-block-content";
|
|
54035
|
+
this.contentDOM.setAttribute("contenteditable", "true");
|
|
54036
|
+
this.dom.appendChild(this.contentDOM);
|
|
54037
|
+
};
|
|
54038
|
+
addToolTip_fn = function() {
|
|
54039
|
+
const { title } = this.node.attrs;
|
|
54040
|
+
this.infoDiv = document.createElement("div");
|
|
54041
|
+
this.infoDiv.className = "sd-document-section-block-info";
|
|
54042
|
+
const textSpan = document.createElement("span");
|
|
54043
|
+
textSpan.textContent = title || "Document section";
|
|
54044
|
+
this.infoDiv.appendChild(textSpan);
|
|
54045
|
+
this.infoDiv.setAttribute("contenteditable", "false");
|
|
54046
|
+
this.dom.appendChild(this.infoDiv);
|
|
54047
|
+
};
|
|
54048
|
+
const getAllSections = (editor) => {
|
|
54049
|
+
if (!editor) return [];
|
|
54050
|
+
const type2 = editor.schema.nodes.documentSection;
|
|
54051
|
+
if (!type2) return [];
|
|
54052
|
+
const sections = [];
|
|
54053
|
+
const { state: state2 } = editor;
|
|
54054
|
+
state2.doc.descendants((node, pos) => {
|
|
54055
|
+
if (node.type.name === type2.name) {
|
|
54056
|
+
sections.push({ node, pos });
|
|
54057
|
+
}
|
|
54058
|
+
});
|
|
54059
|
+
return sections;
|
|
54060
|
+
};
|
|
54061
|
+
const exportSectionsToHTML = (editor) => {
|
|
54062
|
+
const sections = getAllSections(editor);
|
|
54063
|
+
const processedSections = /* @__PURE__ */ new Set();
|
|
54064
|
+
const result = [];
|
|
54065
|
+
sections.forEach(({ node }) => {
|
|
54066
|
+
const { attrs } = node;
|
|
54067
|
+
const { id, title, description } = attrs;
|
|
54068
|
+
if (processedSections.has(id)) return;
|
|
54069
|
+
processedSections.add(id);
|
|
54070
|
+
const html = getHTMLFromNode(node, editor);
|
|
54071
|
+
result.push({
|
|
54072
|
+
id,
|
|
54073
|
+
title,
|
|
54074
|
+
description,
|
|
54075
|
+
html
|
|
54076
|
+
});
|
|
54077
|
+
});
|
|
54078
|
+
return result;
|
|
54079
|
+
};
|
|
54080
|
+
const getHTMLFromNode = (node, editor) => {
|
|
54081
|
+
const tempDocument = document.implementation.createHTMLDocument();
|
|
54082
|
+
const container = tempDocument.createElement("div");
|
|
54083
|
+
const fragment = DOMSerializer.fromSchema(editor.schema).serializeFragment(node.content);
|
|
54084
|
+
container.appendChild(fragment);
|
|
54085
|
+
let html = container.innerHTML;
|
|
54086
|
+
return html;
|
|
54087
|
+
};
|
|
54088
|
+
const exportSectionsToJSON = (editor) => {
|
|
54089
|
+
const sections = getAllSections(editor);
|
|
54090
|
+
const processedSections = /* @__PURE__ */ new Set();
|
|
54091
|
+
const result = [];
|
|
54092
|
+
sections.forEach(({ node }) => {
|
|
54093
|
+
const { attrs } = node;
|
|
54094
|
+
const { id, title, description } = attrs;
|
|
54095
|
+
if (processedSections.has(id)) return;
|
|
54096
|
+
processedSections.add(id);
|
|
54097
|
+
result.push({
|
|
54098
|
+
id,
|
|
54099
|
+
title,
|
|
54100
|
+
description,
|
|
54101
|
+
content: node.toJSON()
|
|
54102
|
+
});
|
|
54103
|
+
});
|
|
54104
|
+
return result;
|
|
54105
|
+
};
|
|
54106
|
+
const getLinkedSectionEditor = (id, options, editor) => {
|
|
54107
|
+
const sections = getAllSections(editor);
|
|
54108
|
+
const section = sections.find((s) => s.node.attrs.id === id);
|
|
54109
|
+
if (!section) return null;
|
|
54110
|
+
const child = editor.createChildEditor({
|
|
54111
|
+
...options,
|
|
54112
|
+
onUpdate: ({ editor: childEditor, transaction }) => {
|
|
54113
|
+
const isFromtLinkedParent = transaction.getMeta("fromLinkedParent");
|
|
54114
|
+
if (isFromtLinkedParent) return;
|
|
54115
|
+
const updatedContent = childEditor.state.doc.content;
|
|
54116
|
+
const sectionNode = getAllSections(editor)?.find((s) => s.node.attrs.id === id);
|
|
54117
|
+
if (!sectionNode) return;
|
|
54118
|
+
const { pos, node } = sectionNode;
|
|
54119
|
+
const newNode = node.type.create(node.attrs, updatedContent, node.marks);
|
|
54120
|
+
const tr = editor.state.tr.replaceWith(pos, pos + node.nodeSize, newNode);
|
|
54121
|
+
tr.setMeta("fromLinkedChild", true);
|
|
54122
|
+
editor.view.dispatch(tr);
|
|
54123
|
+
}
|
|
54124
|
+
});
|
|
54125
|
+
editor.on("update", ({ transaction }) => {
|
|
54126
|
+
const isFromLinkedChild = transaction.getMeta("fromLinkedChild");
|
|
54127
|
+
if (isFromLinkedChild) return;
|
|
54128
|
+
const sectionNode = getAllSections(editor)?.find((s) => s.node.attrs.id === id);
|
|
54129
|
+
if (!sectionNode) return;
|
|
54130
|
+
const sectionContent = sectionNode.node.content;
|
|
54131
|
+
const json = {
|
|
54132
|
+
type: "doc",
|
|
54133
|
+
content: sectionContent.content.map((node) => node.toJSON())
|
|
54134
|
+
};
|
|
54135
|
+
const childTr = child.state.tr;
|
|
54136
|
+
childTr.setMeta("fromLinkedParent", true);
|
|
54137
|
+
childTr.replaceWith(0, child.state.doc.content.size, child.schema.nodeFromJSON(json));
|
|
54138
|
+
child.view.dispatch(childTr);
|
|
54139
|
+
});
|
|
54140
|
+
return child;
|
|
54141
|
+
};
|
|
54142
|
+
const SectionHelpers = {
|
|
54143
|
+
getAllSections,
|
|
54144
|
+
exportSectionsToHTML,
|
|
54145
|
+
exportSectionsToJSON,
|
|
54146
|
+
getLinkedSectionEditor
|
|
54147
|
+
};
|
|
54148
|
+
const DocumentSection = Node$1.create({
|
|
54149
|
+
name: "documentSection",
|
|
54150
|
+
group: "block",
|
|
54151
|
+
content: "block*",
|
|
54152
|
+
atom: true,
|
|
54153
|
+
isolating: true,
|
|
54154
|
+
addOptions() {
|
|
54155
|
+
return {
|
|
54156
|
+
htmlAttributes: {
|
|
54157
|
+
class: "sd-document-section-block",
|
|
54158
|
+
"aria-label": "Structured content block"
|
|
54159
|
+
}
|
|
54160
|
+
};
|
|
54161
|
+
},
|
|
54162
|
+
parseDOM() {
|
|
54163
|
+
return [
|
|
54164
|
+
{
|
|
54165
|
+
tag: "div.sd-document-section-block",
|
|
54166
|
+
priority: 60
|
|
54167
|
+
}
|
|
54168
|
+
];
|
|
54169
|
+
},
|
|
54170
|
+
renderDOM({ htmlAttributes }) {
|
|
54171
|
+
return ["div", Attribute2.mergeAttributes(this.options.htmlAttributes, htmlAttributes), 0];
|
|
54172
|
+
},
|
|
54173
|
+
addAttributes() {
|
|
54174
|
+
return {
|
|
54175
|
+
id: {},
|
|
54176
|
+
sdBlockId: {
|
|
54177
|
+
default: null,
|
|
54178
|
+
keepOnSplit: false,
|
|
54179
|
+
parseDOM: (elem) => elem.getAttribute("data-sd-block-id"),
|
|
54180
|
+
renderDOM: (attrs) => {
|
|
54181
|
+
return attrs.sdBlockId ? { "data-sd-block-id": attrs.sdBlockId } : {};
|
|
54182
|
+
}
|
|
54183
|
+
},
|
|
54184
|
+
title: {},
|
|
54185
|
+
description: {},
|
|
54186
|
+
sectionType: {},
|
|
54187
|
+
isLocked: { default: false }
|
|
54188
|
+
};
|
|
54189
|
+
},
|
|
54190
|
+
addNodeView() {
|
|
54191
|
+
return ({ node, editor, getPos, decorations }) => {
|
|
54192
|
+
return new DocumentSectionView(node, getPos, decorations, editor);
|
|
54193
|
+
};
|
|
54194
|
+
},
|
|
54195
|
+
addCommands() {
|
|
54196
|
+
return {
|
|
54197
|
+
/**
|
|
54198
|
+
* Create a lockable content section
|
|
54199
|
+
* @category Command
|
|
54200
|
+
* @param {SectionCreate} [options={}] - Section configuration
|
|
54201
|
+
* @example
|
|
54202
|
+
* editor.commands.createDocumentSection({
|
|
54203
|
+
* id: 1,
|
|
54204
|
+
* title: 'Terms & Conditions',
|
|
54205
|
+
* isLocked: true,
|
|
54206
|
+
* html: '<p>Legal content...</p>'
|
|
54207
|
+
* })
|
|
54208
|
+
*/
|
|
54209
|
+
createDocumentSection: (options = {}) => ({ tr, state: state2, dispatch, editor }) => {
|
|
54210
|
+
const { selection } = state2;
|
|
54211
|
+
let { from: from2, to } = selection;
|
|
54212
|
+
let content = selection.content().content;
|
|
54213
|
+
const { html: optionsHTML, json: optionsJSON } = options;
|
|
54214
|
+
if (optionsHTML) {
|
|
54215
|
+
const html = htmlHandler(optionsHTML, this.editor);
|
|
54216
|
+
const doc2 = DOMParser$1.fromSchema(this.editor.schema).parse(html);
|
|
54217
|
+
content = doc2.content;
|
|
54218
|
+
}
|
|
54219
|
+
if (optionsJSON) {
|
|
54220
|
+
content = this.editor.schema.nodeFromJSON(optionsJSON);
|
|
54221
|
+
}
|
|
54222
|
+
if (!content?.content?.length) {
|
|
54223
|
+
content = this.editor.schema.nodeFromJSON({ type: "paragraph", content: [] });
|
|
54224
|
+
}
|
|
54225
|
+
if (!options.id) {
|
|
54226
|
+
const allSections = SectionHelpers.getAllSections(editor);
|
|
54227
|
+
options.id = allSections.length + 1;
|
|
54228
|
+
}
|
|
54229
|
+
if (!options.title) {
|
|
54230
|
+
options.title = "Document section";
|
|
54231
|
+
}
|
|
54232
|
+
const node = this.type.createAndFill(options, content);
|
|
54233
|
+
if (!node) return false;
|
|
54234
|
+
const isAlreadyInSdtBlock = findParentNode((node2) => node2.type.name === "documentSection")(selection);
|
|
54235
|
+
if (isAlreadyInSdtBlock && isAlreadyInSdtBlock.node) {
|
|
54236
|
+
const insertPos2 = isAlreadyInSdtBlock.pos + isAlreadyInSdtBlock.node.nodeSize;
|
|
54237
|
+
from2 = insertPos2;
|
|
54238
|
+
to = insertPos2;
|
|
54239
|
+
}
|
|
54240
|
+
tr.replaceRangeWith(from2, to, node);
|
|
54241
|
+
const nodeEnd = from2 + node.nodeSize;
|
|
54242
|
+
let shouldInsertParagraph = true;
|
|
54243
|
+
let insertPos = nodeEnd;
|
|
54244
|
+
if (nodeEnd >= tr.doc.content.size) {
|
|
54245
|
+
insertPos = tr.doc.content.size;
|
|
54246
|
+
if (insertPos > 0) {
|
|
54247
|
+
const $endPos = tr.doc.resolve(insertPos);
|
|
54248
|
+
if ($endPos.nodeBefore && $endPos.nodeBefore.type.name === "paragraph") {
|
|
54249
|
+
shouldInsertParagraph = false;
|
|
54250
|
+
}
|
|
54251
|
+
}
|
|
54252
|
+
}
|
|
54253
|
+
if (shouldInsertParagraph) {
|
|
54254
|
+
const emptyParagraph = tr.doc.type.schema.nodes.paragraph.create();
|
|
54255
|
+
tr.insert(insertPos, emptyParagraph);
|
|
54256
|
+
}
|
|
54257
|
+
if (dispatch) {
|
|
54258
|
+
tr.setMeta("documentSection", { action: "create" });
|
|
54259
|
+
dispatch(tr);
|
|
54260
|
+
setTimeout(() => {
|
|
54261
|
+
try {
|
|
54262
|
+
const currentState = editor.state;
|
|
54263
|
+
const docSize = currentState.doc.content.size;
|
|
54264
|
+
let targetPos = from2 + node.nodeSize;
|
|
54265
|
+
if (shouldInsertParagraph) {
|
|
54266
|
+
targetPos += 1;
|
|
54267
|
+
}
|
|
54268
|
+
targetPos = Math.min(targetPos, docSize);
|
|
54269
|
+
if (targetPos < docSize && targetPos > 0) {
|
|
54270
|
+
const newSelection = Selection.near(currentState.doc.resolve(targetPos));
|
|
54271
|
+
const newTr = currentState.tr.setSelection(newSelection);
|
|
54272
|
+
editor.view.dispatch(newTr);
|
|
54273
|
+
}
|
|
54274
|
+
} catch (e) {
|
|
54275
|
+
console.warn("Could not set delayed selection:", e);
|
|
54276
|
+
}
|
|
54277
|
+
}, 0);
|
|
54278
|
+
}
|
|
54279
|
+
return true;
|
|
54280
|
+
},
|
|
54281
|
+
/**
|
|
54282
|
+
* Remove section wrapper at cursor, preserving its content
|
|
54283
|
+
* @category Command
|
|
54284
|
+
* @example
|
|
54285
|
+
* editor.commands.removeSectionAtSelection()
|
|
54286
|
+
* @note Content stays in document, only section wrapper is removed
|
|
54287
|
+
*/
|
|
54288
|
+
removeSectionAtSelection: () => ({ tr, dispatch }) => {
|
|
54289
|
+
const sdtNode = findParentNode((node2) => node2.type.name === "documentSection")(tr.selection);
|
|
54290
|
+
if (!sdtNode) return false;
|
|
54291
|
+
const { node, pos } = sdtNode;
|
|
54292
|
+
const nodeStart = pos;
|
|
54293
|
+
const nodeEnd = nodeStart + node.nodeSize;
|
|
54294
|
+
const contentToPreserve = node.content;
|
|
54295
|
+
tr.delete(nodeStart, nodeEnd);
|
|
54296
|
+
if (contentToPreserve.size > 0) {
|
|
54297
|
+
tr.insert(nodeStart, contentToPreserve);
|
|
54298
|
+
}
|
|
54299
|
+
const newPos = Math.min(nodeStart, tr.doc.content.size);
|
|
54300
|
+
tr.setSelection(Selection.near(tr.doc.resolve(newPos)));
|
|
54301
|
+
if (dispatch) {
|
|
54302
|
+
tr.setMeta("documentSection", { action: "delete" });
|
|
54303
|
+
dispatch(tr);
|
|
54304
|
+
}
|
|
54305
|
+
return true;
|
|
54306
|
+
},
|
|
54307
|
+
/**
|
|
54308
|
+
* Delete section and all its content
|
|
54309
|
+
* @category Command
|
|
54310
|
+
* @param {number} id - Section to delete
|
|
54311
|
+
* @example
|
|
54312
|
+
* editor.commands.removeSectionById(123)
|
|
54313
|
+
*/
|
|
54314
|
+
removeSectionById: (id) => ({ tr, dispatch }) => {
|
|
54315
|
+
const sections = SectionHelpers.getAllSections(this.editor);
|
|
54316
|
+
const sectionToRemove = sections.find(({ node: node2 }) => node2.attrs.id === id);
|
|
54317
|
+
if (!sectionToRemove) return false;
|
|
54318
|
+
const { pos, node } = sectionToRemove;
|
|
54319
|
+
const nodeStart = pos;
|
|
54320
|
+
const nodeEnd = nodeStart + node.nodeSize;
|
|
54321
|
+
tr.delete(nodeStart, nodeEnd);
|
|
54322
|
+
if (dispatch) {
|
|
54323
|
+
tr.setMeta("documentSection", { action: "delete", id });
|
|
54324
|
+
dispatch(tr);
|
|
54325
|
+
}
|
|
54326
|
+
return true;
|
|
54327
|
+
},
|
|
54328
|
+
/**
|
|
54329
|
+
* Lock section against edits
|
|
54330
|
+
* @category Command
|
|
54331
|
+
* @param {number} id - Section to lock
|
|
54332
|
+
* @example
|
|
54333
|
+
* editor.commands.lockSectionById(123)
|
|
54334
|
+
*/
|
|
54335
|
+
lockSectionById: (id) => ({ tr, dispatch }) => {
|
|
54336
|
+
const sections = SectionHelpers.getAllSections(this.editor);
|
|
54337
|
+
const sectionToLock = sections.find(({ node }) => node.attrs.id === id);
|
|
54338
|
+
if (!sectionToLock) return false;
|
|
54339
|
+
tr.setNodeMarkup(sectionToLock.pos, null, { ...sectionToLock.node.attrs, isLocked: true });
|
|
54340
|
+
if (dispatch) {
|
|
54341
|
+
tr.setMeta("documentSection", { action: "lock", id });
|
|
54342
|
+
dispatch(tr);
|
|
54343
|
+
}
|
|
54344
|
+
return true;
|
|
54345
|
+
},
|
|
54346
|
+
/**
|
|
54347
|
+
* Modify section attributes or content
|
|
54348
|
+
* @category Command
|
|
54349
|
+
* @param {SectionUpdate} options - Changes to apply
|
|
54350
|
+
* @example
|
|
54351
|
+
* editor.commands.updateSectionById({ id: 123, attrs: { isLocked: false } })
|
|
54352
|
+
* editor.commands.updateSectionById({ id: 123, html: '<p>New content</p>' })
|
|
54353
|
+
* editor.commands.updateSectionById({
|
|
54354
|
+
* id: 123,
|
|
54355
|
+
* html: '<p>Updated</p>',
|
|
54356
|
+
* attrs: { title: 'New Title' }
|
|
54357
|
+
* })
|
|
54358
|
+
*/
|
|
54359
|
+
updateSectionById: ({ id, html, json, attrs }) => ({ tr, dispatch, editor }) => {
|
|
54360
|
+
const sections = SectionHelpers.getAllSections(editor || this.editor);
|
|
54361
|
+
const sectionToUpdate = sections.find(({ node: node2 }) => node2.attrs.id === id);
|
|
54362
|
+
if (!sectionToUpdate) return false;
|
|
54363
|
+
const { pos, node } = sectionToUpdate;
|
|
54364
|
+
let newContent = null;
|
|
54365
|
+
if (html) {
|
|
54366
|
+
const htmlDoc = htmlHandler(html, editor || this.editor);
|
|
54367
|
+
const doc2 = DOMParser$1.fromSchema((editor || this.editor).schema).parse(htmlDoc);
|
|
54368
|
+
newContent = doc2.content;
|
|
54369
|
+
}
|
|
54370
|
+
if (json) {
|
|
54371
|
+
newContent = (editor || this.editor).schema.nodeFromJSON(json);
|
|
54372
|
+
}
|
|
54373
|
+
if (!newContent) {
|
|
54374
|
+
newContent = node.content;
|
|
54375
|
+
}
|
|
54376
|
+
const updatedNode = node.type.create({ ...node.attrs, ...attrs }, newContent, node.marks);
|
|
54377
|
+
tr.replaceWith(pos, pos + node.nodeSize, updatedNode);
|
|
54378
|
+
if (dispatch) {
|
|
54379
|
+
tr.setMeta("documentSection", { action: "update", id, attrs });
|
|
54380
|
+
dispatch(tr);
|
|
54381
|
+
}
|
|
54382
|
+
return true;
|
|
54383
|
+
}
|
|
54384
|
+
};
|
|
54385
|
+
},
|
|
54386
|
+
addHelpers() {
|
|
54387
|
+
return {
|
|
54388
|
+
...SectionHelpers
|
|
54389
|
+
};
|
|
54390
|
+
}
|
|
54391
|
+
});
|
|
54392
|
+
const Document = Node$1.create({
|
|
54393
|
+
name: "doc",
|
|
54394
|
+
topNode: true,
|
|
54395
|
+
content: "block+",
|
|
54396
|
+
parseDOM() {
|
|
54397
|
+
return [{ tag: "doc" }];
|
|
54398
|
+
},
|
|
54399
|
+
renderDOM() {
|
|
54400
|
+
return ["doc", 0];
|
|
54401
|
+
},
|
|
54402
|
+
addAttributes() {
|
|
54403
|
+
return {
|
|
54404
|
+
attributes: {
|
|
54405
|
+
rendered: false,
|
|
54406
|
+
"aria-label": "Document node"
|
|
54407
|
+
}
|
|
54408
|
+
};
|
|
54409
|
+
},
|
|
54410
|
+
addCommands() {
|
|
54411
|
+
return {
|
|
54412
|
+
/**
|
|
54413
|
+
* Get document statistics
|
|
54414
|
+
* @category Command
|
|
54415
|
+
* @example
|
|
54416
|
+
* // Get word and character count
|
|
54417
|
+
* const stats = editor.commands.getDocumentStats()
|
|
54418
|
+
* console.log(`${stats.words} words, ${stats.characters} characters`)
|
|
54419
|
+
* @note Returns word count, character count, and paragraph count
|
|
54420
|
+
*/
|
|
54421
|
+
getDocumentStats: () => ({ editor }) => {
|
|
54422
|
+
const text = editor.getText();
|
|
54423
|
+
const words = text.split(/\s+/).filter((word) => word.length > 0).length;
|
|
54424
|
+
const characters = text.length;
|
|
54425
|
+
const paragraphs = editor.state.doc.content.childCount;
|
|
54426
|
+
return {
|
|
54427
|
+
words,
|
|
54428
|
+
characters,
|
|
54429
|
+
paragraphs
|
|
54430
|
+
};
|
|
54431
|
+
},
|
|
54432
|
+
/**
|
|
54433
|
+
* Clear entire document
|
|
54434
|
+
* @category Command
|
|
54435
|
+
* @example
|
|
54436
|
+
* editor.commands.clearDocument()
|
|
54437
|
+
* @note Replaces all content with an empty paragraph
|
|
54438
|
+
*/
|
|
54439
|
+
clearDocument: () => ({ commands: commands2 }) => {
|
|
54440
|
+
return commands2.setContent("<p></p>");
|
|
54441
|
+
}
|
|
54442
|
+
};
|
|
54443
|
+
}
|
|
54444
|
+
});
|
|
54445
|
+
const Text = Node$1.create({
|
|
54446
|
+
name: "text",
|
|
54447
|
+
group: "inline",
|
|
54448
|
+
inline: true,
|
|
54449
|
+
addOptions() {
|
|
54450
|
+
return {};
|
|
54451
|
+
}
|
|
54452
|
+
});
|
|
54453
|
+
const splitRun = () => (props) => {
|
|
54454
|
+
const { state: state2, view, tr } = props;
|
|
54455
|
+
const { $from, empty: empty2 } = state2.selection;
|
|
54456
|
+
if (!empty2) return false;
|
|
54457
|
+
if ($from.parent.type.name !== "run") return false;
|
|
54458
|
+
const handled = splitBlock(state2, (transaction) => {
|
|
54459
|
+
view.dispatch(transaction);
|
|
54460
|
+
});
|
|
54461
|
+
if (handled) {
|
|
54462
|
+
tr.setMeta("preventDispatch", true);
|
|
54463
|
+
}
|
|
54464
|
+
return handled;
|
|
54465
|
+
};
|
|
54466
|
+
const Run = OxmlNode.create({
|
|
54467
|
+
name: "run",
|
|
54468
|
+
oXmlName: "w:r",
|
|
54469
|
+
group: "inline",
|
|
54470
|
+
inline: true,
|
|
54471
|
+
content: "inline*",
|
|
54472
|
+
selectable: false,
|
|
54473
|
+
childToAttributes: ["runProperties"],
|
|
54474
|
+
addOptions() {
|
|
54475
|
+
return {
|
|
54476
|
+
htmlAttributes: {
|
|
54477
|
+
"data-run": "1"
|
|
54478
|
+
}
|
|
54479
|
+
};
|
|
54480
|
+
},
|
|
54481
|
+
addAttributes() {
|
|
54482
|
+
return {
|
|
54483
|
+
runProperties: {
|
|
54484
|
+
default: null,
|
|
54485
|
+
rendered: false,
|
|
54486
|
+
keepOnSplit: true
|
|
54487
|
+
},
|
|
54488
|
+
rsidR: {
|
|
54489
|
+
default: null,
|
|
54490
|
+
rendered: false,
|
|
54491
|
+
keepOnSplit: true
|
|
54492
|
+
},
|
|
54493
|
+
rsidRPr: {
|
|
54494
|
+
default: null,
|
|
54495
|
+
rendered: false,
|
|
54496
|
+
keepOnSplit: true
|
|
54497
|
+
},
|
|
54498
|
+
rsidDel: {
|
|
54499
|
+
default: null,
|
|
54500
|
+
rendered: false,
|
|
54501
|
+
keepOnSplit: true
|
|
54502
|
+
}
|
|
54503
|
+
};
|
|
54504
|
+
},
|
|
54505
|
+
addCommands() {
|
|
54506
|
+
return {
|
|
54507
|
+
splitRun
|
|
54508
|
+
};
|
|
54509
|
+
},
|
|
54510
|
+
parseDOM() {
|
|
54511
|
+
return [{ tag: "span[data-run]" }];
|
|
54512
|
+
},
|
|
54513
|
+
renderDOM({ htmlAttributes }) {
|
|
54514
|
+
const base2 = Attribute2.mergeAttributes(this.options.htmlAttributes, htmlAttributes);
|
|
54515
|
+
return ["span", base2, 0];
|
|
54516
|
+
}
|
|
54517
|
+
});
|
|
54518
|
+
const inputRegex$1 = /^\s*([-+*])\s$/;
|
|
54519
|
+
const BulletList = Node$1.create({
|
|
54520
|
+
name: "bulletList",
|
|
54521
|
+
group: "block list",
|
|
54522
|
+
selectable: false,
|
|
54523
|
+
content() {
|
|
54524
|
+
return `${this.options.itemTypeName}+`;
|
|
54525
|
+
},
|
|
54526
|
+
addOptions() {
|
|
54527
|
+
return {
|
|
54528
|
+
itemTypeName: "listItem",
|
|
54529
|
+
htmlAttributes: {
|
|
54530
|
+
"aria-label": "Bullet list node"
|
|
54531
|
+
},
|
|
54532
|
+
keepMarks: true,
|
|
54533
|
+
keepAttributes: false
|
|
54534
|
+
};
|
|
54535
|
+
},
|
|
54536
|
+
parseDOM() {
|
|
54537
|
+
return [{ tag: "ul" }];
|
|
54538
|
+
},
|
|
54539
|
+
renderDOM({ htmlAttributes }) {
|
|
54540
|
+
const attributes = Attribute2.mergeAttributes(this.options.htmlAttributes, htmlAttributes);
|
|
54541
|
+
return ["ul", attributes, 0];
|
|
54542
|
+
},
|
|
54543
|
+
addAttributes() {
|
|
54544
|
+
return {
|
|
54545
|
+
"list-style-type": {
|
|
54546
|
+
default: "bullet",
|
|
54547
|
+
rendered: false
|
|
54548
|
+
},
|
|
54549
|
+
listId: {
|
|
54550
|
+
rendered: false
|
|
54551
|
+
},
|
|
54552
|
+
sdBlockId: {
|
|
54553
|
+
default: null,
|
|
54554
|
+
keepOnSplit: false,
|
|
54555
|
+
parseDOM: (elem) => elem.getAttribute("data-sd-block-id"),
|
|
54556
|
+
renderDOM: (attrs) => {
|
|
54557
|
+
return attrs.sdBlockId ? { "data-sd-block-id": attrs.sdBlockId } : {};
|
|
54558
|
+
}
|
|
54559
|
+
},
|
|
54560
|
+
attributes: {
|
|
54561
|
+
rendered: false,
|
|
54562
|
+
keepOnSplit: true
|
|
54563
|
+
}
|
|
54564
|
+
};
|
|
54565
|
+
},
|
|
54566
|
+
addCommands() {
|
|
54567
|
+
return {
|
|
54568
|
+
/**
|
|
54569
|
+
* Toggle a bullet list at the current selection
|
|
54570
|
+
* @category Command
|
|
54571
|
+
* @example
|
|
54572
|
+
* // Toggle bullet list on selected text
|
|
54573
|
+
* editor.commands.toggleBulletList()
|
|
54574
|
+
* @note Converts selected paragraphs to list items or removes list formatting
|
|
54575
|
+
*/
|
|
54576
|
+
toggleBulletList: () => (params2) => {
|
|
54577
|
+
return toggleList(this.type)(params2);
|
|
54578
|
+
}
|
|
54579
|
+
};
|
|
54580
|
+
},
|
|
54581
|
+
addShortcuts() {
|
|
54582
|
+
return {
|
|
54583
|
+
"Mod-Shift-8": () => {
|
|
54584
|
+
return this.editor.commands.toggleBulletList();
|
|
54585
|
+
}
|
|
54586
|
+
};
|
|
54587
|
+
},
|
|
54588
|
+
addInputRules() {
|
|
54589
|
+
return [
|
|
54590
|
+
new InputRule({
|
|
54591
|
+
match: inputRegex$1,
|
|
54592
|
+
handler: ({ state: state2, range: range2 }) => {
|
|
54593
|
+
const $pos = state2.selection.$from;
|
|
54594
|
+
const listItemType = state2.schema.nodes.listItem;
|
|
54595
|
+
for (let depth = $pos.depth; depth >= 0; depth--) {
|
|
54596
|
+
if ($pos.node(depth).type === listItemType) {
|
|
54597
|
+
return null;
|
|
54598
|
+
}
|
|
54599
|
+
}
|
|
54600
|
+
const { tr } = state2;
|
|
54601
|
+
tr.delete(range2.from, range2.to);
|
|
54602
|
+
ListHelpers.createNewList({
|
|
54603
|
+
listType: this.type,
|
|
54604
|
+
tr,
|
|
54605
|
+
editor: this.editor
|
|
54606
|
+
});
|
|
54607
|
+
}
|
|
54608
|
+
})
|
|
54609
|
+
];
|
|
54610
|
+
}
|
|
54611
|
+
});
|
|
54612
|
+
const inputRegex = /^(\d+)\.\s$/;
|
|
54613
|
+
const OrderedList = Node$1.create({
|
|
53578
54614
|
name: "orderedList",
|
|
53579
54615
|
group: "block list",
|
|
53580
54616
|
selectable: false,
|
|
@@ -54935,7 +55971,7 @@ class ListItemNodeView {
|
|
|
54935
55971
|
this.decorations = decorations;
|
|
54936
55972
|
this.view = editor.view;
|
|
54937
55973
|
this.getPos = getPos;
|
|
54938
|
-
__privateMethod$1(this, _ListItemNodeView_instances,
|
|
55974
|
+
__privateMethod$1(this, _ListItemNodeView_instances, init_fn3).call(this);
|
|
54939
55975
|
activeListItemNodeViews.add(this);
|
|
54940
55976
|
}
|
|
54941
55977
|
refreshIndentStyling() {
|
|
@@ -54996,7 +56032,7 @@ class ListItemNodeView {
|
|
|
54996
56032
|
}
|
|
54997
56033
|
}
|
|
54998
56034
|
_ListItemNodeView_instances = /* @__PURE__ */ new WeakSet();
|
|
54999
|
-
|
|
56035
|
+
init_fn3 = function() {
|
|
55000
56036
|
const { attrs } = this.node;
|
|
55001
56037
|
const { listLevel, listNumberingType, lvlText, numId, level, customFormat } = attrs;
|
|
55002
56038
|
let orderMarker = "";
|
|
@@ -62105,984 +63141,335 @@ const PageNumber = Node$1.create({
|
|
|
62105
63141
|
}
|
|
62106
63142
|
};
|
|
62107
63143
|
},
|
|
62108
|
-
addAttributes() {
|
|
62109
|
-
return {
|
|
62110
|
-
marksAsAttrs: {
|
|
62111
|
-
default: null,
|
|
62112
|
-
rendered: false
|
|
62113
|
-
}
|
|
62114
|
-
};
|
|
62115
|
-
},
|
|
62116
|
-
addNodeView() {
|
|
62117
|
-
return ({ node, editor, getPos, decorations }) => {
|
|
62118
|
-
const htmlAttributes = this.options.htmlAttributes;
|
|
62119
|
-
return new AutoPageNumberNodeView(node, getPos, decorations, editor, htmlAttributes);
|
|
62120
|
-
};
|
|
62121
|
-
},
|
|
62122
|
-
parseDOM() {
|
|
62123
|
-
return [{ tag: 'span[data-id="auto-page-number"' }];
|
|
62124
|
-
},
|
|
62125
|
-
renderDOM({ htmlAttributes }) {
|
|
62126
|
-
return ["span", Attribute2.mergeAttributes(this.options.htmlAttributes, htmlAttributes)];
|
|
62127
|
-
},
|
|
62128
|
-
addCommands() {
|
|
62129
|
-
return {
|
|
62130
|
-
/**
|
|
62131
|
-
* Insert an automatic page number
|
|
62132
|
-
* @category Command
|
|
62133
|
-
* @returns {Function} Command function
|
|
62134
|
-
* @example
|
|
62135
|
-
* editor.commands.addAutoPageNumber()
|
|
62136
|
-
* @note Only works in header/footer contexts
|
|
62137
|
-
*/
|
|
62138
|
-
addAutoPageNumber: () => ({ tr, dispatch, state: state2, editor }) => {
|
|
62139
|
-
const { options } = editor;
|
|
62140
|
-
if (!options.isHeaderOrFooter) return false;
|
|
62141
|
-
const { schema } = state2;
|
|
62142
|
-
const pageNumberType = schema?.nodes?.["page-number"];
|
|
62143
|
-
if (!pageNumberType) return false;
|
|
62144
|
-
const pageNumberNodeJSON = { type: "page-number" };
|
|
62145
|
-
const pageNumberNode = schema.nodeFromJSON(pageNumberNodeJSON);
|
|
62146
|
-
if (dispatch) {
|
|
62147
|
-
tr.replaceSelectionWith(pageNumberNode, false);
|
|
62148
|
-
tr.setMeta("forceUpdatePagination", true);
|
|
62149
|
-
}
|
|
62150
|
-
return true;
|
|
62151
|
-
}
|
|
62152
|
-
};
|
|
62153
|
-
},
|
|
62154
|
-
addShortcuts() {
|
|
62155
|
-
return {
|
|
62156
|
-
"Mod-Shift-alt-p": () => this.editor.commands.addAutoPageNumber()
|
|
62157
|
-
};
|
|
62158
|
-
}
|
|
62159
|
-
});
|
|
62160
|
-
const TotalPageCount = Node$1.create({
|
|
62161
|
-
name: "total-page-number",
|
|
62162
|
-
group: "inline",
|
|
62163
|
-
inline: true,
|
|
62164
|
-
atom: true,
|
|
62165
|
-
draggable: false,
|
|
62166
|
-
selectable: false,
|
|
62167
|
-
content: "text*",
|
|
62168
|
-
addOptions() {
|
|
62169
|
-
return {
|
|
62170
|
-
htmlAttributes: {
|
|
62171
|
-
contenteditable: false,
|
|
62172
|
-
"data-id": "auto-total-pages",
|
|
62173
|
-
"aria-label": "Total page count node",
|
|
62174
|
-
class: "sd-editor-auto-total-pages"
|
|
62175
|
-
}
|
|
62176
|
-
};
|
|
62177
|
-
},
|
|
62178
|
-
addAttributes() {
|
|
62179
|
-
return {
|
|
62180
|
-
marksAsAttrs: {
|
|
62181
|
-
default: null,
|
|
62182
|
-
rendered: false
|
|
62183
|
-
}
|
|
62184
|
-
};
|
|
62185
|
-
},
|
|
62186
|
-
addNodeView() {
|
|
62187
|
-
return ({ node, editor, getPos, decorations }) => {
|
|
62188
|
-
const htmlAttributes = this.options.htmlAttributes;
|
|
62189
|
-
return new AutoPageNumberNodeView(node, getPos, decorations, editor, htmlAttributes);
|
|
62190
|
-
};
|
|
62191
|
-
},
|
|
62192
|
-
parseDOM() {
|
|
62193
|
-
return [{ tag: 'span[data-id="auto-total-pages"' }];
|
|
62194
|
-
},
|
|
62195
|
-
renderDOM({ htmlAttributes }) {
|
|
62196
|
-
return ["span", Attribute2.mergeAttributes(this.options.htmlAttributes, htmlAttributes), 0];
|
|
62197
|
-
},
|
|
62198
|
-
addCommands() {
|
|
62199
|
-
return {
|
|
62200
|
-
/**
|
|
62201
|
-
* Insert total page count
|
|
62202
|
-
* @category Command
|
|
62203
|
-
* @returns {Function} Command function
|
|
62204
|
-
* @example
|
|
62205
|
-
* editor.commands.addTotalPageCount()
|
|
62206
|
-
* @note Only works in header/footer contexts
|
|
62207
|
-
*/
|
|
62208
|
-
addTotalPageCount: () => ({ tr, dispatch, state: state2, editor }) => {
|
|
62209
|
-
const { options } = editor;
|
|
62210
|
-
if (!options.isHeaderOrFooter) return false;
|
|
62211
|
-
const { schema } = state2;
|
|
62212
|
-
const pageNumberType = schema.nodes?.["total-page-number"];
|
|
62213
|
-
if (!pageNumberType) return false;
|
|
62214
|
-
const currentPages = editor?.options?.parentEditor?.currentTotalPages || 1;
|
|
62215
|
-
const pageNumberNode = {
|
|
62216
|
-
type: "total-page-number",
|
|
62217
|
-
content: [{ type: "text", text: String(currentPages) }]
|
|
62218
|
-
};
|
|
62219
|
-
const pageNode = schema.nodeFromJSON(pageNumberNode);
|
|
62220
|
-
if (dispatch) {
|
|
62221
|
-
tr.replaceSelectionWith(pageNode, false);
|
|
62222
|
-
}
|
|
62223
|
-
return true;
|
|
62224
|
-
}
|
|
62225
|
-
};
|
|
62226
|
-
},
|
|
62227
|
-
addShortcuts() {
|
|
62228
|
-
return {
|
|
62229
|
-
"Mod-Shift-alt-c": () => this.editor.commands.addTotalPageCount()
|
|
62230
|
-
};
|
|
62231
|
-
}
|
|
62232
|
-
});
|
|
62233
|
-
const getNodeAttributes = (nodeName, editor) => {
|
|
62234
|
-
switch (nodeName) {
|
|
62235
|
-
case "page-number":
|
|
62236
|
-
return {
|
|
62237
|
-
text: editor.options.currentPageNumber || "1",
|
|
62238
|
-
className: "sd-editor-auto-page-number",
|
|
62239
|
-
dataId: "auto-page-number",
|
|
62240
|
-
ariaLabel: "Page number node"
|
|
62241
|
-
};
|
|
62242
|
-
case "total-page-number":
|
|
62243
|
-
return {
|
|
62244
|
-
text: editor.options.parentEditor?.currentTotalPages || "1",
|
|
62245
|
-
className: "sd-editor-auto-total-pages",
|
|
62246
|
-
dataId: "auto-total-pages",
|
|
62247
|
-
ariaLabel: "Total page count node"
|
|
62248
|
-
};
|
|
62249
|
-
default:
|
|
62250
|
-
return {};
|
|
62251
|
-
}
|
|
62252
|
-
};
|
|
62253
|
-
class AutoPageNumberNodeView {
|
|
62254
|
-
constructor(node, getPos, decorations, editor, htmlAttributes = {}) {
|
|
62255
|
-
__privateAdd$1(this, _AutoPageNumberNodeView_instances);
|
|
62256
|
-
this.node = node;
|
|
62257
|
-
this.editor = editor;
|
|
62258
|
-
this.view = editor.view;
|
|
62259
|
-
this.getPos = getPos;
|
|
62260
|
-
this.editor = editor;
|
|
62261
|
-
this.dom = __privateMethod$1(this, _AutoPageNumberNodeView_instances, renderDom_fn).call(this, node, htmlAttributes);
|
|
62262
|
-
}
|
|
62263
|
-
update(node) {
|
|
62264
|
-
const incomingType = node?.type?.name;
|
|
62265
|
-
const currentType = this.node?.type?.name;
|
|
62266
|
-
if (!incomingType || incomingType !== currentType) return false;
|
|
62267
|
-
this.node = node;
|
|
62268
|
-
return true;
|
|
62269
|
-
}
|
|
62270
|
-
}
|
|
62271
|
-
_AutoPageNumberNodeView_instances = /* @__PURE__ */ new WeakSet();
|
|
62272
|
-
renderDom_fn = function(node, htmlAttributes) {
|
|
62273
|
-
const attrs = getNodeAttributes(this.node.type.name, this.editor);
|
|
62274
|
-
const content = document.createTextNode(String(attrs.text));
|
|
62275
|
-
const nodeContent = document.createElement("span");
|
|
62276
|
-
nodeContent.className = attrs.className;
|
|
62277
|
-
nodeContent.setAttribute("data-id", attrs.dataId);
|
|
62278
|
-
nodeContent.setAttribute("aria-label", attrs.ariaLabel);
|
|
62279
|
-
const currentPos = this.getPos();
|
|
62280
|
-
const { styles, marks } = getMarksFromNeighbors(currentPos, this.view);
|
|
62281
|
-
__privateMethod$1(this, _AutoPageNumberNodeView_instances, scheduleUpdateNodeStyle_fn).call(this, currentPos, marks);
|
|
62282
|
-
Object.assign(nodeContent.style, styles);
|
|
62283
|
-
nodeContent.appendChild(content);
|
|
62284
|
-
Object.entries(htmlAttributes).forEach(([key2, value]) => {
|
|
62285
|
-
if (value) nodeContent.setAttribute(key2, value);
|
|
62286
|
-
});
|
|
62287
|
-
return nodeContent;
|
|
62288
|
-
};
|
|
62289
|
-
scheduleUpdateNodeStyle_fn = function(pos, marks) {
|
|
62290
|
-
setTimeout(() => {
|
|
62291
|
-
const { state: state2 } = this.editor;
|
|
62292
|
-
const { dispatch } = this.view;
|
|
62293
|
-
const node = state2.doc.nodeAt(pos);
|
|
62294
|
-
if (!node || node.isText) return;
|
|
62295
|
-
const currentMarks = node.attrs.marksAsAttrs || [];
|
|
62296
|
-
const newMarks = marks.map((m2) => ({ type: m2.type.name, attrs: m2.attrs }));
|
|
62297
|
-
const isEqual = JSON.stringify(currentMarks) === JSON.stringify(newMarks);
|
|
62298
|
-
if (isEqual) return;
|
|
62299
|
-
const newAttrs = {
|
|
62300
|
-
...node.attrs,
|
|
62301
|
-
marksAsAttrs: newMarks
|
|
62302
|
-
};
|
|
62303
|
-
const tr = state2.tr.setNodeMarkup(pos, void 0, newAttrs);
|
|
62304
|
-
dispatch(tr);
|
|
62305
|
-
}, 0);
|
|
62306
|
-
};
|
|
62307
|
-
const getMarksFromNeighbors = (currentPos, view) => {
|
|
62308
|
-
const $pos = view.state.doc.resolve(currentPos);
|
|
62309
|
-
const styles = {};
|
|
62310
|
-
const marks = [];
|
|
62311
|
-
const before = $pos.nodeBefore;
|
|
62312
|
-
if (before) {
|
|
62313
|
-
Object.assign(styles, processMarks(before.marks));
|
|
62314
|
-
marks.push(...before.marks);
|
|
62315
|
-
}
|
|
62316
|
-
const after = $pos.nodeAfter;
|
|
62317
|
-
if (after) {
|
|
62318
|
-
Object.assign(styles, { ...styles, ...processMarks(after.marks) });
|
|
62319
|
-
marks.push(...after.marks);
|
|
62320
|
-
}
|
|
62321
|
-
return {
|
|
62322
|
-
styles,
|
|
62323
|
-
marks
|
|
62324
|
-
};
|
|
62325
|
-
};
|
|
62326
|
-
const processMarks = (marks) => {
|
|
62327
|
-
const styles = {};
|
|
62328
|
-
marks.forEach((mark) => {
|
|
62329
|
-
const { type: type2, attrs } = mark;
|
|
62330
|
-
switch (type2.name) {
|
|
62331
|
-
case "textStyle":
|
|
62332
|
-
if (attrs.fontFamily) styles["font-family"] = attrs.fontFamily;
|
|
62333
|
-
if (attrs.fontSize) styles["font-size"] = attrs.fontSize;
|
|
62334
|
-
if (attrs.color) styles["color"] = attrs.color;
|
|
62335
|
-
if (attrs.backgroundColor) styles["background-color"] = attrs.backgroundColor;
|
|
62336
|
-
break;
|
|
62337
|
-
case "bold":
|
|
62338
|
-
styles["font-weight"] = "bold";
|
|
62339
|
-
break;
|
|
62340
|
-
case "italic":
|
|
62341
|
-
styles["font-style"] = "italic";
|
|
62342
|
-
break;
|
|
62343
|
-
case "underline":
|
|
62344
|
-
styles["text-decoration"] = (styles["text-decoration"] || "") + " underline";
|
|
62345
|
-
break;
|
|
62346
|
-
case "strike":
|
|
62347
|
-
styles["text-decoration"] = (styles["text-decoration"] || "") + " line-through";
|
|
62348
|
-
break;
|
|
62349
|
-
default:
|
|
62350
|
-
if (attrs?.style) {
|
|
62351
|
-
Object.entries(attrs.style).forEach(([key2, value]) => {
|
|
62352
|
-
styles[key2] = value;
|
|
62353
|
-
});
|
|
62354
|
-
}
|
|
62355
|
-
break;
|
|
62356
|
-
}
|
|
62357
|
-
});
|
|
62358
|
-
return styles;
|
|
62359
|
-
};
|
|
62360
|
-
const ShapeContainer = Node$1.create({
|
|
62361
|
-
name: "shapeContainer",
|
|
62362
|
-
group: "block",
|
|
62363
|
-
content: "block+",
|
|
62364
|
-
isolating: true,
|
|
62365
|
-
addOptions() {
|
|
62366
|
-
return {
|
|
62367
|
-
htmlAttributes: {
|
|
62368
|
-
class: "sd-editor-shape-container",
|
|
62369
|
-
"aria-label": "Shape container node"
|
|
62370
|
-
}
|
|
62371
|
-
};
|
|
62372
|
-
},
|
|
62373
|
-
addAttributes() {
|
|
62374
|
-
return {
|
|
62375
|
-
fillcolor: {
|
|
62376
|
-
renderDOM: (attrs) => {
|
|
62377
|
-
if (!attrs.fillcolor) return {};
|
|
62378
|
-
return {
|
|
62379
|
-
style: `background-color: ${attrs.fillcolor}`
|
|
62380
|
-
};
|
|
62381
|
-
}
|
|
62382
|
-
},
|
|
62383
|
-
sdBlockId: {
|
|
62384
|
-
default: null,
|
|
62385
|
-
keepOnSplit: false,
|
|
62386
|
-
parseDOM: (elem) => elem.getAttribute("data-sd-block-id"),
|
|
62387
|
-
renderDOM: (attrs) => {
|
|
62388
|
-
return attrs.sdBlockId ? { "data-sd-block-id": attrs.sdBlockId } : {};
|
|
62389
|
-
}
|
|
62390
|
-
},
|
|
62391
|
-
style: {
|
|
62392
|
-
renderDOM: (attrs) => {
|
|
62393
|
-
if (!attrs.style) return {};
|
|
62394
|
-
return {
|
|
62395
|
-
style: attrs.style
|
|
62396
|
-
};
|
|
62397
|
-
}
|
|
62398
|
-
},
|
|
62399
|
-
wrapAttributes: {
|
|
62400
|
-
rendered: false
|
|
62401
|
-
},
|
|
62402
|
-
attributes: {
|
|
62403
|
-
rendered: false
|
|
62404
|
-
}
|
|
62405
|
-
};
|
|
62406
|
-
},
|
|
62407
|
-
parseDOM() {
|
|
62408
|
-
return [
|
|
62409
|
-
{
|
|
62410
|
-
tag: `div[data-type="${this.name}"]`
|
|
62411
|
-
}
|
|
62412
|
-
];
|
|
62413
|
-
},
|
|
62414
|
-
renderDOM({ htmlAttributes }) {
|
|
62415
|
-
return [
|
|
62416
|
-
"div",
|
|
62417
|
-
Attribute2.mergeAttributes(this.options.htmlAttributes, htmlAttributes, { "data-type": this.name }),
|
|
62418
|
-
0
|
|
62419
|
-
];
|
|
62420
|
-
}
|
|
62421
|
-
});
|
|
62422
|
-
const ShapeTextbox = Node$1.create({
|
|
62423
|
-
name: "shapeTextbox",
|
|
62424
|
-
group: "block",
|
|
62425
|
-
content: "paragraph* block*",
|
|
62426
|
-
isolating: true,
|
|
62427
|
-
addOptions() {
|
|
62428
|
-
return {
|
|
62429
|
-
htmlAttributes: {
|
|
62430
|
-
class: "sd-editor-shape-textbox",
|
|
62431
|
-
"aria-label": "Shape textbox node"
|
|
62432
|
-
}
|
|
62433
|
-
};
|
|
62434
|
-
},
|
|
62435
|
-
addAttributes() {
|
|
62436
|
-
return {
|
|
62437
|
-
sdBlockId: {
|
|
62438
|
-
default: null,
|
|
62439
|
-
keepOnSplit: false,
|
|
62440
|
-
parseDOM: (elem) => elem.getAttribute("data-sd-block-id"),
|
|
62441
|
-
renderDOM: (attrs) => {
|
|
62442
|
-
return attrs.sdBlockId ? { "data-sd-block-id": attrs.sdBlockId } : {};
|
|
62443
|
-
}
|
|
62444
|
-
},
|
|
62445
|
-
attributes: {
|
|
62446
|
-
rendered: false
|
|
62447
|
-
}
|
|
62448
|
-
};
|
|
62449
|
-
},
|
|
62450
|
-
parseDOM() {
|
|
62451
|
-
return [
|
|
62452
|
-
{
|
|
62453
|
-
tag: `div[data-type="${this.name}"]`
|
|
62454
|
-
}
|
|
62455
|
-
];
|
|
62456
|
-
},
|
|
62457
|
-
renderDOM({ htmlAttributes }) {
|
|
62458
|
-
return [
|
|
62459
|
-
"div",
|
|
62460
|
-
Attribute2.mergeAttributes(this.options.htmlAttributes, htmlAttributes, { "data-type": this.name }),
|
|
62461
|
-
0
|
|
62462
|
-
];
|
|
62463
|
-
}
|
|
62464
|
-
});
|
|
62465
|
-
const ContentBlock = Node$1.create({
|
|
62466
|
-
name: "contentBlock",
|
|
62467
|
-
group: "inline",
|
|
62468
|
-
content: "",
|
|
62469
|
-
isolating: true,
|
|
62470
|
-
atom: true,
|
|
62471
|
-
inline: true,
|
|
62472
|
-
addOptions() {
|
|
62473
|
-
return {
|
|
62474
|
-
htmlAttributes: {
|
|
62475
|
-
contenteditable: false
|
|
62476
|
-
}
|
|
62477
|
-
};
|
|
62478
|
-
},
|
|
62479
|
-
addAttributes() {
|
|
62480
|
-
return {
|
|
62481
|
-
horizontalRule: {
|
|
62482
|
-
default: false,
|
|
62483
|
-
renderDOM: ({ horizontalRule }) => {
|
|
62484
|
-
if (!horizontalRule) return {};
|
|
62485
|
-
return { "data-horizontal-rule": "true" };
|
|
62486
|
-
}
|
|
62487
|
-
},
|
|
62488
|
-
size: {
|
|
62489
|
-
default: null,
|
|
62490
|
-
renderDOM: ({ size: size2 }) => {
|
|
62491
|
-
if (!size2) return {};
|
|
62492
|
-
let style2 = "";
|
|
62493
|
-
if (size2.top) style2 += `top: ${size2.top}px; `;
|
|
62494
|
-
if (size2.left) style2 += `left: ${size2.left}px; `;
|
|
62495
|
-
if (size2.width) style2 += `width: ${size2.width.toString().endsWith("%") ? size2.width : `${size2.width}px`}; `;
|
|
62496
|
-
if (size2.height)
|
|
62497
|
-
style2 += `height: ${size2.height.toString().endsWith("%") ? size2.height : `${size2.height}px`}; `;
|
|
62498
|
-
return { style: style2 };
|
|
62499
|
-
}
|
|
62500
|
-
},
|
|
62501
|
-
background: {
|
|
62502
|
-
default: null,
|
|
62503
|
-
renderDOM: (attrs) => {
|
|
62504
|
-
if (!attrs.background) return {};
|
|
62505
|
-
return {
|
|
62506
|
-
style: `background-color: ${attrs.background}`
|
|
62507
|
-
};
|
|
62508
|
-
}
|
|
62509
|
-
},
|
|
62510
|
-
drawingContent: {
|
|
62511
|
-
rendered: false
|
|
62512
|
-
},
|
|
62513
|
-
attributes: {
|
|
63144
|
+
addAttributes() {
|
|
63145
|
+
return {
|
|
63146
|
+
marksAsAttrs: {
|
|
63147
|
+
default: null,
|
|
62514
63148
|
rendered: false
|
|
62515
63149
|
}
|
|
62516
63150
|
};
|
|
62517
63151
|
},
|
|
63152
|
+
addNodeView() {
|
|
63153
|
+
return ({ node, editor, getPos, decorations }) => {
|
|
63154
|
+
const htmlAttributes = this.options.htmlAttributes;
|
|
63155
|
+
return new AutoPageNumberNodeView(node, getPos, decorations, editor, htmlAttributes);
|
|
63156
|
+
};
|
|
63157
|
+
},
|
|
62518
63158
|
parseDOM() {
|
|
62519
|
-
return [
|
|
62520
|
-
{
|
|
62521
|
-
tag: `div[data-type="${this.name}"]`
|
|
62522
|
-
}
|
|
62523
|
-
];
|
|
63159
|
+
return [{ tag: 'span[data-id="auto-page-number"' }];
|
|
62524
63160
|
},
|
|
62525
63161
|
renderDOM({ htmlAttributes }) {
|
|
62526
|
-
return ["
|
|
63162
|
+
return ["span", Attribute2.mergeAttributes(this.options.htmlAttributes, htmlAttributes)];
|
|
62527
63163
|
},
|
|
62528
63164
|
addCommands() {
|
|
62529
63165
|
return {
|
|
62530
63166
|
/**
|
|
62531
|
-
* Insert
|
|
62532
|
-
* @category Command
|
|
62533
|
-
* @example
|
|
62534
|
-
* editor.commands.insertHorizontalRule()
|
|
62535
|
-
* @note Creates a visual separator between content sections
|
|
62536
|
-
*/
|
|
62537
|
-
insertHorizontalRule: () => ({ commands: commands2 }) => {
|
|
62538
|
-
return commands2.insertContent({
|
|
62539
|
-
type: this.name,
|
|
62540
|
-
attrs: {
|
|
62541
|
-
horizontalRule: true,
|
|
62542
|
-
size: { width: "100%", height: 2 },
|
|
62543
|
-
background: "#e5e7eb"
|
|
62544
|
-
}
|
|
62545
|
-
});
|
|
62546
|
-
},
|
|
62547
|
-
/**
|
|
62548
|
-
* Insert a content block
|
|
63167
|
+
* Insert an automatic page number
|
|
62549
63168
|
* @category Command
|
|
62550
|
-
* @
|
|
62551
|
-
* @example
|
|
62552
|
-
* // Insert a spacer block
|
|
62553
|
-
* editor.commands.insertContentBlock({ size: { height: 20 } })
|
|
62554
|
-
*
|
|
63169
|
+
* @returns {Function} Command function
|
|
62555
63170
|
* @example
|
|
62556
|
-
*
|
|
62557
|
-
*
|
|
62558
|
-
* size: { width: '50%', height: 3 },
|
|
62559
|
-
* background: '#3b82f6'
|
|
62560
|
-
* })
|
|
62561
|
-
* @note Used for spacing, dividers, and special inline content
|
|
63171
|
+
* editor.commands.addAutoPageNumber()
|
|
63172
|
+
* @note Only works in header/footer contexts
|
|
62562
63173
|
*/
|
|
62563
|
-
|
|
62564
|
-
|
|
62565
|
-
|
|
62566
|
-
|
|
62567
|
-
|
|
63174
|
+
addAutoPageNumber: () => ({ tr, dispatch, state: state2, editor }) => {
|
|
63175
|
+
const { options } = editor;
|
|
63176
|
+
if (!options.isHeaderOrFooter) return false;
|
|
63177
|
+
const { schema } = state2;
|
|
63178
|
+
const pageNumberType = schema?.nodes?.["page-number"];
|
|
63179
|
+
if (!pageNumberType) return false;
|
|
63180
|
+
const pageNumberNodeJSON = { type: "page-number" };
|
|
63181
|
+
const pageNumberNode = schema.nodeFromJSON(pageNumberNodeJSON);
|
|
63182
|
+
if (dispatch) {
|
|
63183
|
+
tr.replaceSelectionWith(pageNumberNode, false);
|
|
63184
|
+
tr.setMeta("forceUpdatePagination", true);
|
|
63185
|
+
}
|
|
63186
|
+
return true;
|
|
62568
63187
|
}
|
|
62569
63188
|
};
|
|
63189
|
+
},
|
|
63190
|
+
addShortcuts() {
|
|
63191
|
+
return {
|
|
63192
|
+
"Mod-Shift-alt-p": () => this.editor.commands.addAutoPageNumber()
|
|
63193
|
+
};
|
|
62570
63194
|
}
|
|
62571
63195
|
});
|
|
62572
|
-
|
|
62573
|
-
|
|
62574
|
-
|
|
62575
|
-
__publicField$1(this, "view");
|
|
62576
|
-
__publicField$1(this, "getPos");
|
|
62577
|
-
__publicField$1(this, "decorations");
|
|
62578
|
-
__publicField$1(this, "innerDecorations");
|
|
62579
|
-
__publicField$1(this, "editor");
|
|
62580
|
-
__publicField$1(this, "extension");
|
|
62581
|
-
__publicField$1(this, "htmlAttributes");
|
|
62582
|
-
__publicField$1(this, "root");
|
|
62583
|
-
__publicField$1(this, "isDragging", false);
|
|
62584
|
-
this.node = props.node;
|
|
62585
|
-
this.view = props.editor.view;
|
|
62586
|
-
this.getPos = props.getPos;
|
|
62587
|
-
this.decorations = props.decorations;
|
|
62588
|
-
this.innerDecorations = props.innerDecorations;
|
|
62589
|
-
this.editor = props.editor;
|
|
62590
|
-
this.extension = props.extension;
|
|
62591
|
-
this.htmlAttributes = props.htmlAttributes;
|
|
62592
|
-
this.mount(props);
|
|
62593
|
-
}
|
|
62594
|
-
mount() {
|
|
62595
|
-
return;
|
|
62596
|
-
}
|
|
62597
|
-
get dom() {
|
|
62598
|
-
return this.root;
|
|
62599
|
-
}
|
|
62600
|
-
get contentDOM() {
|
|
62601
|
-
return null;
|
|
62602
|
-
}
|
|
62603
|
-
update(node, decorations, innerDecorations) {
|
|
62604
|
-
if (node.type !== this.node.type) {
|
|
62605
|
-
return false;
|
|
62606
|
-
}
|
|
62607
|
-
this.node = node;
|
|
62608
|
-
this.decorations = decorations;
|
|
62609
|
-
this.innerDecorations = innerDecorations;
|
|
62610
|
-
this.updateHTMLAttributes();
|
|
62611
|
-
return true;
|
|
62612
|
-
}
|
|
62613
|
-
stopEvent(event) {
|
|
62614
|
-
if (!this.dom) return false;
|
|
62615
|
-
const target = event.target;
|
|
62616
|
-
const isInElement = this.dom.contains(target) && !this.contentDOM?.contains(target);
|
|
62617
|
-
if (!isInElement) return false;
|
|
62618
|
-
const isDragEvent = event.type.startsWith("drag");
|
|
62619
|
-
const isDropEvent = event.type === "drop";
|
|
62620
|
-
const isInput = ["INPUT", "BUTTON", "SELECT", "TEXTAREA"].includes(target.tagName) || target.isContentEditable;
|
|
62621
|
-
if (isInput && !isDropEvent && !isDragEvent) return true;
|
|
62622
|
-
const { isEditable } = this.editor;
|
|
62623
|
-
const { isDragging } = this;
|
|
62624
|
-
const isDraggable = !!this.node.type.spec.draggable;
|
|
62625
|
-
const isSelectable = NodeSelection.isSelectable(this.node);
|
|
62626
|
-
const isCopyEvent = event.type === "copy";
|
|
62627
|
-
const isPasteEvent = event.type === "paste";
|
|
62628
|
-
const isCutEvent = event.type === "cut";
|
|
62629
|
-
const isClickEvent = event.type === "mousedown";
|
|
62630
|
-
if (!isDraggable && isSelectable && isDragEvent && event.target === this.dom) {
|
|
62631
|
-
event.preventDefault();
|
|
62632
|
-
}
|
|
62633
|
-
if (isDraggable && isDragEvent && !isDragging && event.target === this.dom) {
|
|
62634
|
-
event.preventDefault();
|
|
62635
|
-
return false;
|
|
62636
|
-
}
|
|
62637
|
-
if (isDraggable && isEditable && !isDragging && isClickEvent) {
|
|
62638
|
-
const dragHandle = target.closest("[data-drag-handle]");
|
|
62639
|
-
const isValidDragHandle = dragHandle && (this.dom === dragHandle || this.dom.contains(dragHandle));
|
|
62640
|
-
if (isValidDragHandle) {
|
|
62641
|
-
this.isDragging = true;
|
|
62642
|
-
document.addEventListener(
|
|
62643
|
-
"dragend",
|
|
62644
|
-
() => {
|
|
62645
|
-
this.isDragging = false;
|
|
62646
|
-
},
|
|
62647
|
-
{ once: true }
|
|
62648
|
-
);
|
|
62649
|
-
document.addEventListener(
|
|
62650
|
-
"drop",
|
|
62651
|
-
() => {
|
|
62652
|
-
this.isDragging = false;
|
|
62653
|
-
},
|
|
62654
|
-
{ once: true }
|
|
62655
|
-
);
|
|
62656
|
-
document.addEventListener(
|
|
62657
|
-
"mouseup",
|
|
62658
|
-
() => {
|
|
62659
|
-
this.isDragging = false;
|
|
62660
|
-
},
|
|
62661
|
-
{ once: true }
|
|
62662
|
-
);
|
|
62663
|
-
}
|
|
62664
|
-
}
|
|
62665
|
-
if (isDragging || isDropEvent || isCopyEvent || isPasteEvent || isCutEvent || isClickEvent && isSelectable) {
|
|
62666
|
-
return false;
|
|
62667
|
-
}
|
|
62668
|
-
return true;
|
|
62669
|
-
}
|
|
62670
|
-
ignoreMutation(mutation) {
|
|
62671
|
-
if (!this.dom || !this.contentDOM) return true;
|
|
62672
|
-
if (this.node.isLeaf || this.node.isAtom) return true;
|
|
62673
|
-
if (mutation.type === "selection") return false;
|
|
62674
|
-
if (this.contentDOM === mutation.target && mutation.type === "attributes") return true;
|
|
62675
|
-
if (this.contentDOM.contains(mutation.target)) return false;
|
|
62676
|
-
return true;
|
|
62677
|
-
}
|
|
62678
|
-
destroy() {
|
|
62679
|
-
this.dom.remove();
|
|
62680
|
-
this.contentDOM?.remove();
|
|
62681
|
-
}
|
|
62682
|
-
updateAttributes(attrs) {
|
|
62683
|
-
const pos = this.getPos();
|
|
62684
|
-
if (typeof pos !== "number") {
|
|
62685
|
-
return;
|
|
62686
|
-
}
|
|
62687
|
-
return this.view.dispatch(
|
|
62688
|
-
this.view.state.tr.setNodeMarkup(pos, void 0, {
|
|
62689
|
-
...this.node.attrs,
|
|
62690
|
-
...attrs
|
|
62691
|
-
})
|
|
62692
|
-
);
|
|
62693
|
-
}
|
|
62694
|
-
updateHTMLAttributes() {
|
|
62695
|
-
const { extensionService } = this.editor;
|
|
62696
|
-
const { attributes } = extensionService;
|
|
62697
|
-
const extensionAttrs = attributes.filter((i) => i.type === this.node.type.name);
|
|
62698
|
-
this.htmlAttributes = Attribute2.getAttributesToRender(this.node, extensionAttrs);
|
|
62699
|
-
}
|
|
62700
|
-
createDragHandle() {
|
|
62701
|
-
const dragHandle = document.createElement("span");
|
|
62702
|
-
dragHandle.classList.add("sd-structured-content-draggable");
|
|
62703
|
-
dragHandle.draggable = true;
|
|
62704
|
-
dragHandle.contentEditable = "false";
|
|
62705
|
-
dragHandle.dataset.dragHandle = "";
|
|
62706
|
-
const textElement = document.createElement("span");
|
|
62707
|
-
textElement.textContent = "Structured content";
|
|
62708
|
-
dragHandle.append(textElement);
|
|
62709
|
-
return dragHandle;
|
|
62710
|
-
}
|
|
62711
|
-
onDragStart(event) {
|
|
62712
|
-
const { view } = this.editor;
|
|
62713
|
-
const target = event.target;
|
|
62714
|
-
const dragHandle = target.nodeType === 3 ? target.parentElement?.closest("[data-drag-handle]") : target.closest("[data-drag-handle]");
|
|
62715
|
-
if (!this.dom || this.contentDOM?.contains(target) || !dragHandle) {
|
|
62716
|
-
return;
|
|
62717
|
-
}
|
|
62718
|
-
let x = 0;
|
|
62719
|
-
let y2 = 0;
|
|
62720
|
-
if (this.dom !== dragHandle) {
|
|
62721
|
-
const domBox = this.dom.getBoundingClientRect();
|
|
62722
|
-
const handleBox = dragHandle.getBoundingClientRect();
|
|
62723
|
-
const offsetX = event.offsetX ?? event.nativeEvent?.offsetX;
|
|
62724
|
-
const offsetY = event.offsetY ?? event.nativeEvent?.offsetY;
|
|
62725
|
-
x = handleBox.x - domBox.x + offsetX;
|
|
62726
|
-
y2 = handleBox.y - domBox.y + offsetY;
|
|
62727
|
-
}
|
|
62728
|
-
event.dataTransfer?.setDragImage(this.dom, x, y2);
|
|
62729
|
-
const pos = this.getPos();
|
|
62730
|
-
if (typeof pos !== "number") {
|
|
62731
|
-
return;
|
|
62732
|
-
}
|
|
62733
|
-
const selection = NodeSelection.create(view.state.doc, pos);
|
|
62734
|
-
const transaction = view.state.tr.setSelection(selection);
|
|
62735
|
-
view.dispatch(transaction);
|
|
62736
|
-
}
|
|
62737
|
-
}
|
|
62738
|
-
class StructuredContentInlineView extends StructuredContentViewBase {
|
|
62739
|
-
constructor(props) {
|
|
62740
|
-
super(props);
|
|
62741
|
-
}
|
|
62742
|
-
mount() {
|
|
62743
|
-
this.buildView();
|
|
62744
|
-
}
|
|
62745
|
-
get contentDOM() {
|
|
62746
|
-
const contentElement = this.dom?.querySelector(`.${structuredContentInnerClass$1}`);
|
|
62747
|
-
return contentElement || null;
|
|
62748
|
-
}
|
|
62749
|
-
createElement() {
|
|
62750
|
-
const element = document.createElement("span");
|
|
62751
|
-
element.classList.add(structuredContentClass$1);
|
|
62752
|
-
element.setAttribute("data-structured-content", "");
|
|
62753
|
-
const contentElement = document.createElement("span");
|
|
62754
|
-
contentElement.classList.add(structuredContentInnerClass$1);
|
|
62755
|
-
element.append(contentElement);
|
|
62756
|
-
const domAttrs = Attribute2.mergeAttributes(this.htmlAttributes);
|
|
62757
|
-
updateDOMAttributes(element, { ...domAttrs });
|
|
62758
|
-
return { element, contentElement };
|
|
62759
|
-
}
|
|
62760
|
-
buildView() {
|
|
62761
|
-
const { element } = this.createElement();
|
|
62762
|
-
const dragHandle = this.createDragHandle();
|
|
62763
|
-
element.prepend(dragHandle);
|
|
62764
|
-
element.addEventListener("dragstart", (e) => this.onDragStart(e));
|
|
62765
|
-
this.root = element;
|
|
62766
|
-
}
|
|
62767
|
-
updateView() {
|
|
62768
|
-
const domAttrs = Attribute2.mergeAttributes(this.htmlAttributes);
|
|
62769
|
-
updateDOMAttributes(this.dom, { ...domAttrs });
|
|
62770
|
-
}
|
|
62771
|
-
update(node, decorations, innerDecorations) {
|
|
62772
|
-
const result = super.update(node, decorations, innerDecorations);
|
|
62773
|
-
if (!result) return false;
|
|
62774
|
-
this.updateView();
|
|
62775
|
-
return true;
|
|
62776
|
-
}
|
|
62777
|
-
}
|
|
62778
|
-
const structuredContentClass$1 = "sd-structured-content";
|
|
62779
|
-
const structuredContentInnerClass$1 = "sd-structured-content__content";
|
|
62780
|
-
const StructuredContent = Node$1.create({
|
|
62781
|
-
name: "structuredContent",
|
|
62782
|
-
group: "inline structuredContent",
|
|
63196
|
+
const TotalPageCount = Node$1.create({
|
|
63197
|
+
name: "total-page-number",
|
|
63198
|
+
group: "inline",
|
|
62783
63199
|
inline: true,
|
|
62784
|
-
|
|
62785
|
-
|
|
62786
|
-
|
|
62787
|
-
|
|
62788
|
-
draggable: true,
|
|
63200
|
+
atom: true,
|
|
63201
|
+
draggable: false,
|
|
63202
|
+
selectable: false,
|
|
63203
|
+
content: "text*",
|
|
62789
63204
|
addOptions() {
|
|
62790
63205
|
return {
|
|
62791
63206
|
htmlAttributes: {
|
|
62792
|
-
|
|
62793
|
-
"
|
|
63207
|
+
contenteditable: false,
|
|
63208
|
+
"data-id": "auto-total-pages",
|
|
63209
|
+
"aria-label": "Total page count node",
|
|
63210
|
+
class: "sd-editor-auto-total-pages"
|
|
62794
63211
|
}
|
|
62795
63212
|
};
|
|
62796
63213
|
},
|
|
62797
63214
|
addAttributes() {
|
|
62798
63215
|
return {
|
|
62799
|
-
|
|
63216
|
+
marksAsAttrs: {
|
|
62800
63217
|
default: null,
|
|
62801
|
-
parseDOM: (elem) => elem.getAttribute("data-id"),
|
|
62802
|
-
renderDOM: (attrs) => {
|
|
62803
|
-
if (!attrs.id) return {};
|
|
62804
|
-
return { "data-id": attrs.id };
|
|
62805
|
-
}
|
|
62806
|
-
},
|
|
62807
|
-
sdtPr: {
|
|
62808
63218
|
rendered: false
|
|
62809
63219
|
}
|
|
62810
63220
|
};
|
|
62811
63221
|
},
|
|
63222
|
+
addNodeView() {
|
|
63223
|
+
return ({ node, editor, getPos, decorations }) => {
|
|
63224
|
+
const htmlAttributes = this.options.htmlAttributes;
|
|
63225
|
+
return new AutoPageNumberNodeView(node, getPos, decorations, editor, htmlAttributes);
|
|
63226
|
+
};
|
|
63227
|
+
},
|
|
62812
63228
|
parseDOM() {
|
|
62813
|
-
return [{ tag:
|
|
63229
|
+
return [{ tag: 'span[data-id="auto-total-pages"' }];
|
|
62814
63230
|
},
|
|
62815
63231
|
renderDOM({ htmlAttributes }) {
|
|
62816
|
-
return [
|
|
62817
|
-
"span",
|
|
62818
|
-
Attribute2.mergeAttributes(this.options.htmlAttributes, htmlAttributes, {
|
|
62819
|
-
"data-structured-content": ""
|
|
62820
|
-
}),
|
|
62821
|
-
0
|
|
62822
|
-
];
|
|
63232
|
+
return ["span", Attribute2.mergeAttributes(this.options.htmlAttributes, htmlAttributes), 0];
|
|
62823
63233
|
},
|
|
62824
|
-
|
|
62825
|
-
return
|
|
62826
|
-
|
|
63234
|
+
addCommands() {
|
|
63235
|
+
return {
|
|
63236
|
+
/**
|
|
63237
|
+
* Insert total page count
|
|
63238
|
+
* @category Command
|
|
63239
|
+
* @returns {Function} Command function
|
|
63240
|
+
* @example
|
|
63241
|
+
* editor.commands.addTotalPageCount()
|
|
63242
|
+
* @note Only works in header/footer contexts
|
|
63243
|
+
*/
|
|
63244
|
+
addTotalPageCount: () => ({ tr, dispatch, state: state2, editor }) => {
|
|
63245
|
+
const { options } = editor;
|
|
63246
|
+
if (!options.isHeaderOrFooter) return false;
|
|
63247
|
+
const { schema } = state2;
|
|
63248
|
+
const pageNumberType = schema.nodes?.["total-page-number"];
|
|
63249
|
+
if (!pageNumberType) return false;
|
|
63250
|
+
const currentPages = editor?.options?.parentEditor?.currentTotalPages || 1;
|
|
63251
|
+
const pageNumberNode = {
|
|
63252
|
+
type: "total-page-number",
|
|
63253
|
+
content: [{ type: "text", text: String(currentPages) }]
|
|
63254
|
+
};
|
|
63255
|
+
const pageNode = schema.nodeFromJSON(pageNumberNode);
|
|
63256
|
+
if (dispatch) {
|
|
63257
|
+
tr.replaceSelectionWith(pageNode, false);
|
|
63258
|
+
}
|
|
63259
|
+
return true;
|
|
63260
|
+
}
|
|
63261
|
+
};
|
|
63262
|
+
},
|
|
63263
|
+
addShortcuts() {
|
|
63264
|
+
return {
|
|
63265
|
+
"Mod-Shift-alt-c": () => this.editor.commands.addTotalPageCount()
|
|
62827
63266
|
};
|
|
62828
63267
|
}
|
|
62829
63268
|
});
|
|
62830
|
-
|
|
62831
|
-
|
|
62832
|
-
|
|
62833
|
-
|
|
62834
|
-
|
|
62835
|
-
|
|
62836
|
-
|
|
62837
|
-
|
|
62838
|
-
|
|
62839
|
-
|
|
62840
|
-
|
|
62841
|
-
|
|
62842
|
-
|
|
62843
|
-
|
|
62844
|
-
|
|
62845
|
-
|
|
62846
|
-
|
|
62847
|
-
|
|
62848
|
-
const domAttrs = Attribute2.mergeAttributes(this.htmlAttributes);
|
|
62849
|
-
updateDOMAttributes(element, { ...domAttrs });
|
|
62850
|
-
return { element, contentElement };
|
|
62851
|
-
}
|
|
62852
|
-
buildView() {
|
|
62853
|
-
const { element } = this.createElement();
|
|
62854
|
-
const dragHandle = this.createDragHandle();
|
|
62855
|
-
element.prepend(dragHandle);
|
|
62856
|
-
element.addEventListener("dragstart", (e) => this.onDragStart(e));
|
|
62857
|
-
this.root = element;
|
|
63269
|
+
const getNodeAttributes = (nodeName, editor) => {
|
|
63270
|
+
switch (nodeName) {
|
|
63271
|
+
case "page-number":
|
|
63272
|
+
return {
|
|
63273
|
+
text: editor.options.currentPageNumber || "1",
|
|
63274
|
+
className: "sd-editor-auto-page-number",
|
|
63275
|
+
dataId: "auto-page-number",
|
|
63276
|
+
ariaLabel: "Page number node"
|
|
63277
|
+
};
|
|
63278
|
+
case "total-page-number":
|
|
63279
|
+
return {
|
|
63280
|
+
text: editor.options.parentEditor?.currentTotalPages || "1",
|
|
63281
|
+
className: "sd-editor-auto-total-pages",
|
|
63282
|
+
dataId: "auto-total-pages",
|
|
63283
|
+
ariaLabel: "Total page count node"
|
|
63284
|
+
};
|
|
63285
|
+
default:
|
|
63286
|
+
return {};
|
|
62858
63287
|
}
|
|
62859
|
-
|
|
62860
|
-
|
|
62861
|
-
|
|
63288
|
+
};
|
|
63289
|
+
class AutoPageNumberNodeView {
|
|
63290
|
+
constructor(node, getPos, decorations, editor, htmlAttributes = {}) {
|
|
63291
|
+
__privateAdd$1(this, _AutoPageNumberNodeView_instances);
|
|
63292
|
+
this.node = node;
|
|
63293
|
+
this.editor = editor;
|
|
63294
|
+
this.view = editor.view;
|
|
63295
|
+
this.getPos = getPos;
|
|
63296
|
+
this.editor = editor;
|
|
63297
|
+
this.dom = __privateMethod$1(this, _AutoPageNumberNodeView_instances, renderDom_fn).call(this, node, htmlAttributes);
|
|
62862
63298
|
}
|
|
62863
|
-
update(node
|
|
62864
|
-
const
|
|
62865
|
-
|
|
62866
|
-
|
|
63299
|
+
update(node) {
|
|
63300
|
+
const incomingType = node?.type?.name;
|
|
63301
|
+
const currentType = this.node?.type?.name;
|
|
63302
|
+
if (!incomingType || incomingType !== currentType) return false;
|
|
63303
|
+
this.node = node;
|
|
62867
63304
|
return true;
|
|
62868
63305
|
}
|
|
62869
63306
|
}
|
|
62870
|
-
|
|
62871
|
-
|
|
62872
|
-
const
|
|
62873
|
-
|
|
62874
|
-
|
|
62875
|
-
|
|
63307
|
+
_AutoPageNumberNodeView_instances = /* @__PURE__ */ new WeakSet();
|
|
63308
|
+
renderDom_fn = function(node, htmlAttributes) {
|
|
63309
|
+
const attrs = getNodeAttributes(this.node.type.name, this.editor);
|
|
63310
|
+
const content = document.createTextNode(String(attrs.text));
|
|
63311
|
+
const nodeContent = document.createElement("span");
|
|
63312
|
+
nodeContent.className = attrs.className;
|
|
63313
|
+
nodeContent.setAttribute("data-id", attrs.dataId);
|
|
63314
|
+
nodeContent.setAttribute("aria-label", attrs.ariaLabel);
|
|
63315
|
+
const currentPos = this.getPos();
|
|
63316
|
+
const { styles, marks } = getMarksFromNeighbors(currentPos, this.view);
|
|
63317
|
+
__privateMethod$1(this, _AutoPageNumberNodeView_instances, scheduleUpdateNodeStyle_fn).call(this, currentPos, marks);
|
|
63318
|
+
Object.assign(nodeContent.style, styles);
|
|
63319
|
+
nodeContent.appendChild(content);
|
|
63320
|
+
Object.entries(htmlAttributes).forEach(([key2, value]) => {
|
|
63321
|
+
if (value) nodeContent.setAttribute(key2, value);
|
|
63322
|
+
});
|
|
63323
|
+
return nodeContent;
|
|
63324
|
+
};
|
|
63325
|
+
scheduleUpdateNodeStyle_fn = function(pos, marks) {
|
|
63326
|
+
setTimeout(() => {
|
|
63327
|
+
const { state: state2 } = this.editor;
|
|
63328
|
+
const { dispatch } = this.view;
|
|
63329
|
+
const node = state2.doc.nodeAt(pos);
|
|
63330
|
+
if (!node || node.isText) return;
|
|
63331
|
+
const currentMarks = node.attrs.marksAsAttrs || [];
|
|
63332
|
+
const newMarks = marks.map((m2) => ({ type: m2.type.name, attrs: m2.attrs }));
|
|
63333
|
+
const isEqual = JSON.stringify(currentMarks) === JSON.stringify(newMarks);
|
|
63334
|
+
if (isEqual) return;
|
|
63335
|
+
const newAttrs = {
|
|
63336
|
+
...node.attrs,
|
|
63337
|
+
marksAsAttrs: newMarks
|
|
63338
|
+
};
|
|
63339
|
+
const tr = state2.tr.setNodeMarkup(pos, void 0, newAttrs);
|
|
63340
|
+
dispatch(tr);
|
|
63341
|
+
}, 0);
|
|
63342
|
+
};
|
|
63343
|
+
const getMarksFromNeighbors = (currentPos, view) => {
|
|
63344
|
+
const $pos = view.state.doc.resolve(currentPos);
|
|
63345
|
+
const styles = {};
|
|
63346
|
+
const marks = [];
|
|
63347
|
+
const before = $pos.nodeBefore;
|
|
63348
|
+
if (before) {
|
|
63349
|
+
Object.assign(styles, processMarks(before.marks));
|
|
63350
|
+
marks.push(...before.marks);
|
|
63351
|
+
}
|
|
63352
|
+
const after = $pos.nodeAfter;
|
|
63353
|
+
if (after) {
|
|
63354
|
+
Object.assign(styles, { ...styles, ...processMarks(after.marks) });
|
|
63355
|
+
marks.push(...after.marks);
|
|
63356
|
+
}
|
|
63357
|
+
return {
|
|
63358
|
+
styles,
|
|
63359
|
+
marks
|
|
63360
|
+
};
|
|
63361
|
+
};
|
|
63362
|
+
const processMarks = (marks) => {
|
|
63363
|
+
const styles = {};
|
|
63364
|
+
marks.forEach((mark) => {
|
|
63365
|
+
const { type: type2, attrs } = mark;
|
|
63366
|
+
switch (type2.name) {
|
|
63367
|
+
case "textStyle":
|
|
63368
|
+
if (attrs.fontFamily) styles["font-family"] = attrs.fontFamily;
|
|
63369
|
+
if (attrs.fontSize) styles["font-size"] = attrs.fontSize;
|
|
63370
|
+
if (attrs.color) styles["color"] = attrs.color;
|
|
63371
|
+
if (attrs.backgroundColor) styles["background-color"] = attrs.backgroundColor;
|
|
63372
|
+
break;
|
|
63373
|
+
case "bold":
|
|
63374
|
+
styles["font-weight"] = "bold";
|
|
63375
|
+
break;
|
|
63376
|
+
case "italic":
|
|
63377
|
+
styles["font-style"] = "italic";
|
|
63378
|
+
break;
|
|
63379
|
+
case "underline":
|
|
63380
|
+
styles["text-decoration"] = (styles["text-decoration"] || "") + " underline";
|
|
63381
|
+
break;
|
|
63382
|
+
case "strike":
|
|
63383
|
+
styles["text-decoration"] = (styles["text-decoration"] || "") + " line-through";
|
|
63384
|
+
break;
|
|
63385
|
+
default:
|
|
63386
|
+
if (attrs?.style) {
|
|
63387
|
+
Object.entries(attrs.style).forEach(([key2, value]) => {
|
|
63388
|
+
styles[key2] = value;
|
|
63389
|
+
});
|
|
63390
|
+
}
|
|
63391
|
+
break;
|
|
63392
|
+
}
|
|
63393
|
+
});
|
|
63394
|
+
return styles;
|
|
63395
|
+
};
|
|
63396
|
+
const ShapeContainer = Node$1.create({
|
|
63397
|
+
name: "shapeContainer",
|
|
63398
|
+
group: "block",
|
|
63399
|
+
content: "block+",
|
|
62876
63400
|
isolating: true,
|
|
62877
|
-
atom: false,
|
|
62878
|
-
// false - has editable content.
|
|
62879
|
-
draggable: true,
|
|
62880
63401
|
addOptions() {
|
|
62881
63402
|
return {
|
|
62882
63403
|
htmlAttributes: {
|
|
62883
|
-
class:
|
|
62884
|
-
"aria-label": "
|
|
63404
|
+
class: "sd-editor-shape-container",
|
|
63405
|
+
"aria-label": "Shape container node"
|
|
62885
63406
|
}
|
|
62886
63407
|
};
|
|
62887
63408
|
},
|
|
62888
63409
|
addAttributes() {
|
|
62889
63410
|
return {
|
|
62890
|
-
|
|
63411
|
+
fillcolor: {
|
|
63412
|
+
renderDOM: (attrs) => {
|
|
63413
|
+
if (!attrs.fillcolor) return {};
|
|
63414
|
+
return {
|
|
63415
|
+
style: `background-color: ${attrs.fillcolor}`
|
|
63416
|
+
};
|
|
63417
|
+
}
|
|
63418
|
+
},
|
|
63419
|
+
sdBlockId: {
|
|
62891
63420
|
default: null,
|
|
62892
|
-
|
|
63421
|
+
keepOnSplit: false,
|
|
63422
|
+
parseDOM: (elem) => elem.getAttribute("data-sd-block-id"),
|
|
62893
63423
|
renderDOM: (attrs) => {
|
|
62894
|
-
|
|
62895
|
-
return { "data-id": attrs.id };
|
|
63424
|
+
return attrs.sdBlockId ? { "data-sd-block-id": attrs.sdBlockId } : {};
|
|
62896
63425
|
}
|
|
62897
63426
|
},
|
|
62898
|
-
|
|
63427
|
+
style: {
|
|
63428
|
+
renderDOM: (attrs) => {
|
|
63429
|
+
if (!attrs.style) return {};
|
|
63430
|
+
return {
|
|
63431
|
+
style: attrs.style
|
|
63432
|
+
};
|
|
63433
|
+
}
|
|
63434
|
+
},
|
|
63435
|
+
wrapAttributes: {
|
|
63436
|
+
rendered: false
|
|
63437
|
+
},
|
|
63438
|
+
attributes: {
|
|
62899
63439
|
rendered: false
|
|
62900
63440
|
}
|
|
62901
63441
|
};
|
|
62902
63442
|
},
|
|
62903
63443
|
parseDOM() {
|
|
62904
|
-
return [
|
|
63444
|
+
return [
|
|
63445
|
+
{
|
|
63446
|
+
tag: `div[data-type="${this.name}"]`
|
|
63447
|
+
}
|
|
63448
|
+
];
|
|
62905
63449
|
},
|
|
62906
63450
|
renderDOM({ htmlAttributes }) {
|
|
62907
63451
|
return [
|
|
62908
63452
|
"div",
|
|
62909
|
-
Attribute2.mergeAttributes(this.options.htmlAttributes, htmlAttributes, {
|
|
62910
|
-
"data-structured-content-block": ""
|
|
62911
|
-
}),
|
|
63453
|
+
Attribute2.mergeAttributes(this.options.htmlAttributes, htmlAttributes, { "data-type": this.name }),
|
|
62912
63454
|
0
|
|
62913
63455
|
];
|
|
62914
|
-
},
|
|
62915
|
-
addNodeView() {
|
|
62916
|
-
return (props) => {
|
|
62917
|
-
return new StructuredContentBlockView({ ...props });
|
|
62918
|
-
};
|
|
62919
63456
|
}
|
|
62920
63457
|
});
|
|
62921
|
-
|
|
62922
|
-
|
|
62923
|
-
__privateAdd$1(this, _DocumentSectionView_instances);
|
|
62924
|
-
this.node = node;
|
|
62925
|
-
this.editor = editor;
|
|
62926
|
-
this.decorations = decorations;
|
|
62927
|
-
this.view = editor.view;
|
|
62928
|
-
this.getPos = getPos;
|
|
62929
|
-
__privateMethod$1(this, _DocumentSectionView_instances, init_fn3).call(this);
|
|
62930
|
-
}
|
|
62931
|
-
}
|
|
62932
|
-
_DocumentSectionView_instances = /* @__PURE__ */ new WeakSet();
|
|
62933
|
-
init_fn3 = function() {
|
|
62934
|
-
const { attrs } = this.node;
|
|
62935
|
-
const { id, title, description } = attrs;
|
|
62936
|
-
this.dom = document.createElement("div");
|
|
62937
|
-
this.dom.className = "sd-document-section-block";
|
|
62938
|
-
this.dom.setAttribute("data-id", id);
|
|
62939
|
-
this.dom.setAttribute("data-title", title);
|
|
62940
|
-
this.dom.setAttribute("data-description", description);
|
|
62941
|
-
this.dom.setAttribute("aria-label", "Document section");
|
|
62942
|
-
__privateMethod$1(this, _DocumentSectionView_instances, addToolTip_fn).call(this);
|
|
62943
|
-
this.contentDOM = document.createElement("div");
|
|
62944
|
-
this.contentDOM.className = "sd-document-section-block-content";
|
|
62945
|
-
this.contentDOM.setAttribute("contenteditable", "true");
|
|
62946
|
-
this.dom.appendChild(this.contentDOM);
|
|
62947
|
-
};
|
|
62948
|
-
addToolTip_fn = function() {
|
|
62949
|
-
const { title } = this.node.attrs;
|
|
62950
|
-
this.infoDiv = document.createElement("div");
|
|
62951
|
-
this.infoDiv.className = "sd-document-section-block-info";
|
|
62952
|
-
const textSpan = document.createElement("span");
|
|
62953
|
-
textSpan.textContent = title || "Document section";
|
|
62954
|
-
this.infoDiv.appendChild(textSpan);
|
|
62955
|
-
this.infoDiv.setAttribute("contenteditable", "false");
|
|
62956
|
-
this.dom.appendChild(this.infoDiv);
|
|
62957
|
-
};
|
|
62958
|
-
const getAllSections = (editor) => {
|
|
62959
|
-
if (!editor) return [];
|
|
62960
|
-
const type2 = editor.schema.nodes.documentSection;
|
|
62961
|
-
if (!type2) return [];
|
|
62962
|
-
const sections = [];
|
|
62963
|
-
const { state: state2 } = editor;
|
|
62964
|
-
state2.doc.descendants((node, pos) => {
|
|
62965
|
-
if (node.type.name === type2.name) {
|
|
62966
|
-
sections.push({ node, pos });
|
|
62967
|
-
}
|
|
62968
|
-
});
|
|
62969
|
-
return sections;
|
|
62970
|
-
};
|
|
62971
|
-
const exportSectionsToHTML = (editor) => {
|
|
62972
|
-
const sections = getAllSections(editor);
|
|
62973
|
-
const processedSections = /* @__PURE__ */ new Set();
|
|
62974
|
-
const result = [];
|
|
62975
|
-
sections.forEach(({ node }) => {
|
|
62976
|
-
const { attrs } = node;
|
|
62977
|
-
const { id, title, description } = attrs;
|
|
62978
|
-
if (processedSections.has(id)) return;
|
|
62979
|
-
processedSections.add(id);
|
|
62980
|
-
const html = getHTMLFromNode(node, editor);
|
|
62981
|
-
result.push({
|
|
62982
|
-
id,
|
|
62983
|
-
title,
|
|
62984
|
-
description,
|
|
62985
|
-
html
|
|
62986
|
-
});
|
|
62987
|
-
});
|
|
62988
|
-
return result;
|
|
62989
|
-
};
|
|
62990
|
-
const getHTMLFromNode = (node, editor) => {
|
|
62991
|
-
const tempDocument = document.implementation.createHTMLDocument();
|
|
62992
|
-
const container = tempDocument.createElement("div");
|
|
62993
|
-
const fragment = DOMSerializer.fromSchema(editor.schema).serializeFragment(node.content);
|
|
62994
|
-
container.appendChild(fragment);
|
|
62995
|
-
let html = container.innerHTML;
|
|
62996
|
-
return html;
|
|
62997
|
-
};
|
|
62998
|
-
const exportSectionsToJSON = (editor) => {
|
|
62999
|
-
const sections = getAllSections(editor);
|
|
63000
|
-
const processedSections = /* @__PURE__ */ new Set();
|
|
63001
|
-
const result = [];
|
|
63002
|
-
sections.forEach(({ node }) => {
|
|
63003
|
-
const { attrs } = node;
|
|
63004
|
-
const { id, title, description } = attrs;
|
|
63005
|
-
if (processedSections.has(id)) return;
|
|
63006
|
-
processedSections.add(id);
|
|
63007
|
-
result.push({
|
|
63008
|
-
id,
|
|
63009
|
-
title,
|
|
63010
|
-
description,
|
|
63011
|
-
content: node.toJSON()
|
|
63012
|
-
});
|
|
63013
|
-
});
|
|
63014
|
-
return result;
|
|
63015
|
-
};
|
|
63016
|
-
const getLinkedSectionEditor = (id, options, editor) => {
|
|
63017
|
-
const sections = getAllSections(editor);
|
|
63018
|
-
const section = sections.find((s) => s.node.attrs.id === id);
|
|
63019
|
-
if (!section) return null;
|
|
63020
|
-
const child = editor.createChildEditor({
|
|
63021
|
-
...options,
|
|
63022
|
-
onUpdate: ({ editor: childEditor, transaction }) => {
|
|
63023
|
-
const isFromtLinkedParent = transaction.getMeta("fromLinkedParent");
|
|
63024
|
-
if (isFromtLinkedParent) return;
|
|
63025
|
-
const updatedContent = childEditor.state.doc.content;
|
|
63026
|
-
const sectionNode = getAllSections(editor)?.find((s) => s.node.attrs.id === id);
|
|
63027
|
-
if (!sectionNode) return;
|
|
63028
|
-
const { pos, node } = sectionNode;
|
|
63029
|
-
const newNode = node.type.create(node.attrs, updatedContent, node.marks);
|
|
63030
|
-
const tr = editor.state.tr.replaceWith(pos, pos + node.nodeSize, newNode);
|
|
63031
|
-
tr.setMeta("fromLinkedChild", true);
|
|
63032
|
-
editor.view.dispatch(tr);
|
|
63033
|
-
}
|
|
63034
|
-
});
|
|
63035
|
-
editor.on("update", ({ transaction }) => {
|
|
63036
|
-
const isFromLinkedChild = transaction.getMeta("fromLinkedChild");
|
|
63037
|
-
if (isFromLinkedChild) return;
|
|
63038
|
-
const sectionNode = getAllSections(editor)?.find((s) => s.node.attrs.id === id);
|
|
63039
|
-
if (!sectionNode) return;
|
|
63040
|
-
const sectionContent = sectionNode.node.content;
|
|
63041
|
-
const json = {
|
|
63042
|
-
type: "doc",
|
|
63043
|
-
content: sectionContent.content.map((node) => node.toJSON())
|
|
63044
|
-
};
|
|
63045
|
-
const childTr = child.state.tr;
|
|
63046
|
-
childTr.setMeta("fromLinkedParent", true);
|
|
63047
|
-
childTr.replaceWith(0, child.state.doc.content.size, child.schema.nodeFromJSON(json));
|
|
63048
|
-
child.view.dispatch(childTr);
|
|
63049
|
-
});
|
|
63050
|
-
return child;
|
|
63051
|
-
};
|
|
63052
|
-
const SectionHelpers = {
|
|
63053
|
-
getAllSections,
|
|
63054
|
-
exportSectionsToHTML,
|
|
63055
|
-
exportSectionsToJSON,
|
|
63056
|
-
getLinkedSectionEditor
|
|
63057
|
-
};
|
|
63058
|
-
const DocumentSection = Node$1.create({
|
|
63059
|
-
name: "documentSection",
|
|
63458
|
+
const ShapeTextbox = Node$1.create({
|
|
63459
|
+
name: "shapeTextbox",
|
|
63060
63460
|
group: "block",
|
|
63061
|
-
content: "block*",
|
|
63062
|
-
atom: true,
|
|
63461
|
+
content: "paragraph* block*",
|
|
63063
63462
|
isolating: true,
|
|
63064
63463
|
addOptions() {
|
|
63065
63464
|
return {
|
|
63066
63465
|
htmlAttributes: {
|
|
63067
|
-
class: "sd-
|
|
63068
|
-
"aria-label": "
|
|
63466
|
+
class: "sd-editor-shape-textbox",
|
|
63467
|
+
"aria-label": "Shape textbox node"
|
|
63069
63468
|
}
|
|
63070
63469
|
};
|
|
63071
63470
|
},
|
|
63072
|
-
parseDOM() {
|
|
63073
|
-
return [
|
|
63074
|
-
{
|
|
63075
|
-
tag: "div.sd-document-section-block",
|
|
63076
|
-
priority: 60
|
|
63077
|
-
}
|
|
63078
|
-
];
|
|
63079
|
-
},
|
|
63080
|
-
renderDOM({ htmlAttributes }) {
|
|
63081
|
-
return ["div", Attribute2.mergeAttributes(this.options.htmlAttributes, htmlAttributes), 0];
|
|
63082
|
-
},
|
|
63083
63471
|
addAttributes() {
|
|
63084
63472
|
return {
|
|
63085
|
-
id: {},
|
|
63086
63473
|
sdBlockId: {
|
|
63087
63474
|
default: null,
|
|
63088
63475
|
keepOnSplit: false,
|
|
@@ -63091,212 +63478,131 @@ const DocumentSection = Node$1.create({
|
|
|
63091
63478
|
return attrs.sdBlockId ? { "data-sd-block-id": attrs.sdBlockId } : {};
|
|
63092
63479
|
}
|
|
63093
63480
|
},
|
|
63094
|
-
|
|
63095
|
-
|
|
63096
|
-
|
|
63097
|
-
isLocked: { default: false }
|
|
63481
|
+
attributes: {
|
|
63482
|
+
rendered: false
|
|
63483
|
+
}
|
|
63098
63484
|
};
|
|
63099
63485
|
},
|
|
63100
|
-
|
|
63101
|
-
return
|
|
63102
|
-
|
|
63486
|
+
parseDOM() {
|
|
63487
|
+
return [
|
|
63488
|
+
{
|
|
63489
|
+
tag: `div[data-type="${this.name}"]`
|
|
63490
|
+
}
|
|
63491
|
+
];
|
|
63492
|
+
},
|
|
63493
|
+
renderDOM({ htmlAttributes }) {
|
|
63494
|
+
return [
|
|
63495
|
+
"div",
|
|
63496
|
+
Attribute2.mergeAttributes(this.options.htmlAttributes, htmlAttributes, { "data-type": this.name }),
|
|
63497
|
+
0
|
|
63498
|
+
];
|
|
63499
|
+
}
|
|
63500
|
+
});
|
|
63501
|
+
const ContentBlock = Node$1.create({
|
|
63502
|
+
name: "contentBlock",
|
|
63503
|
+
group: "inline",
|
|
63504
|
+
content: "",
|
|
63505
|
+
isolating: true,
|
|
63506
|
+
atom: true,
|
|
63507
|
+
inline: true,
|
|
63508
|
+
addOptions() {
|
|
63509
|
+
return {
|
|
63510
|
+
htmlAttributes: {
|
|
63511
|
+
contenteditable: false
|
|
63512
|
+
}
|
|
63103
63513
|
};
|
|
63104
63514
|
},
|
|
63105
|
-
|
|
63515
|
+
addAttributes() {
|
|
63106
63516
|
return {
|
|
63107
|
-
|
|
63108
|
-
|
|
63109
|
-
|
|
63110
|
-
|
|
63111
|
-
|
|
63112
|
-
* editor.commands.createDocumentSection({
|
|
63113
|
-
* id: 1,
|
|
63114
|
-
* title: 'Terms & Conditions',
|
|
63115
|
-
* isLocked: true,
|
|
63116
|
-
* html: '<p>Legal content...</p>'
|
|
63117
|
-
* })
|
|
63118
|
-
*/
|
|
63119
|
-
createDocumentSection: (options = {}) => ({ tr, state: state2, dispatch, editor }) => {
|
|
63120
|
-
const { selection } = state2;
|
|
63121
|
-
let { from: from2, to } = selection;
|
|
63122
|
-
let content = selection.content().content;
|
|
63123
|
-
const { html: optionsHTML, json: optionsJSON } = options;
|
|
63124
|
-
if (optionsHTML) {
|
|
63125
|
-
const html = htmlHandler(optionsHTML, this.editor);
|
|
63126
|
-
const doc2 = DOMParser$1.fromSchema(this.editor.schema).parse(html);
|
|
63127
|
-
content = doc2.content;
|
|
63128
|
-
}
|
|
63129
|
-
if (optionsJSON) {
|
|
63130
|
-
content = this.editor.schema.nodeFromJSON(optionsJSON);
|
|
63131
|
-
}
|
|
63132
|
-
if (!content?.content?.length) {
|
|
63133
|
-
content = this.editor.schema.nodeFromJSON({ type: "paragraph", content: [] });
|
|
63134
|
-
}
|
|
63135
|
-
if (!options.id) {
|
|
63136
|
-
const allSections = SectionHelpers.getAllSections(editor);
|
|
63137
|
-
options.id = allSections.length + 1;
|
|
63138
|
-
}
|
|
63139
|
-
if (!options.title) {
|
|
63140
|
-
options.title = "Document section";
|
|
63141
|
-
}
|
|
63142
|
-
const node = this.type.createAndFill(options, content);
|
|
63143
|
-
if (!node) return false;
|
|
63144
|
-
const isAlreadyInSdtBlock = findParentNode((node2) => node2.type.name === "documentSection")(selection);
|
|
63145
|
-
if (isAlreadyInSdtBlock && isAlreadyInSdtBlock.node) {
|
|
63146
|
-
const insertPos2 = isAlreadyInSdtBlock.pos + isAlreadyInSdtBlock.node.nodeSize;
|
|
63147
|
-
from2 = insertPos2;
|
|
63148
|
-
to = insertPos2;
|
|
63149
|
-
}
|
|
63150
|
-
tr.replaceRangeWith(from2, to, node);
|
|
63151
|
-
const nodeEnd = from2 + node.nodeSize;
|
|
63152
|
-
let shouldInsertParagraph = true;
|
|
63153
|
-
let insertPos = nodeEnd;
|
|
63154
|
-
if (nodeEnd >= tr.doc.content.size) {
|
|
63155
|
-
insertPos = tr.doc.content.size;
|
|
63156
|
-
if (insertPos > 0) {
|
|
63157
|
-
const $endPos = tr.doc.resolve(insertPos);
|
|
63158
|
-
if ($endPos.nodeBefore && $endPos.nodeBefore.type.name === "paragraph") {
|
|
63159
|
-
shouldInsertParagraph = false;
|
|
63160
|
-
}
|
|
63161
|
-
}
|
|
63162
|
-
}
|
|
63163
|
-
if (shouldInsertParagraph) {
|
|
63164
|
-
const emptyParagraph = tr.doc.type.schema.nodes.paragraph.create();
|
|
63165
|
-
tr.insert(insertPos, emptyParagraph);
|
|
63166
|
-
}
|
|
63167
|
-
if (dispatch) {
|
|
63168
|
-
tr.setMeta("documentSection", { action: "create" });
|
|
63169
|
-
dispatch(tr);
|
|
63170
|
-
setTimeout(() => {
|
|
63171
|
-
try {
|
|
63172
|
-
const currentState = editor.state;
|
|
63173
|
-
const docSize = currentState.doc.content.size;
|
|
63174
|
-
let targetPos = from2 + node.nodeSize;
|
|
63175
|
-
if (shouldInsertParagraph) {
|
|
63176
|
-
targetPos += 1;
|
|
63177
|
-
}
|
|
63178
|
-
targetPos = Math.min(targetPos, docSize);
|
|
63179
|
-
if (targetPos < docSize && targetPos > 0) {
|
|
63180
|
-
const newSelection = Selection.near(currentState.doc.resolve(targetPos));
|
|
63181
|
-
const newTr = currentState.tr.setSelection(newSelection);
|
|
63182
|
-
editor.view.dispatch(newTr);
|
|
63183
|
-
}
|
|
63184
|
-
} catch (e) {
|
|
63185
|
-
console.warn("Could not set delayed selection:", e);
|
|
63186
|
-
}
|
|
63187
|
-
}, 0);
|
|
63517
|
+
horizontalRule: {
|
|
63518
|
+
default: false,
|
|
63519
|
+
renderDOM: ({ horizontalRule }) => {
|
|
63520
|
+
if (!horizontalRule) return {};
|
|
63521
|
+
return { "data-horizontal-rule": "true" };
|
|
63188
63522
|
}
|
|
63189
|
-
return true;
|
|
63190
63523
|
},
|
|
63191
|
-
|
|
63192
|
-
|
|
63193
|
-
|
|
63194
|
-
|
|
63195
|
-
|
|
63196
|
-
|
|
63197
|
-
|
|
63198
|
-
|
|
63199
|
-
|
|
63200
|
-
|
|
63201
|
-
|
|
63202
|
-
const nodeStart = pos;
|
|
63203
|
-
const nodeEnd = nodeStart + node.nodeSize;
|
|
63204
|
-
const contentToPreserve = node.content;
|
|
63205
|
-
tr.delete(nodeStart, nodeEnd);
|
|
63206
|
-
if (contentToPreserve.size > 0) {
|
|
63207
|
-
tr.insert(nodeStart, contentToPreserve);
|
|
63208
|
-
}
|
|
63209
|
-
const newPos = Math.min(nodeStart, tr.doc.content.size);
|
|
63210
|
-
tr.setSelection(Selection.near(tr.doc.resolve(newPos)));
|
|
63211
|
-
if (dispatch) {
|
|
63212
|
-
tr.setMeta("documentSection", { action: "delete" });
|
|
63213
|
-
dispatch(tr);
|
|
63524
|
+
size: {
|
|
63525
|
+
default: null,
|
|
63526
|
+
renderDOM: ({ size: size2 }) => {
|
|
63527
|
+
if (!size2) return {};
|
|
63528
|
+
let style2 = "";
|
|
63529
|
+
if (size2.top) style2 += `top: ${size2.top}px; `;
|
|
63530
|
+
if (size2.left) style2 += `left: ${size2.left}px; `;
|
|
63531
|
+
if (size2.width) style2 += `width: ${size2.width.toString().endsWith("%") ? size2.width : `${size2.width}px`}; `;
|
|
63532
|
+
if (size2.height)
|
|
63533
|
+
style2 += `height: ${size2.height.toString().endsWith("%") ? size2.height : `${size2.height}px`}; `;
|
|
63534
|
+
return { style: style2 };
|
|
63214
63535
|
}
|
|
63215
|
-
return true;
|
|
63216
63536
|
},
|
|
63217
|
-
|
|
63218
|
-
|
|
63219
|
-
|
|
63220
|
-
|
|
63221
|
-
|
|
63222
|
-
|
|
63223
|
-
|
|
63224
|
-
removeSectionById: (id) => ({ tr, dispatch }) => {
|
|
63225
|
-
const sections = SectionHelpers.getAllSections(this.editor);
|
|
63226
|
-
const sectionToRemove = sections.find(({ node: node2 }) => node2.attrs.id === id);
|
|
63227
|
-
if (!sectionToRemove) return false;
|
|
63228
|
-
const { pos, node } = sectionToRemove;
|
|
63229
|
-
const nodeStart = pos;
|
|
63230
|
-
const nodeEnd = nodeStart + node.nodeSize;
|
|
63231
|
-
tr.delete(nodeStart, nodeEnd);
|
|
63232
|
-
if (dispatch) {
|
|
63233
|
-
tr.setMeta("documentSection", { action: "delete", id });
|
|
63234
|
-
dispatch(tr);
|
|
63537
|
+
background: {
|
|
63538
|
+
default: null,
|
|
63539
|
+
renderDOM: (attrs) => {
|
|
63540
|
+
if (!attrs.background) return {};
|
|
63541
|
+
return {
|
|
63542
|
+
style: `background-color: ${attrs.background}`
|
|
63543
|
+
};
|
|
63235
63544
|
}
|
|
63236
|
-
return true;
|
|
63237
63545
|
},
|
|
63546
|
+
drawingContent: {
|
|
63547
|
+
rendered: false
|
|
63548
|
+
},
|
|
63549
|
+
attributes: {
|
|
63550
|
+
rendered: false
|
|
63551
|
+
}
|
|
63552
|
+
};
|
|
63553
|
+
},
|
|
63554
|
+
parseDOM() {
|
|
63555
|
+
return [
|
|
63556
|
+
{
|
|
63557
|
+
tag: `div[data-type="${this.name}"]`
|
|
63558
|
+
}
|
|
63559
|
+
];
|
|
63560
|
+
},
|
|
63561
|
+
renderDOM({ htmlAttributes }) {
|
|
63562
|
+
return ["div", Attribute2.mergeAttributes(this.options.htmlAttributes, htmlAttributes, { "data-type": this.name })];
|
|
63563
|
+
},
|
|
63564
|
+
addCommands() {
|
|
63565
|
+
return {
|
|
63238
63566
|
/**
|
|
63239
|
-
*
|
|
63567
|
+
* Insert a horizontal rule
|
|
63240
63568
|
* @category Command
|
|
63241
|
-
* @param {number} id - Section to lock
|
|
63242
63569
|
* @example
|
|
63243
|
-
* editor.commands.
|
|
63570
|
+
* editor.commands.insertHorizontalRule()
|
|
63571
|
+
* @note Creates a visual separator between content sections
|
|
63244
63572
|
*/
|
|
63245
|
-
|
|
63246
|
-
|
|
63247
|
-
|
|
63248
|
-
|
|
63249
|
-
|
|
63250
|
-
|
|
63251
|
-
|
|
63252
|
-
|
|
63253
|
-
}
|
|
63254
|
-
return true;
|
|
63573
|
+
insertHorizontalRule: () => ({ commands: commands2 }) => {
|
|
63574
|
+
return commands2.insertContent({
|
|
63575
|
+
type: this.name,
|
|
63576
|
+
attrs: {
|
|
63577
|
+
horizontalRule: true,
|
|
63578
|
+
size: { width: "100%", height: 2 },
|
|
63579
|
+
background: "#e5e7eb"
|
|
63580
|
+
}
|
|
63581
|
+
});
|
|
63255
63582
|
},
|
|
63256
63583
|
/**
|
|
63257
|
-
*
|
|
63584
|
+
* Insert a content block
|
|
63258
63585
|
* @category Command
|
|
63259
|
-
* @param {
|
|
63586
|
+
* @param {ContentBlockConfig} config - Block configuration
|
|
63260
63587
|
* @example
|
|
63261
|
-
*
|
|
63262
|
-
* editor.commands.
|
|
63263
|
-
*
|
|
63264
|
-
*
|
|
63265
|
-
*
|
|
63266
|
-
*
|
|
63588
|
+
* // Insert a spacer block
|
|
63589
|
+
* editor.commands.insertContentBlock({ size: { height: 20 } })
|
|
63590
|
+
*
|
|
63591
|
+
* @example
|
|
63592
|
+
* // Insert a colored divider
|
|
63593
|
+
* editor.commands.insertContentBlock({
|
|
63594
|
+
* size: { width: '50%', height: 3 },
|
|
63595
|
+
* background: '#3b82f6'
|
|
63267
63596
|
* })
|
|
63597
|
+
* @note Used for spacing, dividers, and special inline content
|
|
63268
63598
|
*/
|
|
63269
|
-
|
|
63270
|
-
|
|
63271
|
-
|
|
63272
|
-
|
|
63273
|
-
|
|
63274
|
-
let newContent = null;
|
|
63275
|
-
if (html) {
|
|
63276
|
-
const htmlDoc = htmlHandler(html, editor || this.editor);
|
|
63277
|
-
const doc2 = DOMParser$1.fromSchema((editor || this.editor).schema).parse(htmlDoc);
|
|
63278
|
-
newContent = doc2.content;
|
|
63279
|
-
}
|
|
63280
|
-
if (json) {
|
|
63281
|
-
newContent = (editor || this.editor).schema.nodeFromJSON(json);
|
|
63282
|
-
}
|
|
63283
|
-
if (!newContent) {
|
|
63284
|
-
newContent = node.content;
|
|
63285
|
-
}
|
|
63286
|
-
const updatedNode = node.type.create({ ...node.attrs, ...attrs }, newContent, node.marks);
|
|
63287
|
-
tr.replaceWith(pos, pos + node.nodeSize, updatedNode);
|
|
63288
|
-
if (dispatch) {
|
|
63289
|
-
tr.setMeta("documentSection", { action: "update", id, attrs });
|
|
63290
|
-
dispatch(tr);
|
|
63291
|
-
}
|
|
63292
|
-
return true;
|
|
63599
|
+
insertContentBlock: (config2) => ({ commands: commands2 }) => {
|
|
63600
|
+
return commands2.insertContent({
|
|
63601
|
+
type: this.name,
|
|
63602
|
+
attrs: config2
|
|
63603
|
+
});
|
|
63293
63604
|
}
|
|
63294
63605
|
};
|
|
63295
|
-
},
|
|
63296
|
-
addHelpers() {
|
|
63297
|
-
return {
|
|
63298
|
-
...SectionHelpers
|
|
63299
|
-
};
|
|
63300
63606
|
}
|
|
63301
63607
|
});
|
|
63302
63608
|
const { findChildren } = helpers;
|
|
@@ -70146,6 +70452,7 @@ const getStarterExtensions = () => {
|
|
|
70146
70452
|
Search,
|
|
70147
70453
|
StructuredContent,
|
|
70148
70454
|
StructuredContentBlock,
|
|
70455
|
+
StructuredContentCommands,
|
|
70149
70456
|
DocumentSection,
|
|
70150
70457
|
NodeResizer,
|
|
70151
70458
|
CustomSelection,
|