superdoc 0.31.0-next.10 → 0.31.0-next.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/chunks/{PdfViewer-CxLHqmsp.cjs → PdfViewer-D9P6oSyP.cjs} +1 -1
- package/dist/chunks/{PdfViewer-Ck2UtdkO.es.js → PdfViewer-DrGdcxMi.es.js} +1 -1
- package/dist/chunks/{index-S2kR904m.es.js → index-8TkBu9O_.es.js} +3 -3
- package/dist/chunks/{index-qZtf9OYt.cjs → index-ZC9yiay1.cjs} +3 -3
- package/dist/chunks/{index-TPvf306Z-DLAdtd9g.es.js → index-hUtaGvC8-Vf8Tdemp.es.js} +1 -1
- package/dist/chunks/{index-TPvf306Z-Dymhw354.cjs → index-hUtaGvC8-aunRWvRG.cjs} +1 -1
- package/dist/chunks/{super-editor.es-d0fSEchl.cjs → super-editor.es-4uI_8knu.cjs} +2315 -2525
- package/dist/chunks/{super-editor.es-CNPHD-mt.es.js → super-editor.es-DS6vzo6Y.es.js} +2315 -2525
- package/dist/super-editor/ai-writer.es.js +2 -2
- package/dist/super-editor/chunks/{converter-CuN7BQ8r.js → converter-DNZlAyEp.js} +236 -129
- package/dist/super-editor/chunks/{docx-zipper-DvU3g1QE.js → docx-zipper-CGXr6ESB.js} +1 -1
- package/dist/super-editor/chunks/{editor-CJUnMzXV.js → editor-BG6XbVA7.js} +1808 -2103
- package/dist/super-editor/chunks/{index-TPvf306Z.js → index-hUtaGvC8.js} +1 -1
- package/dist/super-editor/chunks/{toolbar-_AUH-ukY.js → toolbar-8Nf_jruN.js} +2 -2
- package/dist/super-editor/converter.es.js +2 -2
- 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/super-editor/src/components/toolbar/defaultItems.d.ts.map +1 -1
- package/dist/super-editor/super-editor/src/components/toolbar/super-toolbar.d.ts.map +1 -1
- package/dist/super-editor/super-editor/src/core/commands/changeListLevel.d.ts.map +1 -1
- package/dist/super-editor/super-editor/src/core/commands/index.d.ts +2 -0
- package/dist/super-editor/super-editor/src/core/commands/lineHeight.d.ts +7 -0
- package/dist/super-editor/super-editor/src/core/commands/lineHeight.d.ts.map +1 -0
- package/dist/super-editor/super-editor/src/core/commands/list-helpers/is-list.d.ts.map +1 -1
- package/dist/super-editor/super-editor/src/core/commands/removeNumberingProperties.d.ts.map +1 -1
- package/dist/super-editor/super-editor/src/core/commands/resetAttributes.d.ts.map +1 -1
- package/dist/super-editor/super-editor/src/core/commands/restartNumbering.d.ts.map +1 -1
- package/dist/super-editor/super-editor/src/core/commands/textIndent.d.ts +5 -0
- package/dist/super-editor/super-editor/src/core/commands/textIndent.d.ts.map +1 -0
- package/dist/super-editor/super-editor/src/core/commands/toggleList.d.ts.map +1 -1
- package/dist/super-editor/super-editor/src/core/commands/updateAttributes.d.ts +4 -4
- package/dist/super-editor/super-editor/src/core/commands/updateAttributes.d.ts.map +1 -1
- package/dist/super-editor/super-editor/src/core/super-converter/styles.d.ts +57 -12
- package/dist/super-editor/super-editor/src/core/super-converter/styles.d.ts.map +1 -1
- package/dist/super-editor/super-editor/src/core/super-converter/v2/importer/types/index.d.ts +4 -0
- package/dist/super-editor/super-editor/src/core/super-converter/v2/importer/types/index.d.ts.map +1 -1
- package/dist/super-editor/super-editor/src/core/super-converter/v3/handlers/w/p/helpers/generate-paragraph-properties.d.ts.map +1 -1
- package/dist/super-editor/super-editor/src/core/super-converter/v3/handlers/w/p/helpers/legacy-handle-paragraph-node.d.ts.map +1 -1
- package/dist/super-editor/super-editor/src/core/utilities/deleteProps.d.ts.map +1 -1
- package/dist/super-editor/super-editor/src/extensions/index.d.ts +1 -3
- package/dist/super-editor/super-editor/src/extensions/index.d.ts.map +1 -1
- package/dist/super-editor/super-editor/src/extensions/linked-styles/helpers.d.ts.map +1 -1
- package/dist/super-editor/super-editor/src/extensions/linked-styles/linked-styles.d.ts.map +1 -1
- package/dist/super-editor/super-editor/src/extensions/linked-styles/plugin.d.ts.map +1 -1
- package/dist/super-editor/super-editor/src/extensions/paragraph/ParagraphNodeView.d.ts.map +1 -1
- package/dist/super-editor/super-editor/src/extensions/paragraph/dropcapPlugin.d.ts +4 -0
- package/dist/super-editor/super-editor/src/extensions/paragraph/dropcapPlugin.d.ts.map +1 -0
- package/dist/super-editor/super-editor/src/extensions/paragraph/numberingPlugin.d.ts.map +1 -1
- package/dist/super-editor/super-editor/src/extensions/paragraph/paragraph.d.ts +0 -9
- package/dist/super-editor/super-editor/src/extensions/paragraph/paragraph.d.ts.map +1 -1
- package/dist/super-editor/super-editor/src/extensions/paragraph/resolvedPropertiesCache.d.ts +3 -0
- package/dist/super-editor/super-editor/src/extensions/paragraph/resolvedPropertiesCache.d.ts.map +1 -0
- package/dist/super-editor/super-editor/src/extensions/tab/helpers/tabDecorations.d.ts.map +1 -1
- package/dist/super-editor/super-editor/src/extensions/text-align/text-align.d.ts +0 -12
- package/dist/super-editor/super-editor/src/extensions/text-align/text-align.d.ts.map +1 -1
- package/dist/super-editor/super-editor/src/tests/data/annotations_doc_content.d.ts +113 -61
- package/dist/super-editor/super-editor.es.js +41 -63
- 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 +2320 -2530
- package/dist/superdoc.umd.js.map +1 -1
- package/package.json +1 -1
- package/dist/super-editor/super-editor/src/extensions/line-height/index.d.ts +0 -2
- package/dist/super-editor/super-editor/src/extensions/line-height/index.d.ts.map +0 -1
- package/dist/super-editor/super-editor/src/extensions/line-height/line-height.d.ts +0 -44
- package/dist/super-editor/super-editor/src/extensions/line-height/line-height.d.ts.map +0 -1
- package/dist/super-editor/super-editor/src/extensions/text-indent/index.d.ts +0 -2
- package/dist/super-editor/super-editor/src/extensions/text-indent/index.d.ts.map +0 -1
- package/dist/super-editor/super-editor/src/extensions/text-indent/text-indent.d.ts +0 -37
- package/dist/super-editor/super-editor/src/extensions/text-indent/text-indent.d.ts.map +0 -1
|
@@ -9,11 +9,11 @@ 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, isElementNode_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, getPluginKeyName_fn, createExtensionService_fn, createCommandService_fn, createConverter_fn, initMedia_fn, initFonts_fn, checkFonts_fn, determineUnsupportedFonts_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, _ParagraphNodeView_instances, updateHTMLAttributes_fn, updateListStyles_fn, initList_fn, checkIsList_fn, createMarker_fn, createSeparator_fn, calculateTabSeparatorStyle_fn, calculateMarkerStyle_fn, removeList_fn, getParagraphContext_fn, scheduleAnimation_fn, cancelScheduledAnimation_fn, _FieldAnnotationView_instances, createAnnotation_fn, _AutoPageNumberNodeView_instances, renderDom_fn, scheduleUpdateNodeStyle_fn;
|
|
12
|
+
var _Attribute_static, getGlobalAttributes_fn, getNodeAndMarksAttributes_fn, isElementNode_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, getPluginKeyName_fn, createExtensionService_fn, createCommandService_fn, createConverter_fn, initMedia_fn, initFonts_fn, checkFonts_fn, determineUnsupportedFonts_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, _ParagraphNodeView_instances, updateHTMLAttributes_fn, updateDOMStyles_fn, updateListStyles_fn, initList_fn, checkIsList_fn, createMarker_fn, createSeparator_fn, calculateTabSeparatorStyle_fn, calculateMarkerStyle_fn, removeList_fn, getParagraphContext_fn, scheduleAnimation_fn, cancelScheduledAnimation_fn, _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 htmlHandler, E as ReplaceStep,
|
|
16
|
-
import { D as DocxZipper } from "./docx-zipper-
|
|
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 htmlHandler, E as ReplaceStep, G as ptToTwips, H as getResolvedParagraphProperties, I as linesToTwips, L as ListHelpers, J as updateNumberingProperties, K as changeListLevel, O as findParentNode, Q as isList, U as isMacOS, V as isIOS, W as getSchemaTypeByName, X as inputRulesPlugin, Y as TrackDeleteMarkName, Z as TrackInsertMarkName, _ as v4, $ as TrackFormatMarkName, a0 as comments_module_events, a1 as findMark, a2 as objectIncludes, a3 as AddMarkStep, a4 as RemoveMarkStep, a5 as twipsToLines, a6 as pixelsToTwips, a7 as helpers, a8 as posToDOMRect, a9 as CommandService, aa as SuperConverter, ab as createDocument, ac as createDocFromMarkdown, ad as createDocFromHTML, ae as EditorState, af as hasSomeParentWithClass, ag as isActive, ah as unflattenListsInHtml, ai as parseSizeUnit, aj as minMax, ak as updateDOMAttributes, al as findChildren$5, am as generateRandomSigned32BitIntStrId, an as twipsToPixels, ao as calculateResolvedParagraphProperties, ap as encodeCSSFromPPr, aq as resolveRunProperties, ar as encodeCSSFromRPr, as as docxNumberingHelpers, at as InputRule, au as convertSizeToCSS, av as SelectionRange, aw as Transform, ax as findParentNodeClosestToPos, ay as isInTable$1, az as generateDocxRandomId, aA as insertNewRelationship, aB as inchesToPixels, aC as kebabCase, aD as getUnderlineCssString } from "./converter-DNZlAyEp.js";
|
|
16
|
+
import { D as DocxZipper } from "./docx-zipper-CGXr6ESB.js";
|
|
17
17
|
import { ref, computed, createElementBlock, openBlock, withModifiers, Fragment as Fragment$1, renderList, normalizeClass, createCommentVNode, toDisplayString, createElementVNode, createApp } from "vue";
|
|
18
18
|
var GOOD_LEAF_SIZE = 200;
|
|
19
19
|
var RopeSequence = function RopeSequence2() {
|
|
@@ -9028,22 +9028,53 @@ const updateAttributes = (typeOrName, attrs = {}) => ({ tr, state, dispatch }) =
|
|
|
9028
9028
|
const to = range.$to.pos;
|
|
9029
9029
|
state.doc.nodesBetween(from2, to, (node, pos) => {
|
|
9030
9030
|
if (nodeType && nodeType === node.type) {
|
|
9031
|
-
|
|
9031
|
+
const resolvedAttrs = mergeAttributes(node.attrs, attrs);
|
|
9032
|
+
tr.setNodeMarkup(pos, void 0, resolvedAttrs);
|
|
9032
9033
|
}
|
|
9033
9034
|
if (markType && node.marks.length) {
|
|
9034
9035
|
node.marks.forEach((mark) => {
|
|
9035
9036
|
if (markType === mark.type) {
|
|
9036
9037
|
const trimmedFrom = Math.max(pos, from2);
|
|
9037
9038
|
const trimmedTo = Math.min(pos + node.nodeSize, to);
|
|
9038
|
-
|
|
9039
|
+
const resolvedAttrs = mergeAttributes(mark.attrs, attrs);
|
|
9040
|
+
tr.addMark(trimmedFrom, trimmedTo, markType.create(resolvedAttrs));
|
|
9039
9041
|
}
|
|
9040
9042
|
});
|
|
9041
9043
|
}
|
|
9042
9044
|
});
|
|
9043
9045
|
});
|
|
9046
|
+
dispatch(tr);
|
|
9044
9047
|
}
|
|
9045
9048
|
return true;
|
|
9046
9049
|
};
|
|
9050
|
+
const isPlainObject = (value) => Boolean(value) && typeof value === "object" && !Array.isArray(value);
|
|
9051
|
+
const assignNestedValue = (target, path, value) => {
|
|
9052
|
+
if (!path.includes(".")) {
|
|
9053
|
+
target[path] = value;
|
|
9054
|
+
return;
|
|
9055
|
+
}
|
|
9056
|
+
const parts = path.split(".");
|
|
9057
|
+
let current = target;
|
|
9058
|
+
for (let i = 0; i < parts.length; i += 1) {
|
|
9059
|
+
const part = parts[i];
|
|
9060
|
+
const isLast = i === parts.length - 1;
|
|
9061
|
+
if (isLast) {
|
|
9062
|
+
current[part] = value;
|
|
9063
|
+
} else {
|
|
9064
|
+
if (!isPlainObject(current[part])) {
|
|
9065
|
+
current[part] = {};
|
|
9066
|
+
}
|
|
9067
|
+
current = current[part];
|
|
9068
|
+
}
|
|
9069
|
+
}
|
|
9070
|
+
};
|
|
9071
|
+
const mergeAttributes = (existingAttrs = {}, newAttrs = {}) => {
|
|
9072
|
+
const expandedAttrs = JSON.parse(JSON.stringify(existingAttrs));
|
|
9073
|
+
Object.entries(newAttrs).forEach(([key2, value]) => {
|
|
9074
|
+
assignNestedValue(expandedAttrs, key2, value);
|
|
9075
|
+
});
|
|
9076
|
+
return expandedAttrs;
|
|
9077
|
+
};
|
|
9047
9078
|
const resetAttributes = (typeOrName, attrs) => ({ tr, state, dispatch }) => {
|
|
9048
9079
|
let nodeType = null;
|
|
9049
9080
|
let markType = null;
|
|
@@ -9073,6 +9104,7 @@ const resetAttributes = (typeOrName, attrs) => ({ tr, state, dispatch }) => {
|
|
|
9073
9104
|
}
|
|
9074
9105
|
});
|
|
9075
9106
|
});
|
|
9107
|
+
dispatch(tr);
|
|
9076
9108
|
}
|
|
9077
9109
|
return true;
|
|
9078
9110
|
};
|
|
@@ -9351,12 +9383,92 @@ const undoInputRule = () => ({ state, dispatch }) => {
|
|
|
9351
9383
|
}
|
|
9352
9384
|
return false;
|
|
9353
9385
|
};
|
|
9386
|
+
const defaultIncrementPoints = 36;
|
|
9387
|
+
const increaseTextIndent = () => modifyIndentation((node) => calculateNewIndentation(node, 1));
|
|
9388
|
+
const decreaseTextIndent = () => modifyIndentation((node) => calculateNewIndentation(node, -1));
|
|
9389
|
+
const setTextIndentation = (points) => modifyIndentation(() => ptToTwips(points));
|
|
9390
|
+
const unsetTextIndentation = () => modifyIndentation(() => null);
|
|
9391
|
+
function calculateNewIndentation(node, delta) {
|
|
9392
|
+
let { indent } = getResolvedParagraphProperties(node);
|
|
9393
|
+
let { left: left2 } = indent || {};
|
|
9394
|
+
const increment = ptToTwips(delta * defaultIncrementPoints);
|
|
9395
|
+
if (!left2) {
|
|
9396
|
+
left2 = increment;
|
|
9397
|
+
} else {
|
|
9398
|
+
left2 += increment;
|
|
9399
|
+
}
|
|
9400
|
+
if (left2 <= 0) {
|
|
9401
|
+
left2 = null;
|
|
9402
|
+
}
|
|
9403
|
+
return left2;
|
|
9404
|
+
}
|
|
9405
|
+
function modifyIndentation(calcFunc) {
|
|
9406
|
+
return ({ state, dispatch }) => {
|
|
9407
|
+
const tr = state.tr;
|
|
9408
|
+
const { from: from2, to } = state.selection;
|
|
9409
|
+
const results = [];
|
|
9410
|
+
state.doc.nodesBetween(from2, to, (node, pos) => {
|
|
9411
|
+
if (node.type.name === "paragraph") {
|
|
9412
|
+
let left2 = calcFunc(node);
|
|
9413
|
+
if (Number.isNaN(left2)) {
|
|
9414
|
+
results.push(false);
|
|
9415
|
+
return false;
|
|
9416
|
+
}
|
|
9417
|
+
const newAttrs = {
|
|
9418
|
+
...node.attrs,
|
|
9419
|
+
paragraphProperties: {
|
|
9420
|
+
...node.attrs.paragraphProperties || {},
|
|
9421
|
+
indent: {
|
|
9422
|
+
...node.attrs.paragraphProperties?.indent || {},
|
|
9423
|
+
left: left2
|
|
9424
|
+
}
|
|
9425
|
+
}
|
|
9426
|
+
};
|
|
9427
|
+
if (left2 == null) {
|
|
9428
|
+
delete newAttrs.paragraphProperties.indent.left;
|
|
9429
|
+
if (Object.keys(newAttrs.paragraphProperties.indent).length === 0) {
|
|
9430
|
+
delete newAttrs.paragraphProperties.indent;
|
|
9431
|
+
}
|
|
9432
|
+
}
|
|
9433
|
+
tr.setNodeMarkup(pos, void 0, newAttrs);
|
|
9434
|
+
results.push(true);
|
|
9435
|
+
return false;
|
|
9436
|
+
}
|
|
9437
|
+
return true;
|
|
9438
|
+
});
|
|
9439
|
+
const success = results.every((result) => result);
|
|
9440
|
+
if (dispatch && success) {
|
|
9441
|
+
dispatch(tr);
|
|
9442
|
+
}
|
|
9443
|
+
return success;
|
|
9444
|
+
};
|
|
9445
|
+
}
|
|
9446
|
+
const setLineHeight = (lineHeight) => ({ commands: commands2 }) => {
|
|
9447
|
+
if (!lineHeight) return false;
|
|
9448
|
+
return commands2.updateAttributes("paragraph", {
|
|
9449
|
+
"paragraphProperties.spacing.line": linesToTwips(lineHeight),
|
|
9450
|
+
"paragraphProperties.spacing.lineRule": "auto"
|
|
9451
|
+
});
|
|
9452
|
+
};
|
|
9453
|
+
const unsetLineHeight = () => ({ commands: commands2 }) => {
|
|
9454
|
+
return commands2.resetAttributes(
|
|
9455
|
+
"paragraph",
|
|
9456
|
+
"paragraphProperties.spacing.line",
|
|
9457
|
+
"paragraphProperties.spacing.lineRule"
|
|
9458
|
+
);
|
|
9459
|
+
};
|
|
9354
9460
|
const toggleList = (listType) => ({ editor, state, tr, dispatch }) => {
|
|
9355
9461
|
let predicate;
|
|
9356
9462
|
if (listType === "orderedList") {
|
|
9357
|
-
predicate = (n) =>
|
|
9463
|
+
predicate = (n) => {
|
|
9464
|
+
const paraProps = getResolvedParagraphProperties(n);
|
|
9465
|
+
return paraProps.numberingProperties && n.attrs.listRendering && n.attrs.listRendering.numberingType !== "bullet";
|
|
9466
|
+
};
|
|
9358
9467
|
} else if (listType === "bulletList") {
|
|
9359
|
-
predicate = (n) =>
|
|
9468
|
+
predicate = (n) => {
|
|
9469
|
+
const paraProps = getResolvedParagraphProperties(n);
|
|
9470
|
+
return paraProps.numberingProperties && n.attrs.listRendering && n.attrs.listRendering.numberingType === "bullet";
|
|
9471
|
+
};
|
|
9360
9472
|
} else {
|
|
9361
9473
|
return false;
|
|
9362
9474
|
}
|
|
@@ -9394,7 +9506,8 @@ const toggleList = (listType) => ({ editor, state, tr, dispatch }) => {
|
|
|
9394
9506
|
mode = "remove";
|
|
9395
9507
|
} else {
|
|
9396
9508
|
mode = "reuse";
|
|
9397
|
-
const
|
|
9509
|
+
const paraProps = getResolvedParagraphProperties(firstListNode);
|
|
9510
|
+
const baseNumbering = paraProps.numberingProperties || {};
|
|
9398
9511
|
sharedNumberingProperties = {
|
|
9399
9512
|
...baseNumbering,
|
|
9400
9513
|
ilvl: baseNumbering.ilvl ?? 0
|
|
@@ -9445,7 +9558,7 @@ const removeNumberingProperties = ({ checkType = "startParagraph" } = {}) => (pr
|
|
|
9445
9558
|
const { $from, empty: empty2 } = state.selection;
|
|
9446
9559
|
if ((!empty2 || $from.parentOffset !== 0) && !isVisuallyEmptyParagraph(paragraph)) return false;
|
|
9447
9560
|
}
|
|
9448
|
-
const ilvl = paragraph.
|
|
9561
|
+
const ilvl = getResolvedParagraphProperties(paragraph).numberingProperties.ilvl;
|
|
9449
9562
|
if (ilvl > 0) {
|
|
9450
9563
|
const outdented = decreaseListIndent()(props);
|
|
9451
9564
|
if (outdented) {
|
|
@@ -9540,6 +9653,7 @@ const commands$1 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.definePr
|
|
|
9540
9653
|
command,
|
|
9541
9654
|
createParagraphNear,
|
|
9542
9655
|
decreaseListIndent,
|
|
9656
|
+
decreaseTextIndent,
|
|
9543
9657
|
defaultStyleDetector,
|
|
9544
9658
|
deleteSelection,
|
|
9545
9659
|
exitCode,
|
|
@@ -9548,6 +9662,7 @@ const commands$1 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.definePr
|
|
|
9548
9662
|
getSelectionMarks,
|
|
9549
9663
|
getStyleIdFromMarks,
|
|
9550
9664
|
increaseListIndent,
|
|
9665
|
+
increaseTextIndent,
|
|
9551
9666
|
insertContent,
|
|
9552
9667
|
insertContentAt,
|
|
9553
9668
|
insertTabChar,
|
|
@@ -9569,9 +9684,11 @@ const commands$1 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.definePr
|
|
|
9569
9684
|
selectNodeForward,
|
|
9570
9685
|
selectTextblockEnd,
|
|
9571
9686
|
selectTextblockStart,
|
|
9687
|
+
setLineHeight,
|
|
9572
9688
|
setMark,
|
|
9573
9689
|
setMeta,
|
|
9574
9690
|
setNode,
|
|
9691
|
+
setTextIndentation,
|
|
9575
9692
|
setTextSelection,
|
|
9576
9693
|
splitBlock: splitBlock$1,
|
|
9577
9694
|
toggleList,
|
|
@@ -9580,7 +9697,9 @@ const commands$1 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.definePr
|
|
|
9580
9697
|
toggleNode,
|
|
9581
9698
|
undoInputRule,
|
|
9582
9699
|
unsetAllMarks,
|
|
9700
|
+
unsetLineHeight,
|
|
9583
9701
|
unsetMark,
|
|
9702
|
+
unsetTextIndentation,
|
|
9584
9703
|
updateAttributes,
|
|
9585
9704
|
updateNumberingProperties
|
|
9586
9705
|
}, Symbol.toStringTag, { value: "Module" }));
|
|
@@ -13502,7 +13621,7 @@ const getLevel = (node) => {
|
|
|
13502
13621
|
const lvl = node.getAttribute("data-level");
|
|
13503
13622
|
return lvl ? parseInt(lvl, 10) : 0;
|
|
13504
13623
|
};
|
|
13505
|
-
const summaryVersion = "0.31.0-next.
|
|
13624
|
+
const summaryVersion = "0.31.0-next.11";
|
|
13506
13625
|
const nodeKeys = [
|
|
13507
13626
|
"group",
|
|
13508
13627
|
"content",
|
|
@@ -14222,7 +14341,7 @@ const _Editor = class _Editor extends EventEmitter {
|
|
|
14222
14341
|
{ default: remarkStringify },
|
|
14223
14342
|
{ default: remarkGfm }
|
|
14224
14343
|
] = await Promise.all([
|
|
14225
|
-
import("./index-
|
|
14344
|
+
import("./index-hUtaGvC8.js"),
|
|
14226
14345
|
import("./index-DRCvimau.js"),
|
|
14227
14346
|
import("./index-C_x_N6Uh.js"),
|
|
14228
14347
|
import("./index-D_sWOSiG.js"),
|
|
@@ -14423,7 +14542,7 @@ const _Editor = class _Editor extends EventEmitter {
|
|
|
14423
14542
|
* Process collaboration migrations
|
|
14424
14543
|
*/
|
|
14425
14544
|
processCollaborationMigrations() {
|
|
14426
|
-
console.debug("[checkVersionMigrations] Current editor version", "0.31.0-next.
|
|
14545
|
+
console.debug("[checkVersionMigrations] Current editor version", "0.31.0-next.11");
|
|
14427
14546
|
if (!this.options.ydoc) return;
|
|
14428
14547
|
const metaMap = this.options.ydoc.getMap("meta");
|
|
14429
14548
|
let docVersion = metaMap.get("version");
|
|
@@ -15339,37 +15458,9 @@ const TextAlign = Extension.create({
|
|
|
15339
15458
|
name: "textAlign",
|
|
15340
15459
|
addOptions() {
|
|
15341
15460
|
return {
|
|
15342
|
-
types: ["heading", "paragraph"],
|
|
15343
15461
|
alignments: ["left", "center", "right", "justify"]
|
|
15344
15462
|
};
|
|
15345
15463
|
},
|
|
15346
|
-
addGlobalAttributes() {
|
|
15347
|
-
return [
|
|
15348
|
-
{
|
|
15349
|
-
types: this.options.types,
|
|
15350
|
-
attributes: {
|
|
15351
|
-
/**
|
|
15352
|
-
* @category Attribute
|
|
15353
|
-
* @param {string} [textAlign='left'] - Text alignment value (left, center, right, justify)
|
|
15354
|
-
*/
|
|
15355
|
-
textAlign: {
|
|
15356
|
-
default: this.options.defaultAlignment,
|
|
15357
|
-
parseDOM: (el) => {
|
|
15358
|
-
const alignment = el.style.textAlign || this.options.defaultAlignment;
|
|
15359
|
-
const containsAlignment = this.options.alignments.includes(alignment);
|
|
15360
|
-
return containsAlignment ? alignment : this.options.defaultAlignment;
|
|
15361
|
-
},
|
|
15362
|
-
renderDOM: (attrs) => {
|
|
15363
|
-
if (attrs.textAlign === this.options.defaultAlignment) return {};
|
|
15364
|
-
const textAlign = attrs.textAlign === "both" ? "justify" : attrs.textAlign;
|
|
15365
|
-
if (!textAlign) return {};
|
|
15366
|
-
return { style: `text-align: ${textAlign}` };
|
|
15367
|
-
}
|
|
15368
|
-
}
|
|
15369
|
-
}
|
|
15370
|
-
}
|
|
15371
|
-
];
|
|
15372
|
-
},
|
|
15373
15464
|
addCommands() {
|
|
15374
15465
|
return {
|
|
15375
15466
|
/**
|
|
@@ -15379,12 +15470,11 @@ const TextAlign = Extension.create({
|
|
|
15379
15470
|
* @example
|
|
15380
15471
|
* editor.commands.setTextAlign('center')
|
|
15381
15472
|
* editor.commands.setTextAlign('justify')
|
|
15382
|
-
* @note Applies to all configured node types (heading, paragraph by default)
|
|
15383
15473
|
*/
|
|
15384
15474
|
setTextAlign: (alignment) => ({ commands: commands2 }) => {
|
|
15385
15475
|
const containsAlignment = this.options.alignments.includes(alignment);
|
|
15386
15476
|
if (!containsAlignment) return false;
|
|
15387
|
-
return
|
|
15477
|
+
return commands2.updateAttributes("paragraph", { "paragraphProperties.justification": alignment });
|
|
15388
15478
|
},
|
|
15389
15479
|
/**
|
|
15390
15480
|
* Remove text alignment (reset to default)
|
|
@@ -15393,9 +15483,7 @@ const TextAlign = Extension.create({
|
|
|
15393
15483
|
* editor.commands.unsetTextAlign()
|
|
15394
15484
|
* @note Resets alignment to the default value
|
|
15395
15485
|
*/
|
|
15396
|
-
unsetTextAlign: () => ({ commands: commands2 }) =>
|
|
15397
|
-
return this.options.types.map((type) => commands2.resetAttributes(type, "textAlign")).every((result) => result);
|
|
15398
|
-
}
|
|
15486
|
+
unsetTextAlign: () => ({ commands: commands2 }) => commands2.resetAttributes("paragraph", "paragraphProperties.justification")
|
|
15399
15487
|
};
|
|
15400
15488
|
},
|
|
15401
15489
|
addShortcuts() {
|
|
@@ -15407,189 +15495,6 @@ const TextAlign = Extension.create({
|
|
|
15407
15495
|
};
|
|
15408
15496
|
}
|
|
15409
15497
|
});
|
|
15410
|
-
const TextIndent = Extension.create({
|
|
15411
|
-
name: "textIndent",
|
|
15412
|
-
addOptions() {
|
|
15413
|
-
return {
|
|
15414
|
-
types: ["heading", "paragraph"],
|
|
15415
|
-
defaults: {
|
|
15416
|
-
unit: "in",
|
|
15417
|
-
increment: 0.125
|
|
15418
|
-
}
|
|
15419
|
-
};
|
|
15420
|
-
},
|
|
15421
|
-
addGlobalAttributes() {
|
|
15422
|
-
return [
|
|
15423
|
-
{
|
|
15424
|
-
types: this.options.types,
|
|
15425
|
-
attributes: {
|
|
15426
|
-
/**
|
|
15427
|
-
* @category Attribute
|
|
15428
|
-
* @param {string} [textIndent] - Text indentation value with unit (e.g., '0.5in')
|
|
15429
|
-
*/
|
|
15430
|
-
textIndent: {
|
|
15431
|
-
default: null,
|
|
15432
|
-
parseDOM: (el) => el.style.textIndent,
|
|
15433
|
-
renderDOM: (attrs) => {
|
|
15434
|
-
if (!attrs.textIndent) return {};
|
|
15435
|
-
let [value, unit] = parseSizeUnit(attrs.textIndent);
|
|
15436
|
-
if (Number.isNaN(value) || !value) return {};
|
|
15437
|
-
unit = unit ? unit : this.options.defaults.unit;
|
|
15438
|
-
return { style: `margin-left: ${value}${unit}` };
|
|
15439
|
-
}
|
|
15440
|
-
}
|
|
15441
|
-
}
|
|
15442
|
-
}
|
|
15443
|
-
];
|
|
15444
|
-
},
|
|
15445
|
-
addCommands() {
|
|
15446
|
-
return {
|
|
15447
|
-
/**
|
|
15448
|
-
* Set text indentation
|
|
15449
|
-
* @category Command
|
|
15450
|
-
* @param {string} indent - Indentation value with unit (e.g., '0.5in', '2cm')
|
|
15451
|
-
* @returns {Function} Command function
|
|
15452
|
-
* @example
|
|
15453
|
-
* // Set to 0.5 inches
|
|
15454
|
-
* setTextIndent('0.5in')
|
|
15455
|
-
*
|
|
15456
|
-
* // Set to 2 centimeters
|
|
15457
|
-
* setTextIndent('2cm')
|
|
15458
|
-
* @note Accepts any valid CSS unit (in, cm, px, em, etc.)
|
|
15459
|
-
*/
|
|
15460
|
-
setTextIndent: (indent) => ({ commands: commands2 }) => {
|
|
15461
|
-
if (!indent) return false;
|
|
15462
|
-
return this.options.types.map((type) => commands2.updateAttributes(type, { textIndent: indent })).every((result) => result);
|
|
15463
|
-
},
|
|
15464
|
-
/**
|
|
15465
|
-
* Remove text indentation
|
|
15466
|
-
* @category Command
|
|
15467
|
-
* @returns {Function} Command function
|
|
15468
|
-
* @example
|
|
15469
|
-
* unsetTextIndent()
|
|
15470
|
-
* @note Removes all indentation from the selected nodes
|
|
15471
|
-
*/
|
|
15472
|
-
unsetTextIndent: () => ({ commands: commands2 }) => {
|
|
15473
|
-
return this.options.types.map((type) => commands2.resetAttributes(type, "textIndent")).every((result) => result);
|
|
15474
|
-
},
|
|
15475
|
-
/**
|
|
15476
|
-
* Increase text indentation
|
|
15477
|
-
* @category Command
|
|
15478
|
-
* @returns {Function} Command function
|
|
15479
|
-
* @example
|
|
15480
|
-
* increaseTextIndent()
|
|
15481
|
-
* @note Increments by the default value (0.125in by default)
|
|
15482
|
-
* @note Creates initial indent if none exists
|
|
15483
|
-
*/
|
|
15484
|
-
increaseTextIndent: () => ({ commands: commands2 }) => {
|
|
15485
|
-
return this.options.types.map((type) => {
|
|
15486
|
-
let { textIndent } = this.editor.getAttributes(type);
|
|
15487
|
-
if (!textIndent) {
|
|
15488
|
-
let { increment, unit: unit2 } = this.options.defaults;
|
|
15489
|
-
return commands2.updateAttributes(type, {
|
|
15490
|
-
textIndent: `${increment}${unit2}`
|
|
15491
|
-
});
|
|
15492
|
-
}
|
|
15493
|
-
let [value, unit] = parseSizeUnit(textIndent);
|
|
15494
|
-
value = Number(value) + this.options.defaults.increment;
|
|
15495
|
-
unit = unit ? unit : this.options.defaults.unit;
|
|
15496
|
-
if (Number.isNaN(value)) return false;
|
|
15497
|
-
return commands2.updateAttributes(type, {
|
|
15498
|
-
textIndent: `${value}${unit}`
|
|
15499
|
-
});
|
|
15500
|
-
}).every((result) => result);
|
|
15501
|
-
},
|
|
15502
|
-
/**
|
|
15503
|
-
* Decrease text indentation
|
|
15504
|
-
* @category Command
|
|
15505
|
-
* @returns {Function} Command function
|
|
15506
|
-
* @example
|
|
15507
|
-
* decreaseTextIndent()
|
|
15508
|
-
* @note Decrements by the default value (0.125in by default)
|
|
15509
|
-
* @note Removes indentation completely if it reaches 0 or below
|
|
15510
|
-
*/
|
|
15511
|
-
decreaseTextIndent: () => ({ commands: commands2 }) => {
|
|
15512
|
-
return this.options.types.map((type) => {
|
|
15513
|
-
let { textIndent } = this.editor.getAttributes(type);
|
|
15514
|
-
if (!textIndent) return false;
|
|
15515
|
-
let [value, unit] = parseSizeUnit(textIndent);
|
|
15516
|
-
value = Number(value) - this.options.defaults.increment;
|
|
15517
|
-
unit = unit ? unit : this.options.defaults.unit;
|
|
15518
|
-
if (Number.isNaN(value)) return false;
|
|
15519
|
-
if (value <= 0) {
|
|
15520
|
-
return commands2.unsetTextIndent();
|
|
15521
|
-
}
|
|
15522
|
-
return commands2.updateAttributes(type, {
|
|
15523
|
-
textIndent: `${value}${unit}`
|
|
15524
|
-
});
|
|
15525
|
-
}).every((result) => result);
|
|
15526
|
-
}
|
|
15527
|
-
};
|
|
15528
|
-
}
|
|
15529
|
-
});
|
|
15530
|
-
const LineHeight = Extension.create({
|
|
15531
|
-
name: "lineHeight",
|
|
15532
|
-
addOptions() {
|
|
15533
|
-
return {
|
|
15534
|
-
types: ["heading", "paragraph"],
|
|
15535
|
-
defaults: {
|
|
15536
|
-
unit: ""
|
|
15537
|
-
}
|
|
15538
|
-
};
|
|
15539
|
-
},
|
|
15540
|
-
addGlobalAttributes() {
|
|
15541
|
-
return [
|
|
15542
|
-
{
|
|
15543
|
-
types: this.options.types,
|
|
15544
|
-
attributes: {
|
|
15545
|
-
lineHeight: {
|
|
15546
|
-
default: null,
|
|
15547
|
-
parseDOM: (el) => el.style.lineHeight,
|
|
15548
|
-
renderDOM: (attrs) => {
|
|
15549
|
-
if (!attrs.lineHeight) return {};
|
|
15550
|
-
const lineHeightStyle = getLineHeightValueString(
|
|
15551
|
-
attrs.lineHeight,
|
|
15552
|
-
this.options.defaults.unit,
|
|
15553
|
-
attrs.spacing?.lineRule
|
|
15554
|
-
);
|
|
15555
|
-
return {
|
|
15556
|
-
style: `${lineHeightStyle}`
|
|
15557
|
-
};
|
|
15558
|
-
}
|
|
15559
|
-
}
|
|
15560
|
-
}
|
|
15561
|
-
}
|
|
15562
|
-
];
|
|
15563
|
-
},
|
|
15564
|
-
addCommands() {
|
|
15565
|
-
return {
|
|
15566
|
-
/**
|
|
15567
|
-
* Set line height for blocks
|
|
15568
|
-
* @category Command
|
|
15569
|
-
* @param {LineHeightValue} lineHeight - Line height to apply
|
|
15570
|
-
* @example
|
|
15571
|
-
* editor.commands.setLineHeight(1.5)
|
|
15572
|
-
* editor.commands.setLineHeight('24px')
|
|
15573
|
-
* editor.commands.setLineHeight(2)
|
|
15574
|
-
* @note Applies to paragraphs and headings
|
|
15575
|
-
*/
|
|
15576
|
-
setLineHeight: (lineHeight) => ({ commands: commands2 }) => {
|
|
15577
|
-
if (!lineHeight) return false;
|
|
15578
|
-
return this.options.types.map((type) => commands2.updateAttributes(type, { lineHeight })).every((result) => result);
|
|
15579
|
-
},
|
|
15580
|
-
/**
|
|
15581
|
-
* Remove line height
|
|
15582
|
-
* @category Command
|
|
15583
|
-
* @example
|
|
15584
|
-
* editor.commands.unsetLineHeight()
|
|
15585
|
-
* @note Reverts to default line spacing
|
|
15586
|
-
*/
|
|
15587
|
-
unsetLineHeight: () => ({ commands: commands2 }) => {
|
|
15588
|
-
return this.options.types.map((type) => commands2.resetAttributes(type, "lineHeight")).every((result) => result);
|
|
15589
|
-
}
|
|
15590
|
-
};
|
|
15591
|
-
}
|
|
15592
|
-
});
|
|
15593
15498
|
const FormatCommands = Extension.create({
|
|
15594
15499
|
name: "formatCommands",
|
|
15595
15500
|
addOptions() {
|
|
@@ -17979,1301 +17884,462 @@ const Run = OxmlNode.create({
|
|
|
17979
17884
|
return ["span", base2, 0];
|
|
17980
17885
|
}
|
|
17981
17886
|
});
|
|
17982
|
-
const
|
|
17983
|
-
|
|
17984
|
-
|
|
17985
|
-
const
|
|
17986
|
-
|
|
17987
|
-
|
|
17988
|
-
|
|
17989
|
-
|
|
17990
|
-
|
|
17991
|
-
|
|
17992
|
-
|
|
17993
|
-
|
|
17994
|
-
}
|
|
17995
|
-
|
|
17996
|
-
const DEFAULT_SELECTION_STATE = Object.freeze({
|
|
17997
|
-
focused: false,
|
|
17998
|
-
preservedSelection: null,
|
|
17999
|
-
showVisualSelection: false,
|
|
18000
|
-
skipFocusReset: false
|
|
18001
|
-
});
|
|
18002
|
-
const normalizeSelectionState = (state = {}) => ({
|
|
18003
|
-
...DEFAULT_SELECTION_STATE,
|
|
18004
|
-
...state
|
|
18005
|
-
});
|
|
18006
|
-
const CustomSelectionPluginKey = new PluginKey("CustomSelection");
|
|
18007
|
-
const handleClickOutside = (event, editor) => {
|
|
18008
|
-
const editorElem = editor?.options?.element;
|
|
18009
|
-
if (!editorElem) return;
|
|
18010
|
-
const isInsideEditor = editorElem?.contains(event.target);
|
|
18011
|
-
if (!isInsideEditor) {
|
|
18012
|
-
editor.setOptions({
|
|
18013
|
-
focusTarget: event.target
|
|
18014
|
-
});
|
|
18015
|
-
} else {
|
|
18016
|
-
editor.setOptions({
|
|
18017
|
-
focusTarget: null
|
|
18018
|
-
});
|
|
18019
|
-
}
|
|
18020
|
-
};
|
|
18021
|
-
function getFocusMeta(tr) {
|
|
18022
|
-
return tr.getMeta(CustomSelectionPluginKey);
|
|
18023
|
-
}
|
|
18024
|
-
function setFocusMeta(tr, value) {
|
|
18025
|
-
return tr.setMeta(CustomSelectionPluginKey, value);
|
|
18026
|
-
}
|
|
18027
|
-
function getFocusState(state) {
|
|
18028
|
-
return CustomSelectionPluginKey.getState(state);
|
|
18029
|
-
}
|
|
18030
|
-
const isToolbarInput = (target) => {
|
|
18031
|
-
return !!target?.closest(".button-text-input") || target?.classList?.contains("button-text-input");
|
|
18032
|
-
};
|
|
18033
|
-
const isToolbarButton = (target) => {
|
|
18034
|
-
return !!target?.closest(".toolbar-button") || target?.classList?.contains("toolbar-button");
|
|
18035
|
-
};
|
|
18036
|
-
const CustomSelection = Extension.create({
|
|
18037
|
-
name: "customSelection",
|
|
18038
|
-
addPmPlugins() {
|
|
18039
|
-
const editor = this.editor;
|
|
18040
|
-
const customSelectionPlugin = new Plugin({
|
|
18041
|
-
key: CustomSelectionPluginKey,
|
|
18042
|
-
state: {
|
|
18043
|
-
init: () => ({ ...DEFAULT_SELECTION_STATE }),
|
|
18044
|
-
apply: (tr, value) => {
|
|
18045
|
-
const meta = getFocusMeta(tr);
|
|
18046
|
-
if (meta !== void 0) {
|
|
18047
|
-
return { ...value, ...meta };
|
|
18048
|
-
}
|
|
18049
|
-
return value;
|
|
18050
|
-
}
|
|
18051
|
-
},
|
|
18052
|
-
view: () => {
|
|
18053
|
-
const clickHandler = (event) => handleClickOutside(event, editor);
|
|
18054
|
-
document?.addEventListener("mousedown", clickHandler);
|
|
18055
|
-
return {
|
|
18056
|
-
destroy: () => {
|
|
18057
|
-
document?.removeEventListener("mousedown", clickHandler);
|
|
18058
|
-
}
|
|
18059
|
-
};
|
|
18060
|
-
},
|
|
18061
|
-
props: {
|
|
18062
|
-
handleDOMEvents: {
|
|
18063
|
-
contextmenu: (view, event) => {
|
|
18064
|
-
if (shouldAllowNativeContextMenu(event)) {
|
|
18065
|
-
return false;
|
|
18066
|
-
}
|
|
18067
|
-
event.preventDefault();
|
|
18068
|
-
const { selection } = view.state;
|
|
18069
|
-
if (!selection.empty) {
|
|
18070
|
-
view.dispatch(
|
|
18071
|
-
setFocusMeta(view.state.tr, {
|
|
18072
|
-
focused: true,
|
|
18073
|
-
preservedSelection: selection,
|
|
18074
|
-
showVisualSelection: true,
|
|
18075
|
-
skipFocusReset: true
|
|
18076
|
-
})
|
|
18077
|
-
);
|
|
18078
|
-
}
|
|
18079
|
-
setTimeout(() => {
|
|
18080
|
-
view.focus();
|
|
18081
|
-
}, 0);
|
|
18082
|
-
return false;
|
|
18083
|
-
},
|
|
18084
|
-
mousedown: (view, event) => {
|
|
18085
|
-
if (event.button === 2) {
|
|
18086
|
-
if (shouldAllowNativeContextMenu(event)) {
|
|
18087
|
-
return false;
|
|
18088
|
-
}
|
|
18089
|
-
event.preventDefault();
|
|
18090
|
-
const { selection: selection2 } = view.state;
|
|
18091
|
-
if (!selection2.empty) {
|
|
18092
|
-
view.dispatch(
|
|
18093
|
-
setFocusMeta(view.state.tr, {
|
|
18094
|
-
focused: true,
|
|
18095
|
-
preservedSelection: selection2,
|
|
18096
|
-
showVisualSelection: true,
|
|
18097
|
-
skipFocusReset: true
|
|
18098
|
-
})
|
|
18099
|
-
);
|
|
18100
|
-
this.editor.setOptions({
|
|
18101
|
-
lastSelection: selection2,
|
|
18102
|
-
preservedSelection: selection2
|
|
18103
|
-
});
|
|
18104
|
-
}
|
|
18105
|
-
return false;
|
|
18106
|
-
}
|
|
18107
|
-
const { selection } = view.state;
|
|
18108
|
-
const target = event.target;
|
|
18109
|
-
const isElement2 = target instanceof Element;
|
|
18110
|
-
const isToolbarBtn = isElement2 && isToolbarButton(target);
|
|
18111
|
-
const isToolbarInp = isElement2 && isToolbarInput(target);
|
|
18112
|
-
this.editor.setOptions({
|
|
18113
|
-
focusTarget: target
|
|
18114
|
-
});
|
|
18115
|
-
if (isToolbarInp && !selection.empty) {
|
|
18116
|
-
view.dispatch(
|
|
18117
|
-
setFocusMeta(view.state.tr, {
|
|
18118
|
-
focused: true,
|
|
18119
|
-
preservedSelection: selection,
|
|
18120
|
-
showVisualSelection: true,
|
|
18121
|
-
skipFocusReset: false
|
|
18122
|
-
})
|
|
18123
|
-
);
|
|
18124
|
-
this.editor.setOptions({
|
|
18125
|
-
lastSelection: selection,
|
|
18126
|
-
preservedSelection: selection
|
|
18127
|
-
});
|
|
18128
|
-
return false;
|
|
18129
|
-
}
|
|
18130
|
-
if (isToolbarBtn && !isToolbarInp) {
|
|
18131
|
-
if (!selection.empty) {
|
|
18132
|
-
this.editor.setOptions({
|
|
18133
|
-
lastSelection: selection
|
|
18134
|
-
});
|
|
18135
|
-
view.dispatch(
|
|
18136
|
-
setFocusMeta(view.state.tr, {
|
|
18137
|
-
focused: true,
|
|
18138
|
-
preservedSelection: selection,
|
|
18139
|
-
showVisualSelection: true,
|
|
18140
|
-
skipFocusReset: false
|
|
18141
|
-
})
|
|
18142
|
-
);
|
|
18143
|
-
}
|
|
18144
|
-
return false;
|
|
18145
|
-
}
|
|
18146
|
-
if (!isToolbarBtn && !isToolbarInp) {
|
|
18147
|
-
view.dispatch(
|
|
18148
|
-
setFocusMeta(view.state.tr, {
|
|
18149
|
-
focused: false,
|
|
18150
|
-
preservedSelection: null,
|
|
18151
|
-
showVisualSelection: false,
|
|
18152
|
-
skipFocusReset: false
|
|
18153
|
-
})
|
|
18154
|
-
);
|
|
18155
|
-
if (!selection.empty && !this.editor.options.element?.contains(target)) {
|
|
18156
|
-
this.editor.setOptions({
|
|
18157
|
-
lastSelection: selection
|
|
18158
|
-
});
|
|
18159
|
-
const clearSelectionTr = view.state.tr.setSelection(TextSelection.create(view.state.doc, 0));
|
|
18160
|
-
view.dispatch(clearSelectionTr);
|
|
18161
|
-
}
|
|
18162
|
-
}
|
|
18163
|
-
},
|
|
18164
|
-
focus: (view) => {
|
|
18165
|
-
const target = this.editor.options.focusTarget;
|
|
18166
|
-
const isElement2 = target instanceof Element;
|
|
18167
|
-
const isToolbarBtn = isElement2 && isToolbarButton(target);
|
|
18168
|
-
const isToolbarInp = isElement2 && isToolbarInput(target);
|
|
18169
|
-
const focusState = getFocusState(view.state);
|
|
18170
|
-
if (focusState?.skipFocusReset) {
|
|
18171
|
-
view.dispatch(
|
|
18172
|
-
setFocusMeta(view.state.tr, normalizeSelectionState({ ...focusState, skipFocusReset: false }))
|
|
18173
|
-
);
|
|
18174
|
-
return false;
|
|
18175
|
-
}
|
|
18176
|
-
if (!isToolbarBtn && !isToolbarInp) {
|
|
18177
|
-
view.dispatch(
|
|
18178
|
-
setFocusMeta(view.state.tr, {
|
|
18179
|
-
focused: false,
|
|
18180
|
-
preservedSelection: null,
|
|
18181
|
-
showVisualSelection: false,
|
|
18182
|
-
skipFocusReset: false
|
|
18183
|
-
})
|
|
18184
|
-
);
|
|
18185
|
-
}
|
|
18186
|
-
},
|
|
18187
|
-
blur: (view) => {
|
|
18188
|
-
const target = this.editor.options.focusTarget;
|
|
18189
|
-
const isElement2 = target instanceof Element;
|
|
18190
|
-
const isToolbarBtn = isElement2 && isToolbarButton(target);
|
|
18191
|
-
const isToolbarInp = isElement2 && isToolbarInput(target);
|
|
18192
|
-
const state = getFocusState(view.state);
|
|
18193
|
-
if (state?.skipFocusReset) {
|
|
18194
|
-
return false;
|
|
18195
|
-
}
|
|
18196
|
-
if (isToolbarBtn || isToolbarInp) {
|
|
18197
|
-
view.dispatch(
|
|
18198
|
-
setFocusMeta(view.state.tr, {
|
|
18199
|
-
focused: true,
|
|
18200
|
-
preservedSelection: state.preservedSelection || view.state.selection,
|
|
18201
|
-
showVisualSelection: true,
|
|
18202
|
-
skipFocusReset: false
|
|
18203
|
-
})
|
|
18204
|
-
);
|
|
18205
|
-
} else {
|
|
18206
|
-
view.dispatch(
|
|
18207
|
-
setFocusMeta(view.state.tr, {
|
|
18208
|
-
focused: false,
|
|
18209
|
-
preservedSelection: null,
|
|
18210
|
-
showVisualSelection: false,
|
|
18211
|
-
skipFocusReset: false
|
|
18212
|
-
})
|
|
18213
|
-
);
|
|
18214
|
-
}
|
|
18215
|
-
}
|
|
18216
|
-
},
|
|
18217
|
-
decorations: (state) => {
|
|
18218
|
-
const { selection, doc: doc2 } = state;
|
|
18219
|
-
const focusState = getFocusState(state);
|
|
18220
|
-
const shouldShowSelection = focusState.showVisualSelection && (focusState.preservedSelection || !selection.empty && focusState.focused);
|
|
18221
|
-
if (!shouldShowSelection) {
|
|
18222
|
-
return null;
|
|
18223
|
-
}
|
|
18224
|
-
const targetSelection = focusState.preservedSelection || selection;
|
|
18225
|
-
if (targetSelection.empty) {
|
|
18226
|
-
return null;
|
|
18227
|
-
}
|
|
18228
|
-
return DecorationSet.create(doc2, [
|
|
18229
|
-
Decoration.inline(targetSelection.from, targetSelection.to, {
|
|
18230
|
-
class: "sd-custom-selection"
|
|
18231
|
-
})
|
|
18232
|
-
]);
|
|
18233
|
-
}
|
|
18234
|
-
}
|
|
18235
|
-
});
|
|
18236
|
-
return [customSelectionPlugin];
|
|
18237
|
-
},
|
|
18238
|
-
addCommands() {
|
|
18239
|
-
return {
|
|
18240
|
-
/**
|
|
18241
|
-
* Restore the preserved selection
|
|
18242
|
-
* @category Command
|
|
18243
|
-
* @returns {Function} Command function
|
|
18244
|
-
* @example
|
|
18245
|
-
* // Restore selection after toolbar interaction
|
|
18246
|
-
* editor.commands.restorePreservedSelection()
|
|
18247
|
-
* @note Used internally to maintain selection when interacting with toolbar
|
|
18248
|
-
*/
|
|
18249
|
-
restorePreservedSelection: () => ({ tr, state }) => {
|
|
18250
|
-
const focusState = getFocusState(state);
|
|
18251
|
-
if (focusState.preservedSelection) {
|
|
18252
|
-
return tr.setSelection(focusState.preservedSelection);
|
|
18253
|
-
}
|
|
18254
|
-
const lastSelection = this.editor.options.lastSelection;
|
|
18255
|
-
if (lastSelection) {
|
|
18256
|
-
return tr.setSelection(lastSelection);
|
|
18257
|
-
}
|
|
18258
|
-
return tr;
|
|
17887
|
+
const restartNumbering = ({ editor, tr, state, dispatch }) => {
|
|
17888
|
+
const { node: paragraph, pos } = findParentNode(isList)(state.selection) || {};
|
|
17889
|
+
if (!paragraph) return false;
|
|
17890
|
+
const allParagraphs = [{ node: paragraph, pos }];
|
|
17891
|
+
const startPos = pos + paragraph.nodeSize;
|
|
17892
|
+
const myNumId = getResolvedParagraphProperties(paragraph).numberingProperties.numId;
|
|
17893
|
+
let stop = false;
|
|
17894
|
+
state.doc.nodesBetween(startPos, state.doc.content.size, (node, nodePos) => {
|
|
17895
|
+
if (node.type.name === "paragraph") {
|
|
17896
|
+
const paraProps = getResolvedParagraphProperties(node);
|
|
17897
|
+
if (isList(node) && paraProps.numberingProperties?.numId === myNumId) {
|
|
17898
|
+
allParagraphs.push({ node, pos: nodePos });
|
|
17899
|
+
} else {
|
|
17900
|
+
stop = true;
|
|
18259
17901
|
}
|
|
18260
|
-
|
|
18261
|
-
|
|
18262
|
-
|
|
18263
|
-
|
|
18264
|
-
const
|
|
18265
|
-
const
|
|
18266
|
-
const
|
|
18267
|
-
|
|
17902
|
+
return false;
|
|
17903
|
+
}
|
|
17904
|
+
return !stop;
|
|
17905
|
+
});
|
|
17906
|
+
const { numberingType } = paragraph.attrs.listRendering || {};
|
|
17907
|
+
const listType = numberingType === "bullet" ? "bulletList" : "orderedList";
|
|
17908
|
+
const numId = ListHelpers.getNewListId(editor);
|
|
17909
|
+
ListHelpers.generateNewListDefinition({ numId: Number(numId), listType, editor });
|
|
17910
|
+
allParagraphs.forEach(({ node, pos: pos2 }) => {
|
|
17911
|
+
const paragraphProps = getResolvedParagraphProperties(node);
|
|
17912
|
+
updateNumberingProperties(
|
|
17913
|
+
{
|
|
17914
|
+
...paragraphProps.numberingProperties || {},
|
|
17915
|
+
numId: Number(numId)
|
|
17916
|
+
},
|
|
17917
|
+
node,
|
|
17918
|
+
pos2,
|
|
17919
|
+
editor,
|
|
17920
|
+
tr
|
|
17921
|
+
);
|
|
17922
|
+
});
|
|
17923
|
+
if (dispatch) dispatch(tr);
|
|
17924
|
+
return true;
|
|
18268
17925
|
};
|
|
18269
|
-
const
|
|
18270
|
-
|
|
18271
|
-
|
|
18272
|
-
const
|
|
18273
|
-
const
|
|
18274
|
-
|
|
18275
|
-
|
|
18276
|
-
|
|
18277
|
-
|
|
18278
|
-
|
|
18279
|
-
|
|
18280
|
-
|
|
18281
|
-
|
|
18282
|
-
|
|
18283
|
-
|
|
17926
|
+
const defaultTabDistance = 48;
|
|
17927
|
+
const defaultLineLength = 816;
|
|
17928
|
+
const getTabDecorations = (doc2, view, helpers2, from2 = 0, to = null) => {
|
|
17929
|
+
const decorations = [];
|
|
17930
|
+
const paragraphCache = /* @__PURE__ */ new Map();
|
|
17931
|
+
const coordCache = /* @__PURE__ */ new Map();
|
|
17932
|
+
const domPosCache = /* @__PURE__ */ new Map();
|
|
17933
|
+
const end2 = to ?? doc2.content.size;
|
|
17934
|
+
doc2.nodesBetween(from2, end2, (node, pos) => {
|
|
17935
|
+
if (node.type.name !== "tab") return;
|
|
17936
|
+
const $pos = doc2.resolve(pos);
|
|
17937
|
+
const paragraphContext = findParagraphContext($pos, paragraphCache, helpers2);
|
|
17938
|
+
if (!paragraphContext) return;
|
|
17939
|
+
const blockParent2 = $pos.node(paragraphContext.paragraphDepth);
|
|
17940
|
+
const style = calculateTabStyle(node.nodeSize, view, pos, blockParent2, paragraphContext, coordCache, domPosCache);
|
|
17941
|
+
if (style) {
|
|
17942
|
+
decorations.push(
|
|
17943
|
+
Decoration.node(pos, pos + node.nodeSize, {
|
|
17944
|
+
style
|
|
17945
|
+
})
|
|
17946
|
+
);
|
|
17947
|
+
}
|
|
17948
|
+
});
|
|
17949
|
+
return decorations;
|
|
18284
17950
|
};
|
|
18285
|
-
|
|
18286
|
-
let
|
|
18287
|
-
|
|
18288
|
-
|
|
18289
|
-
|
|
18290
|
-
|
|
18291
|
-
if (lineRule === "exact" && line) {
|
|
18292
|
-
line = String(line);
|
|
18293
|
-
}
|
|
18294
|
-
const textStyleMark = marks?.find((mark) => mark.type === "textStyle");
|
|
18295
|
-
const fontSize = textStyleMark?.attrs?.fontSize;
|
|
18296
|
-
before = twipsToPixels(before);
|
|
18297
|
-
if (beforeAutospacing) {
|
|
18298
|
-
if (fontSize) {
|
|
18299
|
-
before += halfPointToPixels(parseInt(fontSize) * 0.5);
|
|
17951
|
+
function calculateTabStyle(nodeSize2, view, pos, blockParent2, paragraphContext, coordCache = null, domPosCache = null) {
|
|
17952
|
+
let extraStyles = "";
|
|
17953
|
+
try {
|
|
17954
|
+
const { tabStops, flattened, positionMap, startPos } = paragraphContext;
|
|
17955
|
+
if (paragraphContext.indentWidth === void 0) {
|
|
17956
|
+
paragraphContext.indentWidth = getIndentWidth(view, startPos, paragraphContext.indent, coordCache, domPosCache);
|
|
18300
17957
|
}
|
|
18301
|
-
if (
|
|
18302
|
-
|
|
17958
|
+
if (paragraphContext.tabHeight === void 0) {
|
|
17959
|
+
paragraphContext.tabHeight = calcTabHeight(blockParent2);
|
|
18303
17960
|
}
|
|
18304
|
-
|
|
18305
|
-
|
|
18306
|
-
if (afterAutospacing) {
|
|
18307
|
-
if (fontSize) {
|
|
18308
|
-
after += halfPointToPixels(parseInt(fontSize) * 0.5);
|
|
17961
|
+
if (paragraphContext.paragraphWidth === void 0) {
|
|
17962
|
+
paragraphContext.paragraphWidth = getBlockNodeWidth(view, startPos);
|
|
18309
17963
|
}
|
|
18310
|
-
|
|
18311
|
-
|
|
17964
|
+
const indentWidth = paragraphContext.indentWidth;
|
|
17965
|
+
const hanging = twipsToPixels(Number(paragraphContext.indent.hanging) || 0);
|
|
17966
|
+
if (hanging > 0) {
|
|
17967
|
+
tabStops.unshift({ val: "start", pos: indentWidth + hanging });
|
|
17968
|
+
}
|
|
17969
|
+
const accumulatedTabWidth = paragraphContext.accumulatedTabWidth || 0;
|
|
17970
|
+
const currentWidth = indentWidth + measureRangeWidth(view, startPos + 1, pos, coordCache, domPosCache) + accumulatedTabWidth;
|
|
17971
|
+
let tabWidth;
|
|
17972
|
+
if (tabStops.length) {
|
|
17973
|
+
const tabStop = tabStops.find((stop) => stop.pos > currentWidth && stop.val !== "clear");
|
|
17974
|
+
if (tabStop) {
|
|
17975
|
+
tabWidth = Math.min(tabStop.pos, paragraphContext.paragraphWidth) - currentWidth;
|
|
17976
|
+
let val = tabStop.val;
|
|
17977
|
+
const aliases = { left: "start", right: "end" };
|
|
17978
|
+
if (aliases[val]) val = aliases[val];
|
|
17979
|
+
if (val === "center" || val === "end" || val === "right") {
|
|
17980
|
+
const entryIndex = positionMap.get(pos);
|
|
17981
|
+
if (entryIndex === void 0) return;
|
|
17982
|
+
const nextTabIndex = findNextTabIndex(flattened, entryIndex + 1);
|
|
17983
|
+
const segmentStartPos = pos + nodeSize2;
|
|
17984
|
+
const segmentEndPos = nextTabIndex === -1 ? startPos + paragraphContext.paragraph.nodeSize - 1 : flattened[nextTabIndex].pos;
|
|
17985
|
+
const segmentWidth = measureRangeWidth(view, segmentStartPos, segmentEndPos, coordCache, domPosCache);
|
|
17986
|
+
tabWidth -= val === "center" ? segmentWidth / 2 : segmentWidth;
|
|
17987
|
+
} else if (val === "decimal" || val === "num") {
|
|
17988
|
+
const entryIndex = positionMap.get(pos);
|
|
17989
|
+
if (entryIndex === void 0) return;
|
|
17990
|
+
const breakChar = tabStop.decimalChar || ".";
|
|
17991
|
+
const decimalPos = findDecimalBreakPos(flattened, entryIndex + 1, breakChar);
|
|
17992
|
+
const integralWidth = decimalPos ? measureRangeWidth(view, pos + nodeSize2, decimalPos, coordCache, domPosCache) : measureRangeWidth(
|
|
17993
|
+
view,
|
|
17994
|
+
pos + nodeSize2,
|
|
17995
|
+
startPos + paragraphContext.paragraph.nodeSize - 1,
|
|
17996
|
+
coordCache,
|
|
17997
|
+
domPosCache
|
|
17998
|
+
);
|
|
17999
|
+
tabWidth -= integralWidth;
|
|
18000
|
+
}
|
|
18001
|
+
if (tabStop.leader) {
|
|
18002
|
+
const leaderStyles = {
|
|
18003
|
+
dot: "border-bottom: 1px dotted black;",
|
|
18004
|
+
heavy: "border-bottom: 2px solid black;",
|
|
18005
|
+
hyphen: "border-bottom: 1px solid black;",
|
|
18006
|
+
middleDot: "border-bottom: 1px dotted black; margin-bottom: 2px;",
|
|
18007
|
+
underscore: "border-bottom: 1px solid black;"
|
|
18008
|
+
};
|
|
18009
|
+
extraStyles += leaderStyles[tabStop.leader] || "";
|
|
18010
|
+
}
|
|
18011
|
+
}
|
|
18312
18012
|
}
|
|
18013
|
+
if (!tabWidth || tabWidth < 1) {
|
|
18014
|
+
tabWidth = defaultTabDistance - currentWidth % defaultLineLength % defaultTabDistance;
|
|
18015
|
+
if (tabWidth === 0) tabWidth = defaultTabDistance;
|
|
18016
|
+
}
|
|
18017
|
+
const tabHeight = paragraphContext.tabHeight;
|
|
18018
|
+
paragraphContext.accumulatedTabWidth = accumulatedTabWidth + tabWidth;
|
|
18019
|
+
return `width: ${tabWidth}px; height: ${tabHeight}; ${extraStyles}`;
|
|
18020
|
+
} catch (error) {
|
|
18021
|
+
console.error("tab decoration error", error);
|
|
18313
18022
|
}
|
|
18314
|
-
|
|
18315
|
-
|
|
18316
|
-
|
|
18317
|
-
|
|
18318
|
-
|
|
18319
|
-
|
|
18320
|
-
|
|
18321
|
-
|
|
18322
|
-
|
|
18323
|
-
|
|
18324
|
-
|
|
18325
|
-
styles += `font-weight: bold; `;
|
|
18326
|
-
break;
|
|
18327
|
-
case "italic":
|
|
18328
|
-
styles += `font-style: italic; `;
|
|
18329
|
-
break;
|
|
18330
|
-
case "underline":
|
|
18331
|
-
styles += `text-decoration: underline; `;
|
|
18332
|
-
break;
|
|
18333
|
-
case "highlight":
|
|
18334
|
-
styles += `background-color: ${attr.attrs.color}; `;
|
|
18335
|
-
break;
|
|
18336
|
-
case "textStyle":
|
|
18337
|
-
const { fontFamily, fontSize } = attr.attrs;
|
|
18338
|
-
styles += `${fontFamily ? `font-family: ${fontFamily};` : ""} ${fontSize ? `font-size: ${fontSize};` : ""}`;
|
|
18339
|
-
break;
|
|
18023
|
+
}
|
|
18024
|
+
function findParagraphContext($pos, cache, helpers2) {
|
|
18025
|
+
for (let depth = $pos.depth; depth >= 0; depth--) {
|
|
18026
|
+
const node = $pos.node(depth);
|
|
18027
|
+
if (node?.type?.name === "paragraph") {
|
|
18028
|
+
const startPos = $pos.start(depth);
|
|
18029
|
+
if (!cache.has(startPos)) {
|
|
18030
|
+
const paragraphContext = extractParagraphContext(node, startPos, helpers2, depth);
|
|
18031
|
+
cache.set(startPos, paragraphContext);
|
|
18032
|
+
}
|
|
18033
|
+
return cache.get(startPos);
|
|
18340
18034
|
}
|
|
18341
18035
|
}
|
|
18342
|
-
return
|
|
18343
|
-
}
|
|
18344
|
-
|
|
18345
|
-
|
|
18346
|
-
|
|
18347
|
-
|
|
18348
|
-
|
|
18349
|
-
|
|
18350
|
-
|
|
18351
|
-
|
|
18352
|
-
|
|
18353
|
-
|
|
18354
|
-
|
|
18355
|
-
|
|
18356
|
-
|
|
18357
|
-
|
|
18358
|
-
const
|
|
18359
|
-
|
|
18360
|
-
|
|
18361
|
-
|
|
18362
|
-
|
|
18363
|
-
|
|
18364
|
-
|
|
18365
|
-
|
|
18366
|
-
|
|
18367
|
-
|
|
18368
|
-
|
|
18369
|
-
|
|
18370
|
-
|
|
18371
|
-
|
|
18036
|
+
return null;
|
|
18037
|
+
}
|
|
18038
|
+
function extractParagraphContext(node, startPos, helpers2, depth = 0) {
|
|
18039
|
+
const paragraphProperties = getResolvedParagraphProperties(node);
|
|
18040
|
+
let tabStops = [];
|
|
18041
|
+
if (Array.isArray(paragraphProperties.tabStops)) {
|
|
18042
|
+
tabStops = paragraphProperties.tabStops.map((stop) => {
|
|
18043
|
+
const ref2 = stop?.tab;
|
|
18044
|
+
if (!ref2) return stop || null;
|
|
18045
|
+
return {
|
|
18046
|
+
val: ref2.tabType || "start",
|
|
18047
|
+
pos: twipsToPixels(Number(ref2.pos) || 0),
|
|
18048
|
+
leader: ref2.leader
|
|
18049
|
+
};
|
|
18050
|
+
}).filter(Boolean);
|
|
18051
|
+
}
|
|
18052
|
+
const { entries, positionMap } = flattenParagraph(node, startPos);
|
|
18053
|
+
return {
|
|
18054
|
+
paragraph: node,
|
|
18055
|
+
paragraphDepth: depth,
|
|
18056
|
+
startPos,
|
|
18057
|
+
indent: paragraphProperties.indent || {},
|
|
18058
|
+
tabStops,
|
|
18059
|
+
flattened: entries,
|
|
18060
|
+
positionMap,
|
|
18061
|
+
// Store position map for O(1) lookups
|
|
18062
|
+
accumulatedTabWidth: 0
|
|
18063
|
+
};
|
|
18064
|
+
}
|
|
18065
|
+
function flattenParagraph(paragraph, paragraphStartPos) {
|
|
18066
|
+
const entries = [];
|
|
18067
|
+
const positionMap = /* @__PURE__ */ new Map();
|
|
18068
|
+
const walk = (node, basePos) => {
|
|
18069
|
+
if (!node) return;
|
|
18070
|
+
if (node.type?.name === "run") {
|
|
18071
|
+
node.forEach((child, offset2) => {
|
|
18072
|
+
const childPos = basePos + offset2 + 1;
|
|
18073
|
+
walk(child, childPos);
|
|
18074
|
+
});
|
|
18075
|
+
return;
|
|
18372
18076
|
}
|
|
18077
|
+
const pos = basePos - 1;
|
|
18078
|
+
const index2 = entries.length;
|
|
18079
|
+
entries.push({ node, pos });
|
|
18080
|
+
positionMap.set(pos, index2);
|
|
18081
|
+
};
|
|
18082
|
+
paragraph.forEach((child, offset2) => {
|
|
18083
|
+
const childPos = paragraphStartPos + offset2 + 1;
|
|
18084
|
+
walk(child, childPos);
|
|
18373
18085
|
});
|
|
18374
|
-
|
|
18375
|
-
|
|
18376
|
-
|
|
18377
|
-
|
|
18378
|
-
|
|
18379
|
-
|
|
18380
|
-
|
|
18381
|
-
|
|
18382
|
-
|
|
18383
|
-
|
|
18384
|
-
|
|
18086
|
+
return { entries, positionMap };
|
|
18087
|
+
}
|
|
18088
|
+
function findNextTabIndex(flattened, fromIndex) {
|
|
18089
|
+
for (let i = fromIndex; i < flattened.length; i++) {
|
|
18090
|
+
if (flattened[i]?.node?.type?.name === "tab") {
|
|
18091
|
+
return i;
|
|
18092
|
+
}
|
|
18093
|
+
}
|
|
18094
|
+
return -1;
|
|
18095
|
+
}
|
|
18096
|
+
function findDecimalBreakPos(flattened, startIndex, breakChar) {
|
|
18097
|
+
for (let i = startIndex; i < flattened.length; i++) {
|
|
18098
|
+
const entry = flattened[i];
|
|
18099
|
+
if (!entry) break;
|
|
18100
|
+
if (entry.node.type?.name === "tab") break;
|
|
18101
|
+
if (entry.node.type?.name === "text") {
|
|
18102
|
+
const index2 = entry.node.text?.indexOf(breakChar);
|
|
18103
|
+
if (index2 !== void 0 && index2 !== -1) {
|
|
18104
|
+
return entry.pos + index2 + 1;
|
|
18385
18105
|
}
|
|
18386
|
-
flattenedMarks.push({ key: n.type.name, value: n.attrs[key2] });
|
|
18387
|
-
});
|
|
18388
|
-
const underlineNone = node?.marks?.some((m) => m.type?.name === "underline" && m.attrs?.underlineType === "none");
|
|
18389
|
-
if (underlineNone) {
|
|
18390
|
-
markValue["text-decoration"] = "none";
|
|
18391
18106
|
}
|
|
18392
|
-
|
|
18393
|
-
|
|
18394
|
-
|
|
18395
|
-
|
|
18396
|
-
|
|
18397
|
-
|
|
18398
|
-
|
|
18399
|
-
|
|
18400
|
-
|
|
18401
|
-
|
|
18402
|
-
|
|
18403
|
-
|
|
18404
|
-
|
|
18405
|
-
|
|
18406
|
-
|
|
18407
|
-
|
|
18408
|
-
|
|
18409
|
-
|
|
18410
|
-
|
|
18411
|
-
|
|
18412
|
-
|
|
18413
|
-
|
|
18414
|
-
|
|
18415
|
-
|
|
18416
|
-
|
|
18417
|
-
|
|
18418
|
-
|
|
18419
|
-
|
|
18420
|
-
|
|
18421
|
-
|
|
18422
|
-
|
|
18423
|
-
|
|
18424
|
-
|
|
18425
|
-
|
|
18426
|
-
|
|
18427
|
-
|
|
18428
|
-
|
|
18429
|
-
|
|
18430
|
-
|
|
18431
|
-
|
|
18432
|
-
|
|
18433
|
-
|
|
18434
|
-
|
|
18435
|
-
|
|
18436
|
-
|
|
18437
|
-
|
|
18438
|
-
|
|
18439
|
-
|
|
18440
|
-
|
|
18441
|
-
|
|
18442
|
-
|
|
18443
|
-
|
|
18444
|
-
|
|
18445
|
-
|
|
18446
|
-
|
|
18447
|
-
|
|
18448
|
-
|
|
18449
|
-
|
|
18450
|
-
|
|
18451
|
-
|
|
18452
|
-
|
|
18453
|
-
|
|
18454
|
-
|
|
18455
|
-
|
|
18456
|
-
|
|
18457
|
-
|
|
18458
|
-
|
|
18459
|
-
|
|
18460
|
-
|
|
18461
|
-
|
|
18462
|
-
|
|
18463
|
-
|
|
18464
|
-
|
|
18465
|
-
|
|
18466
|
-
|
|
18467
|
-
|
|
18468
|
-
|
|
18469
|
-
|
|
18470
|
-
|
|
18471
|
-
|
|
18472
|
-
|
|
18473
|
-
|
|
18474
|
-
|
|
18107
|
+
}
|
|
18108
|
+
return null;
|
|
18109
|
+
}
|
|
18110
|
+
function measureRangeWidth(view, from2, to, coordCache = null, domPosCache = null) {
|
|
18111
|
+
if (!Number.isFinite(from2) || !Number.isFinite(to) || to <= from2) return 0;
|
|
18112
|
+
try {
|
|
18113
|
+
const range = document.createRange();
|
|
18114
|
+
const fromRef = getCachedDomAtPos(view, from2, domPosCache);
|
|
18115
|
+
const toRef = getCachedDomAtPos(view, to, domPosCache);
|
|
18116
|
+
range.setStart(fromRef.node, fromRef.offset);
|
|
18117
|
+
range.setEnd(toRef.node, toRef.offset);
|
|
18118
|
+
const rect = range.getBoundingClientRect();
|
|
18119
|
+
range.detach?.();
|
|
18120
|
+
return rect.width || 0;
|
|
18121
|
+
} catch {
|
|
18122
|
+
const startLeft = getLeftCoord(view, from2, coordCache, domPosCache);
|
|
18123
|
+
const endLeft = getLeftCoord(view, to, coordCache, domPosCache);
|
|
18124
|
+
if (startLeft == null || endLeft == null) return 0;
|
|
18125
|
+
return Math.max(0, endLeft - startLeft);
|
|
18126
|
+
}
|
|
18127
|
+
}
|
|
18128
|
+
function getIndentWidth(view, paragraphStartPos, indentAttrs = {}, coordCache = null, domPosCache = null) {
|
|
18129
|
+
const marginLeft = getLeftCoord(view, paragraphStartPos, coordCache, domPosCache);
|
|
18130
|
+
const lineLeft = getLeftCoord(view, paragraphStartPos + 1, coordCache, domPosCache);
|
|
18131
|
+
if (marginLeft != null && lineLeft != null) {
|
|
18132
|
+
const diff = lineLeft - marginLeft;
|
|
18133
|
+
if (!Number.isNaN(diff) && Math.abs(diff) > 0.5) {
|
|
18134
|
+
return diff;
|
|
18135
|
+
}
|
|
18136
|
+
}
|
|
18137
|
+
return calculateIndentFallback(indentAttrs);
|
|
18138
|
+
}
|
|
18139
|
+
function getBlockNodeWidth(view, blockStartPos) {
|
|
18140
|
+
const blockDom = view.nodeDOM(blockStartPos - 1);
|
|
18141
|
+
if (blockDom instanceof HTMLElement) {
|
|
18142
|
+
const styles = window.getComputedStyle(blockDom);
|
|
18143
|
+
const width = blockDom.clientWidth + parseFloat(styles.marginLeft || "0") + parseFloat(styles.marginRight || "0") + parseFloat(styles.borderLeftWidth || "0") + parseFloat(styles.borderRightWidth || "0") + parseFloat(styles.paddingLeft || "0") + parseFloat(styles.paddingRight || "0");
|
|
18144
|
+
return width;
|
|
18145
|
+
}
|
|
18146
|
+
return defaultLineLength;
|
|
18147
|
+
}
|
|
18148
|
+
function calculateIndentFallback(indentAttrs = {}) {
|
|
18149
|
+
if (!indentAttrs) return 0;
|
|
18150
|
+
const left2 = twipsToPixels(Number(indentAttrs.left) || 0);
|
|
18151
|
+
const firstLine = twipsToPixels(Number(indentAttrs.firstLine) || 0);
|
|
18152
|
+
const hanging = twipsToPixels(Number(indentAttrs.hanging) || 0);
|
|
18153
|
+
let textIndent = 0;
|
|
18154
|
+
if (firstLine && hanging) {
|
|
18155
|
+
textIndent = firstLine - hanging;
|
|
18156
|
+
} else if (firstLine) {
|
|
18157
|
+
textIndent = firstLine;
|
|
18158
|
+
} else if (hanging) {
|
|
18159
|
+
textIndent = -hanging;
|
|
18160
|
+
}
|
|
18161
|
+
if (textIndent) return left2 + textIndent;
|
|
18162
|
+
if (left2) return left2;
|
|
18163
|
+
return 0;
|
|
18164
|
+
}
|
|
18165
|
+
function getLeftCoord(view, pos, coordCache = null, domPosCache = null) {
|
|
18166
|
+
if (!Number.isFinite(pos)) return null;
|
|
18167
|
+
if (coordCache && coordCache.has(pos)) {
|
|
18168
|
+
return coordCache.get(pos);
|
|
18169
|
+
}
|
|
18170
|
+
let result = null;
|
|
18171
|
+
try {
|
|
18172
|
+
result = view.coordsAtPos(pos).left;
|
|
18173
|
+
} catch {
|
|
18174
|
+
try {
|
|
18175
|
+
const ref2 = getCachedDomAtPos(view, pos, domPosCache);
|
|
18176
|
+
const range = document.createRange();
|
|
18177
|
+
range.setStart(ref2.node, ref2.offset);
|
|
18178
|
+
range.setEnd(ref2.node, ref2.offset);
|
|
18179
|
+
const rect = range.getBoundingClientRect();
|
|
18180
|
+
range.detach?.();
|
|
18181
|
+
result = rect.left;
|
|
18182
|
+
} catch {
|
|
18183
|
+
result = null;
|
|
18184
|
+
}
|
|
18185
|
+
}
|
|
18186
|
+
if (coordCache) {
|
|
18187
|
+
coordCache.set(pos, result);
|
|
18188
|
+
}
|
|
18189
|
+
return result;
|
|
18190
|
+
}
|
|
18191
|
+
function getCachedDomAtPos(view, pos, domPosCache = null) {
|
|
18192
|
+
if (domPosCache && domPosCache.has(pos)) {
|
|
18193
|
+
return domPosCache.get(pos);
|
|
18194
|
+
}
|
|
18195
|
+
const result = view.domAtPos(pos);
|
|
18196
|
+
if (domPosCache) {
|
|
18197
|
+
domPosCache.set(pos, result);
|
|
18198
|
+
}
|
|
18199
|
+
return result;
|
|
18200
|
+
}
|
|
18201
|
+
function calcTabHeight(blockParent2) {
|
|
18202
|
+
const ptToPxRatio = 1.333;
|
|
18203
|
+
const defaultFontSize = 16;
|
|
18204
|
+
const defaultLineHeight = 1.1;
|
|
18205
|
+
const parentTextStyleMark = blockParent2.firstChild?.marks?.find((mark) => mark.type.name === "textStyle");
|
|
18206
|
+
const fontSize = parseInt(parentTextStyleMark?.attrs.fontSize) * ptToPxRatio || defaultFontSize;
|
|
18207
|
+
return `${fontSize * defaultLineHeight}px`;
|
|
18208
|
+
}
|
|
18209
|
+
class ParagraphNodeView {
|
|
18210
|
+
/**
|
|
18211
|
+
* @param {import('prosemirror-model').Node} node Current paragraph node.
|
|
18212
|
+
* @param {import('../../core/Editor').Editor} editor Editor instance providing schema/helpers.
|
|
18213
|
+
* @param {() => number} getPos Position getter provided by ProseMirror.
|
|
18214
|
+
* @param {import('prosemirror-view').Decoration[]} decorations Decorations applied to this node.
|
|
18215
|
+
* @param {Record<string, unknown>} extensionAttrs Extra attributes declared by the paragraph extension.
|
|
18216
|
+
*/
|
|
18217
|
+
constructor(node, editor, getPos, decorations, extensionAttrs) {
|
|
18218
|
+
__privateAdd(this, _ParagraphNodeView_instances);
|
|
18219
|
+
this.node = node;
|
|
18220
|
+
this.editor = editor;
|
|
18221
|
+
this.getPos = getPos;
|
|
18222
|
+
this.decorations = decorations;
|
|
18223
|
+
this.extensionAttrs = extensionAttrs;
|
|
18224
|
+
this._animationFrameRequest = null;
|
|
18225
|
+
calculateResolvedParagraphProperties(this.editor, this.node, this.editor.state.doc.resolve(this.getPos()));
|
|
18226
|
+
this.dom = document.createElement("p");
|
|
18227
|
+
this.contentDOM = document.createElement("span");
|
|
18228
|
+
this.dom.appendChild(this.contentDOM);
|
|
18229
|
+
if (__privateMethod(this, _ParagraphNodeView_instances, checkIsList_fn).call(this)) {
|
|
18230
|
+
__privateMethod(this, _ParagraphNodeView_instances, initList_fn).call(this, node.attrs.listRendering);
|
|
18231
|
+
__privateMethod(this, _ParagraphNodeView_instances, scheduleAnimation_fn).call(this, () => {
|
|
18232
|
+
if (!__privateMethod(this, _ParagraphNodeView_instances, checkIsList_fn).call(this)) {
|
|
18233
|
+
return;
|
|
18475
18234
|
}
|
|
18476
|
-
|
|
18477
|
-
|
|
18478
|
-
}
|
|
18235
|
+
__privateMethod(this, _ParagraphNodeView_instances, updateListStyles_fn).call(this);
|
|
18236
|
+
});
|
|
18479
18237
|
}
|
|
18480
|
-
|
|
18481
|
-
|
|
18482
|
-
return final;
|
|
18483
|
-
};
|
|
18484
|
-
const applyLinkedStyleToTransaction = (tr, editor, style) => {
|
|
18485
|
-
if (!style) return false;
|
|
18486
|
-
let selection = tr.selection;
|
|
18487
|
-
const state = editor.state;
|
|
18488
|
-
const focusState = CustomSelectionPluginKey.getState(state);
|
|
18489
|
-
if (selection.empty && focusState?.preservedSelection && !focusState?.preservedSelection.empty) {
|
|
18490
|
-
selection = focusState.preservedSelection;
|
|
18491
|
-
tr.setSelection(selection);
|
|
18492
|
-
} else if (selection.empty && editor.options.lastSelection) {
|
|
18493
|
-
selection = editor.options.lastSelection;
|
|
18494
|
-
tr.setSelection(selection);
|
|
18238
|
+
__privateMethod(this, _ParagraphNodeView_instances, updateHTMLAttributes_fn).call(this);
|
|
18239
|
+
__privateMethod(this, _ParagraphNodeView_instances, updateDOMStyles_fn).call(this);
|
|
18495
18240
|
}
|
|
18496
|
-
|
|
18497
|
-
|
|
18498
|
-
|
|
18499
|
-
|
|
18500
|
-
|
|
18501
|
-
|
|
18502
|
-
|
|
18503
|
-
|
|
18504
|
-
|
|
18505
|
-
|
|
18506
|
-
return cleanAttrs;
|
|
18507
|
-
};
|
|
18508
|
-
const clearFormattingMarks = (startPos, endPos) => {
|
|
18509
|
-
tr.doc.nodesBetween(startPos, endPos, (node, pos) => {
|
|
18510
|
-
if (node.isText && node.marks.length > 0) {
|
|
18511
|
-
const marksToRemove = [
|
|
18512
|
-
"textStyle",
|
|
18513
|
-
"bold",
|
|
18514
|
-
"italic",
|
|
18515
|
-
"underline",
|
|
18516
|
-
"strike",
|
|
18517
|
-
"subscript",
|
|
18518
|
-
"superscript",
|
|
18519
|
-
"highlight"
|
|
18520
|
-
];
|
|
18521
|
-
node.marks.forEach((mark) => {
|
|
18522
|
-
if (marksToRemove.includes(mark.type.name)) {
|
|
18523
|
-
tr.removeMark(pos, pos + node.nodeSize, mark);
|
|
18524
|
-
}
|
|
18525
|
-
});
|
|
18526
|
-
}
|
|
18241
|
+
/**
|
|
18242
|
+
* @param {import('prosemirror-model').Node} node
|
|
18243
|
+
* @param {import('prosemirror-view').Decoration[]} decorations
|
|
18244
|
+
*/
|
|
18245
|
+
update(node, decorations) {
|
|
18246
|
+
const oldAttrs = this.node.attrs;
|
|
18247
|
+
const newAttrs = node.attrs;
|
|
18248
|
+
this.node = node;
|
|
18249
|
+
this.decorations = decorations;
|
|
18250
|
+
if (JSON.stringify(oldAttrs) === JSON.stringify(newAttrs)) {
|
|
18527
18251
|
return true;
|
|
18528
|
-
});
|
|
18529
|
-
};
|
|
18530
|
-
if (from2 === to) {
|
|
18531
|
-
let pos = from2;
|
|
18532
|
-
let paragraphNode = tr.doc.nodeAt(from2);
|
|
18533
|
-
if (paragraphNode?.type.name !== "paragraph") {
|
|
18534
|
-
const parentNode2 = findParentNode((node) => node.type.name === "paragraph")(selection);
|
|
18535
|
-
if (!parentNode2) return false;
|
|
18536
|
-
pos = parentNode2.pos;
|
|
18537
|
-
paragraphNode = parentNode2.node;
|
|
18538
18252
|
}
|
|
18539
|
-
|
|
18540
|
-
|
|
18253
|
+
calculateResolvedParagraphProperties(this.editor, this.node, this.editor.state.doc.resolve(this.getPos()));
|
|
18254
|
+
__privateMethod(this, _ParagraphNodeView_instances, updateHTMLAttributes_fn).call(this);
|
|
18255
|
+
__privateMethod(this, _ParagraphNodeView_instances, updateDOMStyles_fn).call(this);
|
|
18256
|
+
if (!__privateMethod(this, _ParagraphNodeView_instances, checkIsList_fn).call(this)) {
|
|
18257
|
+
__privateMethod(this, _ParagraphNodeView_instances, removeList_fn).call(this);
|
|
18258
|
+
return true;
|
|
18259
|
+
}
|
|
18260
|
+
__privateMethod(this, _ParagraphNodeView_instances, initList_fn).call(this, node.attrs.listRendering);
|
|
18261
|
+
__privateMethod(this, _ParagraphNodeView_instances, scheduleAnimation_fn).call(this, () => {
|
|
18262
|
+
__privateMethod(this, _ParagraphNodeView_instances, initList_fn).call(this, node.attrs.listRendering);
|
|
18263
|
+
__privateMethod(this, _ParagraphNodeView_instances, updateListStyles_fn).call(this);
|
|
18264
|
+
});
|
|
18541
18265
|
return true;
|
|
18542
18266
|
}
|
|
18543
|
-
|
|
18544
|
-
|
|
18545
|
-
|
|
18546
|
-
|
|
18267
|
+
/**
|
|
18268
|
+
* @param {MutationRecord} mutation
|
|
18269
|
+
*/
|
|
18270
|
+
ignoreMutation(mutation) {
|
|
18271
|
+
if (this.marker && (mutation.target === this.marker || this.marker.contains(mutation.target))) {
|
|
18272
|
+
return true;
|
|
18273
|
+
}
|
|
18274
|
+
if (this.separator && (mutation.target === this.separator || this.separator.contains(mutation.target))) {
|
|
18275
|
+
return true;
|
|
18276
|
+
}
|
|
18277
|
+
if (mutation.type === "attributes" && mutation.target === this.dom && mutation.attributeName === "style") {
|
|
18278
|
+
return true;
|
|
18279
|
+
}
|
|
18280
|
+
if (mutation.type === "childList") {
|
|
18281
|
+
if (this.marker && Array.from(mutation.removedNodes).includes(this.marker)) {
|
|
18282
|
+
return true;
|
|
18283
|
+
}
|
|
18284
|
+
if (this.marker && Array.from(mutation.addedNodes).includes(this.marker)) {
|
|
18285
|
+
return true;
|
|
18286
|
+
}
|
|
18287
|
+
if (this.separator && Array.from(mutation.removedNodes).includes(this.separator)) {
|
|
18288
|
+
return true;
|
|
18289
|
+
}
|
|
18290
|
+
if (this.separator && Array.from(mutation.addedNodes).includes(this.separator)) {
|
|
18291
|
+
return true;
|
|
18292
|
+
}
|
|
18547
18293
|
}
|
|
18548
|
-
return true;
|
|
18549
|
-
});
|
|
18550
|
-
paragraphPositions.forEach(({ node, pos }) => {
|
|
18551
|
-
clearFormattingMarks(pos + 1, pos + node.nodeSize - 1);
|
|
18552
|
-
tr.setNodeMarkup(pos, void 0, getCleanParagraphAttrs(node));
|
|
18553
|
-
});
|
|
18554
|
-
return true;
|
|
18555
|
-
};
|
|
18556
|
-
const stepInsertsTextIntoStyledParagraph = (tr, oldEditorState, step, stepIndex) => {
|
|
18557
|
-
if (!step.slice || step.slice.size === 0 || typeof step.from !== "number") {
|
|
18558
18294
|
return false;
|
|
18559
18295
|
}
|
|
18560
|
-
|
|
18561
|
-
|
|
18562
|
-
|
|
18563
|
-
|
|
18564
|
-
|
|
18565
|
-
|
|
18566
|
-
|
|
18567
|
-
|
|
18568
|
-
|
|
18569
|
-
|
|
18570
|
-
|
|
18571
|
-
|
|
18572
|
-
const $pos = docBeforeStep.resolve(resolvedPos);
|
|
18573
|
-
for (let depth = $pos.depth; depth >= 0; depth--) {
|
|
18574
|
-
const node = $pos.node(depth);
|
|
18575
|
-
if (node?.type?.name === "paragraph") {
|
|
18576
|
-
return Boolean(node.attrs?.styleId);
|
|
18296
|
+
destroy() {
|
|
18297
|
+
__privateMethod(this, _ParagraphNodeView_instances, cancelScheduledAnimation_fn).call(this);
|
|
18298
|
+
}
|
|
18299
|
+
}
|
|
18300
|
+
_ParagraphNodeView_instances = new WeakSet();
|
|
18301
|
+
updateHTMLAttributes_fn = function() {
|
|
18302
|
+
const htmlAttributes = Attribute.getAttributesToRender(this.node, this.extensionAttrs);
|
|
18303
|
+
htmlAttributes.style = htmlAttributes.style || "";
|
|
18304
|
+
for (const [key2, value] of Object.entries(htmlAttributes || {})) {
|
|
18305
|
+
if (value == null) {
|
|
18306
|
+
this.dom.removeAttribute(key2);
|
|
18307
|
+
continue;
|
|
18577
18308
|
}
|
|
18309
|
+
this.dom.setAttribute(key2, value);
|
|
18578
18310
|
}
|
|
18579
|
-
|
|
18580
|
-
|
|
18581
|
-
|
|
18582
|
-
|
|
18583
|
-
return new Plugin({
|
|
18584
|
-
key: LinkedStylesPluginKey,
|
|
18585
|
-
state: {
|
|
18586
|
-
/**
|
|
18587
|
-
* Initialize plugin state with styles and decorations
|
|
18588
|
-
* @returns {Object} Initial state with styles and decorations
|
|
18589
|
-
* @private
|
|
18590
|
-
*/
|
|
18591
|
-
init() {
|
|
18592
|
-
if (!editor.converter || editor.options.mode !== "docx") return {};
|
|
18593
|
-
const styles = editor.converter?.linkedStyles || [];
|
|
18594
|
-
return {
|
|
18595
|
-
styles,
|
|
18596
|
-
decorations: generateDecorations(editor.state, styles)
|
|
18597
|
-
};
|
|
18598
|
-
},
|
|
18599
|
-
/**
|
|
18600
|
-
* Update decorations when document changes
|
|
18601
|
-
* @param {Object} tr - The transaction
|
|
18602
|
-
* @param {Object} prev - Previous plugin state
|
|
18603
|
-
* @param {Object} oldEditorState - Old editor state
|
|
18604
|
-
* @param {Object} newEditorState - New editor state
|
|
18605
|
-
* @returns {Object} Updated state with styles and decorations
|
|
18606
|
-
* @private
|
|
18607
|
-
*/
|
|
18608
|
-
apply(tr, prev, oldEditorState, newEditorState) {
|
|
18609
|
-
if (!editor.converter || editor.options.mode !== "docx") return { ...prev };
|
|
18610
|
-
let decorations = prev.decorations || DecorationSet.empty;
|
|
18611
|
-
if (tr.docChanged) {
|
|
18612
|
-
let mightAffectStyles = false;
|
|
18613
|
-
const styleRelatedMarks = /* @__PURE__ */ new Set(["textStyle", "bold", "italic", "underline", "strike"]);
|
|
18614
|
-
tr.steps.forEach((step, index2) => {
|
|
18615
|
-
if (step.slice) {
|
|
18616
|
-
step.slice.content.descendants((node) => {
|
|
18617
|
-
if (node.attrs?.styleId) {
|
|
18618
|
-
mightAffectStyles = true;
|
|
18619
|
-
return false;
|
|
18620
|
-
}
|
|
18621
|
-
if (node.marks.length > 0) {
|
|
18622
|
-
const hasStyleMarks = node.marks.some((mark) => styleRelatedMarks.has(mark.type.name));
|
|
18623
|
-
if (hasStyleMarks) {
|
|
18624
|
-
mightAffectStyles = true;
|
|
18625
|
-
return false;
|
|
18626
|
-
}
|
|
18627
|
-
}
|
|
18628
|
-
});
|
|
18629
|
-
}
|
|
18630
|
-
if (step.jsonID === "addMark" || step.jsonID === "removeMark") {
|
|
18631
|
-
if (step.mark && styleRelatedMarks.has(step.mark.type.name)) {
|
|
18632
|
-
mightAffectStyles = true;
|
|
18633
|
-
}
|
|
18634
|
-
}
|
|
18635
|
-
if (!mightAffectStyles && stepInsertsTextIntoStyledParagraph(tr, oldEditorState, step, index2)) {
|
|
18636
|
-
mightAffectStyles = true;
|
|
18637
|
-
}
|
|
18638
|
-
});
|
|
18639
|
-
if (mightAffectStyles) {
|
|
18640
|
-
const styles = LinkedStylesPluginKey.getState(editor.state).styles;
|
|
18641
|
-
decorations = generateDecorations(newEditorState, styles);
|
|
18642
|
-
} else {
|
|
18643
|
-
decorations = decorations.map(tr.mapping, tr.doc);
|
|
18644
|
-
}
|
|
18645
|
-
}
|
|
18646
|
-
return { ...prev, decorations };
|
|
18647
|
-
}
|
|
18648
|
-
},
|
|
18649
|
-
props: {
|
|
18650
|
-
/**
|
|
18651
|
-
* Provide decorations to the editor view
|
|
18652
|
-
* @param {Object} state - Current editor state
|
|
18653
|
-
* @returns {Object} The decoration set
|
|
18654
|
-
* @private
|
|
18655
|
-
*/
|
|
18656
|
-
decorations(state) {
|
|
18657
|
-
return LinkedStylesPluginKey.getState(state)?.decorations;
|
|
18658
|
-
}
|
|
18659
|
-
}
|
|
18660
|
-
});
|
|
18661
|
-
};
|
|
18662
|
-
const generateDecorations = (state, styles) => {
|
|
18663
|
-
const decorations = [];
|
|
18664
|
-
const doc2 = state?.doc;
|
|
18665
|
-
const getParagraphStyleId = (pos) => {
|
|
18666
|
-
const $pos = state.doc.resolve(pos);
|
|
18667
|
-
for (let d2 = $pos.depth; d2 >= 0; d2--) {
|
|
18668
|
-
const n = $pos.node(d2);
|
|
18669
|
-
if (n?.type?.name === "paragraph") return n.attrs?.styleId || null;
|
|
18670
|
-
}
|
|
18671
|
-
return null;
|
|
18672
|
-
};
|
|
18673
|
-
doc2.descendants((node, pos) => {
|
|
18674
|
-
const { name } = node.type;
|
|
18675
|
-
if (name !== "text") return;
|
|
18676
|
-
const paragraphStyleId = getParagraphStyleId(pos);
|
|
18677
|
-
let runStyleId = null;
|
|
18678
|
-
let inlineTextStyleId = null;
|
|
18679
|
-
for (const mark of node.marks) {
|
|
18680
|
-
if (mark.type.name === "run") {
|
|
18681
|
-
const rp = mark.attrs?.runProperties;
|
|
18682
|
-
if (rp && typeof rp === "object" && !Array.isArray(rp) && rp.styleId) runStyleId = rp.styleId;
|
|
18683
|
-
else if (Array.isArray(rp)) {
|
|
18684
|
-
const ent = rp.find((e) => e?.xmlName === "w:rStyle");
|
|
18685
|
-
const sid = ent?.attributes?.["w:val"];
|
|
18686
|
-
if (sid) runStyleId = sid;
|
|
18687
|
-
}
|
|
18688
|
-
} else if (mark.type.name === "textStyle" && mark.attrs?.styleId) {
|
|
18689
|
-
inlineTextStyleId = mark.attrs.styleId;
|
|
18690
|
-
}
|
|
18691
|
-
}
|
|
18692
|
-
const buildStyleMap = (sid) => {
|
|
18693
|
-
if (!sid) return {};
|
|
18694
|
-
const { linkedStyle, basedOnStyle: basedOnStyle2 } = getLinkedStyle(sid, styles);
|
|
18695
|
-
if (!linkedStyle) return {};
|
|
18696
|
-
const base2 = { ...basedOnStyle2?.definition?.styles || {} };
|
|
18697
|
-
return { ...base2, ...linkedStyle.definition?.styles || {} };
|
|
18698
|
-
};
|
|
18699
|
-
const pMap = buildStyleMap(paragraphStyleId);
|
|
18700
|
-
let tMap;
|
|
18701
|
-
if (paragraphStyleId?.startsWith("TOC")) {
|
|
18702
|
-
tMap = {};
|
|
18703
|
-
} else {
|
|
18704
|
-
tMap = buildStyleMap(inlineTextStyleId);
|
|
18705
|
-
}
|
|
18706
|
-
const rMap = buildStyleMap(runStyleId);
|
|
18707
|
-
const finalStyles = { ...pMap, ...tMap, ...rMap };
|
|
18708
|
-
if (Object.keys(finalStyles).length === 0) return;
|
|
18709
|
-
const mergedLinkedStyle = { definition: { styles: finalStyles, attrs: {} } };
|
|
18710
|
-
const basedOnStyle = null;
|
|
18711
|
-
const $pos = state.doc.resolve(pos);
|
|
18712
|
-
const parent = $pos.parent;
|
|
18713
|
-
const styleString = generateLinkedStyleString(mergedLinkedStyle, basedOnStyle, node, parent);
|
|
18714
|
-
if (!styleString) return;
|
|
18715
|
-
const decoration = Decoration.inline(pos, pos + node.nodeSize, { style: styleString });
|
|
18716
|
-
decorations.push(decoration);
|
|
18717
|
-
});
|
|
18718
|
-
return DecorationSet.create(doc2, decorations);
|
|
18719
|
-
};
|
|
18720
|
-
const LinkedStyles = Extension.create({
|
|
18721
|
-
name: "linkedStyles",
|
|
18722
|
-
priority: 1,
|
|
18723
|
-
// We need this plugin to run before the list plugins
|
|
18724
|
-
addOptions() {
|
|
18725
|
-
return {};
|
|
18726
|
-
},
|
|
18727
|
-
addPmPlugins() {
|
|
18728
|
-
return [createLinkedStylesPlugin(this.editor)];
|
|
18729
|
-
},
|
|
18730
|
-
addCommands() {
|
|
18731
|
-
return {
|
|
18732
|
-
/**
|
|
18733
|
-
* Apply a linked style to the selected paragraphs
|
|
18734
|
-
* @category Command
|
|
18735
|
-
* @param {LinkedStyle} style - The style object to apply
|
|
18736
|
-
* @example
|
|
18737
|
-
* const style = editor.helpers.linkedStyles.getStyleById('Heading1');
|
|
18738
|
-
* editor.commands.setLinkedStyle(style);
|
|
18739
|
-
* @note Clears existing formatting when applying a style
|
|
18740
|
-
* @note Works with custom selection preservation
|
|
18741
|
-
*/
|
|
18742
|
-
setLinkedStyle: (style) => (params2) => {
|
|
18743
|
-
const { tr } = params2;
|
|
18744
|
-
return applyLinkedStyleToTransaction(tr, this.editor, style);
|
|
18745
|
-
},
|
|
18746
|
-
/**
|
|
18747
|
-
* Toggle a linked style on the current selection
|
|
18748
|
-
* @category Command
|
|
18749
|
-
* @param {LinkedStyle} style - The linked style to apply (with id property)
|
|
18750
|
-
* @param {string|null} [nodeType=null] - Node type to restrict toggle to (e.g., 'paragraph')
|
|
18751
|
-
* @example
|
|
18752
|
-
* const style = editor.helpers.linkedStyles.getStyleById('Heading1');
|
|
18753
|
-
* editor.commands.toggleLinkedStyle(style)
|
|
18754
|
-
* editor.commands.toggleLinkedStyle(style, 'paragraph')
|
|
18755
|
-
* @note If selection is empty, returns false
|
|
18756
|
-
* @note Removes style if already applied, applies it if not
|
|
18757
|
-
*/
|
|
18758
|
-
toggleLinkedStyle: (style, nodeType = null) => (params2) => {
|
|
18759
|
-
const { tr } = params2;
|
|
18760
|
-
if (tr.selection.empty) {
|
|
18761
|
-
return false;
|
|
18762
|
-
}
|
|
18763
|
-
let node = tr.doc.nodeAt(tr.selection.$from.pos);
|
|
18764
|
-
if (node && nodeType && node.type.name !== nodeType) {
|
|
18765
|
-
node = findParentNodeClosestToPos(tr.selection.$from, (n) => {
|
|
18766
|
-
return nodeType ? n.type.name === nodeType : true;
|
|
18767
|
-
})?.node;
|
|
18768
|
-
}
|
|
18769
|
-
if (!node) {
|
|
18770
|
-
return false;
|
|
18771
|
-
}
|
|
18772
|
-
const currentStyleId = node.attrs.styleId;
|
|
18773
|
-
if (currentStyleId === style.id) {
|
|
18774
|
-
return applyLinkedStyleToTransaction(tr, this.editor, { id: null });
|
|
18775
|
-
}
|
|
18776
|
-
return applyLinkedStyleToTransaction(tr, this.editor, style);
|
|
18777
|
-
},
|
|
18778
|
-
/**
|
|
18779
|
-
* Apply a linked style by its ID
|
|
18780
|
-
* @category Command
|
|
18781
|
-
* @param {string} styleId - The style ID to apply (e.g., 'Heading1')
|
|
18782
|
-
* @example
|
|
18783
|
-
* editor.commands.setStyleById('Heading1')
|
|
18784
|
-
* editor.commands.setStyleById('Normal')
|
|
18785
|
-
* @note Looks up the style from loaded Word styles
|
|
18786
|
-
*/
|
|
18787
|
-
setStyleById: (styleId) => (params2) => {
|
|
18788
|
-
const { state, tr } = params2;
|
|
18789
|
-
const pluginState = LinkedStylesPluginKey.getState(state);
|
|
18790
|
-
if (!pluginState) return false;
|
|
18791
|
-
const style = pluginState.styles?.find((s2) => s2.id === styleId);
|
|
18792
|
-
if (!style) return false;
|
|
18793
|
-
return applyLinkedStyleToTransaction(tr, this.editor, style);
|
|
18794
|
-
}
|
|
18795
|
-
};
|
|
18796
|
-
},
|
|
18797
|
-
addHelpers() {
|
|
18798
|
-
return {
|
|
18799
|
-
/**
|
|
18800
|
-
* Get all available linked styles
|
|
18801
|
-
* @category Helper
|
|
18802
|
-
* @returns {Array} Array of linked style objects
|
|
18803
|
-
* @example
|
|
18804
|
-
* const styles = editor.helpers.linkedStyles.getStyles();
|
|
18805
|
-
* // Returns all styles from the Word document
|
|
18806
|
-
*/
|
|
18807
|
-
getStyles: () => {
|
|
18808
|
-
const styles = LinkedStylesPluginKey.getState(this.editor.state)?.styles || [];
|
|
18809
|
-
return styles;
|
|
18810
|
-
},
|
|
18811
|
-
/**
|
|
18812
|
-
* Get a specific style by ID
|
|
18813
|
-
* @category Helper
|
|
18814
|
-
* @param {string} styleId - The style ID to find
|
|
18815
|
-
* @returns {Object} The style object or undefined
|
|
18816
|
-
* @example
|
|
18817
|
-
* const headingStyle = editor.helpers.linkedStyles.getStyleById('Heading1');
|
|
18818
|
-
*/
|
|
18819
|
-
getStyleById: (styleId) => {
|
|
18820
|
-
const styles = this.editor.helpers[this.name].getStyles();
|
|
18821
|
-
return styles.find((s2) => s2.id === styleId);
|
|
18822
|
-
},
|
|
18823
|
-
/**
|
|
18824
|
-
* Get the CSS string for a style
|
|
18825
|
-
* @category Helper
|
|
18826
|
-
* @param {string} styleId - The style ID
|
|
18827
|
-
* @returns {string} CSS style string
|
|
18828
|
-
* @example
|
|
18829
|
-
* const css = editor.helpers.linkedStyles.getLinkedStyleString('Heading1');
|
|
18830
|
-
* // Returns: "font-size: 16pt; font-weight: bold; color: #2E74B5"
|
|
18831
|
-
* @private
|
|
18832
|
-
*/
|
|
18833
|
-
getLinkedStyleString: (styleId) => {
|
|
18834
|
-
const styles = this.editor.helpers.linkedStyles.getStyles();
|
|
18835
|
-
const style = styles.find((s2) => s2.id === styleId);
|
|
18836
|
-
if (!style) return "";
|
|
18837
|
-
return generateLinkedStyleString(style);
|
|
18838
|
-
}
|
|
18839
|
-
};
|
|
18840
|
-
}
|
|
18841
|
-
});
|
|
18842
|
-
const getDefaultSpacing = () => ({
|
|
18843
|
-
after: null,
|
|
18844
|
-
before: null,
|
|
18845
|
-
line: null,
|
|
18846
|
-
lineRule: "auto"
|
|
18847
|
-
});
|
|
18848
|
-
const restartNumbering = ({ editor, tr, state, dispatch }) => {
|
|
18849
|
-
const { node: paragraph, pos } = findParentNode(isList)(state.selection) || {};
|
|
18850
|
-
if (!paragraph) return false;
|
|
18851
|
-
const allParagraphs = [{ node: paragraph, pos }];
|
|
18852
|
-
const startPos = pos + paragraph.nodeSize;
|
|
18853
|
-
const myNumId = paragraph.attrs.numberingProperties.numId;
|
|
18854
|
-
let stop = false;
|
|
18855
|
-
state.doc.nodesBetween(startPos, state.doc.content.size, (node, nodePos) => {
|
|
18856
|
-
if (node.type.name === "paragraph") {
|
|
18857
|
-
if (isList(node) && node.attrs.paragraphProperties?.numberingProperties?.numId === myNumId) {
|
|
18858
|
-
allParagraphs.push({ node, pos: nodePos });
|
|
18859
|
-
} else {
|
|
18860
|
-
stop = true;
|
|
18861
|
-
}
|
|
18862
|
-
return false;
|
|
18863
|
-
}
|
|
18864
|
-
return !stop;
|
|
18865
|
-
});
|
|
18866
|
-
const { numberingType } = paragraph.attrs.listRendering || {};
|
|
18867
|
-
const listType = numberingType === "bullet" ? "bulletList" : "orderedList";
|
|
18868
|
-
const numId = ListHelpers.getNewListId(editor);
|
|
18869
|
-
ListHelpers.generateNewListDefinition({ numId: Number(numId), listType, editor });
|
|
18870
|
-
allParagraphs.forEach(({ node, pos: pos2 }) => {
|
|
18871
|
-
updateNumberingProperties(
|
|
18872
|
-
{
|
|
18873
|
-
...node.attrs.numberingProperties,
|
|
18874
|
-
numId: Number(numId)
|
|
18875
|
-
},
|
|
18876
|
-
node,
|
|
18877
|
-
pos2,
|
|
18878
|
-
editor,
|
|
18879
|
-
tr
|
|
18880
|
-
);
|
|
18881
|
-
});
|
|
18882
|
-
if (dispatch) dispatch(tr);
|
|
18883
|
-
return true;
|
|
18884
|
-
};
|
|
18885
|
-
const defaultTabDistance = 48;
|
|
18886
|
-
const defaultLineLength = 816;
|
|
18887
|
-
const getTabDecorations = (doc2, view, helpers2, from2 = 0, to = null) => {
|
|
18888
|
-
const decorations = [];
|
|
18889
|
-
const paragraphCache = /* @__PURE__ */ new Map();
|
|
18890
|
-
const coordCache = /* @__PURE__ */ new Map();
|
|
18891
|
-
const domPosCache = /* @__PURE__ */ new Map();
|
|
18892
|
-
const end2 = to ?? doc2.content.size;
|
|
18893
|
-
doc2.nodesBetween(from2, end2, (node, pos) => {
|
|
18894
|
-
if (node.type.name !== "tab") return;
|
|
18895
|
-
const $pos = doc2.resolve(pos);
|
|
18896
|
-
const paragraphContext = findParagraphContext($pos, paragraphCache, helpers2);
|
|
18897
|
-
if (!paragraphContext) return;
|
|
18898
|
-
const blockParent2 = $pos.node(paragraphContext.paragraphDepth);
|
|
18899
|
-
const style = calculateTabStyle(node.nodeSize, view, pos, blockParent2, paragraphContext, coordCache, domPosCache);
|
|
18900
|
-
if (style) {
|
|
18901
|
-
decorations.push(
|
|
18902
|
-
Decoration.node(pos, pos + node.nodeSize, {
|
|
18903
|
-
style
|
|
18904
|
-
})
|
|
18905
|
-
);
|
|
18906
|
-
}
|
|
18907
|
-
});
|
|
18908
|
-
return decorations;
|
|
18909
|
-
};
|
|
18910
|
-
function calculateTabStyle(nodeSize2, view, pos, blockParent2, paragraphContext, coordCache = null, domPosCache = null) {
|
|
18911
|
-
let extraStyles = "";
|
|
18912
|
-
try {
|
|
18913
|
-
const { tabStops, flattened, positionMap, startPos } = paragraphContext;
|
|
18914
|
-
if (paragraphContext.indentWidth === void 0) {
|
|
18915
|
-
paragraphContext.indentWidth = getIndentWidth(view, startPos, paragraphContext.indent, coordCache, domPosCache);
|
|
18916
|
-
}
|
|
18917
|
-
if (paragraphContext.tabHeight === void 0) {
|
|
18918
|
-
paragraphContext.tabHeight = calcTabHeight(blockParent2);
|
|
18919
|
-
}
|
|
18920
|
-
if (paragraphContext.paragraphWidth === void 0) {
|
|
18921
|
-
paragraphContext.paragraphWidth = getBlockNodeWidth(view, startPos);
|
|
18922
|
-
}
|
|
18923
|
-
const indentWidth = paragraphContext.indentWidth;
|
|
18924
|
-
const hanging = twipsToPixels(Number(paragraphContext.indent.hanging) || 0);
|
|
18925
|
-
if (hanging > 0) {
|
|
18926
|
-
tabStops.unshift({ val: "start", pos: indentWidth + hanging });
|
|
18927
|
-
}
|
|
18928
|
-
const accumulatedTabWidth = paragraphContext.accumulatedTabWidth || 0;
|
|
18929
|
-
const currentWidth = indentWidth + measureRangeWidth(view, startPos + 1, pos, coordCache, domPosCache) + accumulatedTabWidth;
|
|
18930
|
-
let tabWidth;
|
|
18931
|
-
if (tabStops.length) {
|
|
18932
|
-
const tabStop = tabStops.find((stop) => stop.pos > currentWidth && stop.val !== "clear");
|
|
18933
|
-
if (tabStop) {
|
|
18934
|
-
tabWidth = Math.min(tabStop.pos, paragraphContext.paragraphWidth) - currentWidth;
|
|
18935
|
-
let val = tabStop.val;
|
|
18936
|
-
const aliases = { left: "start", right: "end" };
|
|
18937
|
-
if (aliases[val]) val = aliases[val];
|
|
18938
|
-
if (val === "center" || val === "end" || val === "right") {
|
|
18939
|
-
const entryIndex = positionMap.get(pos);
|
|
18940
|
-
if (entryIndex === void 0) return;
|
|
18941
|
-
const nextTabIndex = findNextTabIndex(flattened, entryIndex + 1);
|
|
18942
|
-
const segmentStartPos = pos + nodeSize2;
|
|
18943
|
-
const segmentEndPos = nextTabIndex === -1 ? startPos + paragraphContext.paragraph.nodeSize - 1 : flattened[nextTabIndex].pos;
|
|
18944
|
-
const segmentWidth = measureRangeWidth(view, segmentStartPos, segmentEndPos, coordCache, domPosCache);
|
|
18945
|
-
tabWidth -= val === "center" ? segmentWidth / 2 : segmentWidth;
|
|
18946
|
-
} else if (val === "decimal" || val === "num") {
|
|
18947
|
-
const entryIndex = positionMap.get(pos);
|
|
18948
|
-
if (entryIndex === void 0) return;
|
|
18949
|
-
const breakChar = tabStop.decimalChar || ".";
|
|
18950
|
-
const decimalPos = findDecimalBreakPos(flattened, entryIndex + 1, breakChar);
|
|
18951
|
-
const integralWidth = decimalPos ? measureRangeWidth(view, pos + nodeSize2, decimalPos, coordCache, domPosCache) : measureRangeWidth(
|
|
18952
|
-
view,
|
|
18953
|
-
pos + nodeSize2,
|
|
18954
|
-
startPos + paragraphContext.paragraph.nodeSize - 1,
|
|
18955
|
-
coordCache,
|
|
18956
|
-
domPosCache
|
|
18957
|
-
);
|
|
18958
|
-
tabWidth -= integralWidth;
|
|
18959
|
-
}
|
|
18960
|
-
if (tabStop.leader) {
|
|
18961
|
-
const leaderStyles = {
|
|
18962
|
-
dot: "border-bottom: 1px dotted black;",
|
|
18963
|
-
heavy: "border-bottom: 2px solid black;",
|
|
18964
|
-
hyphen: "border-bottom: 1px solid black;",
|
|
18965
|
-
middleDot: "border-bottom: 1px dotted black; margin-bottom: 2px;",
|
|
18966
|
-
underscore: "border-bottom: 1px solid black;"
|
|
18967
|
-
};
|
|
18968
|
-
extraStyles += leaderStyles[tabStop.leader] || "";
|
|
18969
|
-
}
|
|
18970
|
-
}
|
|
18971
|
-
}
|
|
18972
|
-
if (!tabWidth || tabWidth < 1) {
|
|
18973
|
-
tabWidth = defaultTabDistance - currentWidth % defaultLineLength % defaultTabDistance;
|
|
18974
|
-
if (tabWidth === 0) tabWidth = defaultTabDistance;
|
|
18975
|
-
}
|
|
18976
|
-
const tabHeight = paragraphContext.tabHeight;
|
|
18977
|
-
paragraphContext.accumulatedTabWidth = accumulatedTabWidth + tabWidth;
|
|
18978
|
-
return `width: ${tabWidth}px; height: ${tabHeight}; ${extraStyles}`;
|
|
18979
|
-
} catch (error) {
|
|
18980
|
-
console.error("tab decoration error", error);
|
|
18981
|
-
}
|
|
18982
|
-
}
|
|
18983
|
-
function findParagraphContext($pos, cache, helpers2) {
|
|
18984
|
-
for (let depth = $pos.depth; depth >= 0; depth--) {
|
|
18985
|
-
const node = $pos.node(depth);
|
|
18986
|
-
if (node?.type?.name === "paragraph") {
|
|
18987
|
-
const startPos = $pos.start(depth);
|
|
18988
|
-
if (!cache.has(startPos)) {
|
|
18989
|
-
const paragraphContext = extractParagraphContext(node, startPos, helpers2, depth);
|
|
18990
|
-
cache.set(startPos, paragraphContext);
|
|
18991
|
-
}
|
|
18992
|
-
return cache.get(startPos);
|
|
18993
|
-
}
|
|
18994
|
-
}
|
|
18995
|
-
return null;
|
|
18996
|
-
}
|
|
18997
|
-
function extractParagraphContext(node, startPos, helpers2, depth = 0) {
|
|
18998
|
-
let tabStops = [];
|
|
18999
|
-
if (Array.isArray(node.attrs?.tabStops)) {
|
|
19000
|
-
tabStops = node.attrs.tabStops.map((stop) => {
|
|
19001
|
-
const ref2 = stop?.tab;
|
|
19002
|
-
if (!ref2) return stop || null;
|
|
19003
|
-
return {
|
|
19004
|
-
val: ref2.tabType || "start",
|
|
19005
|
-
pos: twipsToPixels(Number(ref2.pos) || 0),
|
|
19006
|
-
leader: ref2.leader
|
|
19007
|
-
};
|
|
19008
|
-
}).filter(Boolean);
|
|
18311
|
+
const paragraphProperties = getResolvedParagraphProperties(this.node);
|
|
18312
|
+
if (__privateMethod(this, _ParagraphNodeView_instances, checkIsList_fn).call(this)) {
|
|
18313
|
+
this.dom.setAttribute("data-num-id", paragraphProperties.numberingProperties.numId);
|
|
18314
|
+
this.dom.setAttribute("data-level", paragraphProperties.numberingProperties.ilvl);
|
|
19009
18315
|
} else {
|
|
19010
|
-
|
|
19011
|
-
|
|
19012
|
-
tabStops = style.definition.styles.tabStops;
|
|
19013
|
-
}
|
|
19014
|
-
}
|
|
19015
|
-
const { entries, positionMap } = flattenParagraph(node, startPos);
|
|
19016
|
-
return {
|
|
19017
|
-
paragraph: node,
|
|
19018
|
-
paragraphDepth: depth,
|
|
19019
|
-
startPos,
|
|
19020
|
-
indent: node.attrs?.indent || {},
|
|
19021
|
-
tabStops,
|
|
19022
|
-
flattened: entries,
|
|
19023
|
-
positionMap,
|
|
19024
|
-
// Store position map for O(1) lookups
|
|
19025
|
-
accumulatedTabWidth: 0
|
|
19026
|
-
};
|
|
19027
|
-
}
|
|
19028
|
-
function flattenParagraph(paragraph, paragraphStartPos) {
|
|
19029
|
-
const entries = [];
|
|
19030
|
-
const positionMap = /* @__PURE__ */ new Map();
|
|
19031
|
-
const walk = (node, basePos) => {
|
|
19032
|
-
if (!node) return;
|
|
19033
|
-
if (node.type?.name === "run") {
|
|
19034
|
-
node.forEach((child, offset2) => {
|
|
19035
|
-
const childPos = basePos + offset2 + 1;
|
|
19036
|
-
walk(child, childPos);
|
|
19037
|
-
});
|
|
19038
|
-
return;
|
|
19039
|
-
}
|
|
19040
|
-
const pos = basePos - 1;
|
|
19041
|
-
const index2 = entries.length;
|
|
19042
|
-
entries.push({ node, pos });
|
|
19043
|
-
positionMap.set(pos, index2);
|
|
19044
|
-
};
|
|
19045
|
-
paragraph.forEach((child, offset2) => {
|
|
19046
|
-
const childPos = paragraphStartPos + offset2 + 1;
|
|
19047
|
-
walk(child, childPos);
|
|
19048
|
-
});
|
|
19049
|
-
return { entries, positionMap };
|
|
19050
|
-
}
|
|
19051
|
-
function findNextTabIndex(flattened, fromIndex) {
|
|
19052
|
-
for (let i = fromIndex; i < flattened.length; i++) {
|
|
19053
|
-
if (flattened[i]?.node?.type?.name === "tab") {
|
|
19054
|
-
return i;
|
|
19055
|
-
}
|
|
19056
|
-
}
|
|
19057
|
-
return -1;
|
|
19058
|
-
}
|
|
19059
|
-
function findDecimalBreakPos(flattened, startIndex, breakChar) {
|
|
19060
|
-
for (let i = startIndex; i < flattened.length; i++) {
|
|
19061
|
-
const entry = flattened[i];
|
|
19062
|
-
if (!entry) break;
|
|
19063
|
-
if (entry.node.type?.name === "tab") break;
|
|
19064
|
-
if (entry.node.type?.name === "text") {
|
|
19065
|
-
const index2 = entry.node.text?.indexOf(breakChar);
|
|
19066
|
-
if (index2 !== void 0 && index2 !== -1) {
|
|
19067
|
-
return entry.pos + index2 + 1;
|
|
19068
|
-
}
|
|
19069
|
-
}
|
|
19070
|
-
}
|
|
19071
|
-
return null;
|
|
19072
|
-
}
|
|
19073
|
-
function measureRangeWidth(view, from2, to, coordCache = null, domPosCache = null) {
|
|
19074
|
-
if (!Number.isFinite(from2) || !Number.isFinite(to) || to <= from2) return 0;
|
|
19075
|
-
try {
|
|
19076
|
-
const range = document.createRange();
|
|
19077
|
-
const fromRef = getCachedDomAtPos(view, from2, domPosCache);
|
|
19078
|
-
const toRef = getCachedDomAtPos(view, to, domPosCache);
|
|
19079
|
-
range.setStart(fromRef.node, fromRef.offset);
|
|
19080
|
-
range.setEnd(toRef.node, toRef.offset);
|
|
19081
|
-
const rect = range.getBoundingClientRect();
|
|
19082
|
-
range.detach?.();
|
|
19083
|
-
return rect.width || 0;
|
|
19084
|
-
} catch {
|
|
19085
|
-
const startLeft = getLeftCoord(view, from2, coordCache, domPosCache);
|
|
19086
|
-
const endLeft = getLeftCoord(view, to, coordCache, domPosCache);
|
|
19087
|
-
if (startLeft == null || endLeft == null) return 0;
|
|
19088
|
-
return Math.max(0, endLeft - startLeft);
|
|
19089
|
-
}
|
|
19090
|
-
}
|
|
19091
|
-
function getIndentWidth(view, paragraphStartPos, indentAttrs = {}, coordCache = null, domPosCache = null) {
|
|
19092
|
-
const marginLeft = getLeftCoord(view, paragraphStartPos, coordCache, domPosCache);
|
|
19093
|
-
const lineLeft = getLeftCoord(view, paragraphStartPos + 1, coordCache, domPosCache);
|
|
19094
|
-
if (marginLeft != null && lineLeft != null) {
|
|
19095
|
-
const diff = lineLeft - marginLeft;
|
|
19096
|
-
if (!Number.isNaN(diff) && Math.abs(diff) > 0.5) {
|
|
19097
|
-
return diff;
|
|
19098
|
-
}
|
|
19099
|
-
}
|
|
19100
|
-
return calculateIndentFallback(indentAttrs);
|
|
19101
|
-
}
|
|
19102
|
-
function getBlockNodeWidth(view, blockStartPos) {
|
|
19103
|
-
const blockDom = view.nodeDOM(blockStartPos - 1);
|
|
19104
|
-
if (blockDom instanceof HTMLElement) {
|
|
19105
|
-
const styles = window.getComputedStyle(blockDom);
|
|
19106
|
-
const width = blockDom.clientWidth + parseFloat(styles.marginLeft || "0") + parseFloat(styles.marginRight || "0") + parseFloat(styles.borderLeftWidth || "0") + parseFloat(styles.borderRightWidth || "0") + parseFloat(styles.paddingLeft || "0") + parseFloat(styles.paddingRight || "0");
|
|
19107
|
-
return width;
|
|
19108
|
-
}
|
|
19109
|
-
return defaultLineLength;
|
|
19110
|
-
}
|
|
19111
|
-
function calculateIndentFallback(indentAttrs = {}) {
|
|
19112
|
-
if (!indentAttrs) return 0;
|
|
19113
|
-
const left2 = twipsToPixels(Number(indentAttrs.left) || 0);
|
|
19114
|
-
const firstLine = twipsToPixels(Number(indentAttrs.firstLine) || 0);
|
|
19115
|
-
const hanging = twipsToPixels(Number(indentAttrs.hanging) || 0);
|
|
19116
|
-
let textIndent = 0;
|
|
19117
|
-
if (firstLine && hanging) {
|
|
19118
|
-
textIndent = firstLine - hanging;
|
|
19119
|
-
} else if (firstLine) {
|
|
19120
|
-
textIndent = firstLine;
|
|
19121
|
-
} else if (hanging) {
|
|
19122
|
-
textIndent = -hanging;
|
|
18316
|
+
this.dom.removeAttribute("data-num-id");
|
|
18317
|
+
this.dom.removeAttribute("data-level");
|
|
19123
18318
|
}
|
|
19124
|
-
if (
|
|
19125
|
-
|
|
19126
|
-
|
|
19127
|
-
|
|
19128
|
-
function getLeftCoord(view, pos, coordCache = null, domPosCache = null) {
|
|
19129
|
-
if (!Number.isFinite(pos)) return null;
|
|
19130
|
-
if (coordCache && coordCache.has(pos)) {
|
|
19131
|
-
return coordCache.get(pos);
|
|
19132
|
-
}
|
|
19133
|
-
let result = null;
|
|
19134
|
-
try {
|
|
19135
|
-
result = view.coordsAtPos(pos).left;
|
|
19136
|
-
} catch {
|
|
19137
|
-
try {
|
|
19138
|
-
const ref2 = getCachedDomAtPos(view, pos, domPosCache);
|
|
19139
|
-
const range = document.createRange();
|
|
19140
|
-
range.setStart(ref2.node, ref2.offset);
|
|
19141
|
-
range.setEnd(ref2.node, ref2.offset);
|
|
19142
|
-
const rect = range.getBoundingClientRect();
|
|
19143
|
-
range.detach?.();
|
|
19144
|
-
result = rect.left;
|
|
19145
|
-
} catch {
|
|
19146
|
-
result = null;
|
|
19147
|
-
}
|
|
19148
|
-
}
|
|
19149
|
-
if (coordCache) {
|
|
19150
|
-
coordCache.set(pos, result);
|
|
19151
|
-
}
|
|
19152
|
-
return result;
|
|
19153
|
-
}
|
|
19154
|
-
function getCachedDomAtPos(view, pos, domPosCache = null) {
|
|
19155
|
-
if (domPosCache && domPosCache.has(pos)) {
|
|
19156
|
-
return domPosCache.get(pos);
|
|
19157
|
-
}
|
|
19158
|
-
const result = view.domAtPos(pos);
|
|
19159
|
-
if (domPosCache) {
|
|
19160
|
-
domPosCache.set(pos, result);
|
|
19161
|
-
}
|
|
19162
|
-
return result;
|
|
19163
|
-
}
|
|
19164
|
-
function calcTabHeight(blockParent2) {
|
|
19165
|
-
const ptToPxRatio = 1.333;
|
|
19166
|
-
const defaultFontSize = 16;
|
|
19167
|
-
const defaultLineHeight = 1.1;
|
|
19168
|
-
const parentTextStyleMark = blockParent2.firstChild?.marks?.find((mark) => mark.type.name === "textStyle");
|
|
19169
|
-
const fontSize = parseInt(parentTextStyleMark?.attrs.fontSize) * ptToPxRatio || defaultFontSize;
|
|
19170
|
-
return `${fontSize * defaultLineHeight}px`;
|
|
19171
|
-
}
|
|
19172
|
-
class ParagraphNodeView {
|
|
19173
|
-
/**
|
|
19174
|
-
* @param {import('prosemirror-model').Node} node Current paragraph node.
|
|
19175
|
-
* @param {import('../../core/Editor').Editor} editor Editor instance providing schema/helpers.
|
|
19176
|
-
* @param {() => number} getPos Position getter provided by ProseMirror.
|
|
19177
|
-
* @param {import('prosemirror-view').Decoration[]} decorations Decorations applied to this node.
|
|
19178
|
-
* @param {Record<string, unknown>} extensionAttrs Extra attributes declared by the paragraph extension.
|
|
19179
|
-
*/
|
|
19180
|
-
constructor(node, editor, getPos, decorations, extensionAttrs) {
|
|
19181
|
-
__privateAdd(this, _ParagraphNodeView_instances);
|
|
19182
|
-
this.node = node;
|
|
19183
|
-
this.editor = editor;
|
|
19184
|
-
this.getPos = getPos;
|
|
19185
|
-
this.decorations = decorations;
|
|
19186
|
-
this.extensionAttrs = extensionAttrs;
|
|
19187
|
-
this._animationFrameRequest = null;
|
|
19188
|
-
this.dom = document.createElement("p");
|
|
19189
|
-
this.contentDOM = document.createElement("span");
|
|
19190
|
-
this.dom.appendChild(this.contentDOM);
|
|
19191
|
-
if (__privateMethod(this, _ParagraphNodeView_instances, checkIsList_fn).call(this)) {
|
|
19192
|
-
__privateMethod(this, _ParagraphNodeView_instances, initList_fn).call(this, node.attrs.listRendering);
|
|
19193
|
-
__privateMethod(this, _ParagraphNodeView_instances, scheduleAnimation_fn).call(this, () => {
|
|
19194
|
-
if (!__privateMethod(this, _ParagraphNodeView_instances, checkIsList_fn).call(this)) {
|
|
19195
|
-
return;
|
|
19196
|
-
}
|
|
19197
|
-
__privateMethod(this, _ParagraphNodeView_instances, updateListStyles_fn).call(this);
|
|
19198
|
-
});
|
|
19199
|
-
}
|
|
19200
|
-
__privateMethod(this, _ParagraphNodeView_instances, updateHTMLAttributes_fn).call(this);
|
|
19201
|
-
}
|
|
19202
|
-
/**
|
|
19203
|
-
* @param {import('prosemirror-model').Node} node
|
|
19204
|
-
* @param {import('prosemirror-view').Decoration[]} decorations
|
|
19205
|
-
*/
|
|
19206
|
-
update(node, decorations) {
|
|
19207
|
-
const oldAttrs = this.node.attrs;
|
|
19208
|
-
const newAttrs = node.attrs;
|
|
19209
|
-
this.node = node;
|
|
19210
|
-
this.decorations = decorations;
|
|
19211
|
-
if (JSON.stringify(oldAttrs) === JSON.stringify(newAttrs)) {
|
|
19212
|
-
return true;
|
|
19213
|
-
}
|
|
19214
|
-
__privateMethod(this, _ParagraphNodeView_instances, updateHTMLAttributes_fn).call(this);
|
|
19215
|
-
if (!__privateMethod(this, _ParagraphNodeView_instances, checkIsList_fn).call(this)) {
|
|
19216
|
-
__privateMethod(this, _ParagraphNodeView_instances, removeList_fn).call(this);
|
|
19217
|
-
return true;
|
|
19218
|
-
}
|
|
19219
|
-
__privateMethod(this, _ParagraphNodeView_instances, initList_fn).call(this, node.attrs.listRendering);
|
|
19220
|
-
__privateMethod(this, _ParagraphNodeView_instances, scheduleAnimation_fn).call(this, () => {
|
|
19221
|
-
__privateMethod(this, _ParagraphNodeView_instances, initList_fn).call(this, node.attrs.listRendering);
|
|
19222
|
-
__privateMethod(this, _ParagraphNodeView_instances, updateListStyles_fn).call(this);
|
|
19223
|
-
});
|
|
19224
|
-
return true;
|
|
19225
|
-
}
|
|
19226
|
-
/**
|
|
19227
|
-
* @param {MutationRecord} mutation
|
|
19228
|
-
*/
|
|
19229
|
-
ignoreMutation(mutation) {
|
|
19230
|
-
if (this.marker && (mutation.target === this.marker || this.marker.contains(mutation.target))) {
|
|
19231
|
-
return true;
|
|
19232
|
-
}
|
|
19233
|
-
if (this.separator && (mutation.target === this.separator || this.separator.contains(mutation.target))) {
|
|
19234
|
-
return true;
|
|
19235
|
-
}
|
|
19236
|
-
if (mutation.type === "attributes" && mutation.target === this.dom && mutation.attributeName === "style") {
|
|
19237
|
-
return true;
|
|
19238
|
-
}
|
|
19239
|
-
if (mutation.type === "childList") {
|
|
19240
|
-
if (this.marker && Array.from(mutation.removedNodes).includes(this.marker)) {
|
|
19241
|
-
return true;
|
|
19242
|
-
}
|
|
19243
|
-
if (this.marker && Array.from(mutation.addedNodes).includes(this.marker)) {
|
|
19244
|
-
return true;
|
|
19245
|
-
}
|
|
19246
|
-
if (this.separator && Array.from(mutation.removedNodes).includes(this.separator)) {
|
|
19247
|
-
return true;
|
|
19248
|
-
}
|
|
19249
|
-
if (this.separator && Array.from(mutation.addedNodes).includes(this.separator)) {
|
|
19250
|
-
return true;
|
|
19251
|
-
}
|
|
19252
|
-
}
|
|
19253
|
-
return false;
|
|
19254
|
-
}
|
|
19255
|
-
destroy() {
|
|
19256
|
-
__privateMethod(this, _ParagraphNodeView_instances, cancelScheduledAnimation_fn).call(this);
|
|
18319
|
+
if (paragraphProperties.framePr?.dropCap) {
|
|
18320
|
+
this.dom.classList.add("sd-editor-dropcap");
|
|
18321
|
+
} else {
|
|
18322
|
+
this.dom.classList.remove("sd-editor-dropcap");
|
|
19257
18323
|
}
|
|
19258
|
-
|
|
19259
|
-
|
|
19260
|
-
updateHTMLAttributes_fn = function() {
|
|
19261
|
-
const htmlAttributes = Attribute.getAttributesToRender(this.node, this.extensionAttrs);
|
|
19262
|
-
htmlAttributes.style = htmlAttributes.style || "";
|
|
19263
|
-
for (const [key2, value] of Object.entries(htmlAttributes || {})) {
|
|
19264
|
-
if (value == null) {
|
|
19265
|
-
this.dom.removeAttribute(key2);
|
|
19266
|
-
continue;
|
|
19267
|
-
}
|
|
19268
|
-
this.dom.setAttribute(key2, value);
|
|
18324
|
+
if (paragraphProperties.styleId) {
|
|
18325
|
+
this.dom.setAttribute("styleid", paragraphProperties.styleId);
|
|
19269
18326
|
}
|
|
19270
18327
|
};
|
|
18328
|
+
updateDOMStyles_fn = function() {
|
|
18329
|
+
this.dom.style.cssText = "";
|
|
18330
|
+
const paragraphProperties = getResolvedParagraphProperties(this.node);
|
|
18331
|
+
const style = encodeCSSFromPPr(paragraphProperties);
|
|
18332
|
+
Object.entries(style).forEach(([k2, v]) => {
|
|
18333
|
+
this.dom.style[k2] = v;
|
|
18334
|
+
});
|
|
18335
|
+
};
|
|
19271
18336
|
updateListStyles_fn = function() {
|
|
19272
18337
|
let { suffix, justification } = this.node.attrs.listRendering;
|
|
19273
18338
|
suffix = suffix ?? "tab";
|
|
19274
18339
|
__privateMethod(this, _ParagraphNodeView_instances, calculateMarkerStyle_fn).call(this, justification);
|
|
19275
18340
|
if (suffix === "tab") {
|
|
19276
|
-
|
|
18341
|
+
const paragraphProperties = getResolvedParagraphProperties(this.node);
|
|
18342
|
+
__privateMethod(this, _ParagraphNodeView_instances, calculateTabSeparatorStyle_fn).call(this, justification, paragraphProperties.indent);
|
|
19277
18343
|
} else {
|
|
19278
18344
|
this.separator.textContent = suffix === "space" ? " " : "";
|
|
19279
18345
|
}
|
|
@@ -19390,10 +18456,11 @@ calculateTabSeparatorStyle_fn = function(justification, indent) {
|
|
|
19390
18456
|
* @param {'left' | 'right' | 'center'} justification
|
|
19391
18457
|
*/
|
|
19392
18458
|
calculateMarkerStyle_fn = function(justification) {
|
|
18459
|
+
const paragraphProperties = getResolvedParagraphProperties(this.node);
|
|
19393
18460
|
const runProperties = resolveRunProperties(
|
|
19394
18461
|
{ docx: this.editor.converter.convertedXml, numbering: this.editor.converter.numbering },
|
|
19395
|
-
|
|
19396
|
-
|
|
18462
|
+
paragraphProperties.runProperties || {},
|
|
18463
|
+
paragraphProperties,
|
|
19397
18464
|
true,
|
|
19398
18465
|
Boolean(this.node.attrs.paragraphProperties.numberingProperties)
|
|
19399
18466
|
);
|
|
@@ -19857,10 +18924,11 @@ function createNumberingPlugin(editor) {
|
|
|
19857
18924
|
tr.setMeta("orderedListSync", true);
|
|
19858
18925
|
numberingManager.enableCache();
|
|
19859
18926
|
newState.doc.descendants((node, pos) => {
|
|
19860
|
-
|
|
18927
|
+
let resolvedProps = calculateResolvedParagraphProperties(editor, node, newState.doc.resolve(pos));
|
|
18928
|
+
if (node.type.name !== "paragraph" || !resolvedProps.numberingProperties) {
|
|
19861
18929
|
return;
|
|
19862
18930
|
}
|
|
19863
|
-
const { numId, ilvl: level = 0 } =
|
|
18931
|
+
const { numId, ilvl: level = 0 } = resolvedProps.numberingProperties;
|
|
19864
18932
|
const definitionDetails = ListHelpers.getListDefinitionDetails({ numId, level, editor });
|
|
19865
18933
|
if (!definitionDetails || Object.keys(definitionDetails).length === 0) {
|
|
19866
18934
|
tr.setNodeAttribute(pos, "listRendering", null);
|
|
@@ -19904,6 +18972,110 @@ function createNumberingPlugin(editor) {
|
|
|
19904
18972
|
}
|
|
19905
18973
|
});
|
|
19906
18974
|
}
|
|
18975
|
+
function createDropcapPlugin(editor) {
|
|
18976
|
+
const { view } = editor;
|
|
18977
|
+
const dropcapWidthCache = /* @__PURE__ */ new Map();
|
|
18978
|
+
const invalidateCacheForRange = (from2, to) => {
|
|
18979
|
+
for (const [pos] of dropcapWidthCache) {
|
|
18980
|
+
if (pos >= from2 && pos <= to) {
|
|
18981
|
+
dropcapWidthCache.delete(pos);
|
|
18982
|
+
}
|
|
18983
|
+
}
|
|
18984
|
+
};
|
|
18985
|
+
const getDropcapDecorations = (state, view2, widthCache) => {
|
|
18986
|
+
const decorations = [];
|
|
18987
|
+
state.doc.descendants((node, pos) => {
|
|
18988
|
+
if (hasDropcapParagraph(node, pos, state)) {
|
|
18989
|
+
const width = getDropcapWidth(view2, pos, widthCache);
|
|
18990
|
+
decorations.push(Decoration.inline(pos, pos + node.nodeSize, { style: `margin-left: -${width}px;` }));
|
|
18991
|
+
return false;
|
|
18992
|
+
}
|
|
18993
|
+
return node.type.name !== "paragraph";
|
|
18994
|
+
});
|
|
18995
|
+
return decorations;
|
|
18996
|
+
};
|
|
18997
|
+
function getDropcapWidth(view2, pos, widthCache) {
|
|
18998
|
+
if (widthCache.has(pos)) {
|
|
18999
|
+
return widthCache.get(pos);
|
|
19000
|
+
}
|
|
19001
|
+
const domNode = view2.nodeDOM(pos);
|
|
19002
|
+
if (domNode) {
|
|
19003
|
+
const range = document.createRange();
|
|
19004
|
+
range.selectNodeContents(domNode);
|
|
19005
|
+
const width = range.getBoundingClientRect().width;
|
|
19006
|
+
widthCache.set(pos, width);
|
|
19007
|
+
return width;
|
|
19008
|
+
}
|
|
19009
|
+
return 0;
|
|
19010
|
+
}
|
|
19011
|
+
const hasDropcapParagraph = (node, pos, state) => {
|
|
19012
|
+
if (node.type.name !== "paragraph") return false;
|
|
19013
|
+
const paragraphProps = calculateResolvedParagraphProperties(editor, node, state.doc.resolve(pos));
|
|
19014
|
+
return paragraphProps.framePr?.dropCap === "margin";
|
|
19015
|
+
};
|
|
19016
|
+
return new Plugin({
|
|
19017
|
+
name: "dropcapPlugin",
|
|
19018
|
+
key: new PluginKey("dropcapPlugin"),
|
|
19019
|
+
state: {
|
|
19020
|
+
init(_, state) {
|
|
19021
|
+
const decorations = getDropcapDecorations(state, view, dropcapWidthCache);
|
|
19022
|
+
return DecorationSet.create(state.doc, decorations);
|
|
19023
|
+
},
|
|
19024
|
+
apply(tr, oldDecorationSet, oldState, newState) {
|
|
19025
|
+
if (!tr.docChanged) return oldDecorationSet;
|
|
19026
|
+
let hasDropcaps = false;
|
|
19027
|
+
newState.doc.descendants((node, pos) => {
|
|
19028
|
+
if (hasDropcapParagraph(node, pos, newState)) {
|
|
19029
|
+
hasDropcaps = true;
|
|
19030
|
+
return false;
|
|
19031
|
+
}
|
|
19032
|
+
});
|
|
19033
|
+
if (!hasDropcaps) {
|
|
19034
|
+
dropcapWidthCache.clear();
|
|
19035
|
+
return DecorationSet.empty;
|
|
19036
|
+
}
|
|
19037
|
+
let affectsDropcaps = false;
|
|
19038
|
+
tr.steps.forEach((step) => {
|
|
19039
|
+
if (step.slice?.content) {
|
|
19040
|
+
step.slice.content.descendants((node, pos) => {
|
|
19041
|
+
if (hasDropcapParagraph(node, pos, newState)) {
|
|
19042
|
+
affectsDropcaps = true;
|
|
19043
|
+
return false;
|
|
19044
|
+
}
|
|
19045
|
+
});
|
|
19046
|
+
}
|
|
19047
|
+
if (step.jsonID === "replace" && step.from !== void 0 && step.to !== void 0) {
|
|
19048
|
+
try {
|
|
19049
|
+
oldState.doc.nodesBetween(step.from, step.to, (node, pos) => {
|
|
19050
|
+
if (hasDropcapParagraph(node, pos, newState)) {
|
|
19051
|
+
affectsDropcaps = true;
|
|
19052
|
+
return false;
|
|
19053
|
+
}
|
|
19054
|
+
});
|
|
19055
|
+
} catch {
|
|
19056
|
+
affectsDropcaps = true;
|
|
19057
|
+
}
|
|
19058
|
+
}
|
|
19059
|
+
});
|
|
19060
|
+
if (!affectsDropcaps) {
|
|
19061
|
+
return oldDecorationSet.map(tr.mapping, tr.doc);
|
|
19062
|
+
}
|
|
19063
|
+
tr.steps.forEach((step) => {
|
|
19064
|
+
if (step.from !== void 0 && step.to !== void 0) {
|
|
19065
|
+
invalidateCacheForRange(step.from, step.to);
|
|
19066
|
+
}
|
|
19067
|
+
});
|
|
19068
|
+
const decorations = getDropcapDecorations(newState, view, dropcapWidthCache);
|
|
19069
|
+
return DecorationSet.create(newState.doc, decorations);
|
|
19070
|
+
}
|
|
19071
|
+
},
|
|
19072
|
+
props: {
|
|
19073
|
+
decorations(state) {
|
|
19074
|
+
return this.getState(state);
|
|
19075
|
+
}
|
|
19076
|
+
}
|
|
19077
|
+
});
|
|
19078
|
+
}
|
|
19907
19079
|
const bulletInputRegex = /^\s*([-+*])\s$/;
|
|
19908
19080
|
const orderedInputRegex = /^(\d+)\.\s$/;
|
|
19909
19081
|
const Paragraph = OxmlNode.create({
|
|
@@ -19929,33 +19101,6 @@ const Paragraph = OxmlNode.create({
|
|
|
19929
19101
|
rsidP: { rendered: false },
|
|
19930
19102
|
rsidRPr: { rendered: false },
|
|
19931
19103
|
rsidDel: { rendered: false },
|
|
19932
|
-
spacing: {
|
|
19933
|
-
default: getDefaultSpacing(),
|
|
19934
|
-
parseDOM: (element) => {
|
|
19935
|
-
if (element && element.closest("[data-superdoc-import]")) {
|
|
19936
|
-
return {
|
|
19937
|
-
after: pixelsToTwips(11),
|
|
19938
|
-
before: 0,
|
|
19939
|
-
line: linesToTwips(1.15),
|
|
19940
|
-
lineRule: "auto"
|
|
19941
|
-
};
|
|
19942
|
-
}
|
|
19943
|
-
return void 0;
|
|
19944
|
-
},
|
|
19945
|
-
renderDOM: (attrs) => {
|
|
19946
|
-
const { spacing, marksAttrs } = attrs;
|
|
19947
|
-
if (!spacing) return { style: null };
|
|
19948
|
-
const spacingCopy = { ...spacing };
|
|
19949
|
-
if (attrs.lineHeight) delete spacingCopy.line;
|
|
19950
|
-
const style = getSpacingStyleString(
|
|
19951
|
-
spacingCopy,
|
|
19952
|
-
marksAttrs ?? [],
|
|
19953
|
-
Boolean(attrs.paragraphProperties?.numberingProperties)
|
|
19954
|
-
);
|
|
19955
|
-
if (style) return { style };
|
|
19956
|
-
return { style: null };
|
|
19957
|
-
}
|
|
19958
|
-
},
|
|
19959
19104
|
extraAttrs: {
|
|
19960
19105
|
default: {},
|
|
19961
19106
|
parseDOM: (element) => {
|
|
@@ -19969,78 +19114,6 @@ const Paragraph = OxmlNode.create({
|
|
|
19969
19114
|
return attributes.extraAttrs || {};
|
|
19970
19115
|
}
|
|
19971
19116
|
},
|
|
19972
|
-
marksAttrs: {
|
|
19973
|
-
renderDOM: (attrs) => {
|
|
19974
|
-
const { marksAttrs } = attrs;
|
|
19975
|
-
if (!marksAttrs?.length) return {};
|
|
19976
|
-
const style = getMarksStyle(marksAttrs);
|
|
19977
|
-
if (style) return { style };
|
|
19978
|
-
return {};
|
|
19979
|
-
}
|
|
19980
|
-
},
|
|
19981
|
-
indent: {
|
|
19982
|
-
default: null,
|
|
19983
|
-
renderDOM: ({ indent }) => {
|
|
19984
|
-
if (!indent) return { style: null };
|
|
19985
|
-
const { left: left2, right: right2, firstLine, hanging } = indent;
|
|
19986
|
-
if (indent && Object.values(indent).every((v) => v === 0)) {
|
|
19987
|
-
return { style: null };
|
|
19988
|
-
}
|
|
19989
|
-
let style = "";
|
|
19990
|
-
if (left2) style += `margin-left: ${twipsToPixels(left2)}px;`;
|
|
19991
|
-
if (right2) style += `margin-right: ${twipsToPixels(right2)}px;`;
|
|
19992
|
-
if (firstLine && !hanging) style += `text-indent: ${twipsToPixels(firstLine)}px;`;
|
|
19993
|
-
if (firstLine && hanging) style += `text-indent: ${twipsToPixels(firstLine - hanging)}px;`;
|
|
19994
|
-
if (!firstLine && hanging) style += `text-indent: ${twipsToPixels(-hanging)}px;`;
|
|
19995
|
-
return { style };
|
|
19996
|
-
}
|
|
19997
|
-
},
|
|
19998
|
-
borders: {
|
|
19999
|
-
default: null,
|
|
20000
|
-
renderDOM: ({ borders }) => {
|
|
20001
|
-
if (!borders) return {};
|
|
20002
|
-
const sideOrder = ["top", "right", "bottom", "left"];
|
|
20003
|
-
const valToCss = {
|
|
20004
|
-
single: "solid",
|
|
20005
|
-
dashed: "dashed",
|
|
20006
|
-
dotted: "dotted",
|
|
20007
|
-
double: "double"
|
|
20008
|
-
};
|
|
20009
|
-
let style = "";
|
|
20010
|
-
sideOrder.forEach((side) => {
|
|
20011
|
-
const b = borders[side];
|
|
20012
|
-
if (!b) return;
|
|
20013
|
-
if (["nil", "none", void 0, null].includes(b.val)) {
|
|
20014
|
-
style += `border-${side}: none;`;
|
|
20015
|
-
return;
|
|
20016
|
-
}
|
|
20017
|
-
const width = b.size != null ? `${eighthPointsToPixels(b.size)}px` : "1px";
|
|
20018
|
-
const cssStyle = valToCss[b.val] || "solid";
|
|
20019
|
-
const color = !b.color || b.color === "auto" ? "#000000" : `#${b.color}`;
|
|
20020
|
-
style += `border-${side}: ${width} ${cssStyle} ${color};`;
|
|
20021
|
-
if (b.space != null && side === "bottom") {
|
|
20022
|
-
style += `padding-bottom: ${eighthPointsToPixels(b.space)}px;`;
|
|
20023
|
-
}
|
|
20024
|
-
});
|
|
20025
|
-
return style ? { style } : {};
|
|
20026
|
-
}
|
|
20027
|
-
},
|
|
20028
|
-
class: {
|
|
20029
|
-
renderDOM: (attributes) => {
|
|
20030
|
-
if (attributes.dropcap) {
|
|
20031
|
-
return { class: `sd-editor-dropcap` };
|
|
20032
|
-
}
|
|
20033
|
-
return null;
|
|
20034
|
-
}
|
|
20035
|
-
},
|
|
20036
|
-
styleId: {
|
|
20037
|
-
default: null,
|
|
20038
|
-
keepOnSplit: false,
|
|
20039
|
-
renderDOM: (attrs) => {
|
|
20040
|
-
if (!attrs.styleId) return {};
|
|
20041
|
-
return { styleid: attrs.styleId };
|
|
20042
|
-
}
|
|
20043
|
-
},
|
|
20044
19117
|
sdBlockId: {
|
|
20045
19118
|
default: null,
|
|
20046
19119
|
keepOnSplit: false,
|
|
@@ -20053,23 +19126,8 @@ const Paragraph = OxmlNode.create({
|
|
|
20053
19126
|
rendered: false
|
|
20054
19127
|
},
|
|
20055
19128
|
filename: { rendered: false },
|
|
20056
|
-
keepLines: { rendered: false },
|
|
20057
|
-
keepNext: { rendered: false },
|
|
20058
19129
|
paragraphProperties: { rendered: false },
|
|
20059
|
-
dropcap: { rendered: false },
|
|
20060
19130
|
pageBreakSource: { rendered: false },
|
|
20061
|
-
textAlign: {
|
|
20062
|
-
renderDOM: ({ textAlign }) => {
|
|
20063
|
-
if (!textAlign) return {};
|
|
20064
|
-
let style = "";
|
|
20065
|
-
if (textAlign === "left") style += "text-align: left;";
|
|
20066
|
-
else if (textAlign === "right") style += "text-align: right;";
|
|
20067
|
-
else if (textAlign === "center") style += "text-align: center;";
|
|
20068
|
-
else if (textAlign === "both") style += "text-align: justify;";
|
|
20069
|
-
return { style };
|
|
20070
|
-
}
|
|
20071
|
-
},
|
|
20072
|
-
tabStops: { rendered: false },
|
|
20073
19131
|
listRendering: {
|
|
20074
19132
|
keepOnSplit: false,
|
|
20075
19133
|
renderDOM: ({ listRendering }) => {
|
|
@@ -20079,15 +19137,6 @@ const Paragraph = OxmlNode.create({
|
|
|
20079
19137
|
"data-list-numbering-type": listRendering?.numberingType
|
|
20080
19138
|
};
|
|
20081
19139
|
}
|
|
20082
|
-
},
|
|
20083
|
-
numberingProperties: {
|
|
20084
|
-
keepOnSplit: true,
|
|
20085
|
-
renderDOM: ({ numberingProperties }) => {
|
|
20086
|
-
return {
|
|
20087
|
-
"data-num-id": numberingProperties?.numId,
|
|
20088
|
-
"data-level": numberingProperties?.ilvl
|
|
20089
|
-
};
|
|
20090
|
-
}
|
|
20091
19140
|
}
|
|
20092
19141
|
};
|
|
20093
19142
|
},
|
|
@@ -20125,12 +19174,6 @@ const Paragraph = OxmlNode.create({
|
|
|
20125
19174
|
return acc;
|
|
20126
19175
|
}, {});
|
|
20127
19176
|
if (Object.keys(numberingProperties).length > 0) {
|
|
20128
|
-
const resolvedParagraphProperties = resolveParagraphProperties(
|
|
20129
|
-
{ docx: this.editor.converter.convertedXml, numbering: this.editor.converter.numbering },
|
|
20130
|
-
{ styleId, numberingProperties, indent, spacing },
|
|
20131
|
-
false,
|
|
20132
|
-
true
|
|
20133
|
-
);
|
|
20134
19177
|
return {
|
|
20135
19178
|
paragraphProperties: {
|
|
20136
19179
|
numberingProperties,
|
|
@@ -20138,17 +19181,10 @@ const Paragraph = OxmlNode.create({
|
|
|
20138
19181
|
spacing,
|
|
20139
19182
|
styleId: styleId || null
|
|
20140
19183
|
},
|
|
20141
|
-
indent: resolvedParagraphProperties.indent,
|
|
20142
|
-
spacing: resolvedParagraphProperties.spacing,
|
|
20143
|
-
numberingProperties,
|
|
20144
|
-
styleId: styleId || null,
|
|
20145
19184
|
extraAttrs
|
|
20146
19185
|
};
|
|
20147
19186
|
}
|
|
20148
19187
|
return {
|
|
20149
|
-
styleId: styleId || null,
|
|
20150
|
-
indent,
|
|
20151
|
-
spacing,
|
|
20152
19188
|
extraAttrs
|
|
20153
19189
|
};
|
|
20154
19190
|
}
|
|
@@ -20165,11 +19201,11 @@ const Paragraph = OxmlNode.create({
|
|
|
20165
19201
|
},
|
|
20166
19202
|
{
|
|
20167
19203
|
tag: "blockquote",
|
|
20168
|
-
attrs: { styleId: "BlockQuote" }
|
|
19204
|
+
attrs: { paragraphProperties: { styleId: "BlockQuote" } }
|
|
20169
19205
|
},
|
|
20170
19206
|
...this.options.headingLevels.map((level) => ({
|
|
20171
19207
|
tag: `h${level}`,
|
|
20172
|
-
attrs: { level, styleId: `Heading${level}` }
|
|
19208
|
+
attrs: { level, paragraphProperties: { styleId: `Heading${level}` } }
|
|
20173
19209
|
}))
|
|
20174
19210
|
];
|
|
20175
19211
|
},
|
|
@@ -20272,109 +19308,11 @@ const Paragraph = OxmlNode.create({
|
|
|
20272
19308
|
};
|
|
20273
19309
|
},
|
|
20274
19310
|
addPmPlugins() {
|
|
20275
|
-
const
|
|
20276
|
-
const dropcapWidthCache = /* @__PURE__ */ new Map();
|
|
20277
|
-
const hasDropcapParagraph = (node) => node.type.name === "paragraph" && node.attrs.dropcap?.type === "margin";
|
|
20278
|
-
const invalidateCacheForRange = (from2, to) => {
|
|
20279
|
-
for (const [pos] of dropcapWidthCache) {
|
|
20280
|
-
if (pos >= from2 && pos <= to) {
|
|
20281
|
-
dropcapWidthCache.delete(pos);
|
|
20282
|
-
}
|
|
20283
|
-
}
|
|
20284
|
-
};
|
|
20285
|
-
const dropcapPlugin = new Plugin({
|
|
20286
|
-
name: "dropcapPlugin",
|
|
20287
|
-
key: new PluginKey("dropcapPlugin"),
|
|
20288
|
-
state: {
|
|
20289
|
-
init(_, state) {
|
|
20290
|
-
const decorations = getDropcapDecorations(state, view, dropcapWidthCache);
|
|
20291
|
-
return DecorationSet.create(state.doc, decorations);
|
|
20292
|
-
},
|
|
20293
|
-
apply(tr, oldDecorationSet, oldState, newState) {
|
|
20294
|
-
if (!tr.docChanged) return oldDecorationSet;
|
|
20295
|
-
let hasDropcaps = false;
|
|
20296
|
-
newState.doc.descendants((node) => {
|
|
20297
|
-
if (hasDropcapParagraph(node)) {
|
|
20298
|
-
hasDropcaps = true;
|
|
20299
|
-
return false;
|
|
20300
|
-
}
|
|
20301
|
-
});
|
|
20302
|
-
if (!hasDropcaps) {
|
|
20303
|
-
dropcapWidthCache.clear();
|
|
20304
|
-
return DecorationSet.empty;
|
|
20305
|
-
}
|
|
20306
|
-
let affectsDropcaps = false;
|
|
20307
|
-
tr.steps.forEach((step) => {
|
|
20308
|
-
if (step.slice?.content) {
|
|
20309
|
-
step.slice.content.descendants((node) => {
|
|
20310
|
-
if (hasDropcapParagraph(node)) {
|
|
20311
|
-
affectsDropcaps = true;
|
|
20312
|
-
return false;
|
|
20313
|
-
}
|
|
20314
|
-
});
|
|
20315
|
-
}
|
|
20316
|
-
if (step.jsonID === "replace" && step.from !== void 0 && step.to !== void 0) {
|
|
20317
|
-
try {
|
|
20318
|
-
oldState.doc.nodesBetween(step.from, step.to, (node) => {
|
|
20319
|
-
if (hasDropcapParagraph(node)) {
|
|
20320
|
-
affectsDropcaps = true;
|
|
20321
|
-
return false;
|
|
20322
|
-
}
|
|
20323
|
-
});
|
|
20324
|
-
} catch {
|
|
20325
|
-
affectsDropcaps = true;
|
|
20326
|
-
}
|
|
20327
|
-
}
|
|
20328
|
-
});
|
|
20329
|
-
if (!affectsDropcaps) {
|
|
20330
|
-
return oldDecorationSet.map(tr.mapping, tr.doc);
|
|
20331
|
-
}
|
|
20332
|
-
tr.steps.forEach((step) => {
|
|
20333
|
-
if (step.from !== void 0 && step.to !== void 0) {
|
|
20334
|
-
invalidateCacheForRange(step.from, step.to);
|
|
20335
|
-
}
|
|
20336
|
-
});
|
|
20337
|
-
const decorations = getDropcapDecorations(newState, view, dropcapWidthCache);
|
|
20338
|
-
return DecorationSet.create(newState.doc, decorations);
|
|
20339
|
-
}
|
|
20340
|
-
},
|
|
20341
|
-
props: {
|
|
20342
|
-
decorations(state) {
|
|
20343
|
-
return this.getState(state);
|
|
20344
|
-
}
|
|
20345
|
-
}
|
|
20346
|
-
});
|
|
19311
|
+
const dropcapPlugin = createDropcapPlugin(this.editor);
|
|
20347
19312
|
const numberingPlugin = createNumberingPlugin(this.editor);
|
|
20348
19313
|
return [dropcapPlugin, numberingPlugin];
|
|
20349
19314
|
}
|
|
20350
19315
|
});
|
|
20351
|
-
const getDropcapDecorations = (state, view, widthCache) => {
|
|
20352
|
-
const decorations = [];
|
|
20353
|
-
state.doc.descendants((node, pos) => {
|
|
20354
|
-
if (node.type.name === "paragraph") {
|
|
20355
|
-
if (node.attrs.dropcap?.type === "margin") {
|
|
20356
|
-
const width = getDropcapWidth(view, pos, widthCache);
|
|
20357
|
-
decorations.push(Decoration.inline(pos, pos + node.nodeSize, { style: `margin-left: -${width}px;` }));
|
|
20358
|
-
}
|
|
20359
|
-
return false;
|
|
20360
|
-
}
|
|
20361
|
-
});
|
|
20362
|
-
return decorations;
|
|
20363
|
-
};
|
|
20364
|
-
function getDropcapWidth(view, pos, widthCache) {
|
|
20365
|
-
if (widthCache.has(pos)) {
|
|
20366
|
-
return widthCache.get(pos);
|
|
20367
|
-
}
|
|
20368
|
-
const domNode = view.nodeDOM(pos);
|
|
20369
|
-
if (domNode) {
|
|
20370
|
-
const range = document.createRange();
|
|
20371
|
-
range.selectNodeContents(domNode);
|
|
20372
|
-
const width = range.getBoundingClientRect().width;
|
|
20373
|
-
widthCache.set(pos, width);
|
|
20374
|
-
return width;
|
|
20375
|
-
}
|
|
20376
|
-
return 0;
|
|
20377
|
-
}
|
|
20378
19316
|
const Heading = Extension.create({
|
|
20379
19317
|
name: "heading",
|
|
20380
19318
|
addOptions() {
|
|
@@ -30652,434 +29590,1205 @@ class ShapeGroupView {
|
|
|
30652
29590
|
svg.appendChild(shapeElement);
|
|
30653
29591
|
}
|
|
30654
29592
|
}
|
|
30655
|
-
});
|
|
30656
|
-
}
|
|
30657
|
-
container.appendChild(svg);
|
|
30658
|
-
return { element: container };
|
|
30659
|
-
}
|
|
30660
|
-
createShapeElement(shape) {
|
|
30661
|
-
const attrs = shape.attrs;
|
|
30662
|
-
if (!attrs) return null;
|
|
30663
|
-
const x = attrs.x || 0;
|
|
30664
|
-
const y = attrs.y || 0;
|
|
30665
|
-
const width = attrs.width || 100;
|
|
30666
|
-
const height = attrs.height || 100;
|
|
30667
|
-
const g = document.createElementNS("http://www.w3.org/2000/svg", "g");
|
|
30668
|
-
const transforms = [];
|
|
30669
|
-
transforms.push(`translate(${x}, ${y})`);
|
|
30670
|
-
if (attrs.rotation !== 0) {
|
|
30671
|
-
transforms.push(`rotate(${attrs.rotation} ${width / 2} ${height / 2})`);
|
|
30672
|
-
}
|
|
30673
|
-
if (attrs.flipH) {
|
|
30674
|
-
transforms.push(`scale(-1, 1) translate(${-width}, 0)`);
|
|
30675
|
-
}
|
|
30676
|
-
if (attrs.flipV) {
|
|
30677
|
-
transforms.push(`scale(1, -1) translate(0, ${-height})`);
|
|
30678
|
-
}
|
|
30679
|
-
if (transforms.length > 0) {
|
|
30680
|
-
g.setAttribute("transform", transforms.join(" "));
|
|
30681
|
-
}
|
|
30682
|
-
const shapeKind = attrs.kind || "rect";
|
|
30683
|
-
const fillColor = attrs.fillColor || "#5b9bd5";
|
|
30684
|
-
const strokeColor = attrs.strokeColor || "#000000";
|
|
30685
|
-
const strokeWidth = attrs.strokeWidth || 1;
|
|
30686
|
-
try {
|
|
30687
|
-
const svgContent = k({
|
|
30688
|
-
preset: shapeKind,
|
|
30689
|
-
styleOverrides: {
|
|
30690
|
-
fill: fillColor || "none",
|
|
30691
|
-
stroke: strokeColor || "none",
|
|
30692
|
-
strokeWidth: strokeWidth || 0
|
|
30693
|
-
},
|
|
30694
|
-
width,
|
|
30695
|
-
height
|
|
30696
|
-
});
|
|
30697
|
-
if (svgContent) {
|
|
30698
|
-
const tempDiv = document.createElement("div");
|
|
30699
|
-
tempDiv.innerHTML = svgContent;
|
|
30700
|
-
const svgElement = tempDiv.querySelector("svg");
|
|
30701
|
-
if (svgElement) {
|
|
30702
|
-
Array.from(svgElement.children).forEach((child) => {
|
|
30703
|
-
const clonedChild = child.cloneNode(true);
|
|
30704
|
-
if (clonedChild.tagName === "ellipse") {
|
|
30705
|
-
clonedChild.setAttribute("cx", (width / 2).toString());
|
|
30706
|
-
clonedChild.setAttribute("cy", (height / 2).toString());
|
|
30707
|
-
clonedChild.setAttribute("rx", (width / 2).toString());
|
|
30708
|
-
clonedChild.setAttribute("ry", (height / 2).toString());
|
|
30709
|
-
} else if (clonedChild.tagName === "circle") {
|
|
30710
|
-
if (width !== height) {
|
|
30711
|
-
const ellipse = document.createElementNS("http://www.w3.org/2000/svg", "ellipse");
|
|
30712
|
-
ellipse.setAttribute("cx", (width / 2).toString());
|
|
30713
|
-
ellipse.setAttribute("cy", (height / 2).toString());
|
|
30714
|
-
ellipse.setAttribute("rx", (width / 2).toString());
|
|
30715
|
-
ellipse.setAttribute("ry", (height / 2).toString());
|
|
30716
|
-
Array.from(clonedChild.attributes).forEach((attr) => {
|
|
30717
|
-
if (!["cx", "cy", "r"].includes(attr.name)) {
|
|
30718
|
-
ellipse.setAttribute(attr.name, attr.value);
|
|
30719
|
-
}
|
|
29593
|
+
});
|
|
29594
|
+
}
|
|
29595
|
+
container.appendChild(svg);
|
|
29596
|
+
return { element: container };
|
|
29597
|
+
}
|
|
29598
|
+
createShapeElement(shape) {
|
|
29599
|
+
const attrs = shape.attrs;
|
|
29600
|
+
if (!attrs) return null;
|
|
29601
|
+
const x = attrs.x || 0;
|
|
29602
|
+
const y = attrs.y || 0;
|
|
29603
|
+
const width = attrs.width || 100;
|
|
29604
|
+
const height = attrs.height || 100;
|
|
29605
|
+
const g = document.createElementNS("http://www.w3.org/2000/svg", "g");
|
|
29606
|
+
const transforms = [];
|
|
29607
|
+
transforms.push(`translate(${x}, ${y})`);
|
|
29608
|
+
if (attrs.rotation !== 0) {
|
|
29609
|
+
transforms.push(`rotate(${attrs.rotation} ${width / 2} ${height / 2})`);
|
|
29610
|
+
}
|
|
29611
|
+
if (attrs.flipH) {
|
|
29612
|
+
transforms.push(`scale(-1, 1) translate(${-width}, 0)`);
|
|
29613
|
+
}
|
|
29614
|
+
if (attrs.flipV) {
|
|
29615
|
+
transforms.push(`scale(1, -1) translate(0, ${-height})`);
|
|
29616
|
+
}
|
|
29617
|
+
if (transforms.length > 0) {
|
|
29618
|
+
g.setAttribute("transform", transforms.join(" "));
|
|
29619
|
+
}
|
|
29620
|
+
const shapeKind = attrs.kind || "rect";
|
|
29621
|
+
const fillColor = attrs.fillColor || "#5b9bd5";
|
|
29622
|
+
const strokeColor = attrs.strokeColor || "#000000";
|
|
29623
|
+
const strokeWidth = attrs.strokeWidth || 1;
|
|
29624
|
+
try {
|
|
29625
|
+
const svgContent = k({
|
|
29626
|
+
preset: shapeKind,
|
|
29627
|
+
styleOverrides: {
|
|
29628
|
+
fill: fillColor || "none",
|
|
29629
|
+
stroke: strokeColor || "none",
|
|
29630
|
+
strokeWidth: strokeWidth || 0
|
|
29631
|
+
},
|
|
29632
|
+
width,
|
|
29633
|
+
height
|
|
29634
|
+
});
|
|
29635
|
+
if (svgContent) {
|
|
29636
|
+
const tempDiv = document.createElement("div");
|
|
29637
|
+
tempDiv.innerHTML = svgContent;
|
|
29638
|
+
const svgElement = tempDiv.querySelector("svg");
|
|
29639
|
+
if (svgElement) {
|
|
29640
|
+
Array.from(svgElement.children).forEach((child) => {
|
|
29641
|
+
const clonedChild = child.cloneNode(true);
|
|
29642
|
+
if (clonedChild.tagName === "ellipse") {
|
|
29643
|
+
clonedChild.setAttribute("cx", (width / 2).toString());
|
|
29644
|
+
clonedChild.setAttribute("cy", (height / 2).toString());
|
|
29645
|
+
clonedChild.setAttribute("rx", (width / 2).toString());
|
|
29646
|
+
clonedChild.setAttribute("ry", (height / 2).toString());
|
|
29647
|
+
} else if (clonedChild.tagName === "circle") {
|
|
29648
|
+
if (width !== height) {
|
|
29649
|
+
const ellipse = document.createElementNS("http://www.w3.org/2000/svg", "ellipse");
|
|
29650
|
+
ellipse.setAttribute("cx", (width / 2).toString());
|
|
29651
|
+
ellipse.setAttribute("cy", (height / 2).toString());
|
|
29652
|
+
ellipse.setAttribute("rx", (width / 2).toString());
|
|
29653
|
+
ellipse.setAttribute("ry", (height / 2).toString());
|
|
29654
|
+
Array.from(clonedChild.attributes).forEach((attr) => {
|
|
29655
|
+
if (!["cx", "cy", "r"].includes(attr.name)) {
|
|
29656
|
+
ellipse.setAttribute(attr.name, attr.value);
|
|
29657
|
+
}
|
|
29658
|
+
});
|
|
29659
|
+
g.appendChild(ellipse);
|
|
29660
|
+
return;
|
|
29661
|
+
} else {
|
|
29662
|
+
clonedChild.setAttribute("cx", (width / 2).toString());
|
|
29663
|
+
clonedChild.setAttribute("cy", (height / 2).toString());
|
|
29664
|
+
clonedChild.setAttribute("r", (width / 2).toString());
|
|
29665
|
+
}
|
|
29666
|
+
} else if (clonedChild.tagName === "rect") {
|
|
29667
|
+
clonedChild.setAttribute("width", width.toString());
|
|
29668
|
+
clonedChild.setAttribute("height", height.toString());
|
|
29669
|
+
} else if (clonedChild.tagName === "path" && svgElement.hasAttribute("viewBox")) {
|
|
29670
|
+
const viewBox = svgElement.getAttribute("viewBox").split(" ").map(Number);
|
|
29671
|
+
if (viewBox.length === 4) {
|
|
29672
|
+
const [, , vbWidth, vbHeight] = viewBox;
|
|
29673
|
+
const scaleX = width / vbWidth;
|
|
29674
|
+
const scaleY = height / vbHeight;
|
|
29675
|
+
if (scaleX !== 1 || scaleY !== 1) {
|
|
29676
|
+
const pathTransform = `scale(${scaleX}, ${scaleY})`;
|
|
29677
|
+
const existingTransform = clonedChild.getAttribute("transform");
|
|
29678
|
+
clonedChild.setAttribute(
|
|
29679
|
+
"transform",
|
|
29680
|
+
existingTransform ? `${existingTransform} ${pathTransform}` : pathTransform
|
|
29681
|
+
);
|
|
29682
|
+
}
|
|
29683
|
+
}
|
|
29684
|
+
} else if (clonedChild.hasAttribute("width")) {
|
|
29685
|
+
clonedChild.setAttribute("width", width.toString());
|
|
29686
|
+
}
|
|
29687
|
+
if (clonedChild.hasAttribute("height") && clonedChild.tagName !== "ellipse") {
|
|
29688
|
+
clonedChild.setAttribute("height", height.toString());
|
|
29689
|
+
}
|
|
29690
|
+
g.appendChild(clonedChild);
|
|
29691
|
+
});
|
|
29692
|
+
}
|
|
29693
|
+
}
|
|
29694
|
+
} catch (error) {
|
|
29695
|
+
console.warn("Failed to generate shape SVG:", error);
|
|
29696
|
+
const rect = document.createElementNS("http://www.w3.org/2000/svg", "rect");
|
|
29697
|
+
rect.setAttribute("width", width.toString());
|
|
29698
|
+
rect.setAttribute("height", height.toString());
|
|
29699
|
+
rect.setAttribute("fill", fillColor);
|
|
29700
|
+
rect.setAttribute("stroke", strokeColor);
|
|
29701
|
+
rect.setAttribute("stroke-width", strokeWidth.toString());
|
|
29702
|
+
g.appendChild(rect);
|
|
29703
|
+
}
|
|
29704
|
+
return g;
|
|
29705
|
+
}
|
|
29706
|
+
buildView() {
|
|
29707
|
+
const { element } = this.createElement();
|
|
29708
|
+
this.root = element;
|
|
29709
|
+
}
|
|
29710
|
+
update() {
|
|
29711
|
+
return false;
|
|
29712
|
+
}
|
|
29713
|
+
}
|
|
29714
|
+
const ShapeGroup = Node$1.create({
|
|
29715
|
+
name: "shapeGroup",
|
|
29716
|
+
group: "inline",
|
|
29717
|
+
inline: true,
|
|
29718
|
+
atom: true,
|
|
29719
|
+
addOptions() {
|
|
29720
|
+
return {
|
|
29721
|
+
htmlAttributes: {
|
|
29722
|
+
contenteditable: false
|
|
29723
|
+
}
|
|
29724
|
+
};
|
|
29725
|
+
},
|
|
29726
|
+
addAttributes() {
|
|
29727
|
+
return {
|
|
29728
|
+
groupTransform: {
|
|
29729
|
+
default: {},
|
|
29730
|
+
renderDOM: () => ({})
|
|
29731
|
+
},
|
|
29732
|
+
shapes: {
|
|
29733
|
+
default: [],
|
|
29734
|
+
renderDOM: () => ({})
|
|
29735
|
+
},
|
|
29736
|
+
size: {
|
|
29737
|
+
default: null,
|
|
29738
|
+
renderDOM: (attrs) => {
|
|
29739
|
+
if (!attrs.size) return {};
|
|
29740
|
+
const sizeData = {};
|
|
29741
|
+
if (attrs.size.width) sizeData["data-width"] = attrs.size.width;
|
|
29742
|
+
if (attrs.size.height) sizeData["data-height"] = attrs.size.height;
|
|
29743
|
+
return sizeData;
|
|
29744
|
+
}
|
|
29745
|
+
},
|
|
29746
|
+
padding: {
|
|
29747
|
+
default: null,
|
|
29748
|
+
renderDOM: (attrs) => {
|
|
29749
|
+
if (!attrs.padding) return {};
|
|
29750
|
+
const paddingData = {};
|
|
29751
|
+
if (attrs.padding.top != null) paddingData["data-padding-top"] = attrs.padding.top;
|
|
29752
|
+
if (attrs.padding.right != null) paddingData["data-padding-right"] = attrs.padding.right;
|
|
29753
|
+
if (attrs.padding.bottom != null) paddingData["data-padding-bottom"] = attrs.padding.bottom;
|
|
29754
|
+
if (attrs.padding.left != null) paddingData["data-padding-left"] = attrs.padding.left;
|
|
29755
|
+
return paddingData;
|
|
29756
|
+
}
|
|
29757
|
+
},
|
|
29758
|
+
marginOffset: {
|
|
29759
|
+
default: null,
|
|
29760
|
+
renderDOM: (attrs) => {
|
|
29761
|
+
if (!attrs.marginOffset) return {};
|
|
29762
|
+
const offsetData = {};
|
|
29763
|
+
if (attrs.marginOffset.horizontal != null) offsetData["data-offset-x"] = attrs.marginOffset.horizontal;
|
|
29764
|
+
if (attrs.marginOffset.top != null) offsetData["data-offset-y"] = attrs.marginOffset.top;
|
|
29765
|
+
return offsetData;
|
|
29766
|
+
}
|
|
29767
|
+
},
|
|
29768
|
+
drawingContent: {
|
|
29769
|
+
rendered: false
|
|
29770
|
+
}
|
|
29771
|
+
};
|
|
29772
|
+
},
|
|
29773
|
+
parseDOM() {
|
|
29774
|
+
return false;
|
|
29775
|
+
},
|
|
29776
|
+
renderDOM({ htmlAttributes }) {
|
|
29777
|
+
return ["div", Attribute.mergeAttributes(this.options.htmlAttributes, htmlAttributes, { "data-shape-group": "" })];
|
|
29778
|
+
},
|
|
29779
|
+
addNodeView() {
|
|
29780
|
+
return (props) => {
|
|
29781
|
+
return new ShapeGroupView({ ...props });
|
|
29782
|
+
};
|
|
29783
|
+
}
|
|
29784
|
+
});
|
|
29785
|
+
const TextStyle = Mark.create({
|
|
29786
|
+
name: "textStyle",
|
|
29787
|
+
addOptions() {
|
|
29788
|
+
return {
|
|
29789
|
+
htmlAttributes: {}
|
|
29790
|
+
};
|
|
29791
|
+
},
|
|
29792
|
+
parseDOM() {
|
|
29793
|
+
return [
|
|
29794
|
+
{
|
|
29795
|
+
tag: "span",
|
|
29796
|
+
getAttrs: (el) => {
|
|
29797
|
+
const hasStyles = el.hasAttribute("style");
|
|
29798
|
+
const isAnnotation = el.classList.contains(annotationClass) || el.classList.contains(annotationContentClass);
|
|
29799
|
+
if (!hasStyles || isAnnotation) return false;
|
|
29800
|
+
return {};
|
|
29801
|
+
}
|
|
29802
|
+
},
|
|
29803
|
+
{
|
|
29804
|
+
getAttrs: (node) => {
|
|
29805
|
+
const fontFamily = node.style.fontFamily?.replace(/['"]+/g, "");
|
|
29806
|
+
const fontSize = node.style.fontSize;
|
|
29807
|
+
const textTransform = node.style.textTransform;
|
|
29808
|
+
if (fontFamily || fontSize || textTransform) {
|
|
29809
|
+
return {
|
|
29810
|
+
fontFamily: fontFamily || null,
|
|
29811
|
+
fontSize: fontSize || null,
|
|
29812
|
+
textTransform: textTransform || null
|
|
29813
|
+
};
|
|
29814
|
+
}
|
|
29815
|
+
return false;
|
|
29816
|
+
}
|
|
29817
|
+
}
|
|
29818
|
+
];
|
|
29819
|
+
},
|
|
29820
|
+
renderDOM({ htmlAttributes }) {
|
|
29821
|
+
return ["span", Attribute.mergeAttributes(this.options.htmlAttributes, htmlAttributes), 0];
|
|
29822
|
+
},
|
|
29823
|
+
addAttributes() {
|
|
29824
|
+
return {
|
|
29825
|
+
/**
|
|
29826
|
+
* @category Attribute
|
|
29827
|
+
* @param {string} [styleId] - Style identifier for referencing predefined styles
|
|
29828
|
+
*/
|
|
29829
|
+
styleId: {}
|
|
29830
|
+
};
|
|
29831
|
+
},
|
|
29832
|
+
addCommands() {
|
|
29833
|
+
return {
|
|
29834
|
+
/**
|
|
29835
|
+
* Remove empty text style marks
|
|
29836
|
+
* @category Command
|
|
29837
|
+
* @example
|
|
29838
|
+
* editor.commands.removeEmptyTextStyle()
|
|
29839
|
+
* @note Cleanup utility to prevent empty span elements
|
|
29840
|
+
* @note Automatically checks if any style attributes exist before removal
|
|
29841
|
+
*/
|
|
29842
|
+
removeEmptyTextStyle: () => ({ state, commands: commands2 }) => {
|
|
29843
|
+
const attributes = Attribute.getMarkAttributes(state, this.type);
|
|
29844
|
+
const hasStyles = Object.entries(attributes).some(([, value]) => !!value);
|
|
29845
|
+
if (hasStyles) return true;
|
|
29846
|
+
return commands2.unsetMark(this.name);
|
|
29847
|
+
}
|
|
29848
|
+
};
|
|
29849
|
+
}
|
|
29850
|
+
});
|
|
29851
|
+
function createCascadeToggleCommands({
|
|
29852
|
+
markName,
|
|
29853
|
+
setCommand,
|
|
29854
|
+
unsetCommand,
|
|
29855
|
+
toggleCommand,
|
|
29856
|
+
negationAttrs,
|
|
29857
|
+
isNegation,
|
|
29858
|
+
extendEmptyMarkRange
|
|
29859
|
+
} = {}) {
|
|
29860
|
+
if (!markName) throw new Error("createCascadeToggleCommands requires a markName");
|
|
29861
|
+
const capitalized = markName.charAt(0).toUpperCase() + markName.slice(1);
|
|
29862
|
+
const setName = setCommand ?? `set${capitalized}`;
|
|
29863
|
+
const unsetName = unsetCommand ?? `unset${capitalized}`;
|
|
29864
|
+
const toggleName = toggleCommand ?? `toggle${capitalized}`;
|
|
29865
|
+
const cascadeOptions = {};
|
|
29866
|
+
if (negationAttrs) cascadeOptions.negationAttrs = negationAttrs;
|
|
29867
|
+
if (typeof isNegation === "function") cascadeOptions.isNegation = isNegation;
|
|
29868
|
+
if (extendEmptyMarkRange !== void 0) cascadeOptions.extendEmptyMarkRange = extendEmptyMarkRange;
|
|
29869
|
+
return {
|
|
29870
|
+
[setName]: () => ({ commands: commands2 }) => commands2.setMark(markName),
|
|
29871
|
+
[unsetName]: () => ({ commands: commands2 }) => commands2.unsetMark(markName),
|
|
29872
|
+
[toggleName]: () => ({ commands: commands2 }) => commands2.toggleMarkCascade(markName, cascadeOptions)
|
|
29873
|
+
};
|
|
29874
|
+
}
|
|
29875
|
+
const Bold = Mark.create({
|
|
29876
|
+
name: "bold",
|
|
29877
|
+
addOptions() {
|
|
29878
|
+
return {
|
|
29879
|
+
htmlAttributes: {}
|
|
29880
|
+
};
|
|
29881
|
+
},
|
|
29882
|
+
addAttributes() {
|
|
29883
|
+
return {
|
|
29884
|
+
value: {
|
|
29885
|
+
default: null,
|
|
29886
|
+
renderDOM: (attrs) => {
|
|
29887
|
+
if (attrs.value == null) return {};
|
|
29888
|
+
if (attrs.value === "0" || !attrs.value) {
|
|
29889
|
+
return { style: "font-weight: normal" };
|
|
29890
|
+
}
|
|
29891
|
+
return {};
|
|
29892
|
+
}
|
|
29893
|
+
}
|
|
29894
|
+
};
|
|
29895
|
+
},
|
|
29896
|
+
parseDOM() {
|
|
29897
|
+
return [
|
|
29898
|
+
{ tag: "strong" },
|
|
29899
|
+
{ tag: "b", getAttrs: (node) => node.style.fontWeight != "normal" && null },
|
|
29900
|
+
{ style: "font-weight=400", clearMark: (m) => m.type.name == "strong" },
|
|
29901
|
+
{ style: "font-weight", getAttrs: (value) => /^(bold(er)?|[5-9]\d{2,})$/.test(value) && null }
|
|
29902
|
+
];
|
|
29903
|
+
},
|
|
29904
|
+
renderDOM({ htmlAttributes }) {
|
|
29905
|
+
const merged = Attribute.mergeAttributes(this.options.htmlAttributes, htmlAttributes);
|
|
29906
|
+
const { value, ...rest } = merged || {};
|
|
29907
|
+
if (value === "0") {
|
|
29908
|
+
return ["span", rest, 0];
|
|
29909
|
+
}
|
|
29910
|
+
return ["strong", rest, 0];
|
|
29911
|
+
},
|
|
29912
|
+
addCommands() {
|
|
29913
|
+
const { setBold, unsetBold, toggleBold } = createCascadeToggleCommands({
|
|
29914
|
+
markName: this.name,
|
|
29915
|
+
negationAttrs: { value: "0" }
|
|
29916
|
+
});
|
|
29917
|
+
return {
|
|
29918
|
+
/**
|
|
29919
|
+
* Apply bold formatting
|
|
29920
|
+
* @category Command
|
|
29921
|
+
* @example
|
|
29922
|
+
* editor.commands.setBold()
|
|
29923
|
+
* @note '0' renders as normal weight
|
|
29924
|
+
*/
|
|
29925
|
+
setBold,
|
|
29926
|
+
/**
|
|
29927
|
+
* Remove bold formatting
|
|
29928
|
+
* @category Command
|
|
29929
|
+
* @example
|
|
29930
|
+
* editor.commands.unsetBold()
|
|
29931
|
+
*/
|
|
29932
|
+
unsetBold,
|
|
29933
|
+
/**
|
|
29934
|
+
* Toggle bold formatting
|
|
29935
|
+
* @category Command
|
|
29936
|
+
* @example
|
|
29937
|
+
* editor.commands.toggleBold()
|
|
29938
|
+
*/
|
|
29939
|
+
toggleBold
|
|
29940
|
+
};
|
|
29941
|
+
},
|
|
29942
|
+
addShortcuts() {
|
|
29943
|
+
return {
|
|
29944
|
+
"Mod-b": () => this.editor.commands.toggleBold(),
|
|
29945
|
+
"Mod-B": () => this.editor.commands.toggleBold()
|
|
29946
|
+
};
|
|
29947
|
+
}
|
|
29948
|
+
});
|
|
29949
|
+
const Italic = Mark.create({
|
|
29950
|
+
name: "italic",
|
|
29951
|
+
addOptions() {
|
|
29952
|
+
return {
|
|
29953
|
+
htmlAttributes: {}
|
|
29954
|
+
};
|
|
29955
|
+
},
|
|
29956
|
+
addAttributes() {
|
|
29957
|
+
return {
|
|
29958
|
+
/**
|
|
29959
|
+
* @category Attribute
|
|
29960
|
+
* @param {string} [value] - Italic toggle value ('0' renders as normal)
|
|
29961
|
+
*/
|
|
29962
|
+
value: {
|
|
29963
|
+
default: null,
|
|
29964
|
+
renderDOM: (attrs) => {
|
|
29965
|
+
if (attrs.value == null) return {};
|
|
29966
|
+
if (attrs.value === "0" || !attrs.value) return { style: "font-style: normal" };
|
|
29967
|
+
return {};
|
|
29968
|
+
}
|
|
29969
|
+
}
|
|
29970
|
+
};
|
|
29971
|
+
},
|
|
29972
|
+
parseDOM() {
|
|
29973
|
+
return [
|
|
29974
|
+
{ tag: "i" },
|
|
29975
|
+
{ tag: "em" },
|
|
29976
|
+
{ style: "font-style=italic" },
|
|
29977
|
+
{ style: "font-style=normal", clearMark: (m) => m.type.name == "em" }
|
|
29978
|
+
];
|
|
29979
|
+
},
|
|
29980
|
+
renderDOM({ htmlAttributes }) {
|
|
29981
|
+
const merged = Attribute.mergeAttributes(this.options.htmlAttributes, htmlAttributes);
|
|
29982
|
+
const { value, ...rest } = merged || {};
|
|
29983
|
+
if (value === "0") {
|
|
29984
|
+
return ["span", rest, 0];
|
|
29985
|
+
}
|
|
29986
|
+
return ["em", rest, 0];
|
|
29987
|
+
},
|
|
29988
|
+
addCommands() {
|
|
29989
|
+
const { setItalic, unsetItalic, toggleItalic } = createCascadeToggleCommands({
|
|
29990
|
+
markName: this.name,
|
|
29991
|
+
negationAttrs: { value: "0" }
|
|
29992
|
+
});
|
|
29993
|
+
return {
|
|
29994
|
+
/**
|
|
29995
|
+
* Apply italic formatting
|
|
29996
|
+
* @category Command
|
|
29997
|
+
* @example
|
|
29998
|
+
* editor.commands.setItalic()
|
|
29999
|
+
*/
|
|
30000
|
+
setItalic,
|
|
30001
|
+
/**
|
|
30002
|
+
* Remove italic formatting
|
|
30003
|
+
* @category Command
|
|
30004
|
+
* @example
|
|
30005
|
+
* editor.commands.unsetItalic()
|
|
30006
|
+
*/
|
|
30007
|
+
unsetItalic,
|
|
30008
|
+
/**
|
|
30009
|
+
* Toggle italic formatting
|
|
30010
|
+
* @category Command
|
|
30011
|
+
* @example
|
|
30012
|
+
* editor.commands.toggleItalic()
|
|
30013
|
+
*/
|
|
30014
|
+
toggleItalic
|
|
30015
|
+
};
|
|
30016
|
+
},
|
|
30017
|
+
addShortcuts() {
|
|
30018
|
+
return {
|
|
30019
|
+
"Mod-i": () => this.editor.commands.toggleItalic(),
|
|
30020
|
+
"Mod-I": () => this.editor.commands.toggleItalic()
|
|
30021
|
+
};
|
|
30022
|
+
}
|
|
30023
|
+
});
|
|
30024
|
+
const isKeyboardInvocation = (event) => {
|
|
30025
|
+
return event.type === "contextmenu" && typeof event.detail === "number" && event.detail === 0 && (event.button === 0 || event.button === void 0) && event.clientX === 0 && event.clientY === 0;
|
|
30026
|
+
};
|
|
30027
|
+
const prefersNativeMenu = (event) => {
|
|
30028
|
+
if (!event) return false;
|
|
30029
|
+
if (event.ctrlKey || event.metaKey) {
|
|
30030
|
+
return true;
|
|
30031
|
+
}
|
|
30032
|
+
return isKeyboardInvocation(event);
|
|
30033
|
+
};
|
|
30034
|
+
const shouldAllowNativeContextMenu = (event) => {
|
|
30035
|
+
return prefersNativeMenu(event);
|
|
30036
|
+
};
|
|
30037
|
+
const shouldBypassContextMenu = shouldAllowNativeContextMenu;
|
|
30038
|
+
const DEFAULT_SELECTION_STATE = Object.freeze({
|
|
30039
|
+
focused: false,
|
|
30040
|
+
preservedSelection: null,
|
|
30041
|
+
showVisualSelection: false,
|
|
30042
|
+
skipFocusReset: false
|
|
30043
|
+
});
|
|
30044
|
+
const normalizeSelectionState = (state = {}) => ({
|
|
30045
|
+
...DEFAULT_SELECTION_STATE,
|
|
30046
|
+
...state
|
|
30047
|
+
});
|
|
30048
|
+
const CustomSelectionPluginKey = new PluginKey("CustomSelection");
|
|
30049
|
+
const handleClickOutside = (event, editor) => {
|
|
30050
|
+
const editorElem = editor?.options?.element;
|
|
30051
|
+
if (!editorElem) return;
|
|
30052
|
+
const isInsideEditor = editorElem?.contains(event.target);
|
|
30053
|
+
if (!isInsideEditor) {
|
|
30054
|
+
editor.setOptions({
|
|
30055
|
+
focusTarget: event.target
|
|
30056
|
+
});
|
|
30057
|
+
} else {
|
|
30058
|
+
editor.setOptions({
|
|
30059
|
+
focusTarget: null
|
|
30060
|
+
});
|
|
30061
|
+
}
|
|
30062
|
+
};
|
|
30063
|
+
function getFocusMeta(tr) {
|
|
30064
|
+
return tr.getMeta(CustomSelectionPluginKey);
|
|
30065
|
+
}
|
|
30066
|
+
function setFocusMeta(tr, value) {
|
|
30067
|
+
return tr.setMeta(CustomSelectionPluginKey, value);
|
|
30068
|
+
}
|
|
30069
|
+
function getFocusState(state) {
|
|
30070
|
+
return CustomSelectionPluginKey.getState(state);
|
|
30071
|
+
}
|
|
30072
|
+
const isToolbarInput = (target) => {
|
|
30073
|
+
return !!target?.closest(".button-text-input") || target?.classList?.contains("button-text-input");
|
|
30074
|
+
};
|
|
30075
|
+
const isToolbarButton = (target) => {
|
|
30076
|
+
return !!target?.closest(".toolbar-button") || target?.classList?.contains("toolbar-button");
|
|
30077
|
+
};
|
|
30078
|
+
const CustomSelection = Extension.create({
|
|
30079
|
+
name: "customSelection",
|
|
30080
|
+
addPmPlugins() {
|
|
30081
|
+
const editor = this.editor;
|
|
30082
|
+
const customSelectionPlugin = new Plugin({
|
|
30083
|
+
key: CustomSelectionPluginKey,
|
|
30084
|
+
state: {
|
|
30085
|
+
init: () => ({ ...DEFAULT_SELECTION_STATE }),
|
|
30086
|
+
apply: (tr, value) => {
|
|
30087
|
+
const meta = getFocusMeta(tr);
|
|
30088
|
+
if (meta !== void 0) {
|
|
30089
|
+
return { ...value, ...meta };
|
|
30090
|
+
}
|
|
30091
|
+
return value;
|
|
30092
|
+
}
|
|
30093
|
+
},
|
|
30094
|
+
view: () => {
|
|
30095
|
+
const clickHandler = (event) => handleClickOutside(event, editor);
|
|
30096
|
+
document?.addEventListener("mousedown", clickHandler);
|
|
30097
|
+
return {
|
|
30098
|
+
destroy: () => {
|
|
30099
|
+
document?.removeEventListener("mousedown", clickHandler);
|
|
30100
|
+
}
|
|
30101
|
+
};
|
|
30102
|
+
},
|
|
30103
|
+
props: {
|
|
30104
|
+
handleDOMEvents: {
|
|
30105
|
+
contextmenu: (view, event) => {
|
|
30106
|
+
if (shouldAllowNativeContextMenu(event)) {
|
|
30107
|
+
return false;
|
|
30108
|
+
}
|
|
30109
|
+
event.preventDefault();
|
|
30110
|
+
const { selection } = view.state;
|
|
30111
|
+
if (!selection.empty) {
|
|
30112
|
+
view.dispatch(
|
|
30113
|
+
setFocusMeta(view.state.tr, {
|
|
30114
|
+
focused: true,
|
|
30115
|
+
preservedSelection: selection,
|
|
30116
|
+
showVisualSelection: true,
|
|
30117
|
+
skipFocusReset: true
|
|
30118
|
+
})
|
|
30119
|
+
);
|
|
30120
|
+
}
|
|
30121
|
+
setTimeout(() => {
|
|
30122
|
+
view.focus();
|
|
30123
|
+
}, 0);
|
|
30124
|
+
return false;
|
|
30125
|
+
},
|
|
30126
|
+
mousedown: (view, event) => {
|
|
30127
|
+
if (event.button === 2) {
|
|
30128
|
+
if (shouldAllowNativeContextMenu(event)) {
|
|
30129
|
+
return false;
|
|
30130
|
+
}
|
|
30131
|
+
event.preventDefault();
|
|
30132
|
+
const { selection: selection2 } = view.state;
|
|
30133
|
+
if (!selection2.empty) {
|
|
30134
|
+
view.dispatch(
|
|
30135
|
+
setFocusMeta(view.state.tr, {
|
|
30136
|
+
focused: true,
|
|
30137
|
+
preservedSelection: selection2,
|
|
30138
|
+
showVisualSelection: true,
|
|
30139
|
+
skipFocusReset: true
|
|
30140
|
+
})
|
|
30141
|
+
);
|
|
30142
|
+
this.editor.setOptions({
|
|
30143
|
+
lastSelection: selection2,
|
|
30144
|
+
preservedSelection: selection2
|
|
30720
30145
|
});
|
|
30721
|
-
g.appendChild(ellipse);
|
|
30722
|
-
return;
|
|
30723
|
-
} else {
|
|
30724
|
-
clonedChild.setAttribute("cx", (width / 2).toString());
|
|
30725
|
-
clonedChild.setAttribute("cy", (height / 2).toString());
|
|
30726
|
-
clonedChild.setAttribute("r", (width / 2).toString());
|
|
30727
30146
|
}
|
|
30728
|
-
|
|
30729
|
-
|
|
30730
|
-
|
|
30731
|
-
|
|
30732
|
-
|
|
30733
|
-
|
|
30734
|
-
|
|
30735
|
-
|
|
30736
|
-
|
|
30737
|
-
|
|
30738
|
-
|
|
30739
|
-
|
|
30740
|
-
|
|
30741
|
-
|
|
30742
|
-
|
|
30743
|
-
|
|
30744
|
-
|
|
30147
|
+
return false;
|
|
30148
|
+
}
|
|
30149
|
+
const { selection } = view.state;
|
|
30150
|
+
const target = event.target;
|
|
30151
|
+
const isElement2 = target instanceof Element;
|
|
30152
|
+
const isToolbarBtn = isElement2 && isToolbarButton(target);
|
|
30153
|
+
const isToolbarInp = isElement2 && isToolbarInput(target);
|
|
30154
|
+
this.editor.setOptions({
|
|
30155
|
+
focusTarget: target
|
|
30156
|
+
});
|
|
30157
|
+
if (isToolbarInp && !selection.empty) {
|
|
30158
|
+
view.dispatch(
|
|
30159
|
+
setFocusMeta(view.state.tr, {
|
|
30160
|
+
focused: true,
|
|
30161
|
+
preservedSelection: selection,
|
|
30162
|
+
showVisualSelection: true,
|
|
30163
|
+
skipFocusReset: false
|
|
30164
|
+
})
|
|
30165
|
+
);
|
|
30166
|
+
this.editor.setOptions({
|
|
30167
|
+
lastSelection: selection,
|
|
30168
|
+
preservedSelection: selection
|
|
30169
|
+
});
|
|
30170
|
+
return false;
|
|
30171
|
+
}
|
|
30172
|
+
if (isToolbarBtn && !isToolbarInp) {
|
|
30173
|
+
if (!selection.empty) {
|
|
30174
|
+
this.editor.setOptions({
|
|
30175
|
+
lastSelection: selection
|
|
30176
|
+
});
|
|
30177
|
+
view.dispatch(
|
|
30178
|
+
setFocusMeta(view.state.tr, {
|
|
30179
|
+
focused: true,
|
|
30180
|
+
preservedSelection: selection,
|
|
30181
|
+
showVisualSelection: true,
|
|
30182
|
+
skipFocusReset: false
|
|
30183
|
+
})
|
|
30184
|
+
);
|
|
30745
30185
|
}
|
|
30746
|
-
|
|
30747
|
-
clonedChild.setAttribute("width", width.toString());
|
|
30186
|
+
return false;
|
|
30748
30187
|
}
|
|
30749
|
-
if (
|
|
30750
|
-
|
|
30188
|
+
if (!isToolbarBtn && !isToolbarInp) {
|
|
30189
|
+
view.dispatch(
|
|
30190
|
+
setFocusMeta(view.state.tr, {
|
|
30191
|
+
focused: false,
|
|
30192
|
+
preservedSelection: null,
|
|
30193
|
+
showVisualSelection: false,
|
|
30194
|
+
skipFocusReset: false
|
|
30195
|
+
})
|
|
30196
|
+
);
|
|
30197
|
+
if (!selection.empty && !this.editor.options.element?.contains(target)) {
|
|
30198
|
+
this.editor.setOptions({
|
|
30199
|
+
lastSelection: selection
|
|
30200
|
+
});
|
|
30201
|
+
const clearSelectionTr = view.state.tr.setSelection(TextSelection.create(view.state.doc, 0));
|
|
30202
|
+
view.dispatch(clearSelectionTr);
|
|
30203
|
+
}
|
|
30751
30204
|
}
|
|
30752
|
-
|
|
30753
|
-
|
|
30205
|
+
},
|
|
30206
|
+
focus: (view) => {
|
|
30207
|
+
const target = this.editor.options.focusTarget;
|
|
30208
|
+
const isElement2 = target instanceof Element;
|
|
30209
|
+
const isToolbarBtn = isElement2 && isToolbarButton(target);
|
|
30210
|
+
const isToolbarInp = isElement2 && isToolbarInput(target);
|
|
30211
|
+
const focusState = getFocusState(view.state);
|
|
30212
|
+
if (focusState?.skipFocusReset) {
|
|
30213
|
+
view.dispatch(
|
|
30214
|
+
setFocusMeta(view.state.tr, normalizeSelectionState({ ...focusState, skipFocusReset: false }))
|
|
30215
|
+
);
|
|
30216
|
+
return false;
|
|
30217
|
+
}
|
|
30218
|
+
if (!isToolbarBtn && !isToolbarInp) {
|
|
30219
|
+
view.dispatch(
|
|
30220
|
+
setFocusMeta(view.state.tr, {
|
|
30221
|
+
focused: false,
|
|
30222
|
+
preservedSelection: null,
|
|
30223
|
+
showVisualSelection: false,
|
|
30224
|
+
skipFocusReset: false
|
|
30225
|
+
})
|
|
30226
|
+
);
|
|
30227
|
+
}
|
|
30228
|
+
},
|
|
30229
|
+
blur: (view) => {
|
|
30230
|
+
const target = this.editor.options.focusTarget;
|
|
30231
|
+
const isElement2 = target instanceof Element;
|
|
30232
|
+
const isToolbarBtn = isElement2 && isToolbarButton(target);
|
|
30233
|
+
const isToolbarInp = isElement2 && isToolbarInput(target);
|
|
30234
|
+
const state = getFocusState(view.state);
|
|
30235
|
+
if (state?.skipFocusReset) {
|
|
30236
|
+
return false;
|
|
30237
|
+
}
|
|
30238
|
+
if (isToolbarBtn || isToolbarInp) {
|
|
30239
|
+
view.dispatch(
|
|
30240
|
+
setFocusMeta(view.state.tr, {
|
|
30241
|
+
focused: true,
|
|
30242
|
+
preservedSelection: state.preservedSelection || view.state.selection,
|
|
30243
|
+
showVisualSelection: true,
|
|
30244
|
+
skipFocusReset: false
|
|
30245
|
+
})
|
|
30246
|
+
);
|
|
30247
|
+
} else {
|
|
30248
|
+
view.dispatch(
|
|
30249
|
+
setFocusMeta(view.state.tr, {
|
|
30250
|
+
focused: false,
|
|
30251
|
+
preservedSelection: null,
|
|
30252
|
+
showVisualSelection: false,
|
|
30253
|
+
skipFocusReset: false
|
|
30254
|
+
})
|
|
30255
|
+
);
|
|
30256
|
+
}
|
|
30257
|
+
}
|
|
30258
|
+
},
|
|
30259
|
+
decorations: (state) => {
|
|
30260
|
+
const { selection, doc: doc2 } = state;
|
|
30261
|
+
const focusState = getFocusState(state);
|
|
30262
|
+
const shouldShowSelection = focusState.showVisualSelection && (focusState.preservedSelection || !selection.empty && focusState.focused);
|
|
30263
|
+
if (!shouldShowSelection) {
|
|
30264
|
+
return null;
|
|
30265
|
+
}
|
|
30266
|
+
const targetSelection = focusState.preservedSelection || selection;
|
|
30267
|
+
if (targetSelection.empty) {
|
|
30268
|
+
return null;
|
|
30269
|
+
}
|
|
30270
|
+
return DecorationSet.create(doc2, [
|
|
30271
|
+
Decoration.inline(targetSelection.from, targetSelection.to, {
|
|
30272
|
+
class: "sd-custom-selection"
|
|
30273
|
+
})
|
|
30274
|
+
]);
|
|
30754
30275
|
}
|
|
30755
30276
|
}
|
|
30756
|
-
}
|
|
30757
|
-
|
|
30758
|
-
|
|
30759
|
-
|
|
30760
|
-
rect.setAttribute("height", height.toString());
|
|
30761
|
-
rect.setAttribute("fill", fillColor);
|
|
30762
|
-
rect.setAttribute("stroke", strokeColor);
|
|
30763
|
-
rect.setAttribute("stroke-width", strokeWidth.toString());
|
|
30764
|
-
g.appendChild(rect);
|
|
30765
|
-
}
|
|
30766
|
-
return g;
|
|
30767
|
-
}
|
|
30768
|
-
buildView() {
|
|
30769
|
-
const { element } = this.createElement();
|
|
30770
|
-
this.root = element;
|
|
30771
|
-
}
|
|
30772
|
-
update() {
|
|
30773
|
-
return false;
|
|
30774
|
-
}
|
|
30775
|
-
}
|
|
30776
|
-
const ShapeGroup = Node$1.create({
|
|
30777
|
-
name: "shapeGroup",
|
|
30778
|
-
group: "inline",
|
|
30779
|
-
inline: true,
|
|
30780
|
-
atom: true,
|
|
30781
|
-
addOptions() {
|
|
30277
|
+
});
|
|
30278
|
+
return [customSelectionPlugin];
|
|
30279
|
+
},
|
|
30280
|
+
addCommands() {
|
|
30782
30281
|
return {
|
|
30783
|
-
|
|
30784
|
-
|
|
30282
|
+
/**
|
|
30283
|
+
* Restore the preserved selection
|
|
30284
|
+
* @category Command
|
|
30285
|
+
* @returns {Function} Command function
|
|
30286
|
+
* @example
|
|
30287
|
+
* // Restore selection after toolbar interaction
|
|
30288
|
+
* editor.commands.restorePreservedSelection()
|
|
30289
|
+
* @note Used internally to maintain selection when interacting with toolbar
|
|
30290
|
+
*/
|
|
30291
|
+
restorePreservedSelection: () => ({ tr, state }) => {
|
|
30292
|
+
const focusState = getFocusState(state);
|
|
30293
|
+
if (focusState.preservedSelection) {
|
|
30294
|
+
return tr.setSelection(focusState.preservedSelection);
|
|
30295
|
+
}
|
|
30296
|
+
const lastSelection = this.editor.options.lastSelection;
|
|
30297
|
+
if (lastSelection) {
|
|
30298
|
+
return tr.setSelection(lastSelection);
|
|
30299
|
+
}
|
|
30300
|
+
return tr;
|
|
30785
30301
|
}
|
|
30786
30302
|
};
|
|
30787
|
-
}
|
|
30788
|
-
|
|
30789
|
-
|
|
30790
|
-
|
|
30791
|
-
|
|
30792
|
-
|
|
30793
|
-
|
|
30794
|
-
|
|
30795
|
-
|
|
30796
|
-
|
|
30797
|
-
|
|
30798
|
-
|
|
30799
|
-
|
|
30800
|
-
|
|
30801
|
-
|
|
30802
|
-
|
|
30803
|
-
|
|
30804
|
-
|
|
30805
|
-
|
|
30303
|
+
}
|
|
30304
|
+
});
|
|
30305
|
+
const getLinkedStyle = (styleId, styles = []) => {
|
|
30306
|
+
const linkedStyle = styles.find((style) => style.id === styleId);
|
|
30307
|
+
const basedOn = linkedStyle?.definition?.attrs?.basedOn;
|
|
30308
|
+
const basedOnStyle = styles.find((style) => style.id === basedOn);
|
|
30309
|
+
return { linkedStyle, basedOnStyle };
|
|
30310
|
+
};
|
|
30311
|
+
const getQuickFormatList = (editor) => {
|
|
30312
|
+
if (!editor?.converter?.linkedStyles) return [];
|
|
30313
|
+
return editor.converter.linkedStyles.filter((style) => style.type === "paragraph" && style.definition?.attrs).sort((a, b) => {
|
|
30314
|
+
const nameA = a.definition.attrs?.name ?? "";
|
|
30315
|
+
const nameB = b.definition.attrs?.name ?? "";
|
|
30316
|
+
return nameA.localeCompare(nameB);
|
|
30317
|
+
});
|
|
30318
|
+
};
|
|
30319
|
+
const generateLinkedStyleString = (linkedStyle, basedOnStyle, node, parent, includeSpacing = true) => {
|
|
30320
|
+
if (!linkedStyle?.definition?.styles) return "";
|
|
30321
|
+
const markValue = {};
|
|
30322
|
+
const linkedDefinitionStyles = { ...linkedStyle.definition.styles };
|
|
30323
|
+
const basedOnDefinitionStyles = { ...basedOnStyle?.definition?.styles };
|
|
30324
|
+
const resultStyles = { ...linkedDefinitionStyles };
|
|
30325
|
+
const inheritKeys = [
|
|
30326
|
+
"font-size",
|
|
30327
|
+
"font-family",
|
|
30328
|
+
"text-transform",
|
|
30329
|
+
"bold",
|
|
30330
|
+
"italic",
|
|
30331
|
+
"underline",
|
|
30332
|
+
"strike",
|
|
30333
|
+
"color",
|
|
30334
|
+
"highlight"
|
|
30335
|
+
];
|
|
30336
|
+
inheritKeys.forEach((k2) => {
|
|
30337
|
+
if (!linkedDefinitionStyles[k2] && basedOnDefinitionStyles[k2]) {
|
|
30338
|
+
resultStyles[k2] = basedOnDefinitionStyles[k2];
|
|
30339
|
+
}
|
|
30340
|
+
});
|
|
30341
|
+
Object.entries(resultStyles).forEach(([k2, value]) => {
|
|
30342
|
+
const key2 = kebabCase(k2);
|
|
30343
|
+
const flattenedMarks = [];
|
|
30344
|
+
node?.marks?.forEach((n) => {
|
|
30345
|
+
if (n.type.name === "textStyle") {
|
|
30346
|
+
Object.entries(n.attrs).forEach(([styleKey, value2]) => {
|
|
30347
|
+
const parsedKey = kebabCase(styleKey);
|
|
30348
|
+
if (!value2) return;
|
|
30349
|
+
flattenedMarks.push({ key: parsedKey, value: value2 });
|
|
30350
|
+
});
|
|
30351
|
+
return;
|
|
30352
|
+
}
|
|
30353
|
+
flattenedMarks.push({ key: n.type.name, value: n.attrs[key2] });
|
|
30354
|
+
});
|
|
30355
|
+
const underlineNone = node?.marks?.some((m) => m.type?.name === "underline" && m.attrs?.underlineType === "none");
|
|
30356
|
+
if (underlineNone) {
|
|
30357
|
+
markValue["text-decoration"] = "none";
|
|
30358
|
+
}
|
|
30359
|
+
const mark = flattenedMarks.find((n) => n.key === key2);
|
|
30360
|
+
if (!mark) {
|
|
30361
|
+
if (key2 === "bold" && node) {
|
|
30362
|
+
const boldValue = typeof value === "object" && value !== null ? value.value : value;
|
|
30363
|
+
const hasInlineBoldOff = node.marks?.some((m) => m.type?.name === "bold" && m.attrs?.value === "0");
|
|
30364
|
+
const hasInlineBoldOn = node.marks?.some((m) => m.type?.name === "bold" && m.attrs?.value !== "0");
|
|
30365
|
+
if (!hasInlineBoldOff && !hasInlineBoldOn && boldValue !== "0" && boldValue !== false) {
|
|
30366
|
+
markValue["font-weight"] = "bold";
|
|
30806
30367
|
}
|
|
30807
|
-
}
|
|
30808
|
-
|
|
30809
|
-
|
|
30810
|
-
|
|
30811
|
-
|
|
30812
|
-
|
|
30813
|
-
if (attrs.padding.top != null) paddingData["data-padding-top"] = attrs.padding.top;
|
|
30814
|
-
if (attrs.padding.right != null) paddingData["data-padding-right"] = attrs.padding.right;
|
|
30815
|
-
if (attrs.padding.bottom != null) paddingData["data-padding-bottom"] = attrs.padding.bottom;
|
|
30816
|
-
if (attrs.padding.left != null) paddingData["data-padding-left"] = attrs.padding.left;
|
|
30817
|
-
return paddingData;
|
|
30368
|
+
} else if (key2 === "italic" && node) {
|
|
30369
|
+
const italicValue = typeof value === "object" && value !== null ? value.value : value;
|
|
30370
|
+
const hasInlineItalicOff = node.marks?.some((m) => m.type?.name === "italic" && m.attrs?.value === "0");
|
|
30371
|
+
const hasInlineItalicOn = node.marks?.some((m) => m.type?.name === "italic" && m.attrs?.value !== "0");
|
|
30372
|
+
if (!hasInlineItalicOff && !hasInlineItalicOn && italicValue !== "0" && italicValue !== false) {
|
|
30373
|
+
markValue["font-style"] = "italic";
|
|
30818
30374
|
}
|
|
30819
|
-
}
|
|
30820
|
-
|
|
30821
|
-
|
|
30822
|
-
|
|
30823
|
-
|
|
30824
|
-
|
|
30825
|
-
|
|
30826
|
-
|
|
30827
|
-
|
|
30375
|
+
} else if (key2 === "strike" && node) {
|
|
30376
|
+
const strikeValue = typeof value === "object" && value !== null ? value.value : value;
|
|
30377
|
+
const hasInlineStrikeOff = node.marks?.some((m) => m.type?.name === "strike" && m.attrs?.value === "0");
|
|
30378
|
+
const hasInlineStrikeOn = node.marks?.some(
|
|
30379
|
+
(m) => m.type?.name === "strike" && (m.attrs?.value === void 0 || m.attrs?.value !== "0")
|
|
30380
|
+
);
|
|
30381
|
+
if (!hasInlineStrikeOff && !hasInlineStrikeOn && strikeValue !== "0" && strikeValue !== false) {
|
|
30382
|
+
markValue["text-decoration"] = "line-through";
|
|
30383
|
+
}
|
|
30384
|
+
} else if (key2 === "text-transform" && node) {
|
|
30385
|
+
markValue[key2] = value;
|
|
30386
|
+
} else if (key2 === "font-size" && node) {
|
|
30387
|
+
markValue[key2] = value;
|
|
30388
|
+
} else if (key2 === "font-family" && node) {
|
|
30389
|
+
markValue[key2] = value;
|
|
30390
|
+
} else if (key2 === "color" && node) {
|
|
30391
|
+
markValue[key2] = value;
|
|
30392
|
+
} else if (key2 === "highlight" && node) {
|
|
30393
|
+
const hasInlineHighlight = node.marks?.some((m) => m.type?.name === "highlight");
|
|
30394
|
+
if (!hasInlineHighlight) {
|
|
30395
|
+
const color = typeof value === "string" ? value : value?.color;
|
|
30396
|
+
if (color) markValue["background-color"] = color;
|
|
30397
|
+
}
|
|
30398
|
+
} else if (key2 === "underline" && node) {
|
|
30399
|
+
const styleValRaw = value?.value ?? value ?? "";
|
|
30400
|
+
const styleVal = styleValRaw.toString().toLowerCase();
|
|
30401
|
+
const hasInlineUnderlineOff = node.marks?.some(
|
|
30402
|
+
(m) => m.type?.name === "underline" && m.attrs?.underlineType === "none"
|
|
30403
|
+
);
|
|
30404
|
+
const hasInlineUnderlineOn = node.marks?.some(
|
|
30405
|
+
(m) => m.type?.name === "underline" && m.attrs?.underlineType && m.attrs.underlineType !== "none"
|
|
30406
|
+
);
|
|
30407
|
+
if (!hasInlineUnderlineOff && !hasInlineUnderlineOn) {
|
|
30408
|
+
if (styleVal && styleVal !== "none" && styleVal !== "0") {
|
|
30409
|
+
const colorVal = value && typeof value === "object" ? value.color || value.underlineColor || null : null;
|
|
30410
|
+
const css = getUnderlineCssString({ type: styleVal, color: colorVal });
|
|
30411
|
+
css.split(";").forEach((decl) => {
|
|
30412
|
+
const d2 = decl.trim();
|
|
30413
|
+
if (!d2) return;
|
|
30414
|
+
const idx = d2.indexOf(":");
|
|
30415
|
+
if (idx === -1) return;
|
|
30416
|
+
const k3 = d2.slice(0, idx).trim();
|
|
30417
|
+
const v = d2.slice(idx + 1).trim();
|
|
30418
|
+
markValue[k3] = v;
|
|
30419
|
+
});
|
|
30420
|
+
}
|
|
30828
30421
|
}
|
|
30829
|
-
}
|
|
30830
|
-
|
|
30831
|
-
rendered: false
|
|
30422
|
+
} else if (typeof value === "string") {
|
|
30423
|
+
markValue[key2] = value;
|
|
30832
30424
|
}
|
|
30833
|
-
}
|
|
30834
|
-
}
|
|
30835
|
-
|
|
30836
|
-
|
|
30837
|
-
|
|
30838
|
-
|
|
30839
|
-
|
|
30840
|
-
|
|
30841
|
-
|
|
30842
|
-
|
|
30843
|
-
|
|
30844
|
-
|
|
30425
|
+
}
|
|
30426
|
+
});
|
|
30427
|
+
const final = Object.entries(markValue).map(([key2, value]) => `${key2}: ${value}`).join(";");
|
|
30428
|
+
return final;
|
|
30429
|
+
};
|
|
30430
|
+
const applyLinkedStyleToTransaction = (tr, editor, style) => {
|
|
30431
|
+
if (!style) return false;
|
|
30432
|
+
let selection = tr.selection;
|
|
30433
|
+
const state = editor.state;
|
|
30434
|
+
const focusState = CustomSelectionPluginKey.getState(state);
|
|
30435
|
+
if (selection.empty && focusState?.preservedSelection && !focusState?.preservedSelection.empty) {
|
|
30436
|
+
selection = focusState.preservedSelection;
|
|
30437
|
+
tr.setSelection(selection);
|
|
30438
|
+
} else if (selection.empty && editor.options.lastSelection) {
|
|
30439
|
+
selection = editor.options.lastSelection;
|
|
30440
|
+
tr.setSelection(selection);
|
|
30845
30441
|
}
|
|
30846
|
-
}
|
|
30847
|
-
const
|
|
30848
|
-
name: "textStyle",
|
|
30849
|
-
addOptions() {
|
|
30442
|
+
const { from: from2, to } = selection;
|
|
30443
|
+
const getUpdatedParagraphAttrs = (node) => {
|
|
30850
30444
|
return {
|
|
30851
|
-
|
|
30445
|
+
...node.attrs,
|
|
30446
|
+
paragraphProperties: {
|
|
30447
|
+
...node.attrs.paragraphProperties || {},
|
|
30448
|
+
styleId: style.id
|
|
30449
|
+
}
|
|
30852
30450
|
};
|
|
30853
|
-
}
|
|
30854
|
-
|
|
30855
|
-
|
|
30856
|
-
{
|
|
30857
|
-
|
|
30858
|
-
|
|
30859
|
-
|
|
30860
|
-
|
|
30861
|
-
|
|
30862
|
-
|
|
30863
|
-
|
|
30864
|
-
|
|
30865
|
-
|
|
30866
|
-
|
|
30867
|
-
|
|
30868
|
-
|
|
30869
|
-
|
|
30870
|
-
if (fontFamily || fontSize || textTransform) {
|
|
30871
|
-
return {
|
|
30872
|
-
fontFamily: fontFamily || null,
|
|
30873
|
-
fontSize: fontSize || null,
|
|
30874
|
-
textTransform: textTransform || null
|
|
30875
|
-
};
|
|
30451
|
+
};
|
|
30452
|
+
const clearFormattingMarks = (startPos, endPos) => {
|
|
30453
|
+
tr.doc.nodesBetween(startPos, endPos, (node, pos) => {
|
|
30454
|
+
if (node.isText && node.marks.length > 0) {
|
|
30455
|
+
const marksToRemove = [
|
|
30456
|
+
"textStyle",
|
|
30457
|
+
"bold",
|
|
30458
|
+
"italic",
|
|
30459
|
+
"underline",
|
|
30460
|
+
"strike",
|
|
30461
|
+
"subscript",
|
|
30462
|
+
"superscript",
|
|
30463
|
+
"highlight"
|
|
30464
|
+
];
|
|
30465
|
+
node.marks.forEach((mark) => {
|
|
30466
|
+
if (marksToRemove.includes(mark.type.name)) {
|
|
30467
|
+
tr.removeMark(pos, pos + node.nodeSize, mark);
|
|
30876
30468
|
}
|
|
30877
|
-
|
|
30878
|
-
}
|
|
30469
|
+
});
|
|
30879
30470
|
}
|
|
30880
|
-
|
|
30881
|
-
|
|
30882
|
-
|
|
30883
|
-
|
|
30884
|
-
|
|
30885
|
-
|
|
30886
|
-
|
|
30471
|
+
return true;
|
|
30472
|
+
});
|
|
30473
|
+
};
|
|
30474
|
+
if (from2 === to) {
|
|
30475
|
+
let pos = from2;
|
|
30476
|
+
let paragraphNode = tr.doc.nodeAt(from2);
|
|
30477
|
+
if (paragraphNode?.type.name !== "paragraph") {
|
|
30478
|
+
const parentNode2 = findParentNode((node) => node.type.name === "paragraph")(selection);
|
|
30479
|
+
if (!parentNode2) return false;
|
|
30480
|
+
pos = parentNode2.pos;
|
|
30481
|
+
paragraphNode = parentNode2.node;
|
|
30482
|
+
}
|
|
30483
|
+
clearFormattingMarks(pos + 1, pos + paragraphNode.nodeSize - 1);
|
|
30484
|
+
tr.setNodeMarkup(pos, void 0, getUpdatedParagraphAttrs(paragraphNode));
|
|
30485
|
+
return true;
|
|
30486
|
+
}
|
|
30487
|
+
const paragraphPositions = [];
|
|
30488
|
+
tr.doc.nodesBetween(from2, to, (node, pos) => {
|
|
30489
|
+
if (node.type.name === "paragraph") {
|
|
30490
|
+
paragraphPositions.push({ node, pos });
|
|
30491
|
+
}
|
|
30492
|
+
return true;
|
|
30493
|
+
});
|
|
30494
|
+
paragraphPositions.forEach(({ node, pos }) => {
|
|
30495
|
+
clearFormattingMarks(pos + 1, pos + node.nodeSize - 1);
|
|
30496
|
+
tr.setNodeMarkup(pos, void 0, getUpdatedParagraphAttrs(node));
|
|
30497
|
+
});
|
|
30498
|
+
return true;
|
|
30499
|
+
};
|
|
30500
|
+
const stepInsertsTextIntoStyledParagraph = (tr, oldEditorState, step, stepIndex) => {
|
|
30501
|
+
if (!step.slice || step.slice.size === 0 || typeof step.from !== "number") {
|
|
30502
|
+
return false;
|
|
30503
|
+
}
|
|
30504
|
+
let insertsText = false;
|
|
30505
|
+
step.slice.content.descendants((node) => {
|
|
30506
|
+
if (node.type?.name === "text" && node.text?.length) {
|
|
30507
|
+
insertsText = true;
|
|
30508
|
+
return false;
|
|
30509
|
+
}
|
|
30510
|
+
return true;
|
|
30511
|
+
});
|
|
30512
|
+
if (!insertsText) return false;
|
|
30513
|
+
const docBeforeStep = tr.docs?.[stepIndex] || oldEditorState.doc;
|
|
30514
|
+
if (!docBeforeStep) return false;
|
|
30515
|
+
const resolvedPos = Math.min(step.from, docBeforeStep.content.size);
|
|
30516
|
+
const $pos = docBeforeStep.resolve(resolvedPos);
|
|
30517
|
+
for (let depth = $pos.depth; depth >= 0; depth--) {
|
|
30518
|
+
const node = $pos.node(depth);
|
|
30519
|
+
if (node?.type?.name === "paragraph") {
|
|
30520
|
+
return Boolean(node.attrs?.paragraphProperties?.styleId);
|
|
30521
|
+
}
|
|
30522
|
+
}
|
|
30523
|
+
return false;
|
|
30524
|
+
};
|
|
30525
|
+
const LinkedStylesPluginKey = new PluginKey("linkedStyles");
|
|
30526
|
+
const createLinkedStylesPlugin = (editor) => {
|
|
30527
|
+
return new Plugin({
|
|
30528
|
+
key: LinkedStylesPluginKey,
|
|
30529
|
+
state: {
|
|
30887
30530
|
/**
|
|
30888
|
-
*
|
|
30889
|
-
* @
|
|
30531
|
+
* Initialize plugin state with styles and decorations
|
|
30532
|
+
* @returns {Object} Initial state with styles and decorations
|
|
30533
|
+
* @private
|
|
30890
30534
|
*/
|
|
30891
|
-
|
|
30892
|
-
|
|
30893
|
-
|
|
30894
|
-
|
|
30895
|
-
|
|
30535
|
+
init() {
|
|
30536
|
+
if (!editor.converter || editor.options.mode !== "docx") return {};
|
|
30537
|
+
const styles = editor.converter?.linkedStyles || [];
|
|
30538
|
+
return {
|
|
30539
|
+
styles,
|
|
30540
|
+
decorations: generateDecorations(editor.state, styles)
|
|
30541
|
+
};
|
|
30542
|
+
},
|
|
30896
30543
|
/**
|
|
30897
|
-
*
|
|
30898
|
-
* @
|
|
30899
|
-
* @
|
|
30900
|
-
* editor
|
|
30901
|
-
* @
|
|
30902
|
-
* @
|
|
30544
|
+
* Update decorations when document changes
|
|
30545
|
+
* @param {Object} tr - The transaction
|
|
30546
|
+
* @param {Object} prev - Previous plugin state
|
|
30547
|
+
* @param {Object} oldEditorState - Old editor state
|
|
30548
|
+
* @param {Object} newEditorState - New editor state
|
|
30549
|
+
* @returns {Object} Updated state with styles and decorations
|
|
30550
|
+
* @private
|
|
30903
30551
|
*/
|
|
30904
|
-
|
|
30905
|
-
|
|
30906
|
-
|
|
30907
|
-
if (
|
|
30908
|
-
|
|
30552
|
+
apply(tr, prev, oldEditorState, newEditorState) {
|
|
30553
|
+
if (!editor.converter || editor.options.mode !== "docx") return { ...prev };
|
|
30554
|
+
let decorations = prev.decorations || DecorationSet.empty;
|
|
30555
|
+
if (tr.docChanged) {
|
|
30556
|
+
let mightAffectStyles = false;
|
|
30557
|
+
const styleRelatedMarks = /* @__PURE__ */ new Set(["textStyle", "bold", "italic", "underline", "strike"]);
|
|
30558
|
+
tr.steps.forEach((step, index2) => {
|
|
30559
|
+
if (step.slice) {
|
|
30560
|
+
step.slice.content.descendants((node, pos) => {
|
|
30561
|
+
if (node.type.name === "paragraph") {
|
|
30562
|
+
const paragraphProps = calculateResolvedParagraphProperties(
|
|
30563
|
+
editor,
|
|
30564
|
+
node,
|
|
30565
|
+
newEditorState.doc.resolve(pos)
|
|
30566
|
+
);
|
|
30567
|
+
if (paragraphProps.styleId) {
|
|
30568
|
+
mightAffectStyles = true;
|
|
30569
|
+
}
|
|
30570
|
+
return false;
|
|
30571
|
+
}
|
|
30572
|
+
if (node.marks.length > 0) {
|
|
30573
|
+
const hasStyleMarks = node.marks.some((mark) => styleRelatedMarks.has(mark.type.name));
|
|
30574
|
+
if (hasStyleMarks) {
|
|
30575
|
+
mightAffectStyles = true;
|
|
30576
|
+
return false;
|
|
30577
|
+
}
|
|
30578
|
+
}
|
|
30579
|
+
});
|
|
30580
|
+
}
|
|
30581
|
+
if (step.jsonID === "addMark" || step.jsonID === "removeMark") {
|
|
30582
|
+
if (step.mark && styleRelatedMarks.has(step.mark.type.name)) {
|
|
30583
|
+
mightAffectStyles = true;
|
|
30584
|
+
}
|
|
30585
|
+
}
|
|
30586
|
+
if (!mightAffectStyles && stepInsertsTextIntoStyledParagraph(tr, oldEditorState, step, index2)) {
|
|
30587
|
+
mightAffectStyles = true;
|
|
30588
|
+
}
|
|
30589
|
+
});
|
|
30590
|
+
if (mightAffectStyles) {
|
|
30591
|
+
const styles = LinkedStylesPluginKey.getState(editor.state).styles;
|
|
30592
|
+
decorations = generateDecorations(newEditorState, styles);
|
|
30593
|
+
} else {
|
|
30594
|
+
decorations = decorations.map(tr.mapping, tr.doc);
|
|
30595
|
+
}
|
|
30596
|
+
}
|
|
30597
|
+
return { ...prev, decorations };
|
|
30909
30598
|
}
|
|
30910
|
-
}
|
|
30911
|
-
|
|
30912
|
-
|
|
30913
|
-
|
|
30914
|
-
|
|
30915
|
-
|
|
30916
|
-
|
|
30917
|
-
|
|
30918
|
-
|
|
30919
|
-
|
|
30920
|
-
|
|
30921
|
-
}
|
|
30922
|
-
|
|
30923
|
-
|
|
30924
|
-
|
|
30925
|
-
const
|
|
30926
|
-
const
|
|
30927
|
-
const
|
|
30928
|
-
|
|
30929
|
-
|
|
30930
|
-
|
|
30931
|
-
|
|
30932
|
-
|
|
30933
|
-
|
|
30934
|
-
|
|
30599
|
+
},
|
|
30600
|
+
props: {
|
|
30601
|
+
/**
|
|
30602
|
+
* Provide decorations to the editor view
|
|
30603
|
+
* @param {Object} state - Current editor state
|
|
30604
|
+
* @returns {Object} The decoration set
|
|
30605
|
+
* @private
|
|
30606
|
+
*/
|
|
30607
|
+
decorations(state) {
|
|
30608
|
+
return LinkedStylesPluginKey.getState(state)?.decorations;
|
|
30609
|
+
}
|
|
30610
|
+
}
|
|
30611
|
+
});
|
|
30612
|
+
};
|
|
30613
|
+
const generateDecorations = (state, styles) => {
|
|
30614
|
+
const decorations = [];
|
|
30615
|
+
const doc2 = state?.doc;
|
|
30616
|
+
const getParagraphStyleId = (pos) => {
|
|
30617
|
+
const $pos = state.doc.resolve(pos);
|
|
30618
|
+
for (let d2 = $pos.depth; d2 >= 0; d2--) {
|
|
30619
|
+
const n = $pos.node(d2);
|
|
30620
|
+
if (n?.type?.name === "paragraph") {
|
|
30621
|
+
const paragraphProps = getResolvedParagraphProperties(n);
|
|
30622
|
+
return paragraphProps.styleId || null;
|
|
30623
|
+
}
|
|
30624
|
+
}
|
|
30625
|
+
return null;
|
|
30935
30626
|
};
|
|
30936
|
-
|
|
30937
|
-
const
|
|
30938
|
-
|
|
30939
|
-
|
|
30940
|
-
|
|
30941
|
-
|
|
30942
|
-
|
|
30943
|
-
|
|
30944
|
-
|
|
30945
|
-
|
|
30946
|
-
|
|
30947
|
-
|
|
30948
|
-
|
|
30949
|
-
if (
|
|
30950
|
-
if (attrs.value === "0" || !attrs.value) {
|
|
30951
|
-
return { style: "font-weight: normal" };
|
|
30952
|
-
}
|
|
30953
|
-
return {};
|
|
30627
|
+
doc2.descendants((node, pos) => {
|
|
30628
|
+
const { name } = node.type;
|
|
30629
|
+
if (name !== "text") return;
|
|
30630
|
+
const paragraphStyleId = getParagraphStyleId(pos);
|
|
30631
|
+
let runStyleId = null;
|
|
30632
|
+
let inlineTextStyleId = null;
|
|
30633
|
+
for (const mark of node.marks) {
|
|
30634
|
+
if (mark.type.name === "run") {
|
|
30635
|
+
const rp = mark.attrs?.runProperties;
|
|
30636
|
+
if (rp && typeof rp === "object" && !Array.isArray(rp) && rp.styleId) runStyleId = rp.styleId;
|
|
30637
|
+
else if (Array.isArray(rp)) {
|
|
30638
|
+
const ent = rp.find((e) => e?.xmlName === "w:rStyle");
|
|
30639
|
+
const sid = ent?.attributes?.["w:val"];
|
|
30640
|
+
if (sid) runStyleId = sid;
|
|
30954
30641
|
}
|
|
30642
|
+
} else if (mark.type.name === "textStyle" && mark.attrs?.styleId) {
|
|
30643
|
+
inlineTextStyleId = mark.attrs.styleId;
|
|
30955
30644
|
}
|
|
30645
|
+
}
|
|
30646
|
+
const buildStyleMap = (sid) => {
|
|
30647
|
+
if (!sid) return {};
|
|
30648
|
+
const { linkedStyle, basedOnStyle: basedOnStyle2 } = getLinkedStyle(sid, styles);
|
|
30649
|
+
if (!linkedStyle) return {};
|
|
30650
|
+
const base2 = { ...basedOnStyle2?.definition?.styles || {} };
|
|
30651
|
+
return { ...base2, ...linkedStyle.definition?.styles || {} };
|
|
30956
30652
|
};
|
|
30957
|
-
|
|
30958
|
-
|
|
30959
|
-
|
|
30960
|
-
|
|
30961
|
-
|
|
30962
|
-
|
|
30963
|
-
{ style: "font-weight", getAttrs: (value) => /^(bold(er)?|[5-9]\d{2,})$/.test(value) && null }
|
|
30964
|
-
];
|
|
30965
|
-
},
|
|
30966
|
-
renderDOM({ htmlAttributes }) {
|
|
30967
|
-
const merged = Attribute.mergeAttributes(this.options.htmlAttributes, htmlAttributes);
|
|
30968
|
-
const { value, ...rest } = merged || {};
|
|
30969
|
-
if (value === "0") {
|
|
30970
|
-
return ["span", rest, 0];
|
|
30653
|
+
const pMap = buildStyleMap(paragraphStyleId);
|
|
30654
|
+
let tMap;
|
|
30655
|
+
if (paragraphStyleId?.startsWith("TOC")) {
|
|
30656
|
+
tMap = {};
|
|
30657
|
+
} else {
|
|
30658
|
+
tMap = buildStyleMap(inlineTextStyleId);
|
|
30971
30659
|
}
|
|
30972
|
-
|
|
30660
|
+
const rMap = buildStyleMap(runStyleId);
|
|
30661
|
+
const finalStyles = { ...pMap, ...tMap, ...rMap };
|
|
30662
|
+
if (Object.keys(finalStyles).length === 0) return;
|
|
30663
|
+
const mergedLinkedStyle = { definition: { styles: finalStyles, attrs: {} } };
|
|
30664
|
+
const basedOnStyle = null;
|
|
30665
|
+
const $pos = state.doc.resolve(pos);
|
|
30666
|
+
$pos.parent;
|
|
30667
|
+
const styleString = generateLinkedStyleString(mergedLinkedStyle, basedOnStyle, node);
|
|
30668
|
+
if (!styleString) return;
|
|
30669
|
+
const decoration = Decoration.inline(pos, pos + node.nodeSize, { style: styleString });
|
|
30670
|
+
decorations.push(decoration);
|
|
30671
|
+
});
|
|
30672
|
+
return DecorationSet.create(doc2, decorations);
|
|
30673
|
+
};
|
|
30674
|
+
const LinkedStyles = Extension.create({
|
|
30675
|
+
name: "linkedStyles",
|
|
30676
|
+
priority: 1,
|
|
30677
|
+
// We need this plugin to run before the list plugins
|
|
30678
|
+
addOptions() {
|
|
30679
|
+
return {};
|
|
30680
|
+
},
|
|
30681
|
+
addPmPlugins() {
|
|
30682
|
+
return [createLinkedStylesPlugin(this.editor)];
|
|
30973
30683
|
},
|
|
30974
30684
|
addCommands() {
|
|
30975
|
-
const { setBold, unsetBold, toggleBold } = createCascadeToggleCommands({
|
|
30976
|
-
markName: this.name,
|
|
30977
|
-
negationAttrs: { value: "0" }
|
|
30978
|
-
});
|
|
30979
30685
|
return {
|
|
30980
30686
|
/**
|
|
30981
|
-
* Apply
|
|
30687
|
+
* Apply a linked style to the selected paragraphs
|
|
30982
30688
|
* @category Command
|
|
30689
|
+
* @param {LinkedStyle} style - The style object to apply
|
|
30983
30690
|
* @example
|
|
30984
|
-
* editor.
|
|
30985
|
-
*
|
|
30691
|
+
* const style = editor.helpers.linkedStyles.getStyleById('Heading1');
|
|
30692
|
+
* editor.commands.setLinkedStyle(style);
|
|
30693
|
+
* @note Clears existing formatting when applying a style
|
|
30694
|
+
* @note Works with custom selection preservation
|
|
30986
30695
|
*/
|
|
30987
|
-
|
|
30696
|
+
setLinkedStyle: (style) => (params2) => {
|
|
30697
|
+
const { tr } = params2;
|
|
30698
|
+
return applyLinkedStyleToTransaction(tr, this.editor, style);
|
|
30699
|
+
},
|
|
30988
30700
|
/**
|
|
30989
|
-
*
|
|
30701
|
+
* Toggle a linked style on the current selection
|
|
30990
30702
|
* @category Command
|
|
30703
|
+
* @param {LinkedStyle} style - The linked style to apply (with id property)
|
|
30991
30704
|
* @example
|
|
30992
|
-
* editor.
|
|
30705
|
+
* const style = editor.helpers.linkedStyles.getStyleById('Heading1');
|
|
30706
|
+
* editor.commands.toggleLinkedStyle(style)
|
|
30707
|
+
* @note If selection is empty, returns false
|
|
30708
|
+
* @note Removes style if already applied, applies it if not
|
|
30993
30709
|
*/
|
|
30994
|
-
|
|
30710
|
+
toggleLinkedStyle: (style) => (params2) => {
|
|
30711
|
+
const { tr } = params2;
|
|
30712
|
+
if (tr.selection.empty) {
|
|
30713
|
+
return false;
|
|
30714
|
+
}
|
|
30715
|
+
let node = tr.doc.nodeAt(tr.selection.$from.pos);
|
|
30716
|
+
if (node && node.type.name !== "paragraph") {
|
|
30717
|
+
node = findParentNodeClosestToPos(tr.selection.$from, (n) => {
|
|
30718
|
+
return n.type.name === "paragraph";
|
|
30719
|
+
})?.node;
|
|
30720
|
+
}
|
|
30721
|
+
if (!node) {
|
|
30722
|
+
return false;
|
|
30723
|
+
}
|
|
30724
|
+
const paragraphProps = getResolvedParagraphProperties(node);
|
|
30725
|
+
const currentStyleId = paragraphProps.styleId;
|
|
30726
|
+
if (currentStyleId === style.id) {
|
|
30727
|
+
return applyLinkedStyleToTransaction(tr, this.editor, { id: null });
|
|
30728
|
+
}
|
|
30729
|
+
return applyLinkedStyleToTransaction(tr, this.editor, style);
|
|
30730
|
+
},
|
|
30995
30731
|
/**
|
|
30996
|
-
*
|
|
30732
|
+
* Apply a linked style by its ID
|
|
30997
30733
|
* @category Command
|
|
30734
|
+
* @param {string} styleId - The style ID to apply (e.g., 'Heading1')
|
|
30998
30735
|
* @example
|
|
30999
|
-
* editor.commands.
|
|
31000
|
-
|
|
31001
|
-
|
|
31002
|
-
};
|
|
31003
|
-
},
|
|
31004
|
-
addShortcuts() {
|
|
31005
|
-
return {
|
|
31006
|
-
"Mod-b": () => this.editor.commands.toggleBold(),
|
|
31007
|
-
"Mod-B": () => this.editor.commands.toggleBold()
|
|
31008
|
-
};
|
|
31009
|
-
}
|
|
31010
|
-
});
|
|
31011
|
-
const Italic = Mark.create({
|
|
31012
|
-
name: "italic",
|
|
31013
|
-
addOptions() {
|
|
31014
|
-
return {
|
|
31015
|
-
htmlAttributes: {}
|
|
31016
|
-
};
|
|
31017
|
-
},
|
|
31018
|
-
addAttributes() {
|
|
31019
|
-
return {
|
|
31020
|
-
/**
|
|
31021
|
-
* @category Attribute
|
|
31022
|
-
* @param {string} [value] - Italic toggle value ('0' renders as normal)
|
|
30736
|
+
* editor.commands.setStyleById('Heading1')
|
|
30737
|
+
* editor.commands.setStyleById('Normal')
|
|
30738
|
+
* @note Looks up the style from loaded Word styles
|
|
31023
30739
|
*/
|
|
31024
|
-
|
|
31025
|
-
|
|
31026
|
-
|
|
31027
|
-
|
|
31028
|
-
|
|
31029
|
-
|
|
31030
|
-
|
|
30740
|
+
setStyleById: (styleId) => (params2) => {
|
|
30741
|
+
const { state, tr } = params2;
|
|
30742
|
+
const pluginState = LinkedStylesPluginKey.getState(state);
|
|
30743
|
+
if (!pluginState) return false;
|
|
30744
|
+
const style = pluginState.styles?.find((s2) => s2.id === styleId);
|
|
30745
|
+
if (!style) return false;
|
|
30746
|
+
return applyLinkedStyleToTransaction(tr, this.editor, style);
|
|
31031
30747
|
}
|
|
31032
30748
|
};
|
|
31033
30749
|
},
|
|
31034
|
-
|
|
31035
|
-
return [
|
|
31036
|
-
{ tag: "i" },
|
|
31037
|
-
{ tag: "em" },
|
|
31038
|
-
{ style: "font-style=italic" },
|
|
31039
|
-
{ style: "font-style=normal", clearMark: (m) => m.type.name == "em" }
|
|
31040
|
-
];
|
|
31041
|
-
},
|
|
31042
|
-
renderDOM({ htmlAttributes }) {
|
|
31043
|
-
const merged = Attribute.mergeAttributes(this.options.htmlAttributes, htmlAttributes);
|
|
31044
|
-
const { value, ...rest } = merged || {};
|
|
31045
|
-
if (value === "0") {
|
|
31046
|
-
return ["span", rest, 0];
|
|
31047
|
-
}
|
|
31048
|
-
return ["em", rest, 0];
|
|
31049
|
-
},
|
|
31050
|
-
addCommands() {
|
|
31051
|
-
const { setItalic, unsetItalic, toggleItalic } = createCascadeToggleCommands({
|
|
31052
|
-
markName: this.name,
|
|
31053
|
-
negationAttrs: { value: "0" }
|
|
31054
|
-
});
|
|
30750
|
+
addHelpers() {
|
|
31055
30751
|
return {
|
|
31056
30752
|
/**
|
|
31057
|
-
*
|
|
31058
|
-
* @category
|
|
30753
|
+
* Get all available linked styles
|
|
30754
|
+
* @category Helper
|
|
30755
|
+
* @returns {Array} Array of linked style objects
|
|
31059
30756
|
* @example
|
|
31060
|
-
* editor.
|
|
30757
|
+
* const styles = editor.helpers.linkedStyles.getStyles();
|
|
30758
|
+
* // Returns all styles from the Word document
|
|
31061
30759
|
*/
|
|
31062
|
-
|
|
30760
|
+
getStyles: () => {
|
|
30761
|
+
const styles = LinkedStylesPluginKey.getState(this.editor.state)?.styles || [];
|
|
30762
|
+
return styles;
|
|
30763
|
+
},
|
|
31063
30764
|
/**
|
|
31064
|
-
*
|
|
31065
|
-
* @category
|
|
30765
|
+
* Get a specific style by ID
|
|
30766
|
+
* @category Helper
|
|
30767
|
+
* @param {string} styleId - The style ID to find
|
|
30768
|
+
* @returns {Object} The style object or undefined
|
|
31066
30769
|
* @example
|
|
31067
|
-
* editor.
|
|
30770
|
+
* const headingStyle = editor.helpers.linkedStyles.getStyleById('Heading1');
|
|
31068
30771
|
*/
|
|
31069
|
-
|
|
30772
|
+
getStyleById: (styleId) => {
|
|
30773
|
+
const styles = this.editor.helpers[this.name].getStyles();
|
|
30774
|
+
return styles.find((s2) => s2.id === styleId);
|
|
30775
|
+
},
|
|
31070
30776
|
/**
|
|
31071
|
-
*
|
|
31072
|
-
* @category
|
|
30777
|
+
* Get the CSS string for a style
|
|
30778
|
+
* @category Helper
|
|
30779
|
+
* @param {string} styleId - The style ID
|
|
30780
|
+
* @returns {string} CSS style string
|
|
31073
30781
|
* @example
|
|
31074
|
-
* editor.
|
|
30782
|
+
* const css = editor.helpers.linkedStyles.getLinkedStyleString('Heading1');
|
|
30783
|
+
* // Returns: "font-size: 16pt; font-weight: bold; color: #2E74B5"
|
|
30784
|
+
* @private
|
|
31075
30785
|
*/
|
|
31076
|
-
|
|
31077
|
-
|
|
31078
|
-
|
|
31079
|
-
|
|
31080
|
-
|
|
31081
|
-
|
|
31082
|
-
"Mod-I": () => this.editor.commands.toggleItalic()
|
|
30786
|
+
getLinkedStyleString: (styleId) => {
|
|
30787
|
+
const styles = this.editor.helpers.linkedStyles.getStyles();
|
|
30788
|
+
const style = styles.find((s2) => s2.id === styleId);
|
|
30789
|
+
if (!style) return "";
|
|
30790
|
+
return generateLinkedStyleString(style);
|
|
30791
|
+
}
|
|
31083
30792
|
};
|
|
31084
30793
|
}
|
|
31085
30794
|
});
|
|
@@ -37667,13 +37376,11 @@ const getRichTextExtensions = () => {
|
|
|
37667
37376
|
History,
|
|
37668
37377
|
Heading,
|
|
37669
37378
|
Italic,
|
|
37670
|
-
LineHeight,
|
|
37671
37379
|
Link,
|
|
37672
37380
|
Paragraph,
|
|
37673
37381
|
Strike,
|
|
37674
37382
|
Text,
|
|
37675
37383
|
TextAlign,
|
|
37676
|
-
TextIndent,
|
|
37677
37384
|
TextStyle,
|
|
37678
37385
|
Underline,
|
|
37679
37386
|
Placeholder,
|
|
@@ -37710,7 +37417,6 @@ const getStarterExtensions = () => {
|
|
|
37710
37417
|
History,
|
|
37711
37418
|
Heading,
|
|
37712
37419
|
Italic,
|
|
37713
|
-
LineHeight,
|
|
37714
37420
|
Link,
|
|
37715
37421
|
Paragraph,
|
|
37716
37422
|
LineBreak,
|
|
@@ -37722,7 +37428,6 @@ const getStarterExtensions = () => {
|
|
|
37722
37428
|
TableOfContents,
|
|
37723
37429
|
Text,
|
|
37724
37430
|
TextAlign,
|
|
37725
|
-
TextIndent,
|
|
37726
37431
|
TextStyle,
|
|
37727
37432
|
Underline,
|
|
37728
37433
|
FormatCommands,
|