@harbour-enterprises/superdoc 0.22.0-next.9 → 0.23.0-next.1
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-DyWe33pN.cjs → PdfViewer-C9SGNZr6.cjs} +1 -1
- package/dist/chunks/{PdfViewer-HN-tp5RN.es.js → PdfViewer-D9atA783.es.js} +1 -1
- package/dist/chunks/{index-ir6efMuz.es.js → index-C8q6lenv.es.js} +3 -3
- package/dist/chunks/{index-BeVpZc19.cjs → index-CIbe1VMu.cjs} +3 -3
- package/dist/chunks/{super-editor.es-BwqYS285.es.js → super-editor.es-Dj6Sxtr7.es.js} +2891 -2008
- package/dist/chunks/{super-editor.es-CKfdmK-8.cjs → super-editor.es-DxScE0ep.cjs} +2891 -2008
- package/dist/core/types/index.d.ts.map +1 -1
- package/dist/style.css +4 -0
- package/dist/super-editor/ai-writer.es.js +2 -2
- package/dist/super-editor/chunks/{converter-BgedUNCW.js → converter-C08GQjNi.js} +1536 -1056
- package/dist/super-editor/chunks/{docx-zipper-ByLK3trM.js → docx-zipper-C3-uf2tI.js} +1 -1
- package/dist/super-editor/chunks/{editor-CFqh_xBx.js → editor-C2IwVkIp.js} +1251 -846
- package/dist/super-editor/chunks/{toolbar-DdfyWgZF.js → toolbar-De8G_9NV.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/core/super-converter/exporter.d.ts +4 -4
- package/dist/super-editor/src/core/super-converter/field-references/fld-preprocessors/hyperlink-preprocessor.d.ts +9 -0
- package/dist/super-editor/src/core/super-converter/field-references/fld-preprocessors/index.d.ts +2 -0
- package/dist/super-editor/src/core/super-converter/field-references/fld-preprocessors/num-pages-preprocessor.d.ts +9 -0
- package/dist/super-editor/src/core/super-converter/field-references/fld-preprocessors/page-preprocessor.d.ts +9 -0
- package/dist/super-editor/src/core/super-converter/field-references/fld-preprocessors/page-ref-preprocessor.d.ts +9 -0
- package/dist/super-editor/src/core/super-converter/field-references/fld-preprocessors/toc-preprocessor.d.ts +8 -0
- package/dist/super-editor/src/core/super-converter/field-references/index.d.ts +1 -0
- package/dist/super-editor/src/core/super-converter/field-references/preProcessNodesForFldChar.d.ts +21 -0
- package/dist/super-editor/src/core/super-converter/v2/exporter/helpers/translateChildNodes.d.ts +3 -3
- package/dist/super-editor/src/core/super-converter/v2/importer/pageReferenceImporter.d.ts +4 -0
- package/dist/super-editor/src/core/super-converter/v2/importer/tableOfContentsImporter.d.ts +4 -0
- package/dist/super-editor/src/core/super-converter/v2/types/index.d.ts +7 -1
- package/dist/super-editor/src/core/super-converter/v3/handlers/sd/pageReference/index.d.ts +1 -0
- package/dist/super-editor/src/core/super-converter/v3/handlers/sd/pageReference/pageReference-translator.d.ts +7 -0
- package/dist/super-editor/src/core/super-converter/v3/handlers/sd/tableOfContents/index.d.ts +1 -0
- package/dist/super-editor/src/core/super-converter/v3/handlers/sd/tableOfContents/tableOfContents-translator.d.ts +10 -0
- package/dist/super-editor/src/core/super-converter/v3/handlers/w/caps/caps-translator.d.ts +7 -0
- package/dist/super-editor/src/core/super-converter/v3/handlers/w/p/helpers/w-p-helpers.d.ts +0 -2
- package/dist/super-editor/src/core/super-converter/v3/handlers/w/sdt/helpers/handle-doc-part-obj.d.ts +9 -1
- package/dist/super-editor/src/core/super-converter/v3/handlers/w/sdt/helpers/translate-document-part-obj.d.ts +6 -0
- package/dist/super-editor/src/core/super-converter/v3/node-translator/node-translator.d.ts +2 -2
- package/dist/super-editor/src/extensions/index.d.ts +2 -1
- package/dist/super-editor/src/extensions/page-reference/index.d.ts +1 -0
- package/dist/super-editor/src/extensions/page-reference/page-reference.d.ts +2 -0
- package/dist/super-editor/src/extensions/structured-content/document-part-object.d.ts +2 -0
- package/dist/super-editor/src/extensions/structured-content/index.d.ts +2 -0
- package/dist/super-editor/src/extensions/structured-content/structured-content-commands.d.ts +67 -0
- package/dist/super-editor/src/extensions/structured-content/structuredContentHelpers/getStructuredContentBlockTags.d.ts +6 -0
- package/dist/super-editor/src/extensions/structured-content/structuredContentHelpers/getStructuredContentInlineTags.d.ts +6 -0
- package/dist/super-editor/src/extensions/structured-content/structuredContentHelpers/getStructuredContentTags.d.ts +6 -0
- package/dist/super-editor/src/extensions/structured-content/structuredContentHelpers/getStructuredContentTagsById.d.ts +7 -0
- package/dist/super-editor/src/extensions/structured-content/structuredContentHelpers/index.d.ts +4 -0
- package/dist/super-editor/src/extensions/tab/helpers/tabDecorations.d.ts +2 -2
- package/dist/super-editor/src/extensions/table-of-contents/index.d.ts +1 -0
- package/dist/super-editor/src/extensions/table-of-contents/table-of-contents.d.ts +2 -0
- package/dist/super-editor/style.css +4 -0
- package/dist/super-editor/super-editor.es.js +10 -8
- 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 +2892 -2009
- package/dist/superdoc.umd.js.map +1 -1
- package/package.json +1 -1
|
@@ -9,12 +9,12 @@ var __privateGet = (obj, member, getter) => (__accessCheck(obj, member, "read fr
|
|
|
9
9
|
var __privateAdd = (obj, member, value) => member.has(obj) ? __typeError("Cannot add the same private member more than once") : member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
|
|
10
10
|
var __privateSet = (obj, member, value, setter) => (__accessCheck(obj, member, "write to private field"), setter ? setter.call(obj, value) : member.set(obj, value), value);
|
|
11
11
|
var __privateMethod = (obj, member, method) => (__accessCheck(obj, member, "access private method"), method);
|
|
12
|
-
var _Attribute_static, getGlobalAttributes_fn, getNodeAndMarksAttributes_fn, _Schema_static, createNodesSchema_fn, createMarksSchema_fn, _events, _ExtensionService_instances, setupExtensions_fn, attachEditorEvents_fn, _editor, _stateValidators, _xmlValidators, _requiredNodeTypes, _requiredMarkTypes, _SuperValidator_instances, initializeValidators_fn, collectValidatorRequirements_fn, analyzeDocument_fn, _commandService, _Editor_instances, initContainerElement_fn, init_fn, initRichText_fn, onFocus_fn, checkHeadless_fn, registerCopyHandler_fn, insertNewFileData_fn, registerPluginByNameIfNotExists_fn, createExtensionService_fn, createCommandService_fn, createConverter_fn, initMedia_fn, initFonts_fn, createSchema_fn, generatePmData_fn, createView_fn, onCollaborationReady_fn, initComments_fn, initPagination_fn, dispatchTransaction_fn, handleNodeSelection_fn, prepareDocumentForImport_fn, prepareDocumentForExport_fn, endCollaboration_fn, validateDocumentInit_fn, validateDocumentExport_fn, initDevTools_fn,
|
|
12
|
+
var _Attribute_static, getGlobalAttributes_fn, getNodeAndMarksAttributes_fn, _Schema_static, createNodesSchema_fn, createMarksSchema_fn, _events, _ExtensionService_instances, setupExtensions_fn, attachEditorEvents_fn, _editor, _stateValidators, _xmlValidators, _requiredNodeTypes, _requiredMarkTypes, _SuperValidator_instances, initializeValidators_fn, collectValidatorRequirements_fn, analyzeDocument_fn, _commandService, _Editor_instances, initContainerElement_fn, init_fn, initRichText_fn, onFocus_fn, checkHeadless_fn, registerCopyHandler_fn, insertNewFileData_fn, registerPluginByNameIfNotExists_fn, createExtensionService_fn, createCommandService_fn, createConverter_fn, initMedia_fn, initFonts_fn, createSchema_fn, generatePmData_fn, createView_fn, onCollaborationReady_fn, initComments_fn, initPagination_fn, dispatchTransaction_fn, handleNodeSelection_fn, prepareDocumentForImport_fn, prepareDocumentForExport_fn, endCollaboration_fn, validateDocumentInit_fn, validateDocumentExport_fn, initDevTools_fn, _DocumentSectionView_instances, init_fn2, addToolTip_fn, _ListItemNodeView_instances, init_fn3, _FieldAnnotationView_instances, createAnnotation_fn, _AutoPageNumberNodeView_instances, renderDom_fn, scheduleUpdateNodeStyle_fn;
|
|
13
13
|
import * as Y from "yjs";
|
|
14
14
|
import { UndoManager, Item as Item$1, ContentType, Text as Text$1, XmlElement, encodeStateAsUpdate } from "yjs";
|
|
15
|
-
import { P as PluginKey, a as Plugin, M as Mapping, N as NodeSelection, S as Selection, T as TextSelection, b as Slice, D as DOMSerializer, F as Fragment, c as DOMParser$1, d as Mark$1, e as dropPoint, A as AllSelection, p as process$1, B as Buffer2, f as callOrGet, g as getExtensionConfigField, h as getMarkType, i as getMarksFromSelection, j as getNodeType, k as getSchemaTypeNameByName, l as Schema$1, m as cleanSchemaItem, n as canSplit, o as defaultBlockAt$1, q as liftTarget, r as canJoin, s as joinPoint, t as replaceStep$1, R as ReplaceAroundStep$1, u as isTextSelection, v as getMarkRange, w as isMarkActive, x as isNodeActive, y as deleteProps, z as processContent, C as ReplaceStep, E as NodeRange, G as findWrapping, L as ListHelpers, H as findParentNode, I as isMacOS, J as isIOS, K as getSchemaTypeByName, O as inputRulesPlugin, Q as TrackDeleteMarkName, U as TrackInsertMarkName, V as v4, W as TrackFormatMarkName, X as comments_module_events, Y as findMark, Z as objectIncludes, _ as AddMarkStep, $ as RemoveMarkStep, a0 as twipsToLines, a1 as pixelsToTwips, a2 as helpers, a3 as posToDOMRect, a4 as CommandService, a5 as SuperConverter, a6 as createDocument, a7 as createDocFromMarkdown, a8 as createDocFromHTML, a9 as EditorState, aa as hasSomeParentWithClass, ab as isActive, ac as unflattenListsInHtml, ad as parseSizeUnit, ae as minMax, af as getLineHeightValueString, ag as
|
|
15
|
+
import { P as PluginKey, a as Plugin, M as Mapping, N as NodeSelection, S as Selection, T as TextSelection, b as Slice, D as DOMSerializer, F as Fragment, c as DOMParser$1, d as Mark$1, e as dropPoint, A as AllSelection, p as process$1, B as Buffer2, f as callOrGet, g as getExtensionConfigField, h as getMarkType, i as getMarksFromSelection, j as getNodeType, k as getSchemaTypeNameByName, l as Schema$1, m as cleanSchemaItem, n as canSplit, o as defaultBlockAt$1, q as liftTarget, r as canJoin, s as joinPoint, t as replaceStep$1, R as ReplaceAroundStep$1, u as isTextSelection, v as getMarkRange, w as isMarkActive, x as isNodeActive, y as deleteProps, z as processContent, C as ReplaceStep, E as NodeRange, G as findWrapping, L as ListHelpers, H as findParentNode, I as isMacOS, J as isIOS, K as getSchemaTypeByName, O as inputRulesPlugin, Q as TrackDeleteMarkName, U as TrackInsertMarkName, V as v4, W as TrackFormatMarkName, X as comments_module_events, Y as findMark, Z as objectIncludes, _ as AddMarkStep, $ as RemoveMarkStep, a0 as twipsToLines, a1 as pixelsToTwips, a2 as helpers, a3 as posToDOMRect, a4 as CommandService, a5 as SuperConverter, a6 as createDocument, a7 as createDocFromMarkdown, a8 as createDocFromHTML, a9 as EditorState, aa as hasSomeParentWithClass, ab as isActive, ac as unflattenListsInHtml, ad as parseSizeUnit, ae as minMax, af as getLineHeightValueString, ag as updateDOMAttributes, ah as findChildren$5, ai as htmlHandler, aj as generateRandomSigned32BitIntStrId, ak as InputRule, al as kebabCase, am as findParentNodeClosestToPos, an as getListItemStyleDefinitions, ao as docxNumberigHelpers, ap as parseIndentElement, aq as combineIndents, ar as SelectionRange, as as Transform, at as isInTable$1, au as generateDocxRandomId, av as insertNewRelationship } from "./converter-C08GQjNi.js";
|
|
16
16
|
import { ref, computed, createElementBlock, openBlock, withModifiers, Fragment as Fragment$1, renderList, normalizeClass, createCommentVNode, toDisplayString, createElementVNode, createApp } from "vue";
|
|
17
|
-
import { D as DocxZipper } from "./docx-zipper-
|
|
17
|
+
import { D as DocxZipper } from "./docx-zipper-C3-uf2tI.js";
|
|
18
18
|
var GOOD_LEAF_SIZE = 200;
|
|
19
19
|
var RopeSequence = function RopeSequence2() {
|
|
20
20
|
};
|
|
@@ -12107,7 +12107,7 @@ const handleTrackedChangeTransaction = (trackedChangeMeta, trackedChanges, newEd
|
|
|
12107
12107
|
if (emitParams) editor.emit("commentsUpdate", emitParams);
|
|
12108
12108
|
return newTrackedChanges;
|
|
12109
12109
|
};
|
|
12110
|
-
const getTrackedChangeText = ({
|
|
12110
|
+
const getTrackedChangeText = ({ nodes, mark, trackedChangeType, isDeletionInsertion }) => {
|
|
12111
12111
|
let trackedChangeText = "";
|
|
12112
12112
|
let deletionText = "";
|
|
12113
12113
|
if (trackedChangeType === TrackInsertMarkName) {
|
|
@@ -12149,10 +12149,8 @@ const createOrUpdateTrackedChangeComment = ({ event, marks, deletionNodes, nodes
|
|
|
12149
12149
|
if (hasMatchingId) nodesWithMark.push(node2);
|
|
12150
12150
|
});
|
|
12151
12151
|
const { deletionText, trackedChangeText } = getTrackedChangeText({
|
|
12152
|
-
state: newEditorState,
|
|
12153
12152
|
nodes: nodesWithMark.length ? nodesWithMark : [node],
|
|
12154
12153
|
mark: trackedMark,
|
|
12155
|
-
marks,
|
|
12156
12154
|
trackedChangeType,
|
|
12157
12155
|
isDeletionInsertion
|
|
12158
12156
|
});
|
|
@@ -14878,7 +14876,7 @@ const _Editor = class _Editor extends EventEmitter {
|
|
|
14878
14876
|
* @returns {Object | void} Migration results
|
|
14879
14877
|
*/
|
|
14880
14878
|
processCollaborationMigrations() {
|
|
14881
|
-
console.debug("[checkVersionMigrations] Current editor version", "0.
|
|
14879
|
+
console.debug("[checkVersionMigrations] Current editor version", "0.22.0");
|
|
14882
14880
|
if (!this.options.ydoc) return;
|
|
14883
14881
|
const metaMap = this.options.ydoc.getMap("meta");
|
|
14884
14882
|
let docVersion = metaMap.get("version");
|
|
@@ -16967,6 +16965,1043 @@ const SlashMenu = Extension.create({
|
|
|
16967
16965
|
return this.editor.options.isHeadless ? [] : [slashMenuPlugin];
|
|
16968
16966
|
}
|
|
16969
16967
|
});
|
|
16968
|
+
class StructuredContentViewBase {
|
|
16969
|
+
constructor(props) {
|
|
16970
|
+
__publicField(this, "node");
|
|
16971
|
+
__publicField(this, "view");
|
|
16972
|
+
__publicField(this, "getPos");
|
|
16973
|
+
__publicField(this, "decorations");
|
|
16974
|
+
__publicField(this, "innerDecorations");
|
|
16975
|
+
__publicField(this, "editor");
|
|
16976
|
+
__publicField(this, "extension");
|
|
16977
|
+
__publicField(this, "htmlAttributes");
|
|
16978
|
+
__publicField(this, "root");
|
|
16979
|
+
__publicField(this, "isDragging", false);
|
|
16980
|
+
this.node = props.node;
|
|
16981
|
+
this.view = props.editor.view;
|
|
16982
|
+
this.getPos = props.getPos;
|
|
16983
|
+
this.decorations = props.decorations;
|
|
16984
|
+
this.innerDecorations = props.innerDecorations;
|
|
16985
|
+
this.editor = props.editor;
|
|
16986
|
+
this.extension = props.extension;
|
|
16987
|
+
this.htmlAttributes = props.htmlAttributes;
|
|
16988
|
+
this.mount(props);
|
|
16989
|
+
}
|
|
16990
|
+
mount() {
|
|
16991
|
+
return;
|
|
16992
|
+
}
|
|
16993
|
+
get dom() {
|
|
16994
|
+
return this.root;
|
|
16995
|
+
}
|
|
16996
|
+
get contentDOM() {
|
|
16997
|
+
return null;
|
|
16998
|
+
}
|
|
16999
|
+
update(node, decorations, innerDecorations) {
|
|
17000
|
+
if (node.type !== this.node.type) {
|
|
17001
|
+
return false;
|
|
17002
|
+
}
|
|
17003
|
+
this.node = node;
|
|
17004
|
+
this.decorations = decorations;
|
|
17005
|
+
this.innerDecorations = innerDecorations;
|
|
17006
|
+
this.updateHTMLAttributes();
|
|
17007
|
+
return true;
|
|
17008
|
+
}
|
|
17009
|
+
stopEvent(event) {
|
|
17010
|
+
if (!this.dom) return false;
|
|
17011
|
+
const target = event.target;
|
|
17012
|
+
const isInElement = this.dom.contains(target) && !this.contentDOM?.contains(target);
|
|
17013
|
+
if (!isInElement) return false;
|
|
17014
|
+
const isDragEvent = event.type.startsWith("drag");
|
|
17015
|
+
const isDropEvent = event.type === "drop";
|
|
17016
|
+
const isInput = ["INPUT", "BUTTON", "SELECT", "TEXTAREA"].includes(target.tagName) || target.isContentEditable;
|
|
17017
|
+
if (isInput && !isDropEvent && !isDragEvent) return true;
|
|
17018
|
+
const { isEditable } = this.editor;
|
|
17019
|
+
const { isDragging } = this;
|
|
17020
|
+
const isDraggable = !!this.node.type.spec.draggable;
|
|
17021
|
+
const isSelectable = NodeSelection.isSelectable(this.node);
|
|
17022
|
+
const isCopyEvent = event.type === "copy";
|
|
17023
|
+
const isPasteEvent = event.type === "paste";
|
|
17024
|
+
const isCutEvent = event.type === "cut";
|
|
17025
|
+
const isClickEvent = event.type === "mousedown";
|
|
17026
|
+
if (!isDraggable && isSelectable && isDragEvent && event.target === this.dom) {
|
|
17027
|
+
event.preventDefault();
|
|
17028
|
+
}
|
|
17029
|
+
if (isDraggable && isDragEvent && !isDragging && event.target === this.dom) {
|
|
17030
|
+
event.preventDefault();
|
|
17031
|
+
return false;
|
|
17032
|
+
}
|
|
17033
|
+
if (isDraggable && isEditable && !isDragging && isClickEvent) {
|
|
17034
|
+
const dragHandle = target.closest("[data-drag-handle]");
|
|
17035
|
+
const isValidDragHandle = dragHandle && (this.dom === dragHandle || this.dom.contains(dragHandle));
|
|
17036
|
+
if (isValidDragHandle) {
|
|
17037
|
+
this.isDragging = true;
|
|
17038
|
+
document.addEventListener(
|
|
17039
|
+
"dragend",
|
|
17040
|
+
() => {
|
|
17041
|
+
this.isDragging = false;
|
|
17042
|
+
},
|
|
17043
|
+
{ once: true }
|
|
17044
|
+
);
|
|
17045
|
+
document.addEventListener(
|
|
17046
|
+
"drop",
|
|
17047
|
+
() => {
|
|
17048
|
+
this.isDragging = false;
|
|
17049
|
+
},
|
|
17050
|
+
{ once: true }
|
|
17051
|
+
);
|
|
17052
|
+
document.addEventListener(
|
|
17053
|
+
"mouseup",
|
|
17054
|
+
() => {
|
|
17055
|
+
this.isDragging = false;
|
|
17056
|
+
},
|
|
17057
|
+
{ once: true }
|
|
17058
|
+
);
|
|
17059
|
+
}
|
|
17060
|
+
}
|
|
17061
|
+
if (isDragging || isDropEvent || isCopyEvent || isPasteEvent || isCutEvent || isClickEvent && isSelectable) {
|
|
17062
|
+
return false;
|
|
17063
|
+
}
|
|
17064
|
+
return true;
|
|
17065
|
+
}
|
|
17066
|
+
ignoreMutation(mutation) {
|
|
17067
|
+
if (!this.dom || !this.contentDOM) return true;
|
|
17068
|
+
if (this.node.isLeaf || this.node.isAtom) return true;
|
|
17069
|
+
if (mutation.type === "selection") return false;
|
|
17070
|
+
if (this.contentDOM === mutation.target && mutation.type === "attributes") return true;
|
|
17071
|
+
if (this.contentDOM.contains(mutation.target)) return false;
|
|
17072
|
+
return true;
|
|
17073
|
+
}
|
|
17074
|
+
destroy() {
|
|
17075
|
+
this.dom.remove();
|
|
17076
|
+
this.contentDOM?.remove();
|
|
17077
|
+
}
|
|
17078
|
+
updateAttributes(attrs) {
|
|
17079
|
+
const pos = this.getPos();
|
|
17080
|
+
if (typeof pos !== "number") {
|
|
17081
|
+
return;
|
|
17082
|
+
}
|
|
17083
|
+
return this.view.dispatch(
|
|
17084
|
+
this.view.state.tr.setNodeMarkup(pos, void 0, {
|
|
17085
|
+
...this.node.attrs,
|
|
17086
|
+
...attrs
|
|
17087
|
+
})
|
|
17088
|
+
);
|
|
17089
|
+
}
|
|
17090
|
+
updateHTMLAttributes() {
|
|
17091
|
+
const { extensionService } = this.editor;
|
|
17092
|
+
const { attributes } = extensionService;
|
|
17093
|
+
const extensionAttrs = attributes.filter((i) => i.type === this.node.type.name);
|
|
17094
|
+
this.htmlAttributes = Attribute.getAttributesToRender(this.node, extensionAttrs);
|
|
17095
|
+
}
|
|
17096
|
+
createDragHandle() {
|
|
17097
|
+
const dragHandle = document.createElement("span");
|
|
17098
|
+
dragHandle.classList.add("sd-structured-content-draggable");
|
|
17099
|
+
dragHandle.draggable = true;
|
|
17100
|
+
dragHandle.contentEditable = "false";
|
|
17101
|
+
dragHandle.dataset.dragHandle = "";
|
|
17102
|
+
const textElement = document.createElement("span");
|
|
17103
|
+
textElement.textContent = this.node.attrs.alias || "Structured content";
|
|
17104
|
+
dragHandle.append(textElement);
|
|
17105
|
+
return dragHandle;
|
|
17106
|
+
}
|
|
17107
|
+
onDragStart(event) {
|
|
17108
|
+
const { view } = this.editor;
|
|
17109
|
+
const target = event.target;
|
|
17110
|
+
const dragHandle = target.nodeType === 3 ? target.parentElement?.closest("[data-drag-handle]") : target.closest("[data-drag-handle]");
|
|
17111
|
+
if (!this.dom || this.contentDOM?.contains(target) || !dragHandle) {
|
|
17112
|
+
return;
|
|
17113
|
+
}
|
|
17114
|
+
let x = 0;
|
|
17115
|
+
let y = 0;
|
|
17116
|
+
if (this.dom !== dragHandle) {
|
|
17117
|
+
const domBox = this.dom.getBoundingClientRect();
|
|
17118
|
+
const handleBox = dragHandle.getBoundingClientRect();
|
|
17119
|
+
const offsetX = event.offsetX ?? event.nativeEvent?.offsetX;
|
|
17120
|
+
const offsetY = event.offsetY ?? event.nativeEvent?.offsetY;
|
|
17121
|
+
x = handleBox.x - domBox.x + offsetX;
|
|
17122
|
+
y = handleBox.y - domBox.y + offsetY;
|
|
17123
|
+
}
|
|
17124
|
+
event.dataTransfer?.setDragImage(this.dom, x, y);
|
|
17125
|
+
const pos = this.getPos();
|
|
17126
|
+
if (typeof pos !== "number") {
|
|
17127
|
+
return;
|
|
17128
|
+
}
|
|
17129
|
+
const selection = NodeSelection.create(view.state.doc, pos);
|
|
17130
|
+
const transaction = view.state.tr.setSelection(selection);
|
|
17131
|
+
view.dispatch(transaction);
|
|
17132
|
+
}
|
|
17133
|
+
}
|
|
17134
|
+
class StructuredContentInlineView extends StructuredContentViewBase {
|
|
17135
|
+
constructor(props) {
|
|
17136
|
+
super(props);
|
|
17137
|
+
}
|
|
17138
|
+
mount() {
|
|
17139
|
+
this.buildView();
|
|
17140
|
+
}
|
|
17141
|
+
get contentDOM() {
|
|
17142
|
+
const contentElement = this.dom?.querySelector(`.${structuredContentInnerClass$1}`);
|
|
17143
|
+
return contentElement || null;
|
|
17144
|
+
}
|
|
17145
|
+
createElement() {
|
|
17146
|
+
const element = document.createElement("span");
|
|
17147
|
+
element.classList.add(structuredContentClass$1);
|
|
17148
|
+
element.setAttribute("data-structured-content", "");
|
|
17149
|
+
const contentElement = document.createElement("span");
|
|
17150
|
+
contentElement.classList.add(structuredContentInnerClass$1);
|
|
17151
|
+
element.append(contentElement);
|
|
17152
|
+
const domAttrs = Attribute.mergeAttributes(this.htmlAttributes);
|
|
17153
|
+
updateDOMAttributes(element, { ...domAttrs });
|
|
17154
|
+
return { element, contentElement };
|
|
17155
|
+
}
|
|
17156
|
+
buildView() {
|
|
17157
|
+
const { element } = this.createElement();
|
|
17158
|
+
const dragHandle = this.createDragHandle();
|
|
17159
|
+
element.prepend(dragHandle);
|
|
17160
|
+
element.addEventListener("dragstart", (e) => this.onDragStart(e));
|
|
17161
|
+
this.root = element;
|
|
17162
|
+
}
|
|
17163
|
+
updateView() {
|
|
17164
|
+
const domAttrs = Attribute.mergeAttributes(this.htmlAttributes);
|
|
17165
|
+
updateDOMAttributes(this.dom, { ...domAttrs });
|
|
17166
|
+
}
|
|
17167
|
+
update(node, decorations, innerDecorations) {
|
|
17168
|
+
const result = super.update(node, decorations, innerDecorations);
|
|
17169
|
+
if (!result) return false;
|
|
17170
|
+
this.updateView();
|
|
17171
|
+
return true;
|
|
17172
|
+
}
|
|
17173
|
+
}
|
|
17174
|
+
const structuredContentClass$1 = "sd-structured-content";
|
|
17175
|
+
const structuredContentInnerClass$1 = "sd-structured-content__content";
|
|
17176
|
+
const StructuredContent = Node$1.create({
|
|
17177
|
+
name: "structuredContent",
|
|
17178
|
+
group: "inline structuredContent",
|
|
17179
|
+
inline: true,
|
|
17180
|
+
content: "inline*",
|
|
17181
|
+
isolating: true,
|
|
17182
|
+
atom: false,
|
|
17183
|
+
// false - has editable content.
|
|
17184
|
+
draggable: true,
|
|
17185
|
+
addOptions() {
|
|
17186
|
+
return {
|
|
17187
|
+
htmlAttributes: {
|
|
17188
|
+
class: structuredContentClass$1,
|
|
17189
|
+
"aria-label": "Structured content node"
|
|
17190
|
+
}
|
|
17191
|
+
};
|
|
17192
|
+
},
|
|
17193
|
+
addAttributes() {
|
|
17194
|
+
return {
|
|
17195
|
+
id: {
|
|
17196
|
+
default: null,
|
|
17197
|
+
parseDOM: (elem) => elem.getAttribute("data-id"),
|
|
17198
|
+
renderDOM: (attrs) => {
|
|
17199
|
+
if (!attrs.id) return {};
|
|
17200
|
+
return { "data-id": attrs.id };
|
|
17201
|
+
}
|
|
17202
|
+
},
|
|
17203
|
+
tag: {
|
|
17204
|
+
default: null,
|
|
17205
|
+
parseDOM: (elem) => elem.getAttribute("data-tag"),
|
|
17206
|
+
renderDOM: (attrs) => {
|
|
17207
|
+
if (!attrs.tag) return {};
|
|
17208
|
+
return { "data-tag": attrs.tag };
|
|
17209
|
+
}
|
|
17210
|
+
},
|
|
17211
|
+
alias: {
|
|
17212
|
+
default: null,
|
|
17213
|
+
parseDOM: (elem) => elem.getAttribute("data-alias"),
|
|
17214
|
+
renderDOM: (attrs) => {
|
|
17215
|
+
if (!attrs.alias) return {};
|
|
17216
|
+
return { "data-alias": attrs.alias };
|
|
17217
|
+
}
|
|
17218
|
+
},
|
|
17219
|
+
sdtPr: {
|
|
17220
|
+
rendered: false
|
|
17221
|
+
}
|
|
17222
|
+
};
|
|
17223
|
+
},
|
|
17224
|
+
parseDOM() {
|
|
17225
|
+
return [{ tag: "span[data-structured-content]" }];
|
|
17226
|
+
},
|
|
17227
|
+
renderDOM({ htmlAttributes }) {
|
|
17228
|
+
return [
|
|
17229
|
+
"span",
|
|
17230
|
+
Attribute.mergeAttributes(this.options.htmlAttributes, htmlAttributes, {
|
|
17231
|
+
"data-structured-content": ""
|
|
17232
|
+
}),
|
|
17233
|
+
0
|
|
17234
|
+
];
|
|
17235
|
+
},
|
|
17236
|
+
addNodeView() {
|
|
17237
|
+
return (props) => {
|
|
17238
|
+
return new StructuredContentInlineView({ ...props });
|
|
17239
|
+
};
|
|
17240
|
+
}
|
|
17241
|
+
});
|
|
17242
|
+
class StructuredContentBlockView extends StructuredContentViewBase {
|
|
17243
|
+
constructor(props) {
|
|
17244
|
+
super(props);
|
|
17245
|
+
}
|
|
17246
|
+
mount() {
|
|
17247
|
+
this.buildView();
|
|
17248
|
+
}
|
|
17249
|
+
get contentDOM() {
|
|
17250
|
+
const contentElement = this.dom?.querySelector(`.${structuredContentInnerClass}`);
|
|
17251
|
+
return contentElement || null;
|
|
17252
|
+
}
|
|
17253
|
+
createElement() {
|
|
17254
|
+
const element = document.createElement("div");
|
|
17255
|
+
element.classList.add(structuredContentClass);
|
|
17256
|
+
element.setAttribute("data-structured-content-block", "");
|
|
17257
|
+
const contentElement = document.createElement("div");
|
|
17258
|
+
contentElement.classList.add(structuredContentInnerClass);
|
|
17259
|
+
element.append(contentElement);
|
|
17260
|
+
const domAttrs = Attribute.mergeAttributes(this.htmlAttributes);
|
|
17261
|
+
updateDOMAttributes(element, { ...domAttrs });
|
|
17262
|
+
return { element, contentElement };
|
|
17263
|
+
}
|
|
17264
|
+
buildView() {
|
|
17265
|
+
const { element } = this.createElement();
|
|
17266
|
+
const dragHandle = this.createDragHandle();
|
|
17267
|
+
element.prepend(dragHandle);
|
|
17268
|
+
element.addEventListener("dragstart", (e) => this.onDragStart(e));
|
|
17269
|
+
this.root = element;
|
|
17270
|
+
}
|
|
17271
|
+
updateView() {
|
|
17272
|
+
const domAttrs = Attribute.mergeAttributes(this.htmlAttributes);
|
|
17273
|
+
updateDOMAttributes(this.dom, { ...domAttrs });
|
|
17274
|
+
}
|
|
17275
|
+
update(node, decorations, innerDecorations) {
|
|
17276
|
+
const result = super.update(node, decorations, innerDecorations);
|
|
17277
|
+
if (!result) return false;
|
|
17278
|
+
this.updateView();
|
|
17279
|
+
return true;
|
|
17280
|
+
}
|
|
17281
|
+
}
|
|
17282
|
+
const structuredContentClass = "sd-structured-content-block";
|
|
17283
|
+
const structuredContentInnerClass = "sd-structured-content-block__content";
|
|
17284
|
+
const StructuredContentBlock = Node$1.create({
|
|
17285
|
+
name: "structuredContentBlock",
|
|
17286
|
+
group: "block structuredContent",
|
|
17287
|
+
content: "block*",
|
|
17288
|
+
isolating: true,
|
|
17289
|
+
atom: false,
|
|
17290
|
+
// false - has editable content.
|
|
17291
|
+
draggable: true,
|
|
17292
|
+
addOptions() {
|
|
17293
|
+
return {
|
|
17294
|
+
htmlAttributes: {
|
|
17295
|
+
class: structuredContentClass,
|
|
17296
|
+
"aria-label": "Structured content block node"
|
|
17297
|
+
}
|
|
17298
|
+
};
|
|
17299
|
+
},
|
|
17300
|
+
addAttributes() {
|
|
17301
|
+
return {
|
|
17302
|
+
id: {
|
|
17303
|
+
default: null,
|
|
17304
|
+
parseDOM: (elem) => elem.getAttribute("data-id"),
|
|
17305
|
+
renderDOM: (attrs) => {
|
|
17306
|
+
if (!attrs.id) return {};
|
|
17307
|
+
return { "data-id": attrs.id };
|
|
17308
|
+
}
|
|
17309
|
+
},
|
|
17310
|
+
tag: {
|
|
17311
|
+
default: null,
|
|
17312
|
+
parseDOM: (elem) => elem.getAttribute("data-tag"),
|
|
17313
|
+
renderDOM: (attrs) => {
|
|
17314
|
+
if (!attrs.tag) return {};
|
|
17315
|
+
return { "data-tag": attrs.tag };
|
|
17316
|
+
}
|
|
17317
|
+
},
|
|
17318
|
+
alias: {
|
|
17319
|
+
default: null,
|
|
17320
|
+
parseDOM: (elem) => elem.getAttribute("data-alias"),
|
|
17321
|
+
renderDOM: (attrs) => {
|
|
17322
|
+
if (!attrs.alias) return {};
|
|
17323
|
+
return { "data-alias": attrs.alias };
|
|
17324
|
+
}
|
|
17325
|
+
},
|
|
17326
|
+
sdtPr: {
|
|
17327
|
+
rendered: false
|
|
17328
|
+
}
|
|
17329
|
+
};
|
|
17330
|
+
},
|
|
17331
|
+
parseDOM() {
|
|
17332
|
+
return [{ tag: "div[data-structured-content-block]" }];
|
|
17333
|
+
},
|
|
17334
|
+
renderDOM({ htmlAttributes }) {
|
|
17335
|
+
return [
|
|
17336
|
+
"div",
|
|
17337
|
+
Attribute.mergeAttributes(this.options.htmlAttributes, htmlAttributes, {
|
|
17338
|
+
"data-structured-content-block": ""
|
|
17339
|
+
}),
|
|
17340
|
+
0
|
|
17341
|
+
];
|
|
17342
|
+
},
|
|
17343
|
+
addNodeView() {
|
|
17344
|
+
return (props) => {
|
|
17345
|
+
return new StructuredContentBlockView({ ...props });
|
|
17346
|
+
};
|
|
17347
|
+
}
|
|
17348
|
+
});
|
|
17349
|
+
function getStructuredContentTagsById(idOrIds, state) {
|
|
17350
|
+
const result = findChildren$5(state.doc, (node) => {
|
|
17351
|
+
const isStructuredContent = ["structuredContent", "structuredContentBlock"].includes(node.type.name);
|
|
17352
|
+
if (Array.isArray(idOrIds)) {
|
|
17353
|
+
return isStructuredContent && idOrIds.includes(node.attrs.id);
|
|
17354
|
+
} else {
|
|
17355
|
+
return isStructuredContent && node.attrs.id === idOrIds;
|
|
17356
|
+
}
|
|
17357
|
+
});
|
|
17358
|
+
return result;
|
|
17359
|
+
}
|
|
17360
|
+
function getStructuredContentTags(state) {
|
|
17361
|
+
const result = findChildren$5(state.doc, (node) => {
|
|
17362
|
+
return node.type.name === "structuredContent" || node.type.name === "structuredContentBlock";
|
|
17363
|
+
});
|
|
17364
|
+
return result;
|
|
17365
|
+
}
|
|
17366
|
+
function getStructuredContentInlineTags(state) {
|
|
17367
|
+
const result = findChildren$5(state.doc, (node) => node.type.name === "structuredContent");
|
|
17368
|
+
return result;
|
|
17369
|
+
}
|
|
17370
|
+
function getStructuredContentBlockTags(state) {
|
|
17371
|
+
const result = findChildren$5(state.doc, (node) => node.type.name === "structuredContentBlock");
|
|
17372
|
+
return result;
|
|
17373
|
+
}
|
|
17374
|
+
const structuredContentHelpers = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
17375
|
+
__proto__: null,
|
|
17376
|
+
getStructuredContentBlockTags,
|
|
17377
|
+
getStructuredContentInlineTags,
|
|
17378
|
+
getStructuredContentTags,
|
|
17379
|
+
getStructuredContentTagsById
|
|
17380
|
+
}, Symbol.toStringTag, { value: "Module" }));
|
|
17381
|
+
const STRUCTURED_CONTENT_NAMES = ["structuredContent", "structuredContentBlock"];
|
|
17382
|
+
const StructuredContentCommands = Extension.create({
|
|
17383
|
+
name: "structuredContentCommands",
|
|
17384
|
+
addCommands() {
|
|
17385
|
+
return {
|
|
17386
|
+
/**
|
|
17387
|
+
* Inserts a structured content inline at selection.
|
|
17388
|
+
* @category Command
|
|
17389
|
+
* @param {StructuredContentInlineInsert} options
|
|
17390
|
+
*/
|
|
17391
|
+
insertStructuredContentInline: (options = {}) => ({ editor, dispatch, state, tr }) => {
|
|
17392
|
+
const { schema } = editor;
|
|
17393
|
+
let { from: from2, to } = state.selection;
|
|
17394
|
+
if (dispatch) {
|
|
17395
|
+
const selectionText = state.doc.textBetween(from2, to);
|
|
17396
|
+
let content = null;
|
|
17397
|
+
if (selectionText) {
|
|
17398
|
+
content = schema.text(selectionText);
|
|
17399
|
+
}
|
|
17400
|
+
if (options.text) {
|
|
17401
|
+
content = schema.text(options.text);
|
|
17402
|
+
}
|
|
17403
|
+
if (options.json) {
|
|
17404
|
+
content = schema.nodeFromJSON(options.json);
|
|
17405
|
+
}
|
|
17406
|
+
if (!content) {
|
|
17407
|
+
content = schema.text(" ");
|
|
17408
|
+
}
|
|
17409
|
+
const attrs = {
|
|
17410
|
+
...options.attrs,
|
|
17411
|
+
id: options.attrs?.id || generateRandomSigned32BitIntStrId(),
|
|
17412
|
+
tag: "inline_text_sdt",
|
|
17413
|
+
alias: options.attrs?.alias || "Structured content"
|
|
17414
|
+
};
|
|
17415
|
+
const node = schema.nodes.structuredContent.create(attrs, content, null);
|
|
17416
|
+
const parent = findParentNode((node2) => node2.type.name === "structuredContent")(state.selection);
|
|
17417
|
+
if (parent) {
|
|
17418
|
+
const insertPos = parent.pos + parent.node.nodeSize;
|
|
17419
|
+
from2 = to = insertPos;
|
|
17420
|
+
}
|
|
17421
|
+
tr.replaceWith(from2, to, node);
|
|
17422
|
+
}
|
|
17423
|
+
return true;
|
|
17424
|
+
},
|
|
17425
|
+
/**
|
|
17426
|
+
* Inserts a structured content block at selection.
|
|
17427
|
+
* @category Command
|
|
17428
|
+
* @param {StructuredContentBlockInsert} options
|
|
17429
|
+
*/
|
|
17430
|
+
insertStructuredContentBlock: (options = {}) => ({ editor, dispatch, state, tr }) => {
|
|
17431
|
+
const { schema } = editor;
|
|
17432
|
+
let { from: from2, to } = state.selection;
|
|
17433
|
+
if (dispatch) {
|
|
17434
|
+
const selectionContent = state.selection.content();
|
|
17435
|
+
let content = null;
|
|
17436
|
+
if (selectionContent.size) {
|
|
17437
|
+
content = selectionContent.content;
|
|
17438
|
+
}
|
|
17439
|
+
if (options.html) {
|
|
17440
|
+
const html = htmlHandler(options.html, editor);
|
|
17441
|
+
const doc2 = DOMParser$1.fromSchema(schema).parse(html);
|
|
17442
|
+
content = doc2.content;
|
|
17443
|
+
}
|
|
17444
|
+
if (options.json) {
|
|
17445
|
+
content = schema.nodeFromJSON(options.json);
|
|
17446
|
+
}
|
|
17447
|
+
if (!content) {
|
|
17448
|
+
content = schema.nodeFromJSON({ type: "paragraph", content: [] });
|
|
17449
|
+
}
|
|
17450
|
+
const attrs = {
|
|
17451
|
+
...options.attrs,
|
|
17452
|
+
id: options.attrs?.id || generateRandomSigned32BitIntStrId(),
|
|
17453
|
+
tag: "block_table_sdt",
|
|
17454
|
+
alias: options.attrs?.alias || "Structured content"
|
|
17455
|
+
};
|
|
17456
|
+
const node = schema.nodes.structuredContentBlock.create(attrs, content, null);
|
|
17457
|
+
const parent = findParentNode((node2) => node2.type.name === "structuredContentBlock")(state.selection);
|
|
17458
|
+
if (parent) {
|
|
17459
|
+
const insertPos = parent.pos + parent.node.nodeSize;
|
|
17460
|
+
from2 = to = insertPos;
|
|
17461
|
+
}
|
|
17462
|
+
tr.replaceRangeWith(from2, to, node);
|
|
17463
|
+
}
|
|
17464
|
+
return true;
|
|
17465
|
+
},
|
|
17466
|
+
/**
|
|
17467
|
+
* Updates a structured content attributes or content.
|
|
17468
|
+
* If the updated node does not match the schema, it will not be updated.
|
|
17469
|
+
* @category Command
|
|
17470
|
+
* @param {string} id
|
|
17471
|
+
* @param {StructuredContentUpdate} options
|
|
17472
|
+
*/
|
|
17473
|
+
updateStructuredContentById: (id, options = {}) => ({ editor, dispatch, state, tr }) => {
|
|
17474
|
+
const structuredContentTags = getStructuredContentTagsById(id, state);
|
|
17475
|
+
if (!structuredContentTags.length) {
|
|
17476
|
+
return true;
|
|
17477
|
+
}
|
|
17478
|
+
const { schema } = editor;
|
|
17479
|
+
if (dispatch) {
|
|
17480
|
+
const structuredContent = structuredContentTags[0];
|
|
17481
|
+
const { pos, node } = structuredContent;
|
|
17482
|
+
const posFrom = pos;
|
|
17483
|
+
const posTo = pos + node.nodeSize;
|
|
17484
|
+
let content = null;
|
|
17485
|
+
if (options.text) {
|
|
17486
|
+
content = schema.text(options.text);
|
|
17487
|
+
}
|
|
17488
|
+
if (options.html) {
|
|
17489
|
+
const html = htmlHandler(options.html, editor);
|
|
17490
|
+
const doc2 = DOMParser$1.fromSchema(schema).parse(html);
|
|
17491
|
+
content = doc2.content;
|
|
17492
|
+
}
|
|
17493
|
+
if (options.json) {
|
|
17494
|
+
content = schema.nodeFromJSON(options.json);
|
|
17495
|
+
}
|
|
17496
|
+
if (!content) {
|
|
17497
|
+
content = node.content;
|
|
17498
|
+
}
|
|
17499
|
+
const updatedNode = node.type.create({ ...node.attrs, ...options.attrs }, content, node.marks);
|
|
17500
|
+
try {
|
|
17501
|
+
updatedNode.check();
|
|
17502
|
+
} catch {
|
|
17503
|
+
console.error("Updated node does not conform to the schema");
|
|
17504
|
+
return false;
|
|
17505
|
+
}
|
|
17506
|
+
tr.replaceWith(posFrom, posTo, updatedNode);
|
|
17507
|
+
}
|
|
17508
|
+
return true;
|
|
17509
|
+
},
|
|
17510
|
+
/**
|
|
17511
|
+
* Removes a structured content.
|
|
17512
|
+
* @category Command
|
|
17513
|
+
* @param {Array<{ node: Node, pos: number }>} structuredContentTags
|
|
17514
|
+
*/
|
|
17515
|
+
deleteStructuredContent: (structuredContentTags) => ({ dispatch, tr }) => {
|
|
17516
|
+
if (!structuredContentTags.length) {
|
|
17517
|
+
return true;
|
|
17518
|
+
}
|
|
17519
|
+
if (dispatch) {
|
|
17520
|
+
structuredContentTags.forEach((structuredContent) => {
|
|
17521
|
+
const { pos, node } = structuredContent;
|
|
17522
|
+
const posFrom = tr.mapping.map(pos);
|
|
17523
|
+
const posTo = tr.mapping.map(pos + node.nodeSize);
|
|
17524
|
+
const currentNode = tr.doc.nodeAt(posFrom);
|
|
17525
|
+
if (currentNode && node.eq(currentNode)) {
|
|
17526
|
+
tr.delete(posFrom, posTo);
|
|
17527
|
+
}
|
|
17528
|
+
});
|
|
17529
|
+
}
|
|
17530
|
+
return true;
|
|
17531
|
+
},
|
|
17532
|
+
/**
|
|
17533
|
+
* Removes a structured content by ID.
|
|
17534
|
+
* @category Command
|
|
17535
|
+
* @param {string | string[]} idOrIds
|
|
17536
|
+
*/
|
|
17537
|
+
deleteStructuredContentById: (idOrIds) => ({ dispatch, state, tr }) => {
|
|
17538
|
+
const structuredContentTags = getStructuredContentTagsById(idOrIds, state);
|
|
17539
|
+
if (!structuredContentTags.length) {
|
|
17540
|
+
return true;
|
|
17541
|
+
}
|
|
17542
|
+
if (dispatch) {
|
|
17543
|
+
structuredContentTags.forEach((structuredContent) => {
|
|
17544
|
+
const { pos, node } = structuredContent;
|
|
17545
|
+
const posFrom = tr.mapping.map(pos);
|
|
17546
|
+
const posTo = tr.mapping.map(pos + node.nodeSize);
|
|
17547
|
+
const currentNode = tr.doc.nodeAt(posFrom);
|
|
17548
|
+
if (currentNode && node.eq(currentNode)) {
|
|
17549
|
+
tr.delete(posFrom, posTo);
|
|
17550
|
+
}
|
|
17551
|
+
});
|
|
17552
|
+
}
|
|
17553
|
+
return true;
|
|
17554
|
+
},
|
|
17555
|
+
/**
|
|
17556
|
+
* Removes a structured content at cursor, preserving its content.
|
|
17557
|
+
* @category Command
|
|
17558
|
+
*/
|
|
17559
|
+
deleteStructuredContentAtSelection: () => ({ dispatch, state, tr }) => {
|
|
17560
|
+
const predicate = (node) => STRUCTURED_CONTENT_NAMES.includes(node.type.name);
|
|
17561
|
+
const structuredContent = findParentNode(predicate)(state.selection);
|
|
17562
|
+
if (!structuredContent) {
|
|
17563
|
+
return true;
|
|
17564
|
+
}
|
|
17565
|
+
if (dispatch) {
|
|
17566
|
+
const { node, pos } = structuredContent;
|
|
17567
|
+
const posFrom = pos;
|
|
17568
|
+
const posTo = posFrom + node.nodeSize;
|
|
17569
|
+
const content = node.content;
|
|
17570
|
+
tr.replaceWith(posFrom, posTo, content);
|
|
17571
|
+
}
|
|
17572
|
+
return true;
|
|
17573
|
+
}
|
|
17574
|
+
};
|
|
17575
|
+
},
|
|
17576
|
+
addHelpers() {
|
|
17577
|
+
return {
|
|
17578
|
+
...structuredContentHelpers
|
|
17579
|
+
};
|
|
17580
|
+
}
|
|
17581
|
+
});
|
|
17582
|
+
class DocumentSectionView {
|
|
17583
|
+
constructor(node, getPos, decorations, editor) {
|
|
17584
|
+
__privateAdd(this, _DocumentSectionView_instances);
|
|
17585
|
+
this.node = node;
|
|
17586
|
+
this.editor = editor;
|
|
17587
|
+
this.decorations = decorations;
|
|
17588
|
+
this.view = editor.view;
|
|
17589
|
+
this.getPos = getPos;
|
|
17590
|
+
__privateMethod(this, _DocumentSectionView_instances, init_fn2).call(this);
|
|
17591
|
+
}
|
|
17592
|
+
}
|
|
17593
|
+
_DocumentSectionView_instances = new WeakSet();
|
|
17594
|
+
init_fn2 = function() {
|
|
17595
|
+
const { attrs } = this.node;
|
|
17596
|
+
const { id, title, description } = attrs;
|
|
17597
|
+
this.dom = document.createElement("div");
|
|
17598
|
+
this.dom.className = "sd-document-section-block";
|
|
17599
|
+
this.dom.setAttribute("data-id", id);
|
|
17600
|
+
this.dom.setAttribute("data-title", title);
|
|
17601
|
+
this.dom.setAttribute("data-description", description);
|
|
17602
|
+
this.dom.setAttribute("aria-label", "Document section");
|
|
17603
|
+
__privateMethod(this, _DocumentSectionView_instances, addToolTip_fn).call(this);
|
|
17604
|
+
this.contentDOM = document.createElement("div");
|
|
17605
|
+
this.contentDOM.className = "sd-document-section-block-content";
|
|
17606
|
+
this.contentDOM.setAttribute("contenteditable", "true");
|
|
17607
|
+
this.dom.appendChild(this.contentDOM);
|
|
17608
|
+
};
|
|
17609
|
+
addToolTip_fn = function() {
|
|
17610
|
+
const { title } = this.node.attrs;
|
|
17611
|
+
this.infoDiv = document.createElement("div");
|
|
17612
|
+
this.infoDiv.className = "sd-document-section-block-info";
|
|
17613
|
+
const textSpan = document.createElement("span");
|
|
17614
|
+
textSpan.textContent = title || "Document section";
|
|
17615
|
+
this.infoDiv.appendChild(textSpan);
|
|
17616
|
+
this.infoDiv.setAttribute("contenteditable", "false");
|
|
17617
|
+
this.dom.appendChild(this.infoDiv);
|
|
17618
|
+
};
|
|
17619
|
+
const getAllSections = (editor) => {
|
|
17620
|
+
if (!editor) return [];
|
|
17621
|
+
const type = editor.schema.nodes.documentSection;
|
|
17622
|
+
if (!type) return [];
|
|
17623
|
+
const sections = [];
|
|
17624
|
+
const { state } = editor;
|
|
17625
|
+
state.doc.descendants((node, pos) => {
|
|
17626
|
+
if (node.type.name === type.name) {
|
|
17627
|
+
sections.push({ node, pos });
|
|
17628
|
+
}
|
|
17629
|
+
});
|
|
17630
|
+
return sections;
|
|
17631
|
+
};
|
|
17632
|
+
const exportSectionsToHTML = (editor) => {
|
|
17633
|
+
const sections = getAllSections(editor);
|
|
17634
|
+
const processedSections = /* @__PURE__ */ new Set();
|
|
17635
|
+
const result = [];
|
|
17636
|
+
sections.forEach(({ node }) => {
|
|
17637
|
+
const { attrs } = node;
|
|
17638
|
+
const { id, title, description } = attrs;
|
|
17639
|
+
if (processedSections.has(id)) return;
|
|
17640
|
+
processedSections.add(id);
|
|
17641
|
+
const html = getHTMLFromNode(node, editor);
|
|
17642
|
+
result.push({
|
|
17643
|
+
id,
|
|
17644
|
+
title,
|
|
17645
|
+
description,
|
|
17646
|
+
html
|
|
17647
|
+
});
|
|
17648
|
+
});
|
|
17649
|
+
return result;
|
|
17650
|
+
};
|
|
17651
|
+
const getHTMLFromNode = (node, editor) => {
|
|
17652
|
+
const tempDocument = document.implementation.createHTMLDocument();
|
|
17653
|
+
const container = tempDocument.createElement("div");
|
|
17654
|
+
const fragment = DOMSerializer.fromSchema(editor.schema).serializeFragment(node.content);
|
|
17655
|
+
container.appendChild(fragment);
|
|
17656
|
+
let html = container.innerHTML;
|
|
17657
|
+
return html;
|
|
17658
|
+
};
|
|
17659
|
+
const exportSectionsToJSON = (editor) => {
|
|
17660
|
+
const sections = getAllSections(editor);
|
|
17661
|
+
const processedSections = /* @__PURE__ */ new Set();
|
|
17662
|
+
const result = [];
|
|
17663
|
+
sections.forEach(({ node }) => {
|
|
17664
|
+
const { attrs } = node;
|
|
17665
|
+
const { id, title, description } = attrs;
|
|
17666
|
+
if (processedSections.has(id)) return;
|
|
17667
|
+
processedSections.add(id);
|
|
17668
|
+
result.push({
|
|
17669
|
+
id,
|
|
17670
|
+
title,
|
|
17671
|
+
description,
|
|
17672
|
+
content: node.toJSON()
|
|
17673
|
+
});
|
|
17674
|
+
});
|
|
17675
|
+
return result;
|
|
17676
|
+
};
|
|
17677
|
+
const getLinkedSectionEditor = (id, options, editor) => {
|
|
17678
|
+
const sections = getAllSections(editor);
|
|
17679
|
+
const section = sections.find((s) => s.node.attrs.id === id);
|
|
17680
|
+
if (!section) return null;
|
|
17681
|
+
const child = editor.createChildEditor({
|
|
17682
|
+
...options,
|
|
17683
|
+
onUpdate: ({ editor: childEditor, transaction }) => {
|
|
17684
|
+
const isFromtLinkedParent = transaction.getMeta("fromLinkedParent");
|
|
17685
|
+
if (isFromtLinkedParent) return;
|
|
17686
|
+
const updatedContent = childEditor.state.doc.content;
|
|
17687
|
+
const sectionNode = getAllSections(editor)?.find((s) => s.node.attrs.id === id);
|
|
17688
|
+
if (!sectionNode) return;
|
|
17689
|
+
const { pos, node } = sectionNode;
|
|
17690
|
+
const newNode = node.type.create(node.attrs, updatedContent, node.marks);
|
|
17691
|
+
const tr = editor.state.tr.replaceWith(pos, pos + node.nodeSize, newNode);
|
|
17692
|
+
tr.setMeta("fromLinkedChild", true);
|
|
17693
|
+
editor.view.dispatch(tr);
|
|
17694
|
+
}
|
|
17695
|
+
});
|
|
17696
|
+
editor.on("update", ({ transaction }) => {
|
|
17697
|
+
const isFromLinkedChild = transaction.getMeta("fromLinkedChild");
|
|
17698
|
+
if (isFromLinkedChild) return;
|
|
17699
|
+
const sectionNode = getAllSections(editor)?.find((s) => s.node.attrs.id === id);
|
|
17700
|
+
if (!sectionNode) return;
|
|
17701
|
+
const sectionContent = sectionNode.node.content;
|
|
17702
|
+
const json = {
|
|
17703
|
+
type: "doc",
|
|
17704
|
+
content: sectionContent.content.map((node) => node.toJSON())
|
|
17705
|
+
};
|
|
17706
|
+
const childTr = child.state.tr;
|
|
17707
|
+
childTr.setMeta("fromLinkedParent", true);
|
|
17708
|
+
childTr.replaceWith(0, child.state.doc.content.size, child.schema.nodeFromJSON(json));
|
|
17709
|
+
child.view.dispatch(childTr);
|
|
17710
|
+
});
|
|
17711
|
+
return child;
|
|
17712
|
+
};
|
|
17713
|
+
const SectionHelpers = {
|
|
17714
|
+
getAllSections,
|
|
17715
|
+
exportSectionsToHTML,
|
|
17716
|
+
exportSectionsToJSON,
|
|
17717
|
+
getLinkedSectionEditor
|
|
17718
|
+
};
|
|
17719
|
+
const DocumentSection = Node$1.create({
|
|
17720
|
+
name: "documentSection",
|
|
17721
|
+
group: "block",
|
|
17722
|
+
content: "block*",
|
|
17723
|
+
atom: true,
|
|
17724
|
+
isolating: true,
|
|
17725
|
+
addOptions() {
|
|
17726
|
+
return {
|
|
17727
|
+
htmlAttributes: {
|
|
17728
|
+
class: "sd-document-section-block",
|
|
17729
|
+
"aria-label": "Structured content block"
|
|
17730
|
+
}
|
|
17731
|
+
};
|
|
17732
|
+
},
|
|
17733
|
+
parseDOM() {
|
|
17734
|
+
return [
|
|
17735
|
+
{
|
|
17736
|
+
tag: "div.sd-document-section-block",
|
|
17737
|
+
priority: 60
|
|
17738
|
+
}
|
|
17739
|
+
];
|
|
17740
|
+
},
|
|
17741
|
+
renderDOM({ htmlAttributes }) {
|
|
17742
|
+
return ["div", Attribute.mergeAttributes(this.options.htmlAttributes, htmlAttributes), 0];
|
|
17743
|
+
},
|
|
17744
|
+
addAttributes() {
|
|
17745
|
+
return {
|
|
17746
|
+
id: {},
|
|
17747
|
+
sdBlockId: {
|
|
17748
|
+
default: null,
|
|
17749
|
+
keepOnSplit: false,
|
|
17750
|
+
parseDOM: (elem) => elem.getAttribute("data-sd-block-id"),
|
|
17751
|
+
renderDOM: (attrs) => {
|
|
17752
|
+
return attrs.sdBlockId ? { "data-sd-block-id": attrs.sdBlockId } : {};
|
|
17753
|
+
}
|
|
17754
|
+
},
|
|
17755
|
+
title: {},
|
|
17756
|
+
description: {},
|
|
17757
|
+
sectionType: {},
|
|
17758
|
+
isLocked: { default: false }
|
|
17759
|
+
};
|
|
17760
|
+
},
|
|
17761
|
+
addNodeView() {
|
|
17762
|
+
return ({ node, editor, getPos, decorations }) => {
|
|
17763
|
+
return new DocumentSectionView(node, getPos, decorations, editor);
|
|
17764
|
+
};
|
|
17765
|
+
},
|
|
17766
|
+
addCommands() {
|
|
17767
|
+
return {
|
|
17768
|
+
/**
|
|
17769
|
+
* Create a lockable content section
|
|
17770
|
+
* @category Command
|
|
17771
|
+
* @param {SectionCreate} [options={}] - Section configuration
|
|
17772
|
+
* @example
|
|
17773
|
+
* editor.commands.createDocumentSection({
|
|
17774
|
+
* id: 1,
|
|
17775
|
+
* title: 'Terms & Conditions',
|
|
17776
|
+
* isLocked: true,
|
|
17777
|
+
* html: '<p>Legal content...</p>'
|
|
17778
|
+
* })
|
|
17779
|
+
*/
|
|
17780
|
+
createDocumentSection: (options = {}) => ({ tr, state, dispatch, editor }) => {
|
|
17781
|
+
const { selection } = state;
|
|
17782
|
+
let { from: from2, to } = selection;
|
|
17783
|
+
let content = selection.content().content;
|
|
17784
|
+
const { html: optionsHTML, json: optionsJSON } = options;
|
|
17785
|
+
if (optionsHTML) {
|
|
17786
|
+
const html = htmlHandler(optionsHTML, this.editor);
|
|
17787
|
+
const doc2 = DOMParser$1.fromSchema(this.editor.schema).parse(html);
|
|
17788
|
+
content = doc2.content;
|
|
17789
|
+
}
|
|
17790
|
+
if (optionsJSON) {
|
|
17791
|
+
content = this.editor.schema.nodeFromJSON(optionsJSON);
|
|
17792
|
+
}
|
|
17793
|
+
if (!content?.content?.length) {
|
|
17794
|
+
content = this.editor.schema.nodeFromJSON({ type: "paragraph", content: [] });
|
|
17795
|
+
}
|
|
17796
|
+
if (!options.id) {
|
|
17797
|
+
const allSections = SectionHelpers.getAllSections(editor);
|
|
17798
|
+
options.id = allSections.length + 1;
|
|
17799
|
+
}
|
|
17800
|
+
if (!options.title) {
|
|
17801
|
+
options.title = "Document section";
|
|
17802
|
+
}
|
|
17803
|
+
const node = this.type.createAndFill(options, content);
|
|
17804
|
+
if (!node) return false;
|
|
17805
|
+
const isAlreadyInSdtBlock = findParentNode((node2) => node2.type.name === "documentSection")(selection);
|
|
17806
|
+
if (isAlreadyInSdtBlock && isAlreadyInSdtBlock.node) {
|
|
17807
|
+
const insertPos2 = isAlreadyInSdtBlock.pos + isAlreadyInSdtBlock.node.nodeSize;
|
|
17808
|
+
from2 = insertPos2;
|
|
17809
|
+
to = insertPos2;
|
|
17810
|
+
}
|
|
17811
|
+
tr.replaceRangeWith(from2, to, node);
|
|
17812
|
+
const nodeEnd = from2 + node.nodeSize;
|
|
17813
|
+
let shouldInsertParagraph = true;
|
|
17814
|
+
let insertPos = nodeEnd;
|
|
17815
|
+
if (nodeEnd >= tr.doc.content.size) {
|
|
17816
|
+
insertPos = tr.doc.content.size;
|
|
17817
|
+
if (insertPos > 0) {
|
|
17818
|
+
const $endPos = tr.doc.resolve(insertPos);
|
|
17819
|
+
if ($endPos.nodeBefore && $endPos.nodeBefore.type.name === "paragraph") {
|
|
17820
|
+
shouldInsertParagraph = false;
|
|
17821
|
+
}
|
|
17822
|
+
}
|
|
17823
|
+
}
|
|
17824
|
+
if (shouldInsertParagraph) {
|
|
17825
|
+
const emptyParagraph = tr.doc.type.schema.nodes.paragraph.create();
|
|
17826
|
+
tr.insert(insertPos, emptyParagraph);
|
|
17827
|
+
}
|
|
17828
|
+
if (dispatch) {
|
|
17829
|
+
tr.setMeta("documentSection", { action: "create" });
|
|
17830
|
+
dispatch(tr);
|
|
17831
|
+
setTimeout(() => {
|
|
17832
|
+
try {
|
|
17833
|
+
const currentState = editor.state;
|
|
17834
|
+
const docSize = currentState.doc.content.size;
|
|
17835
|
+
let targetPos = from2 + node.nodeSize;
|
|
17836
|
+
if (shouldInsertParagraph) {
|
|
17837
|
+
targetPos += 1;
|
|
17838
|
+
}
|
|
17839
|
+
targetPos = Math.min(targetPos, docSize);
|
|
17840
|
+
if (targetPos < docSize && targetPos > 0) {
|
|
17841
|
+
const newSelection = Selection.near(currentState.doc.resolve(targetPos));
|
|
17842
|
+
const newTr = currentState.tr.setSelection(newSelection);
|
|
17843
|
+
editor.view.dispatch(newTr);
|
|
17844
|
+
}
|
|
17845
|
+
} catch (e) {
|
|
17846
|
+
console.warn("Could not set delayed selection:", e);
|
|
17847
|
+
}
|
|
17848
|
+
}, 0);
|
|
17849
|
+
}
|
|
17850
|
+
return true;
|
|
17851
|
+
},
|
|
17852
|
+
/**
|
|
17853
|
+
* Remove section wrapper at cursor, preserving its content
|
|
17854
|
+
* @category Command
|
|
17855
|
+
* @example
|
|
17856
|
+
* editor.commands.removeSectionAtSelection()
|
|
17857
|
+
* @note Content stays in document, only section wrapper is removed
|
|
17858
|
+
*/
|
|
17859
|
+
removeSectionAtSelection: () => ({ tr, dispatch }) => {
|
|
17860
|
+
const sdtNode = findParentNode((node2) => node2.type.name === "documentSection")(tr.selection);
|
|
17861
|
+
if (!sdtNode) return false;
|
|
17862
|
+
const { node, pos } = sdtNode;
|
|
17863
|
+
const nodeStart = pos;
|
|
17864
|
+
const nodeEnd = nodeStart + node.nodeSize;
|
|
17865
|
+
const contentToPreserve = node.content;
|
|
17866
|
+
tr.delete(nodeStart, nodeEnd);
|
|
17867
|
+
if (contentToPreserve.size > 0) {
|
|
17868
|
+
tr.insert(nodeStart, contentToPreserve);
|
|
17869
|
+
}
|
|
17870
|
+
const newPos = Math.min(nodeStart, tr.doc.content.size);
|
|
17871
|
+
tr.setSelection(Selection.near(tr.doc.resolve(newPos)));
|
|
17872
|
+
if (dispatch) {
|
|
17873
|
+
tr.setMeta("documentSection", { action: "delete" });
|
|
17874
|
+
dispatch(tr);
|
|
17875
|
+
}
|
|
17876
|
+
return true;
|
|
17877
|
+
},
|
|
17878
|
+
/**
|
|
17879
|
+
* Delete section and all its content
|
|
17880
|
+
* @category Command
|
|
17881
|
+
* @param {number} id - Section to delete
|
|
17882
|
+
* @example
|
|
17883
|
+
* editor.commands.removeSectionById(123)
|
|
17884
|
+
*/
|
|
17885
|
+
removeSectionById: (id) => ({ tr, dispatch }) => {
|
|
17886
|
+
const sections = SectionHelpers.getAllSections(this.editor);
|
|
17887
|
+
const sectionToRemove = sections.find(({ node: node2 }) => node2.attrs.id === id);
|
|
17888
|
+
if (!sectionToRemove) return false;
|
|
17889
|
+
const { pos, node } = sectionToRemove;
|
|
17890
|
+
const nodeStart = pos;
|
|
17891
|
+
const nodeEnd = nodeStart + node.nodeSize;
|
|
17892
|
+
tr.delete(nodeStart, nodeEnd);
|
|
17893
|
+
if (dispatch) {
|
|
17894
|
+
tr.setMeta("documentSection", { action: "delete", id });
|
|
17895
|
+
dispatch(tr);
|
|
17896
|
+
}
|
|
17897
|
+
return true;
|
|
17898
|
+
},
|
|
17899
|
+
/**
|
|
17900
|
+
* Lock section against edits
|
|
17901
|
+
* @category Command
|
|
17902
|
+
* @param {number} id - Section to lock
|
|
17903
|
+
* @example
|
|
17904
|
+
* editor.commands.lockSectionById(123)
|
|
17905
|
+
*/
|
|
17906
|
+
lockSectionById: (id) => ({ tr, dispatch }) => {
|
|
17907
|
+
const sections = SectionHelpers.getAllSections(this.editor);
|
|
17908
|
+
const sectionToLock = sections.find(({ node }) => node.attrs.id === id);
|
|
17909
|
+
if (!sectionToLock) return false;
|
|
17910
|
+
tr.setNodeMarkup(sectionToLock.pos, null, { ...sectionToLock.node.attrs, isLocked: true });
|
|
17911
|
+
if (dispatch) {
|
|
17912
|
+
tr.setMeta("documentSection", { action: "lock", id });
|
|
17913
|
+
dispatch(tr);
|
|
17914
|
+
}
|
|
17915
|
+
return true;
|
|
17916
|
+
},
|
|
17917
|
+
/**
|
|
17918
|
+
* Modify section attributes or content
|
|
17919
|
+
* @category Command
|
|
17920
|
+
* @param {SectionUpdate} options - Changes to apply
|
|
17921
|
+
* @example
|
|
17922
|
+
* editor.commands.updateSectionById({ id: 123, attrs: { isLocked: false } })
|
|
17923
|
+
* editor.commands.updateSectionById({ id: 123, html: '<p>New content</p>' })
|
|
17924
|
+
* editor.commands.updateSectionById({
|
|
17925
|
+
* id: 123,
|
|
17926
|
+
* html: '<p>Updated</p>',
|
|
17927
|
+
* attrs: { title: 'New Title' }
|
|
17928
|
+
* })
|
|
17929
|
+
*/
|
|
17930
|
+
updateSectionById: ({ id, html, json, attrs }) => ({ tr, dispatch, editor }) => {
|
|
17931
|
+
const sections = SectionHelpers.getAllSections(editor || this.editor);
|
|
17932
|
+
const sectionToUpdate = sections.find(({ node: node2 }) => node2.attrs.id === id);
|
|
17933
|
+
if (!sectionToUpdate) return false;
|
|
17934
|
+
const { pos, node } = sectionToUpdate;
|
|
17935
|
+
let newContent = null;
|
|
17936
|
+
if (html) {
|
|
17937
|
+
const htmlDoc = htmlHandler(html, editor || this.editor);
|
|
17938
|
+
const doc2 = DOMParser$1.fromSchema((editor || this.editor).schema).parse(htmlDoc);
|
|
17939
|
+
newContent = doc2.content;
|
|
17940
|
+
}
|
|
17941
|
+
if (json) {
|
|
17942
|
+
newContent = (editor || this.editor).schema.nodeFromJSON(json);
|
|
17943
|
+
}
|
|
17944
|
+
if (!newContent) {
|
|
17945
|
+
newContent = node.content;
|
|
17946
|
+
}
|
|
17947
|
+
const updatedNode = node.type.create({ ...node.attrs, ...attrs }, newContent, node.marks);
|
|
17948
|
+
tr.replaceWith(pos, pos + node.nodeSize, updatedNode);
|
|
17949
|
+
if (dispatch) {
|
|
17950
|
+
tr.setMeta("documentSection", { action: "update", id, attrs });
|
|
17951
|
+
dispatch(tr);
|
|
17952
|
+
}
|
|
17953
|
+
return true;
|
|
17954
|
+
}
|
|
17955
|
+
};
|
|
17956
|
+
},
|
|
17957
|
+
addHelpers() {
|
|
17958
|
+
return {
|
|
17959
|
+
...SectionHelpers
|
|
17960
|
+
};
|
|
17961
|
+
}
|
|
17962
|
+
});
|
|
17963
|
+
const DocumentPartObject = Node$1.create({
|
|
17964
|
+
name: "documentPartObject",
|
|
17965
|
+
group: "block",
|
|
17966
|
+
content: "block*",
|
|
17967
|
+
isolating: true,
|
|
17968
|
+
addOptions() {
|
|
17969
|
+
return {
|
|
17970
|
+
htmlAttributes: {
|
|
17971
|
+
class: "sd-document-part-object-block",
|
|
17972
|
+
"aria-label": "Structured document part block"
|
|
17973
|
+
}
|
|
17974
|
+
};
|
|
17975
|
+
},
|
|
17976
|
+
parseDOM() {
|
|
17977
|
+
return [
|
|
17978
|
+
{
|
|
17979
|
+
tag: "div.sd-document-part-object-block",
|
|
17980
|
+
priority: 60
|
|
17981
|
+
}
|
|
17982
|
+
];
|
|
17983
|
+
},
|
|
17984
|
+
renderDOM({ htmlAttributes }) {
|
|
17985
|
+
return ["div", Attribute.mergeAttributes(this.options.htmlAttributes, htmlAttributes), 0];
|
|
17986
|
+
},
|
|
17987
|
+
addAttributes() {
|
|
17988
|
+
return {
|
|
17989
|
+
sdBlockId: {
|
|
17990
|
+
default: null,
|
|
17991
|
+
keepOnSplit: false,
|
|
17992
|
+
parseDOM: (elem) => elem.getAttribute("data-sd-block-id"),
|
|
17993
|
+
renderDOM: (attrs) => {
|
|
17994
|
+
return attrs.sdBlockId ? { "data-sd-block-id": attrs.sdBlockId } : {};
|
|
17995
|
+
}
|
|
17996
|
+
},
|
|
17997
|
+
id: {},
|
|
17998
|
+
docPartGallery: {},
|
|
17999
|
+
docPartUnique: {
|
|
18000
|
+
default: true
|
|
18001
|
+
}
|
|
18002
|
+
};
|
|
18003
|
+
}
|
|
18004
|
+
});
|
|
16970
18005
|
const Document = Node$1.create({
|
|
16971
18006
|
name: "doc",
|
|
16972
18007
|
topNode: true,
|
|
@@ -18103,7 +19138,12 @@ const generateDecorations = (state, styles) => {
|
|
|
18103
19138
|
return { ...base2, ...linkedStyle.definition?.styles || {} };
|
|
18104
19139
|
};
|
|
18105
19140
|
const pMap = buildStyleMap(paragraphStyleId);
|
|
18106
|
-
|
|
19141
|
+
let tMap;
|
|
19142
|
+
if (paragraphStyleId?.startsWith("TOC")) {
|
|
19143
|
+
tMap = {};
|
|
19144
|
+
} else {
|
|
19145
|
+
tMap = buildStyleMap(inlineTextStyleId);
|
|
19146
|
+
}
|
|
18107
19147
|
const rMap = buildStyleMap(runStyleId);
|
|
18108
19148
|
const finalStyles = { ...pMap, ...tMap, ...rMap };
|
|
18109
19149
|
if (Object.keys(finalStyles).length === 0) return;
|
|
@@ -18549,7 +19589,7 @@ class ListItemNodeView {
|
|
|
18549
19589
|
this.decorations = decorations;
|
|
18550
19590
|
this.view = editor.view;
|
|
18551
19591
|
this.getPos = getPos;
|
|
18552
|
-
__privateMethod(this, _ListItemNodeView_instances,
|
|
19592
|
+
__privateMethod(this, _ListItemNodeView_instances, init_fn3).call(this);
|
|
18553
19593
|
activeListItemNodeViews.add(this);
|
|
18554
19594
|
}
|
|
18555
19595
|
refreshIndentStyling() {
|
|
@@ -18610,7 +19650,7 @@ class ListItemNodeView {
|
|
|
18610
19650
|
}
|
|
18611
19651
|
}
|
|
18612
19652
|
_ListItemNodeView_instances = new WeakSet();
|
|
18613
|
-
|
|
19653
|
+
init_fn3 = function() {
|
|
18614
19654
|
const { attrs } = this.node;
|
|
18615
19655
|
const { listLevel, listNumberingType, lvlText, numId, level, customFormat } = attrs;
|
|
18616
19656
|
let orderMarker = "";
|
|
@@ -19400,7 +20440,7 @@ const CommentsMark = Mark.create({
|
|
|
19400
20440
|
});
|
|
19401
20441
|
const defaultTabDistance = 48;
|
|
19402
20442
|
const defaultLineLength = 816;
|
|
19403
|
-
const getTabDecorations = (doc2, view, from2 = 0, to = null) => {
|
|
20443
|
+
const getTabDecorations = (doc2, view, helpers2, from2 = 0, to = null) => {
|
|
19404
20444
|
const decorations = [];
|
|
19405
20445
|
const paragraphCache = /* @__PURE__ */ new Map();
|
|
19406
20446
|
const end2 = to ?? doc2.content.size;
|
|
@@ -19408,7 +20448,7 @@ const getTabDecorations = (doc2, view, from2 = 0, to = null) => {
|
|
|
19408
20448
|
if (node.type.name !== "tab") return;
|
|
19409
20449
|
let extraStyles = "";
|
|
19410
20450
|
const $pos = doc2.resolve(pos);
|
|
19411
|
-
const paragraphContext = getParagraphContext($pos, paragraphCache);
|
|
20451
|
+
const paragraphContext = getParagraphContext($pos, paragraphCache, helpers2);
|
|
19412
20452
|
if (!paragraphContext) return;
|
|
19413
20453
|
try {
|
|
19414
20454
|
const { tabStops, flattened, startPos } = paragraphContext;
|
|
@@ -19463,18 +20503,27 @@ const getTabDecorations = (doc2, view, from2 = 0, to = null) => {
|
|
|
19463
20503
|
});
|
|
19464
20504
|
return decorations;
|
|
19465
20505
|
};
|
|
19466
|
-
function getParagraphContext($pos, cache) {
|
|
20506
|
+
function getParagraphContext($pos, cache, helpers2) {
|
|
19467
20507
|
for (let depth = $pos.depth; depth >= 0; depth--) {
|
|
19468
20508
|
const node = $pos.node(depth);
|
|
19469
20509
|
if (node?.type?.name === "paragraph") {
|
|
19470
20510
|
const startPos = $pos.start(depth);
|
|
19471
20511
|
if (!cache.has(startPos)) {
|
|
20512
|
+
let tabStops = [];
|
|
20513
|
+
if (Array.isArray(node.attrs?.tabStops)) {
|
|
20514
|
+
tabStops = node.attrs.tabStops;
|
|
20515
|
+
} else {
|
|
20516
|
+
const style = helpers2.linkedStyles.getStyleById(node.attrs?.styleId);
|
|
20517
|
+
if (Array.isArray(style?.definition?.styles?.tabStops)) {
|
|
20518
|
+
tabStops = style.definition.styles.tabStops;
|
|
20519
|
+
}
|
|
20520
|
+
}
|
|
19472
20521
|
cache.set(startPos, {
|
|
19473
20522
|
paragraph: node,
|
|
19474
20523
|
paragraphDepth: depth,
|
|
19475
20524
|
startPos,
|
|
19476
20525
|
indent: node.attrs?.indent || {},
|
|
19477
|
-
tabStops
|
|
20526
|
+
tabStops,
|
|
19478
20527
|
flattened: flattenParagraph(node, startPos),
|
|
19479
20528
|
accumulatedTabWidth: 0
|
|
19480
20529
|
});
|
|
@@ -19640,7 +20689,7 @@ const TabNode = Node$1.create({
|
|
|
19640
20689
|
};
|
|
19641
20690
|
},
|
|
19642
20691
|
addPmPlugins() {
|
|
19643
|
-
const { view } = this.editor;
|
|
20692
|
+
const { view, helpers: helpers2 } = this.editor;
|
|
19644
20693
|
const tabPlugin = new Plugin({
|
|
19645
20694
|
name: "tabPlugin",
|
|
19646
20695
|
key: new PluginKey("tabPlugin"),
|
|
@@ -19650,7 +20699,7 @@ const TabNode = Node$1.create({
|
|
|
19650
20699
|
},
|
|
19651
20700
|
apply(tr, { decorations }, _oldState, newState) {
|
|
19652
20701
|
if (!decorations) {
|
|
19653
|
-
decorations = DecorationSet.create(newState.doc, getTabDecorations(newState.doc, view));
|
|
20702
|
+
decorations = DecorationSet.create(newState.doc, getTabDecorations(newState.doc, view, helpers2));
|
|
19654
20703
|
}
|
|
19655
20704
|
if (!tr.docChanged) {
|
|
19656
20705
|
return { decorations };
|
|
@@ -19690,7 +20739,7 @@ const TabNode = Node$1.create({
|
|
|
19690
20739
|
rangesToRecalculate.forEach(([start2, end2]) => {
|
|
19691
20740
|
const oldDecorations = decorations.find(start2, end2);
|
|
19692
20741
|
decorations = decorations.remove(oldDecorations);
|
|
19693
|
-
const newDecorations = getTabDecorations(newState.doc, view, start2, end2);
|
|
20742
|
+
const newDecorations = getTabDecorations(newState.doc, view, helpers2, start2, end2);
|
|
19694
20743
|
decorations = decorations.add(newState.doc, newDecorations);
|
|
19695
20744
|
});
|
|
19696
20745
|
return { decorations };
|
|
@@ -25971,83 +27020,66 @@ const processMarks = (marks) => {
|
|
|
25971
27020
|
});
|
|
25972
27021
|
return styles;
|
|
25973
27022
|
};
|
|
25974
|
-
const
|
|
25975
|
-
name: "
|
|
25976
|
-
group: "
|
|
25977
|
-
|
|
25978
|
-
|
|
27023
|
+
const PageReference = Node$1.create({
|
|
27024
|
+
name: "pageReference",
|
|
27025
|
+
group: "inline",
|
|
27026
|
+
inline: true,
|
|
27027
|
+
atom: true,
|
|
27028
|
+
draggable: false,
|
|
27029
|
+
selectable: false,
|
|
27030
|
+
content: "inline*",
|
|
25979
27031
|
addOptions() {
|
|
25980
27032
|
return {
|
|
25981
27033
|
htmlAttributes: {
|
|
25982
|
-
|
|
25983
|
-
"
|
|
27034
|
+
contenteditable: false,
|
|
27035
|
+
"data-id": "auto-page-reference",
|
|
27036
|
+
"aria-label": "Page reference node",
|
|
27037
|
+
class: "sd-editor-page-reference"
|
|
25984
27038
|
}
|
|
25985
27039
|
};
|
|
25986
27040
|
},
|
|
25987
27041
|
addAttributes() {
|
|
25988
27042
|
return {
|
|
25989
|
-
|
|
25990
|
-
renderDOM: (attrs) => {
|
|
25991
|
-
if (!attrs.fillcolor) return {};
|
|
25992
|
-
return {
|
|
25993
|
-
style: `background-color: ${attrs.fillcolor}`
|
|
25994
|
-
};
|
|
25995
|
-
}
|
|
25996
|
-
},
|
|
25997
|
-
sdBlockId: {
|
|
27043
|
+
marksAsAttrs: {
|
|
25998
27044
|
default: null,
|
|
25999
|
-
keepOnSplit: false,
|
|
26000
|
-
parseDOM: (elem) => elem.getAttribute("data-sd-block-id"),
|
|
26001
|
-
renderDOM: (attrs) => {
|
|
26002
|
-
return attrs.sdBlockId ? { "data-sd-block-id": attrs.sdBlockId } : {};
|
|
26003
|
-
}
|
|
26004
|
-
},
|
|
26005
|
-
style: {
|
|
26006
|
-
renderDOM: (attrs) => {
|
|
26007
|
-
if (!attrs.style) return {};
|
|
26008
|
-
return {
|
|
26009
|
-
style: attrs.style
|
|
26010
|
-
};
|
|
26011
|
-
}
|
|
26012
|
-
},
|
|
26013
|
-
wrapAttributes: {
|
|
26014
27045
|
rendered: false
|
|
26015
27046
|
},
|
|
26016
|
-
|
|
27047
|
+
instruction: {
|
|
27048
|
+
default: "",
|
|
26017
27049
|
rendered: false
|
|
26018
27050
|
}
|
|
26019
27051
|
};
|
|
26020
27052
|
},
|
|
26021
27053
|
parseDOM() {
|
|
26022
|
-
return [
|
|
26023
|
-
{
|
|
26024
|
-
tag: `div[data-type="${this.name}"]`
|
|
26025
|
-
}
|
|
26026
|
-
];
|
|
27054
|
+
return [{ tag: 'span[data-id="auto-page-reference"]' }];
|
|
26027
27055
|
},
|
|
26028
27056
|
renderDOM({ htmlAttributes }) {
|
|
26029
|
-
return [
|
|
26030
|
-
"div",
|
|
26031
|
-
Attribute.mergeAttributes(this.options.htmlAttributes, htmlAttributes, { "data-type": this.name }),
|
|
26032
|
-
0
|
|
26033
|
-
];
|
|
27057
|
+
return ["span", Attribute.mergeAttributes(this.options.htmlAttributes, htmlAttributes), 0];
|
|
26034
27058
|
}
|
|
26035
27059
|
});
|
|
26036
|
-
const
|
|
26037
|
-
name: "
|
|
27060
|
+
const ShapeContainer = Node$1.create({
|
|
27061
|
+
name: "shapeContainer",
|
|
26038
27062
|
group: "block",
|
|
26039
|
-
content: "
|
|
27063
|
+
content: "block+",
|
|
26040
27064
|
isolating: true,
|
|
26041
27065
|
addOptions() {
|
|
26042
27066
|
return {
|
|
26043
27067
|
htmlAttributes: {
|
|
26044
|
-
class: "sd-editor-shape-
|
|
26045
|
-
"aria-label": "Shape
|
|
27068
|
+
class: "sd-editor-shape-container",
|
|
27069
|
+
"aria-label": "Shape container node"
|
|
26046
27070
|
}
|
|
26047
27071
|
};
|
|
26048
27072
|
},
|
|
26049
27073
|
addAttributes() {
|
|
26050
27074
|
return {
|
|
27075
|
+
fillcolor: {
|
|
27076
|
+
renderDOM: (attrs) => {
|
|
27077
|
+
if (!attrs.fillcolor) return {};
|
|
27078
|
+
return {
|
|
27079
|
+
style: `background-color: ${attrs.fillcolor}`
|
|
27080
|
+
};
|
|
27081
|
+
}
|
|
27082
|
+
},
|
|
26051
27083
|
sdBlockId: {
|
|
26052
27084
|
default: null,
|
|
26053
27085
|
keepOnSplit: false,
|
|
@@ -26056,72 +27088,15 @@ const ShapeTextbox = Node$1.create({
|
|
|
26056
27088
|
return attrs.sdBlockId ? { "data-sd-block-id": attrs.sdBlockId } : {};
|
|
26057
27089
|
}
|
|
26058
27090
|
},
|
|
26059
|
-
|
|
26060
|
-
rendered: false
|
|
26061
|
-
}
|
|
26062
|
-
};
|
|
26063
|
-
},
|
|
26064
|
-
parseDOM() {
|
|
26065
|
-
return [
|
|
26066
|
-
{
|
|
26067
|
-
tag: `div[data-type="${this.name}"]`
|
|
26068
|
-
}
|
|
26069
|
-
];
|
|
26070
|
-
},
|
|
26071
|
-
renderDOM({ htmlAttributes }) {
|
|
26072
|
-
return [
|
|
26073
|
-
"div",
|
|
26074
|
-
Attribute.mergeAttributes(this.options.htmlAttributes, htmlAttributes, { "data-type": this.name }),
|
|
26075
|
-
0
|
|
26076
|
-
];
|
|
26077
|
-
}
|
|
26078
|
-
});
|
|
26079
|
-
const ContentBlock = Node$1.create({
|
|
26080
|
-
name: "contentBlock",
|
|
26081
|
-
group: "inline",
|
|
26082
|
-
content: "",
|
|
26083
|
-
isolating: true,
|
|
26084
|
-
atom: true,
|
|
26085
|
-
inline: true,
|
|
26086
|
-
addOptions() {
|
|
26087
|
-
return {
|
|
26088
|
-
htmlAttributes: {
|
|
26089
|
-
contenteditable: false
|
|
26090
|
-
}
|
|
26091
|
-
};
|
|
26092
|
-
},
|
|
26093
|
-
addAttributes() {
|
|
26094
|
-
return {
|
|
26095
|
-
horizontalRule: {
|
|
26096
|
-
default: false,
|
|
26097
|
-
renderDOM: ({ horizontalRule }) => {
|
|
26098
|
-
if (!horizontalRule) return {};
|
|
26099
|
-
return { "data-horizontal-rule": "true" };
|
|
26100
|
-
}
|
|
26101
|
-
},
|
|
26102
|
-
size: {
|
|
26103
|
-
default: null,
|
|
26104
|
-
renderDOM: ({ size }) => {
|
|
26105
|
-
if (!size) return {};
|
|
26106
|
-
let style = "";
|
|
26107
|
-
if (size.top) style += `top: ${size.top}px; `;
|
|
26108
|
-
if (size.left) style += `left: ${size.left}px; `;
|
|
26109
|
-
if (size.width) style += `width: ${size.width.toString().endsWith("%") ? size.width : `${size.width}px`}; `;
|
|
26110
|
-
if (size.height)
|
|
26111
|
-
style += `height: ${size.height.toString().endsWith("%") ? size.height : `${size.height}px`}; `;
|
|
26112
|
-
return { style };
|
|
26113
|
-
}
|
|
26114
|
-
},
|
|
26115
|
-
background: {
|
|
26116
|
-
default: null,
|
|
27091
|
+
style: {
|
|
26117
27092
|
renderDOM: (attrs) => {
|
|
26118
|
-
if (!attrs.
|
|
27093
|
+
if (!attrs.style) return {};
|
|
26119
27094
|
return {
|
|
26120
|
-
style:
|
|
27095
|
+
style: attrs.style
|
|
26121
27096
|
};
|
|
26122
27097
|
}
|
|
26123
27098
|
},
|
|
26124
|
-
|
|
27099
|
+
wrapAttributes: {
|
|
26125
27100
|
rendered: false
|
|
26126
27101
|
},
|
|
26127
27102
|
attributes: {
|
|
@@ -26131,786 +27106,167 @@ const ContentBlock = Node$1.create({
|
|
|
26131
27106
|
},
|
|
26132
27107
|
parseDOM() {
|
|
26133
27108
|
return [
|
|
26134
|
-
{
|
|
26135
|
-
tag: `div[data-type="${this.name}"]`
|
|
26136
|
-
}
|
|
26137
|
-
];
|
|
26138
|
-
},
|
|
26139
|
-
renderDOM({ htmlAttributes }) {
|
|
26140
|
-
return [
|
|
26141
|
-
|
|
26142
|
-
|
|
26143
|
-
|
|
26144
|
-
|
|
26145
|
-
* Insert a horizontal rule
|
|
26146
|
-
* @category Command
|
|
26147
|
-
* @example
|
|
26148
|
-
* editor.commands.insertHorizontalRule()
|
|
26149
|
-
* @note Creates a visual separator between content sections
|
|
26150
|
-
*/
|
|
26151
|
-
insertHorizontalRule: () => ({ commands: commands2 }) => {
|
|
26152
|
-
return commands2.insertContent({
|
|
26153
|
-
type: this.name,
|
|
26154
|
-
attrs: {
|
|
26155
|
-
horizontalRule: true,
|
|
26156
|
-
size: { width: "100%", height: 2 },
|
|
26157
|
-
background: "#e5e7eb"
|
|
26158
|
-
}
|
|
26159
|
-
});
|
|
26160
|
-
},
|
|
26161
|
-
/**
|
|
26162
|
-
* Insert a content block
|
|
26163
|
-
* @category Command
|
|
26164
|
-
* @param {ContentBlockConfig} config - Block configuration
|
|
26165
|
-
* @example
|
|
26166
|
-
* // Insert a spacer block
|
|
26167
|
-
* editor.commands.insertContentBlock({ size: { height: 20 } })
|
|
26168
|
-
*
|
|
26169
|
-
* @example
|
|
26170
|
-
* // Insert a colored divider
|
|
26171
|
-
* editor.commands.insertContentBlock({
|
|
26172
|
-
* size: { width: '50%', height: 3 },
|
|
26173
|
-
* background: '#3b82f6'
|
|
26174
|
-
* })
|
|
26175
|
-
* @note Used for spacing, dividers, and special inline content
|
|
26176
|
-
*/
|
|
26177
|
-
insertContentBlock: (config) => ({ commands: commands2 }) => {
|
|
26178
|
-
return commands2.insertContent({
|
|
26179
|
-
type: this.name,
|
|
26180
|
-
attrs: config
|
|
26181
|
-
});
|
|
26182
|
-
}
|
|
26183
|
-
};
|
|
26184
|
-
}
|
|
26185
|
-
});
|
|
26186
|
-
class StructuredContentViewBase {
|
|
26187
|
-
constructor(props) {
|
|
26188
|
-
__publicField(this, "node");
|
|
26189
|
-
__publicField(this, "view");
|
|
26190
|
-
__publicField(this, "getPos");
|
|
26191
|
-
__publicField(this, "decorations");
|
|
26192
|
-
__publicField(this, "innerDecorations");
|
|
26193
|
-
__publicField(this, "editor");
|
|
26194
|
-
__publicField(this, "extension");
|
|
26195
|
-
__publicField(this, "htmlAttributes");
|
|
26196
|
-
__publicField(this, "root");
|
|
26197
|
-
__publicField(this, "isDragging", false);
|
|
26198
|
-
this.node = props.node;
|
|
26199
|
-
this.view = props.editor.view;
|
|
26200
|
-
this.getPos = props.getPos;
|
|
26201
|
-
this.decorations = props.decorations;
|
|
26202
|
-
this.innerDecorations = props.innerDecorations;
|
|
26203
|
-
this.editor = props.editor;
|
|
26204
|
-
this.extension = props.extension;
|
|
26205
|
-
this.htmlAttributes = props.htmlAttributes;
|
|
26206
|
-
this.mount(props);
|
|
26207
|
-
}
|
|
26208
|
-
mount() {
|
|
26209
|
-
return;
|
|
26210
|
-
}
|
|
26211
|
-
get dom() {
|
|
26212
|
-
return this.root;
|
|
26213
|
-
}
|
|
26214
|
-
get contentDOM() {
|
|
26215
|
-
return null;
|
|
26216
|
-
}
|
|
26217
|
-
update(node, decorations, innerDecorations) {
|
|
26218
|
-
if (node.type !== this.node.type) {
|
|
26219
|
-
return false;
|
|
26220
|
-
}
|
|
26221
|
-
this.node = node;
|
|
26222
|
-
this.decorations = decorations;
|
|
26223
|
-
this.innerDecorations = innerDecorations;
|
|
26224
|
-
this.updateHTMLAttributes();
|
|
26225
|
-
return true;
|
|
26226
|
-
}
|
|
26227
|
-
stopEvent(event) {
|
|
26228
|
-
if (!this.dom) return false;
|
|
26229
|
-
const target = event.target;
|
|
26230
|
-
const isInElement = this.dom.contains(target) && !this.contentDOM?.contains(target);
|
|
26231
|
-
if (!isInElement) return false;
|
|
26232
|
-
const isDragEvent = event.type.startsWith("drag");
|
|
26233
|
-
const isDropEvent = event.type === "drop";
|
|
26234
|
-
const isInput = ["INPUT", "BUTTON", "SELECT", "TEXTAREA"].includes(target.tagName) || target.isContentEditable;
|
|
26235
|
-
if (isInput && !isDropEvent && !isDragEvent) return true;
|
|
26236
|
-
const { isEditable } = this.editor;
|
|
26237
|
-
const { isDragging } = this;
|
|
26238
|
-
const isDraggable = !!this.node.type.spec.draggable;
|
|
26239
|
-
const isSelectable = NodeSelection.isSelectable(this.node);
|
|
26240
|
-
const isCopyEvent = event.type === "copy";
|
|
26241
|
-
const isPasteEvent = event.type === "paste";
|
|
26242
|
-
const isCutEvent = event.type === "cut";
|
|
26243
|
-
const isClickEvent = event.type === "mousedown";
|
|
26244
|
-
if (!isDraggable && isSelectable && isDragEvent && event.target === this.dom) {
|
|
26245
|
-
event.preventDefault();
|
|
26246
|
-
}
|
|
26247
|
-
if (isDraggable && isDragEvent && !isDragging && event.target === this.dom) {
|
|
26248
|
-
event.preventDefault();
|
|
26249
|
-
return false;
|
|
26250
|
-
}
|
|
26251
|
-
if (isDraggable && isEditable && !isDragging && isClickEvent) {
|
|
26252
|
-
const dragHandle = target.closest("[data-drag-handle]");
|
|
26253
|
-
const isValidDragHandle = dragHandle && (this.dom === dragHandle || this.dom.contains(dragHandle));
|
|
26254
|
-
if (isValidDragHandle) {
|
|
26255
|
-
this.isDragging = true;
|
|
26256
|
-
document.addEventListener(
|
|
26257
|
-
"dragend",
|
|
26258
|
-
() => {
|
|
26259
|
-
this.isDragging = false;
|
|
26260
|
-
},
|
|
26261
|
-
{ once: true }
|
|
26262
|
-
);
|
|
26263
|
-
document.addEventListener(
|
|
26264
|
-
"drop",
|
|
26265
|
-
() => {
|
|
26266
|
-
this.isDragging = false;
|
|
26267
|
-
},
|
|
26268
|
-
{ once: true }
|
|
26269
|
-
);
|
|
26270
|
-
document.addEventListener(
|
|
26271
|
-
"mouseup",
|
|
26272
|
-
() => {
|
|
26273
|
-
this.isDragging = false;
|
|
26274
|
-
},
|
|
26275
|
-
{ once: true }
|
|
26276
|
-
);
|
|
26277
|
-
}
|
|
26278
|
-
}
|
|
26279
|
-
if (isDragging || isDropEvent || isCopyEvent || isPasteEvent || isCutEvent || isClickEvent && isSelectable) {
|
|
26280
|
-
return false;
|
|
26281
|
-
}
|
|
26282
|
-
return true;
|
|
26283
|
-
}
|
|
26284
|
-
ignoreMutation(mutation) {
|
|
26285
|
-
if (!this.dom || !this.contentDOM) return true;
|
|
26286
|
-
if (this.node.isLeaf || this.node.isAtom) return true;
|
|
26287
|
-
if (mutation.type === "selection") return false;
|
|
26288
|
-
if (this.contentDOM === mutation.target && mutation.type === "attributes") return true;
|
|
26289
|
-
if (this.contentDOM.contains(mutation.target)) return false;
|
|
26290
|
-
return true;
|
|
26291
|
-
}
|
|
26292
|
-
destroy() {
|
|
26293
|
-
this.dom.remove();
|
|
26294
|
-
this.contentDOM?.remove();
|
|
26295
|
-
}
|
|
26296
|
-
updateAttributes(attrs) {
|
|
26297
|
-
const pos = this.getPos();
|
|
26298
|
-
if (typeof pos !== "number") {
|
|
26299
|
-
return;
|
|
26300
|
-
}
|
|
26301
|
-
return this.view.dispatch(
|
|
26302
|
-
this.view.state.tr.setNodeMarkup(pos, void 0, {
|
|
26303
|
-
...this.node.attrs,
|
|
26304
|
-
...attrs
|
|
26305
|
-
})
|
|
26306
|
-
);
|
|
26307
|
-
}
|
|
26308
|
-
updateHTMLAttributes() {
|
|
26309
|
-
const { extensionService } = this.editor;
|
|
26310
|
-
const { attributes } = extensionService;
|
|
26311
|
-
const extensionAttrs = attributes.filter((i) => i.type === this.node.type.name);
|
|
26312
|
-
this.htmlAttributes = Attribute.getAttributesToRender(this.node, extensionAttrs);
|
|
26313
|
-
}
|
|
26314
|
-
createDragHandle() {
|
|
26315
|
-
const dragHandle = document.createElement("span");
|
|
26316
|
-
dragHandle.classList.add("sd-structured-content-draggable");
|
|
26317
|
-
dragHandle.draggable = true;
|
|
26318
|
-
dragHandle.contentEditable = "false";
|
|
26319
|
-
dragHandle.dataset.dragHandle = "";
|
|
26320
|
-
const textElement = document.createElement("span");
|
|
26321
|
-
textElement.textContent = "Structured content";
|
|
26322
|
-
dragHandle.append(textElement);
|
|
26323
|
-
return dragHandle;
|
|
26324
|
-
}
|
|
26325
|
-
onDragStart(event) {
|
|
26326
|
-
const { view } = this.editor;
|
|
26327
|
-
const target = event.target;
|
|
26328
|
-
const dragHandle = target.nodeType === 3 ? target.parentElement?.closest("[data-drag-handle]") : target.closest("[data-drag-handle]");
|
|
26329
|
-
if (!this.dom || this.contentDOM?.contains(target) || !dragHandle) {
|
|
26330
|
-
return;
|
|
26331
|
-
}
|
|
26332
|
-
let x = 0;
|
|
26333
|
-
let y = 0;
|
|
26334
|
-
if (this.dom !== dragHandle) {
|
|
26335
|
-
const domBox = this.dom.getBoundingClientRect();
|
|
26336
|
-
const handleBox = dragHandle.getBoundingClientRect();
|
|
26337
|
-
const offsetX = event.offsetX ?? event.nativeEvent?.offsetX;
|
|
26338
|
-
const offsetY = event.offsetY ?? event.nativeEvent?.offsetY;
|
|
26339
|
-
x = handleBox.x - domBox.x + offsetX;
|
|
26340
|
-
y = handleBox.y - domBox.y + offsetY;
|
|
26341
|
-
}
|
|
26342
|
-
event.dataTransfer?.setDragImage(this.dom, x, y);
|
|
26343
|
-
const pos = this.getPos();
|
|
26344
|
-
if (typeof pos !== "number") {
|
|
26345
|
-
return;
|
|
26346
|
-
}
|
|
26347
|
-
const selection = NodeSelection.create(view.state.doc, pos);
|
|
26348
|
-
const transaction = view.state.tr.setSelection(selection);
|
|
26349
|
-
view.dispatch(transaction);
|
|
26350
|
-
}
|
|
26351
|
-
}
|
|
26352
|
-
class StructuredContentInlineView extends StructuredContentViewBase {
|
|
26353
|
-
constructor(props) {
|
|
26354
|
-
super(props);
|
|
26355
|
-
}
|
|
26356
|
-
mount() {
|
|
26357
|
-
this.buildView();
|
|
26358
|
-
}
|
|
26359
|
-
get contentDOM() {
|
|
26360
|
-
const contentElement = this.dom?.querySelector(`.${structuredContentInnerClass$1}`);
|
|
26361
|
-
return contentElement || null;
|
|
26362
|
-
}
|
|
26363
|
-
createElement() {
|
|
26364
|
-
const element = document.createElement("span");
|
|
26365
|
-
element.classList.add(structuredContentClass$1);
|
|
26366
|
-
element.setAttribute("data-structured-content", "");
|
|
26367
|
-
const contentElement = document.createElement("span");
|
|
26368
|
-
contentElement.classList.add(structuredContentInnerClass$1);
|
|
26369
|
-
element.append(contentElement);
|
|
26370
|
-
const domAttrs = Attribute.mergeAttributes(this.htmlAttributes);
|
|
26371
|
-
updateDOMAttributes(element, { ...domAttrs });
|
|
26372
|
-
return { element, contentElement };
|
|
26373
|
-
}
|
|
26374
|
-
buildView() {
|
|
26375
|
-
const { element } = this.createElement();
|
|
26376
|
-
const dragHandle = this.createDragHandle();
|
|
26377
|
-
element.prepend(dragHandle);
|
|
26378
|
-
element.addEventListener("dragstart", (e) => this.onDragStart(e));
|
|
26379
|
-
this.root = element;
|
|
26380
|
-
}
|
|
26381
|
-
updateView() {
|
|
26382
|
-
const domAttrs = Attribute.mergeAttributes(this.htmlAttributes);
|
|
26383
|
-
updateDOMAttributes(this.dom, { ...domAttrs });
|
|
26384
|
-
}
|
|
26385
|
-
update(node, decorations, innerDecorations) {
|
|
26386
|
-
const result = super.update(node, decorations, innerDecorations);
|
|
26387
|
-
if (!result) return false;
|
|
26388
|
-
this.updateView();
|
|
26389
|
-
return true;
|
|
26390
|
-
}
|
|
26391
|
-
}
|
|
26392
|
-
const structuredContentClass$1 = "sd-structured-content";
|
|
26393
|
-
const structuredContentInnerClass$1 = "sd-structured-content__content";
|
|
26394
|
-
const StructuredContent = Node$1.create({
|
|
26395
|
-
name: "structuredContent",
|
|
26396
|
-
group: "inline structuredContent",
|
|
26397
|
-
inline: true,
|
|
26398
|
-
content: "inline*",
|
|
26399
|
-
isolating: true,
|
|
26400
|
-
atom: false,
|
|
26401
|
-
// false - has editable content.
|
|
26402
|
-
draggable: true,
|
|
26403
|
-
addOptions() {
|
|
26404
|
-
return {
|
|
26405
|
-
htmlAttributes: {
|
|
26406
|
-
class: structuredContentClass$1,
|
|
26407
|
-
"aria-label": "Structured content node"
|
|
26408
|
-
}
|
|
26409
|
-
};
|
|
26410
|
-
},
|
|
26411
|
-
addAttributes() {
|
|
26412
|
-
return {
|
|
26413
|
-
id: {
|
|
26414
|
-
default: null,
|
|
26415
|
-
parseDOM: (elem) => elem.getAttribute("data-id"),
|
|
26416
|
-
renderDOM: (attrs) => {
|
|
26417
|
-
if (!attrs.id) return {};
|
|
26418
|
-
return { "data-id": attrs.id };
|
|
26419
|
-
}
|
|
26420
|
-
},
|
|
26421
|
-
sdtPr: {
|
|
26422
|
-
rendered: false
|
|
26423
|
-
}
|
|
26424
|
-
};
|
|
26425
|
-
},
|
|
26426
|
-
parseDOM() {
|
|
26427
|
-
return [{ tag: "span[data-structured-content]" }];
|
|
26428
|
-
},
|
|
26429
|
-
renderDOM({ htmlAttributes }) {
|
|
26430
|
-
return [
|
|
26431
|
-
"span",
|
|
26432
|
-
Attribute.mergeAttributes(this.options.htmlAttributes, htmlAttributes, {
|
|
26433
|
-
"data-structured-content": ""
|
|
26434
|
-
}),
|
|
26435
|
-
0
|
|
26436
|
-
];
|
|
26437
|
-
},
|
|
26438
|
-
addNodeView() {
|
|
26439
|
-
return (props) => {
|
|
26440
|
-
return new StructuredContentInlineView({ ...props });
|
|
26441
|
-
};
|
|
26442
|
-
}
|
|
26443
|
-
});
|
|
26444
|
-
class StructuredContentBlockView extends StructuredContentViewBase {
|
|
26445
|
-
constructor(props) {
|
|
26446
|
-
super(props);
|
|
26447
|
-
}
|
|
26448
|
-
mount() {
|
|
26449
|
-
this.buildView();
|
|
26450
|
-
}
|
|
26451
|
-
get contentDOM() {
|
|
26452
|
-
const contentElement = this.dom?.querySelector(`.${structuredContentInnerClass}`);
|
|
26453
|
-
return contentElement || null;
|
|
26454
|
-
}
|
|
26455
|
-
createElement() {
|
|
26456
|
-
const element = document.createElement("div");
|
|
26457
|
-
element.classList.add(structuredContentClass);
|
|
26458
|
-
element.setAttribute("data-structured-content-block", "");
|
|
26459
|
-
const contentElement = document.createElement("div");
|
|
26460
|
-
contentElement.classList.add(structuredContentInnerClass);
|
|
26461
|
-
element.append(contentElement);
|
|
26462
|
-
const domAttrs = Attribute.mergeAttributes(this.htmlAttributes);
|
|
26463
|
-
updateDOMAttributes(element, { ...domAttrs });
|
|
26464
|
-
return { element, contentElement };
|
|
26465
|
-
}
|
|
26466
|
-
buildView() {
|
|
26467
|
-
const { element } = this.createElement();
|
|
26468
|
-
const dragHandle = this.createDragHandle();
|
|
26469
|
-
element.prepend(dragHandle);
|
|
26470
|
-
element.addEventListener("dragstart", (e) => this.onDragStart(e));
|
|
26471
|
-
this.root = element;
|
|
26472
|
-
}
|
|
26473
|
-
updateView() {
|
|
26474
|
-
const domAttrs = Attribute.mergeAttributes(this.htmlAttributes);
|
|
26475
|
-
updateDOMAttributes(this.dom, { ...domAttrs });
|
|
26476
|
-
}
|
|
26477
|
-
update(node, decorations, innerDecorations) {
|
|
26478
|
-
const result = super.update(node, decorations, innerDecorations);
|
|
26479
|
-
if (!result) return false;
|
|
26480
|
-
this.updateView();
|
|
26481
|
-
return true;
|
|
27109
|
+
{
|
|
27110
|
+
tag: `div[data-type="${this.name}"]`
|
|
27111
|
+
}
|
|
27112
|
+
];
|
|
27113
|
+
},
|
|
27114
|
+
renderDOM({ htmlAttributes }) {
|
|
27115
|
+
return [
|
|
27116
|
+
"div",
|
|
27117
|
+
Attribute.mergeAttributes(this.options.htmlAttributes, htmlAttributes, { "data-type": this.name }),
|
|
27118
|
+
0
|
|
27119
|
+
];
|
|
26482
27120
|
}
|
|
26483
|
-
}
|
|
26484
|
-
const
|
|
26485
|
-
|
|
26486
|
-
|
|
26487
|
-
|
|
26488
|
-
group: "block structuredContent",
|
|
26489
|
-
content: "block*",
|
|
27121
|
+
});
|
|
27122
|
+
const ShapeTextbox = Node$1.create({
|
|
27123
|
+
name: "shapeTextbox",
|
|
27124
|
+
group: "block",
|
|
27125
|
+
content: "paragraph* block*",
|
|
26490
27126
|
isolating: true,
|
|
26491
|
-
atom: false,
|
|
26492
|
-
// false - has editable content.
|
|
26493
|
-
draggable: true,
|
|
26494
27127
|
addOptions() {
|
|
26495
27128
|
return {
|
|
26496
27129
|
htmlAttributes: {
|
|
26497
|
-
class:
|
|
26498
|
-
"aria-label": "
|
|
27130
|
+
class: "sd-editor-shape-textbox",
|
|
27131
|
+
"aria-label": "Shape textbox node"
|
|
26499
27132
|
}
|
|
26500
27133
|
};
|
|
26501
27134
|
},
|
|
26502
27135
|
addAttributes() {
|
|
26503
27136
|
return {
|
|
26504
|
-
|
|
27137
|
+
sdBlockId: {
|
|
26505
27138
|
default: null,
|
|
26506
|
-
|
|
27139
|
+
keepOnSplit: false,
|
|
27140
|
+
parseDOM: (elem) => elem.getAttribute("data-sd-block-id"),
|
|
26507
27141
|
renderDOM: (attrs) => {
|
|
26508
|
-
|
|
26509
|
-
return { "data-id": attrs.id };
|
|
27142
|
+
return attrs.sdBlockId ? { "data-sd-block-id": attrs.sdBlockId } : {};
|
|
26510
27143
|
}
|
|
26511
27144
|
},
|
|
26512
|
-
|
|
27145
|
+
attributes: {
|
|
26513
27146
|
rendered: false
|
|
26514
27147
|
}
|
|
26515
27148
|
};
|
|
26516
27149
|
},
|
|
26517
27150
|
parseDOM() {
|
|
26518
|
-
return [
|
|
27151
|
+
return [
|
|
27152
|
+
{
|
|
27153
|
+
tag: `div[data-type="${this.name}"]`
|
|
27154
|
+
}
|
|
27155
|
+
];
|
|
26519
27156
|
},
|
|
26520
27157
|
renderDOM({ htmlAttributes }) {
|
|
26521
27158
|
return [
|
|
26522
27159
|
"div",
|
|
26523
|
-
Attribute.mergeAttributes(this.options.htmlAttributes, htmlAttributes, {
|
|
26524
|
-
"data-structured-content-block": ""
|
|
26525
|
-
}),
|
|
27160
|
+
Attribute.mergeAttributes(this.options.htmlAttributes, htmlAttributes, { "data-type": this.name }),
|
|
26526
27161
|
0
|
|
26527
27162
|
];
|
|
26528
|
-
},
|
|
26529
|
-
addNodeView() {
|
|
26530
|
-
return (props) => {
|
|
26531
|
-
return new StructuredContentBlockView({ ...props });
|
|
26532
|
-
};
|
|
26533
27163
|
}
|
|
26534
27164
|
});
|
|
26535
|
-
|
|
26536
|
-
|
|
26537
|
-
|
|
26538
|
-
|
|
26539
|
-
this.editor = editor;
|
|
26540
|
-
this.decorations = decorations;
|
|
26541
|
-
this.view = editor.view;
|
|
26542
|
-
this.getPos = getPos;
|
|
26543
|
-
__privateMethod(this, _DocumentSectionView_instances, init_fn3).call(this);
|
|
26544
|
-
}
|
|
26545
|
-
}
|
|
26546
|
-
_DocumentSectionView_instances = new WeakSet();
|
|
26547
|
-
init_fn3 = function() {
|
|
26548
|
-
const { attrs } = this.node;
|
|
26549
|
-
const { id, title, description } = attrs;
|
|
26550
|
-
this.dom = document.createElement("div");
|
|
26551
|
-
this.dom.className = "sd-document-section-block";
|
|
26552
|
-
this.dom.setAttribute("data-id", id);
|
|
26553
|
-
this.dom.setAttribute("data-title", title);
|
|
26554
|
-
this.dom.setAttribute("data-description", description);
|
|
26555
|
-
this.dom.setAttribute("aria-label", "Document section");
|
|
26556
|
-
__privateMethod(this, _DocumentSectionView_instances, addToolTip_fn).call(this);
|
|
26557
|
-
this.contentDOM = document.createElement("div");
|
|
26558
|
-
this.contentDOM.className = "sd-document-section-block-content";
|
|
26559
|
-
this.contentDOM.setAttribute("contenteditable", "true");
|
|
26560
|
-
this.dom.appendChild(this.contentDOM);
|
|
26561
|
-
};
|
|
26562
|
-
addToolTip_fn = function() {
|
|
26563
|
-
const { title } = this.node.attrs;
|
|
26564
|
-
this.infoDiv = document.createElement("div");
|
|
26565
|
-
this.infoDiv.className = "sd-document-section-block-info";
|
|
26566
|
-
const textSpan = document.createElement("span");
|
|
26567
|
-
textSpan.textContent = title || "Document section";
|
|
26568
|
-
this.infoDiv.appendChild(textSpan);
|
|
26569
|
-
this.infoDiv.setAttribute("contenteditable", "false");
|
|
26570
|
-
this.dom.appendChild(this.infoDiv);
|
|
26571
|
-
};
|
|
26572
|
-
const getAllSections = (editor) => {
|
|
26573
|
-
if (!editor) return [];
|
|
26574
|
-
const type = editor.schema.nodes.documentSection;
|
|
26575
|
-
if (!type) return [];
|
|
26576
|
-
const sections = [];
|
|
26577
|
-
const { state } = editor;
|
|
26578
|
-
state.doc.descendants((node, pos) => {
|
|
26579
|
-
if (node.type.name === type.name) {
|
|
26580
|
-
sections.push({ node, pos });
|
|
26581
|
-
}
|
|
26582
|
-
});
|
|
26583
|
-
return sections;
|
|
26584
|
-
};
|
|
26585
|
-
const exportSectionsToHTML = (editor) => {
|
|
26586
|
-
const sections = getAllSections(editor);
|
|
26587
|
-
const processedSections = /* @__PURE__ */ new Set();
|
|
26588
|
-
const result = [];
|
|
26589
|
-
sections.forEach(({ node }) => {
|
|
26590
|
-
const { attrs } = node;
|
|
26591
|
-
const { id, title, description } = attrs;
|
|
26592
|
-
if (processedSections.has(id)) return;
|
|
26593
|
-
processedSections.add(id);
|
|
26594
|
-
const html = getHTMLFromNode(node, editor);
|
|
26595
|
-
result.push({
|
|
26596
|
-
id,
|
|
26597
|
-
title,
|
|
26598
|
-
description,
|
|
26599
|
-
html
|
|
26600
|
-
});
|
|
26601
|
-
});
|
|
26602
|
-
return result;
|
|
26603
|
-
};
|
|
26604
|
-
const getHTMLFromNode = (node, editor) => {
|
|
26605
|
-
const tempDocument = document.implementation.createHTMLDocument();
|
|
26606
|
-
const container = tempDocument.createElement("div");
|
|
26607
|
-
const fragment = DOMSerializer.fromSchema(editor.schema).serializeFragment(node.content);
|
|
26608
|
-
container.appendChild(fragment);
|
|
26609
|
-
let html = container.innerHTML;
|
|
26610
|
-
return html;
|
|
26611
|
-
};
|
|
26612
|
-
const exportSectionsToJSON = (editor) => {
|
|
26613
|
-
const sections = getAllSections(editor);
|
|
26614
|
-
const processedSections = /* @__PURE__ */ new Set();
|
|
26615
|
-
const result = [];
|
|
26616
|
-
sections.forEach(({ node }) => {
|
|
26617
|
-
const { attrs } = node;
|
|
26618
|
-
const { id, title, description } = attrs;
|
|
26619
|
-
if (processedSections.has(id)) return;
|
|
26620
|
-
processedSections.add(id);
|
|
26621
|
-
result.push({
|
|
26622
|
-
id,
|
|
26623
|
-
title,
|
|
26624
|
-
description,
|
|
26625
|
-
content: node.toJSON()
|
|
26626
|
-
});
|
|
26627
|
-
});
|
|
26628
|
-
return result;
|
|
26629
|
-
};
|
|
26630
|
-
const getLinkedSectionEditor = (id, options, editor) => {
|
|
26631
|
-
const sections = getAllSections(editor);
|
|
26632
|
-
const section = sections.find((s) => s.node.attrs.id === id);
|
|
26633
|
-
if (!section) return null;
|
|
26634
|
-
const child = editor.createChildEditor({
|
|
26635
|
-
...options,
|
|
26636
|
-
onUpdate: ({ editor: childEditor, transaction }) => {
|
|
26637
|
-
const isFromtLinkedParent = transaction.getMeta("fromLinkedParent");
|
|
26638
|
-
if (isFromtLinkedParent) return;
|
|
26639
|
-
const updatedContent = childEditor.state.doc.content;
|
|
26640
|
-
const sectionNode = getAllSections(editor)?.find((s) => s.node.attrs.id === id);
|
|
26641
|
-
if (!sectionNode) return;
|
|
26642
|
-
const { pos, node } = sectionNode;
|
|
26643
|
-
const newNode = node.type.create(node.attrs, updatedContent, node.marks);
|
|
26644
|
-
const tr = editor.state.tr.replaceWith(pos, pos + node.nodeSize, newNode);
|
|
26645
|
-
tr.setMeta("fromLinkedChild", true);
|
|
26646
|
-
editor.view.dispatch(tr);
|
|
26647
|
-
}
|
|
26648
|
-
});
|
|
26649
|
-
editor.on("update", ({ transaction }) => {
|
|
26650
|
-
const isFromLinkedChild = transaction.getMeta("fromLinkedChild");
|
|
26651
|
-
if (isFromLinkedChild) return;
|
|
26652
|
-
const sectionNode = getAllSections(editor)?.find((s) => s.node.attrs.id === id);
|
|
26653
|
-
if (!sectionNode) return;
|
|
26654
|
-
const sectionContent = sectionNode.node.content;
|
|
26655
|
-
const json = {
|
|
26656
|
-
type: "doc",
|
|
26657
|
-
content: sectionContent.content.map((node) => node.toJSON())
|
|
26658
|
-
};
|
|
26659
|
-
const childTr = child.state.tr;
|
|
26660
|
-
childTr.setMeta("fromLinkedParent", true);
|
|
26661
|
-
childTr.replaceWith(0, child.state.doc.content.size, child.schema.nodeFromJSON(json));
|
|
26662
|
-
child.view.dispatch(childTr);
|
|
26663
|
-
});
|
|
26664
|
-
return child;
|
|
26665
|
-
};
|
|
26666
|
-
const SectionHelpers = {
|
|
26667
|
-
getAllSections,
|
|
26668
|
-
exportSectionsToHTML,
|
|
26669
|
-
exportSectionsToJSON,
|
|
26670
|
-
getLinkedSectionEditor
|
|
26671
|
-
};
|
|
26672
|
-
const DocumentSection = Node$1.create({
|
|
26673
|
-
name: "documentSection",
|
|
26674
|
-
group: "block",
|
|
26675
|
-
content: "block*",
|
|
26676
|
-
atom: true,
|
|
27165
|
+
const ContentBlock = Node$1.create({
|
|
27166
|
+
name: "contentBlock",
|
|
27167
|
+
group: "inline",
|
|
27168
|
+
content: "",
|
|
26677
27169
|
isolating: true,
|
|
27170
|
+
atom: true,
|
|
27171
|
+
inline: true,
|
|
26678
27172
|
addOptions() {
|
|
26679
27173
|
return {
|
|
26680
27174
|
htmlAttributes: {
|
|
26681
|
-
|
|
26682
|
-
"aria-label": "Structured content block"
|
|
27175
|
+
contenteditable: false
|
|
26683
27176
|
}
|
|
26684
27177
|
};
|
|
26685
27178
|
},
|
|
26686
|
-
parseDOM() {
|
|
26687
|
-
return [
|
|
26688
|
-
{
|
|
26689
|
-
tag: "div.sd-document-section-block",
|
|
26690
|
-
priority: 60
|
|
26691
|
-
}
|
|
26692
|
-
];
|
|
26693
|
-
},
|
|
26694
|
-
renderDOM({ htmlAttributes }) {
|
|
26695
|
-
return ["div", Attribute.mergeAttributes(this.options.htmlAttributes, htmlAttributes), 0];
|
|
26696
|
-
},
|
|
26697
27179
|
addAttributes() {
|
|
26698
27180
|
return {
|
|
26699
|
-
|
|
26700
|
-
|
|
27181
|
+
horizontalRule: {
|
|
27182
|
+
default: false,
|
|
27183
|
+
renderDOM: ({ horizontalRule }) => {
|
|
27184
|
+
if (!horizontalRule) return {};
|
|
27185
|
+
return { "data-horizontal-rule": "true" };
|
|
27186
|
+
}
|
|
27187
|
+
},
|
|
27188
|
+
size: {
|
|
27189
|
+
default: null,
|
|
27190
|
+
renderDOM: ({ size }) => {
|
|
27191
|
+
if (!size) return {};
|
|
27192
|
+
let style = "";
|
|
27193
|
+
if (size.top) style += `top: ${size.top}px; `;
|
|
27194
|
+
if (size.left) style += `left: ${size.left}px; `;
|
|
27195
|
+
if (size.width) style += `width: ${size.width.toString().endsWith("%") ? size.width : `${size.width}px`}; `;
|
|
27196
|
+
if (size.height)
|
|
27197
|
+
style += `height: ${size.height.toString().endsWith("%") ? size.height : `${size.height}px`}; `;
|
|
27198
|
+
return { style };
|
|
27199
|
+
}
|
|
27200
|
+
},
|
|
27201
|
+
background: {
|
|
26701
27202
|
default: null,
|
|
26702
|
-
keepOnSplit: false,
|
|
26703
|
-
parseDOM: (elem) => elem.getAttribute("data-sd-block-id"),
|
|
26704
27203
|
renderDOM: (attrs) => {
|
|
26705
|
-
|
|
27204
|
+
if (!attrs.background) return {};
|
|
27205
|
+
return {
|
|
27206
|
+
style: `background-color: ${attrs.background}`
|
|
27207
|
+
};
|
|
26706
27208
|
}
|
|
26707
27209
|
},
|
|
26708
|
-
|
|
26709
|
-
|
|
26710
|
-
|
|
26711
|
-
|
|
27210
|
+
drawingContent: {
|
|
27211
|
+
rendered: false
|
|
27212
|
+
},
|
|
27213
|
+
attributes: {
|
|
27214
|
+
rendered: false
|
|
27215
|
+
}
|
|
26712
27216
|
};
|
|
26713
27217
|
},
|
|
26714
|
-
|
|
26715
|
-
return
|
|
26716
|
-
|
|
26717
|
-
|
|
27218
|
+
parseDOM() {
|
|
27219
|
+
return [
|
|
27220
|
+
{
|
|
27221
|
+
tag: `div[data-type="${this.name}"]`
|
|
27222
|
+
}
|
|
27223
|
+
];
|
|
27224
|
+
},
|
|
27225
|
+
renderDOM({ htmlAttributes }) {
|
|
27226
|
+
return ["div", Attribute.mergeAttributes(this.options.htmlAttributes, htmlAttributes, { "data-type": this.name })];
|
|
26718
27227
|
},
|
|
26719
27228
|
addCommands() {
|
|
26720
27229
|
return {
|
|
26721
27230
|
/**
|
|
26722
|
-
*
|
|
27231
|
+
* Insert a horizontal rule
|
|
26723
27232
|
* @category Command
|
|
26724
|
-
* @param {SectionCreate} [options={}] - Section configuration
|
|
26725
27233
|
* @example
|
|
26726
|
-
* editor.commands.
|
|
26727
|
-
*
|
|
26728
|
-
* title: 'Terms & Conditions',
|
|
26729
|
-
* isLocked: true,
|
|
26730
|
-
* html: '<p>Legal content...</p>'
|
|
26731
|
-
* })
|
|
27234
|
+
* editor.commands.insertHorizontalRule()
|
|
27235
|
+
* @note Creates a visual separator between content sections
|
|
26732
27236
|
*/
|
|
26733
|
-
|
|
26734
|
-
|
|
26735
|
-
|
|
26736
|
-
|
|
26737
|
-
|
|
26738
|
-
|
|
26739
|
-
|
|
26740
|
-
const doc2 = DOMParser$1.fromSchema(this.editor.schema).parse(html);
|
|
26741
|
-
content = doc2.content;
|
|
26742
|
-
}
|
|
26743
|
-
if (optionsJSON) {
|
|
26744
|
-
content = this.editor.schema.nodeFromJSON(optionsJSON);
|
|
26745
|
-
}
|
|
26746
|
-
if (!content?.content?.length) {
|
|
26747
|
-
content = this.editor.schema.nodeFromJSON({ type: "paragraph", content: [] });
|
|
26748
|
-
}
|
|
26749
|
-
if (!options.id) {
|
|
26750
|
-
const allSections = SectionHelpers.getAllSections(editor);
|
|
26751
|
-
options.id = allSections.length + 1;
|
|
26752
|
-
}
|
|
26753
|
-
if (!options.title) {
|
|
26754
|
-
options.title = "Document section";
|
|
26755
|
-
}
|
|
26756
|
-
const node = this.type.createAndFill(options, content);
|
|
26757
|
-
if (!node) return false;
|
|
26758
|
-
const isAlreadyInSdtBlock = findParentNode((node2) => node2.type.name === "documentSection")(selection);
|
|
26759
|
-
if (isAlreadyInSdtBlock && isAlreadyInSdtBlock.node) {
|
|
26760
|
-
const insertPos2 = isAlreadyInSdtBlock.pos + isAlreadyInSdtBlock.node.nodeSize;
|
|
26761
|
-
from2 = insertPos2;
|
|
26762
|
-
to = insertPos2;
|
|
26763
|
-
}
|
|
26764
|
-
tr.replaceRangeWith(from2, to, node);
|
|
26765
|
-
const nodeEnd = from2 + node.nodeSize;
|
|
26766
|
-
let shouldInsertParagraph = true;
|
|
26767
|
-
let insertPos = nodeEnd;
|
|
26768
|
-
if (nodeEnd >= tr.doc.content.size) {
|
|
26769
|
-
insertPos = tr.doc.content.size;
|
|
26770
|
-
if (insertPos > 0) {
|
|
26771
|
-
const $endPos = tr.doc.resolve(insertPos);
|
|
26772
|
-
if ($endPos.nodeBefore && $endPos.nodeBefore.type.name === "paragraph") {
|
|
26773
|
-
shouldInsertParagraph = false;
|
|
26774
|
-
}
|
|
27237
|
+
insertHorizontalRule: () => ({ commands: commands2 }) => {
|
|
27238
|
+
return commands2.insertContent({
|
|
27239
|
+
type: this.name,
|
|
27240
|
+
attrs: {
|
|
27241
|
+
horizontalRule: true,
|
|
27242
|
+
size: { width: "100%", height: 2 },
|
|
27243
|
+
background: "#e5e7eb"
|
|
26775
27244
|
}
|
|
26776
|
-
}
|
|
26777
|
-
if (shouldInsertParagraph) {
|
|
26778
|
-
const emptyParagraph = tr.doc.type.schema.nodes.paragraph.create();
|
|
26779
|
-
tr.insert(insertPos, emptyParagraph);
|
|
26780
|
-
}
|
|
26781
|
-
if (dispatch) {
|
|
26782
|
-
tr.setMeta("documentSection", { action: "create" });
|
|
26783
|
-
dispatch(tr);
|
|
26784
|
-
setTimeout(() => {
|
|
26785
|
-
try {
|
|
26786
|
-
const currentState = editor.state;
|
|
26787
|
-
const docSize = currentState.doc.content.size;
|
|
26788
|
-
let targetPos = from2 + node.nodeSize;
|
|
26789
|
-
if (shouldInsertParagraph) {
|
|
26790
|
-
targetPos += 1;
|
|
26791
|
-
}
|
|
26792
|
-
targetPos = Math.min(targetPos, docSize);
|
|
26793
|
-
if (targetPos < docSize && targetPos > 0) {
|
|
26794
|
-
const newSelection = Selection.near(currentState.doc.resolve(targetPos));
|
|
26795
|
-
const newTr = currentState.tr.setSelection(newSelection);
|
|
26796
|
-
editor.view.dispatch(newTr);
|
|
26797
|
-
}
|
|
26798
|
-
} catch (e) {
|
|
26799
|
-
console.warn("Could not set delayed selection:", e);
|
|
26800
|
-
}
|
|
26801
|
-
}, 0);
|
|
26802
|
-
}
|
|
26803
|
-
return true;
|
|
26804
|
-
},
|
|
26805
|
-
/**
|
|
26806
|
-
* Remove section wrapper at cursor, preserving its content
|
|
26807
|
-
* @category Command
|
|
26808
|
-
* @example
|
|
26809
|
-
* editor.commands.removeSectionAtSelection()
|
|
26810
|
-
* @note Content stays in document, only section wrapper is removed
|
|
26811
|
-
*/
|
|
26812
|
-
removeSectionAtSelection: () => ({ tr, dispatch }) => {
|
|
26813
|
-
const sdtNode = findParentNode((node2) => node2.type.name === "documentSection")(tr.selection);
|
|
26814
|
-
if (!sdtNode) return false;
|
|
26815
|
-
const { node, pos } = sdtNode;
|
|
26816
|
-
const nodeStart = pos;
|
|
26817
|
-
const nodeEnd = nodeStart + node.nodeSize;
|
|
26818
|
-
const contentToPreserve = node.content;
|
|
26819
|
-
tr.delete(nodeStart, nodeEnd);
|
|
26820
|
-
if (contentToPreserve.size > 0) {
|
|
26821
|
-
tr.insert(nodeStart, contentToPreserve);
|
|
26822
|
-
}
|
|
26823
|
-
const newPos = Math.min(nodeStart, tr.doc.content.size);
|
|
26824
|
-
tr.setSelection(Selection.near(tr.doc.resolve(newPos)));
|
|
26825
|
-
if (dispatch) {
|
|
26826
|
-
tr.setMeta("documentSection", { action: "delete" });
|
|
26827
|
-
dispatch(tr);
|
|
26828
|
-
}
|
|
26829
|
-
return true;
|
|
26830
|
-
},
|
|
26831
|
-
/**
|
|
26832
|
-
* Delete section and all its content
|
|
26833
|
-
* @category Command
|
|
26834
|
-
* @param {number} id - Section to delete
|
|
26835
|
-
* @example
|
|
26836
|
-
* editor.commands.removeSectionById(123)
|
|
26837
|
-
*/
|
|
26838
|
-
removeSectionById: (id) => ({ tr, dispatch }) => {
|
|
26839
|
-
const sections = SectionHelpers.getAllSections(this.editor);
|
|
26840
|
-
const sectionToRemove = sections.find(({ node: node2 }) => node2.attrs.id === id);
|
|
26841
|
-
if (!sectionToRemove) return false;
|
|
26842
|
-
const { pos, node } = sectionToRemove;
|
|
26843
|
-
const nodeStart = pos;
|
|
26844
|
-
const nodeEnd = nodeStart + node.nodeSize;
|
|
26845
|
-
tr.delete(nodeStart, nodeEnd);
|
|
26846
|
-
if (dispatch) {
|
|
26847
|
-
tr.setMeta("documentSection", { action: "delete", id });
|
|
26848
|
-
dispatch(tr);
|
|
26849
|
-
}
|
|
26850
|
-
return true;
|
|
27245
|
+
});
|
|
26851
27246
|
},
|
|
26852
27247
|
/**
|
|
26853
|
-
*
|
|
27248
|
+
* Insert a content block
|
|
26854
27249
|
* @category Command
|
|
26855
|
-
* @param {
|
|
27250
|
+
* @param {ContentBlockConfig} config - Block configuration
|
|
26856
27251
|
* @example
|
|
26857
|
-
*
|
|
26858
|
-
|
|
26859
|
-
|
|
26860
|
-
const sections = SectionHelpers.getAllSections(this.editor);
|
|
26861
|
-
const sectionToLock = sections.find(({ node }) => node.attrs.id === id);
|
|
26862
|
-
if (!sectionToLock) return false;
|
|
26863
|
-
tr.setNodeMarkup(sectionToLock.pos, null, { ...sectionToLock.node.attrs, isLocked: true });
|
|
26864
|
-
if (dispatch) {
|
|
26865
|
-
tr.setMeta("documentSection", { action: "lock", id });
|
|
26866
|
-
dispatch(tr);
|
|
26867
|
-
}
|
|
26868
|
-
return true;
|
|
26869
|
-
},
|
|
26870
|
-
/**
|
|
26871
|
-
* Modify section attributes or content
|
|
26872
|
-
* @category Command
|
|
26873
|
-
* @param {SectionUpdate} options - Changes to apply
|
|
27252
|
+
* // Insert a spacer block
|
|
27253
|
+
* editor.commands.insertContentBlock({ size: { height: 20 } })
|
|
27254
|
+
*
|
|
26874
27255
|
* @example
|
|
26875
|
-
*
|
|
26876
|
-
* editor.commands.
|
|
26877
|
-
*
|
|
26878
|
-
*
|
|
26879
|
-
* html: '<p>Updated</p>',
|
|
26880
|
-
* attrs: { title: 'New Title' }
|
|
27256
|
+
* // Insert a colored divider
|
|
27257
|
+
* editor.commands.insertContentBlock({
|
|
27258
|
+
* size: { width: '50%', height: 3 },
|
|
27259
|
+
* background: '#3b82f6'
|
|
26881
27260
|
* })
|
|
27261
|
+
* @note Used for spacing, dividers, and special inline content
|
|
26882
27262
|
*/
|
|
26883
|
-
|
|
26884
|
-
|
|
26885
|
-
|
|
26886
|
-
|
|
26887
|
-
|
|
26888
|
-
let newContent = null;
|
|
26889
|
-
if (html) {
|
|
26890
|
-
const htmlDoc = htmlHandler(html, editor || this.editor);
|
|
26891
|
-
const doc2 = DOMParser$1.fromSchema((editor || this.editor).schema).parse(htmlDoc);
|
|
26892
|
-
newContent = doc2.content;
|
|
26893
|
-
}
|
|
26894
|
-
if (json) {
|
|
26895
|
-
newContent = (editor || this.editor).schema.nodeFromJSON(json);
|
|
26896
|
-
}
|
|
26897
|
-
if (!newContent) {
|
|
26898
|
-
newContent = node.content;
|
|
26899
|
-
}
|
|
26900
|
-
const updatedNode = node.type.create({ ...node.attrs, ...attrs }, newContent, node.marks);
|
|
26901
|
-
tr.replaceWith(pos, pos + node.nodeSize, updatedNode);
|
|
26902
|
-
if (dispatch) {
|
|
26903
|
-
tr.setMeta("documentSection", { action: "update", id, attrs });
|
|
26904
|
-
dispatch(tr);
|
|
26905
|
-
}
|
|
26906
|
-
return true;
|
|
27263
|
+
insertContentBlock: (config) => ({ commands: commands2 }) => {
|
|
27264
|
+
return commands2.insertContent({
|
|
27265
|
+
type: this.name,
|
|
27266
|
+
attrs: config
|
|
27267
|
+
});
|
|
26907
27268
|
}
|
|
26908
27269
|
};
|
|
26909
|
-
},
|
|
26910
|
-
addHelpers() {
|
|
26911
|
-
return {
|
|
26912
|
-
...SectionHelpers
|
|
26913
|
-
};
|
|
26914
27270
|
}
|
|
26915
27271
|
});
|
|
26916
27272
|
const { findChildren } = helpers;
|
|
@@ -27114,6 +27470,51 @@ const checkForNewBlockNodesInTrs = (transactions) => {
|
|
|
27114
27470
|
});
|
|
27115
27471
|
});
|
|
27116
27472
|
};
|
|
27473
|
+
const TableOfContents = Node$1.create({
|
|
27474
|
+
name: "tableOfContents",
|
|
27475
|
+
group: "block",
|
|
27476
|
+
content: "paragraph+",
|
|
27477
|
+
inline: false,
|
|
27478
|
+
addOptions() {
|
|
27479
|
+
return {
|
|
27480
|
+
htmlAttributes: {
|
|
27481
|
+
"data-id": "table-of-contents",
|
|
27482
|
+
"aria-label": "Table of Contents"
|
|
27483
|
+
}
|
|
27484
|
+
};
|
|
27485
|
+
},
|
|
27486
|
+
parseDOM() {
|
|
27487
|
+
return [
|
|
27488
|
+
{
|
|
27489
|
+
tag: 'div[data-id="table-of-contents"]'
|
|
27490
|
+
}
|
|
27491
|
+
];
|
|
27492
|
+
},
|
|
27493
|
+
renderDOM({ htmlAttributes }) {
|
|
27494
|
+
return ["div", Attribute.mergeAttributes(this.options.htmlAttributes, htmlAttributes), 0];
|
|
27495
|
+
},
|
|
27496
|
+
addAttributes() {
|
|
27497
|
+
return {
|
|
27498
|
+
instruction: {
|
|
27499
|
+
default: null,
|
|
27500
|
+
rendered: false
|
|
27501
|
+
},
|
|
27502
|
+
/**
|
|
27503
|
+
* @private
|
|
27504
|
+
* @category Attribute
|
|
27505
|
+
* @param {string} [sdBlockId] - Internal block tracking ID (not user-configurable)
|
|
27506
|
+
*/
|
|
27507
|
+
sdBlockId: {
|
|
27508
|
+
default: null,
|
|
27509
|
+
keepOnSplit: false,
|
|
27510
|
+
parseDOM: (elem) => elem.getAttribute("data-sd-block-id"),
|
|
27511
|
+
renderDOM: (attrs) => {
|
|
27512
|
+
return attrs.sdBlockId ? { "data-sd-block-id": attrs.sdBlockId } : {};
|
|
27513
|
+
}
|
|
27514
|
+
}
|
|
27515
|
+
};
|
|
27516
|
+
}
|
|
27517
|
+
});
|
|
27117
27518
|
const TextStyle = Mark.create({
|
|
27118
27519
|
name: "textStyle",
|
|
27119
27520
|
addOptions() {
|
|
@@ -33720,6 +34121,7 @@ const getStarterExtensions = () => {
|
|
|
33720
34121
|
SlashMenu,
|
|
33721
34122
|
Strike,
|
|
33722
34123
|
TabNode,
|
|
34124
|
+
TableOfContents,
|
|
33723
34125
|
Text,
|
|
33724
34126
|
TextAlign,
|
|
33725
34127
|
TextIndent,
|
|
@@ -33754,13 +34156,16 @@ const getStarterExtensions = () => {
|
|
|
33754
34156
|
AiLoaderNode,
|
|
33755
34157
|
PageNumber,
|
|
33756
34158
|
TotalPageCount,
|
|
34159
|
+
PageReference,
|
|
33757
34160
|
ShapeContainer,
|
|
33758
34161
|
ShapeTextbox,
|
|
33759
34162
|
ContentBlock,
|
|
33760
34163
|
Search,
|
|
33761
34164
|
StructuredContent,
|
|
33762
34165
|
StructuredContentBlock,
|
|
34166
|
+
StructuredContentCommands,
|
|
33763
34167
|
DocumentSection,
|
|
34168
|
+
DocumentPartObject,
|
|
33764
34169
|
NodeResizer,
|
|
33765
34170
|
CustomSelection,
|
|
33766
34171
|
TextTransform
|