@harbour-enterprises/superdoc 0.22.0-next.1 → 0.22.0-next.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/chunks/{PdfViewer-BpwMPbUj.es.js → PdfViewer-CJdQmuIm.es.js} +1 -1
- package/dist/chunks/{PdfViewer-B3KmcDup.cjs → PdfViewer-DE1NR4Ve.cjs} +1 -1
- package/dist/chunks/{index-Cw4YywoD.es.js → index-B9sHxXr_.es.js} +53 -26
- package/dist/chunks/{index-BOf6E2I4.cjs → index-nfoifSpX.cjs} +53 -26
- package/dist/chunks/{super-editor.es-DHDx2fsy.cjs → super-editor.es-DAP-fnHo.cjs} +2264 -1648
- package/dist/chunks/{super-editor.es-vfoWxyZL.es.js → super-editor.es-_iVPQ8J8.es.js} +2264 -1648
- package/dist/core/SuperDoc.d.ts +5 -0
- package/dist/core/SuperDoc.d.ts.map +1 -1
- package/dist/core/types/index.d.ts +4 -4
- package/dist/core/types/index.d.ts.map +1 -1
- package/dist/stores/comments-store.d.ts +4 -1
- package/dist/stores/comments-store.d.ts.map +1 -1
- package/dist/style.css +48 -44
- package/dist/super-editor/ai-writer.es.js +2 -2
- package/dist/super-editor/chunks/{converter-BcqEfCTg.js → converter-DK1NMJZB.js} +439 -169
- package/dist/super-editor/chunks/{docx-zipper-DZ9ph0iQ.js → docx-zipper-CmK8TyNb.js} +73 -12
- package/dist/super-editor/chunks/{editor-BC2sSIVa.js → editor-YR4uV-dp.js} +1902 -1607
- package/dist/super-editor/chunks/{toolbar-DNTo5DDf.js → toolbar-DzJyRvb0.js} +2 -2
- package/dist/super-editor/converter.es.js +1 -1
- package/dist/super-editor/docx-zipper.es.js +2 -2
- package/dist/super-editor/editor.es.js +3 -3
- package/dist/super-editor/file-zipper.es.js +1 -1
- package/dist/super-editor/src/core/DocxZipper.d.ts +1 -1
- package/dist/super-editor/src/core/super-converter/SuperConverter.d.ts +1 -13
- package/dist/super-editor/src/core/super-converter/exporter.d.ts +1 -0
- package/dist/super-editor/src/core/super-converter/helpers/tableFallbackHelpers.d.ts +24 -0
- package/dist/super-editor/src/extensions/custom-selection/custom-selection.d.ts +5 -1
- package/dist/super-editor/src/extensions/index.d.ts +2 -1
- package/dist/super-editor/src/extensions/structured-content/index.d.ts +1 -0
- package/dist/super-editor/src/extensions/structured-content/structured-content-commands.d.ts +67 -0
- package/dist/super-editor/src/extensions/structured-content/structuredContentHelpers/getStructuredContentBlockTags.d.ts +7 -0
- package/dist/super-editor/src/extensions/structured-content/structuredContentHelpers/getStructuredContentInlineTags.d.ts +7 -0
- package/dist/super-editor/src/extensions/structured-content/structuredContentHelpers/getStructuredContentTags.d.ts +7 -0
- package/dist/super-editor/src/extensions/structured-content/structuredContentHelpers/getStructuredContentTagsById.d.ts +8 -0
- package/dist/super-editor/src/extensions/structured-content/structuredContentHelpers/index.d.ts +4 -0
- package/dist/super-editor/src/utils/contextmenu-helpers.d.ts +24 -0
- package/dist/super-editor/style.css +4 -0
- package/dist/super-editor/super-editor.es.js +8 -16
- 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 +1665 -1022
- package/dist/superdoc.umd.js.map +1 -1
- package/package.json +1 -1
- package/dist/super-editor/src/components/slash-menu/contextmenu-helpers.d.ts +0 -1
|
@@ -24856,17 +24856,16 @@ const getParagraphSpacing = (node, docx, styleId = "", marks = [], options = {})
|
|
|
24856
24856
|
};
|
|
24857
24857
|
const getDefaultParagraphStyle = (docx, styleId = "") => {
|
|
24858
24858
|
const styles = docx["word/styles.xml"];
|
|
24859
|
-
|
|
24859
|
+
const rootElements = styles?.elements?.[0]?.elements;
|
|
24860
|
+
if (!rootElements?.length) {
|
|
24860
24861
|
return {};
|
|
24861
24862
|
}
|
|
24862
|
-
const defaults =
|
|
24863
|
-
const pDefault = defaults
|
|
24863
|
+
const defaults = rootElements.find((el) => el.name === "w:docDefaults");
|
|
24864
|
+
const pDefault = defaults?.elements?.find((el) => el.name === "w:pPrDefault") || {};
|
|
24864
24865
|
const pPrDefault = pDefault?.elements?.find((el) => el.name === "w:pPr");
|
|
24865
24866
|
const pPrDefaultSpacingTag = pPrDefault?.elements?.find((el) => el.name === "w:spacing") || {};
|
|
24866
24867
|
const pPrDefaultIndentTag = pPrDefault?.elements?.find((el) => el.name === "w:ind") || {};
|
|
24867
|
-
const stylesNormal =
|
|
24868
|
-
(el) => el.name === "w:style" && el.attributes["w:styleId"] === "Normal"
|
|
24869
|
-
);
|
|
24868
|
+
const stylesNormal = rootElements.find((el) => el.name === "w:style" && el.attributes["w:styleId"] === "Normal");
|
|
24870
24869
|
const pPrNormal = stylesNormal?.elements?.find((el) => el.name === "w:pPr");
|
|
24871
24870
|
const pPrNormalSpacingTag = pPrNormal?.elements?.find((el) => el.name === "w:spacing") || {};
|
|
24872
24871
|
const pPrNormalIndentTag = pPrNormal?.elements?.find((el) => el.name === "w:ind") || {};
|
|
@@ -24875,9 +24874,7 @@ const getDefaultParagraphStyle = (docx, styleId = "") => {
|
|
|
24875
24874
|
let pPrStyleIdIndentTag = {};
|
|
24876
24875
|
let pPrStyleJc = {};
|
|
24877
24876
|
if (styleId) {
|
|
24878
|
-
const stylesById =
|
|
24879
|
-
(el) => el.name === "w:style" && el.attributes["w:styleId"] === styleId
|
|
24880
|
-
);
|
|
24877
|
+
const stylesById = rootElements.find((el) => el.name === "w:style" && el.attributes["w:styleId"] === styleId);
|
|
24881
24878
|
const pPrById = stylesById?.elements?.find((el) => el.name === "w:pPr");
|
|
24882
24879
|
pPrStyleIdSpacingTag = pPrById?.elements?.find((el) => el.name === "w:spacing") || {};
|
|
24883
24880
|
pPrStyleIdIndentTag = pPrById?.elements?.find((el) => el.name === "w:ind") || {};
|
|
@@ -27180,6 +27177,68 @@ const config$a = {
|
|
|
27180
27177
|
decode: decode$h
|
|
27181
27178
|
};
|
|
27182
27179
|
const translator$a = NodeTranslator.from(config$a);
|
|
27180
|
+
const DEFAULT_PAGE_WIDTH_TWIPS = 12240;
|
|
27181
|
+
const DEFAULT_PAGE_MARGIN_TWIPS = 1440;
|
|
27182
|
+
const DEFAULT_CONTENT_WIDTH_TWIPS = DEFAULT_PAGE_WIDTH_TWIPS - 2 * DEFAULT_PAGE_MARGIN_TWIPS;
|
|
27183
|
+
const MIN_COLUMN_WIDTH_TWIPS = pixelsToTwips(10);
|
|
27184
|
+
const pctToPercent = (value) => {
|
|
27185
|
+
if (value == null) return null;
|
|
27186
|
+
return value / 50;
|
|
27187
|
+
};
|
|
27188
|
+
const resolveContentWidthTwips = () => DEFAULT_CONTENT_WIDTH_TWIPS;
|
|
27189
|
+
const resolveMeasurementWidthPx = (measurement) => {
|
|
27190
|
+
if (!measurement || typeof measurement.value !== "number" || measurement.value <= 0) return null;
|
|
27191
|
+
const { value, type: type2 } = measurement;
|
|
27192
|
+
if (!type2 || type2 === "auto") return null;
|
|
27193
|
+
if (type2 === "dxa") return twipsToPixels(value);
|
|
27194
|
+
if (type2 === "pct") {
|
|
27195
|
+
const percent2 = pctToPercent(value);
|
|
27196
|
+
if (percent2 == null || percent2 <= 0) return null;
|
|
27197
|
+
const widthTwips = resolveContentWidthTwips() * percent2 / 100;
|
|
27198
|
+
return twipsToPixels(widthTwips);
|
|
27199
|
+
}
|
|
27200
|
+
return null;
|
|
27201
|
+
};
|
|
27202
|
+
const countColumnsInRow = (row) => {
|
|
27203
|
+
if (!row?.elements?.length) return 0;
|
|
27204
|
+
return row.elements.reduce((count, element) => {
|
|
27205
|
+
if (element.name !== "w:tc") return count;
|
|
27206
|
+
const tcPr = element.elements?.find((el) => el.name === "w:tcPr");
|
|
27207
|
+
const gridSpan = tcPr?.elements?.find((el) => el.name === "w:gridSpan");
|
|
27208
|
+
const spanValue = parseInt(gridSpan?.attributes?.["w:val"] || "1", 10);
|
|
27209
|
+
return count + (Number.isFinite(spanValue) && spanValue > 0 ? spanValue : 1);
|
|
27210
|
+
}, 0);
|
|
27211
|
+
};
|
|
27212
|
+
const clampColumnWidthTwips = (value) => Math.max(Math.round(value), MIN_COLUMN_WIDTH_TWIPS);
|
|
27213
|
+
const createFallbackGrid = (columnCount, columnWidthTwips) => Array.from({ length: columnCount }, () => ({ col: clampColumnWidthTwips(columnWidthTwips) }));
|
|
27214
|
+
const buildFallbackGridForTable = ({ params: params2, rows, tableWidth, tableWidthMeasurement }) => {
|
|
27215
|
+
const firstRow = rows.find((row) => row.elements?.some((el) => el.name === "w:tc"));
|
|
27216
|
+
const columnCount = countColumnsInRow(firstRow);
|
|
27217
|
+
if (!columnCount) return null;
|
|
27218
|
+
const schemaDefaultPx = getSchemaDefaultColumnWidthPx(
|
|
27219
|
+
/** @type {any} */
|
|
27220
|
+
params2
|
|
27221
|
+
);
|
|
27222
|
+
const minimumColumnWidthPx = Number.isFinite(schemaDefaultPx) && schemaDefaultPx > 0 ? schemaDefaultPx : DEFAULT_COLUMN_WIDTH_PX;
|
|
27223
|
+
let totalWidthPx;
|
|
27224
|
+
if (tableWidthMeasurement) {
|
|
27225
|
+
const resolved = resolveMeasurementWidthPx(tableWidthMeasurement);
|
|
27226
|
+
if (resolved != null) totalWidthPx = resolved;
|
|
27227
|
+
}
|
|
27228
|
+
if (totalWidthPx == null && tableWidth?.width && tableWidth.width > 0) {
|
|
27229
|
+
totalWidthPx = tableWidth.width;
|
|
27230
|
+
}
|
|
27231
|
+
if (totalWidthPx == null) {
|
|
27232
|
+
totalWidthPx = minimumColumnWidthPx * columnCount;
|
|
27233
|
+
}
|
|
27234
|
+
const rawColumnWidthPx = Math.max(totalWidthPx / columnCount, minimumColumnWidthPx);
|
|
27235
|
+
const columnWidthTwips = clampColumnWidthTwips(pixelsToTwips(rawColumnWidthPx));
|
|
27236
|
+
const fallbackColumnWidthPx = twipsToPixels(columnWidthTwips);
|
|
27237
|
+
return {
|
|
27238
|
+
grid: createFallbackGrid(columnCount, columnWidthTwips),
|
|
27239
|
+
columnWidths: Array(columnCount).fill(fallbackColumnWidthPx)
|
|
27240
|
+
};
|
|
27241
|
+
};
|
|
27183
27242
|
const XML_NODE_NAME$9 = "w:tbl";
|
|
27184
27243
|
const SD_NODE_NAME$9 = "table";
|
|
27185
27244
|
const encode$g = (params2, encodedAttrs) => {
|
|
@@ -27199,7 +27258,6 @@ const encode$g = (params2, encodedAttrs) => {
|
|
|
27199
27258
|
"justification",
|
|
27200
27259
|
"tableLayout",
|
|
27201
27260
|
["tableIndent", ({ value, type: type2 }) => ({ width: twipsToPixels(value), type: type2 })],
|
|
27202
|
-
["tableWidth", ({ value, type: type2 }) => ({ width: twipsToPixels(value), type: type2 })],
|
|
27203
27261
|
["tableCellSpacing", ({ value, type: type2 }) => ({ w: String(value), type: type2 })]
|
|
27204
27262
|
].forEach((prop) => {
|
|
27205
27263
|
let key2;
|
|
@@ -27217,6 +27275,21 @@ const encode$g = (params2, encodedAttrs) => {
|
|
|
27217
27275
|
if (encodedAttrs.tableCellSpacing) {
|
|
27218
27276
|
encodedAttrs["borderCollapse"] = "separate";
|
|
27219
27277
|
}
|
|
27278
|
+
if (encodedAttrs.tableProperties?.tableWidth) {
|
|
27279
|
+
const tableWidthMeasurement = encodedAttrs.tableProperties.tableWidth;
|
|
27280
|
+
const widthPx = twipsToPixels(tableWidthMeasurement.value);
|
|
27281
|
+
if (widthPx != null) {
|
|
27282
|
+
encodedAttrs.tableWidth = {
|
|
27283
|
+
width: widthPx,
|
|
27284
|
+
type: tableWidthMeasurement.type
|
|
27285
|
+
};
|
|
27286
|
+
} else if (tableWidthMeasurement.type === "auto") {
|
|
27287
|
+
encodedAttrs.tableWidth = {
|
|
27288
|
+
width: 0,
|
|
27289
|
+
type: tableWidthMeasurement.type
|
|
27290
|
+
};
|
|
27291
|
+
}
|
|
27292
|
+
}
|
|
27220
27293
|
const { borders, rowBorders } = _processTableBorders(encodedAttrs.tableProperties?.borders || {});
|
|
27221
27294
|
const referencedStyles = _getReferencedTableStyles(encodedAttrs.tableStyleId, params2);
|
|
27222
27295
|
if (referencedStyles?.cellMargins && !encodedAttrs.tableProperties?.cellMargins) {
|
|
@@ -27230,7 +27303,19 @@ const encode$g = (params2, encodedAttrs) => {
|
|
|
27230
27303
|
const borderRowData = Object.assign({}, referencedStyles?.rowBorders || {}, rowBorders || {});
|
|
27231
27304
|
encodedAttrs["borders"] = borderData;
|
|
27232
27305
|
const tblStyleTag = tblPr?.elements?.find((el) => el.name === "w:tblStyle");
|
|
27233
|
-
|
|
27306
|
+
let columnWidths = Array.isArray(encodedAttrs["grid"]) ? encodedAttrs["grid"].map((item) => twipsToPixels(item.col)) : [];
|
|
27307
|
+
if (!columnWidths.length) {
|
|
27308
|
+
const fallback = buildFallbackGridForTable({
|
|
27309
|
+
params: params2,
|
|
27310
|
+
rows,
|
|
27311
|
+
tableWidth: encodedAttrs.tableWidth,
|
|
27312
|
+
tableWidthMeasurement: encodedAttrs.tableProperties?.tableWidth
|
|
27313
|
+
});
|
|
27314
|
+
if (fallback) {
|
|
27315
|
+
encodedAttrs.grid = fallback.grid;
|
|
27316
|
+
columnWidths = fallback.columnWidths;
|
|
27317
|
+
}
|
|
27318
|
+
}
|
|
27234
27319
|
const content = [];
|
|
27235
27320
|
rows.forEach((row) => {
|
|
27236
27321
|
const result = translator$G.encode({
|
|
@@ -28092,6 +28177,9 @@ function handleStructuredContentNode(params2) {
|
|
|
28092
28177
|
const node = nodes[0];
|
|
28093
28178
|
const sdtPr = node.elements.find((el) => el.name === "w:sdtPr");
|
|
28094
28179
|
const sdtContent = node.elements.find((el) => el.name === "w:sdtContent");
|
|
28180
|
+
const id = sdtPr?.elements?.find((el) => el.name === "w:id");
|
|
28181
|
+
const tag = sdtPr?.elements?.find((el) => el.name === "w:tag");
|
|
28182
|
+
const alias = sdtPr?.elements?.find((el) => el.name === "w:alias");
|
|
28095
28183
|
if (!sdtContent) {
|
|
28096
28184
|
return null;
|
|
28097
28185
|
}
|
|
@@ -28103,15 +28191,16 @@ function handleStructuredContentNode(params2) {
|
|
|
28103
28191
|
nodes: sdtContent.elements,
|
|
28104
28192
|
path: [...params2.path || [], sdtContent]
|
|
28105
28193
|
});
|
|
28106
|
-
|
|
28107
|
-
|
|
28108
|
-
sdtContentType = "structuredContentBlock";
|
|
28109
|
-
}
|
|
28194
|
+
const isBlockNode2 = paragraph || table;
|
|
28195
|
+
const sdtContentType = isBlockNode2 ? "structuredContentBlock" : "structuredContent";
|
|
28110
28196
|
let result = {
|
|
28111
28197
|
type: sdtContentType,
|
|
28112
28198
|
content: translatedContent,
|
|
28113
28199
|
marks,
|
|
28114
28200
|
attrs: {
|
|
28201
|
+
id: id?.attributes?.["w:val"] || null,
|
|
28202
|
+
tag: tag?.attributes?.["w:val"] || null,
|
|
28203
|
+
alias: alias?.attributes?.["w:val"] || null,
|
|
28115
28204
|
sdtPr
|
|
28116
28205
|
}
|
|
28117
28206
|
};
|
|
@@ -30369,21 +30458,55 @@ const generateSdtPrTagForDocumentSection = (id, title, tag) => {
|
|
|
30369
30458
|
};
|
|
30370
30459
|
function translateStructuredContent(params2) {
|
|
30371
30460
|
const { node } = params2;
|
|
30372
|
-
const { attrs = {} } = node;
|
|
30373
30461
|
const childContent = translateChildNodes({ ...params2, nodes: node.content });
|
|
30374
|
-
const
|
|
30375
|
-
|
|
30376
|
-
|
|
30377
|
-
elements: childContent
|
|
30378
|
-
}
|
|
30379
|
-
];
|
|
30380
|
-
nodeElements.unshift(attrs.sdtPr);
|
|
30462
|
+
const sdtContent = { name: "w:sdtContent", elements: childContent };
|
|
30463
|
+
const sdtPr = generateSdtPrTagForStructuredContent({ node });
|
|
30464
|
+
const nodeElements = [sdtPr, sdtContent];
|
|
30381
30465
|
const result = {
|
|
30382
30466
|
name: "w:sdt",
|
|
30383
30467
|
elements: nodeElements
|
|
30384
30468
|
};
|
|
30385
30469
|
return result;
|
|
30386
30470
|
}
|
|
30471
|
+
function generateSdtPrTagForStructuredContent({ node }) {
|
|
30472
|
+
const { attrs = {} } = node;
|
|
30473
|
+
const id = {
|
|
30474
|
+
name: "w:id",
|
|
30475
|
+
type: "element",
|
|
30476
|
+
attributes: { "w:val": attrs.id }
|
|
30477
|
+
};
|
|
30478
|
+
const alias = {
|
|
30479
|
+
name: "w:alias",
|
|
30480
|
+
type: "element",
|
|
30481
|
+
attributes: { "w:val": attrs.alias }
|
|
30482
|
+
};
|
|
30483
|
+
const tag = {
|
|
30484
|
+
name: "w:tag",
|
|
30485
|
+
type: "element",
|
|
30486
|
+
attributes: { "w:val": attrs.tag }
|
|
30487
|
+
};
|
|
30488
|
+
const resultElements = [];
|
|
30489
|
+
if (attrs.id) resultElements.push(id);
|
|
30490
|
+
if (attrs.alias) resultElements.push(alias);
|
|
30491
|
+
if (attrs.tag) resultElements.push(tag);
|
|
30492
|
+
if (attrs.sdtPr) {
|
|
30493
|
+
const elements = attrs.sdtPr.elements || [];
|
|
30494
|
+
const elementsToExclude = ["w:id", "w:alias", "w:tag"];
|
|
30495
|
+
const restElements = elements.filter((el) => !elementsToExclude.includes(el.name));
|
|
30496
|
+
const result2 = {
|
|
30497
|
+
name: "w:sdtPr",
|
|
30498
|
+
type: "element",
|
|
30499
|
+
elements: [...resultElements, ...restElements]
|
|
30500
|
+
};
|
|
30501
|
+
return result2;
|
|
30502
|
+
}
|
|
30503
|
+
const result = {
|
|
30504
|
+
name: "w:sdtPr",
|
|
30505
|
+
type: "element",
|
|
30506
|
+
elements: resultElements
|
|
30507
|
+
};
|
|
30508
|
+
return result;
|
|
30509
|
+
}
|
|
30387
30510
|
const XML_NODE_NAME$3 = "w:sdt";
|
|
30388
30511
|
const SD_NODE_NAME$3 = ["fieldAnnotation", "structuredContent", "structuredContentBlock", "documentSection"];
|
|
30389
30512
|
const validXmlAttributes$3 = [];
|
|
@@ -30611,6 +30734,63 @@ const config = {
|
|
|
30611
30734
|
attributes: validXmlAttributes
|
|
30612
30735
|
};
|
|
30613
30736
|
const translator = NodeTranslator.from(config);
|
|
30737
|
+
const DEFAULT_SECTION_PROPS_TWIPS = Object.freeze({
|
|
30738
|
+
pageSize: Object.freeze({ width: "12240", height: "15840" }),
|
|
30739
|
+
pageMargins: Object.freeze({
|
|
30740
|
+
top: "1440",
|
|
30741
|
+
right: "1440",
|
|
30742
|
+
bottom: "1440",
|
|
30743
|
+
left: "1440",
|
|
30744
|
+
header: "720",
|
|
30745
|
+
footer: "720",
|
|
30746
|
+
gutter: "0"
|
|
30747
|
+
})
|
|
30748
|
+
});
|
|
30749
|
+
const ensureSectionLayoutDefaults = (sectPr, converter) => {
|
|
30750
|
+
if (!sectPr) {
|
|
30751
|
+
return {
|
|
30752
|
+
type: "element",
|
|
30753
|
+
name: "w:sectPr",
|
|
30754
|
+
elements: []
|
|
30755
|
+
};
|
|
30756
|
+
}
|
|
30757
|
+
if (!sectPr.elements) sectPr.elements = [];
|
|
30758
|
+
const ensureChild = (name) => {
|
|
30759
|
+
let child = sectPr.elements.find((n) => n.name === name);
|
|
30760
|
+
if (!child) {
|
|
30761
|
+
child = {
|
|
30762
|
+
type: "element",
|
|
30763
|
+
name,
|
|
30764
|
+
elements: [],
|
|
30765
|
+
attributes: {}
|
|
30766
|
+
};
|
|
30767
|
+
sectPr.elements.push(child);
|
|
30768
|
+
} else {
|
|
30769
|
+
if (!child.elements) child.elements = [];
|
|
30770
|
+
if (!child.attributes) child.attributes = {};
|
|
30771
|
+
}
|
|
30772
|
+
return child;
|
|
30773
|
+
};
|
|
30774
|
+
const pageSize = converter?.pageStyles?.pageSize;
|
|
30775
|
+
const pgSz = ensureChild("w:pgSz");
|
|
30776
|
+
if (pageSize?.width != null) pgSz.attributes["w:w"] = String(inchesToTwips(pageSize.width));
|
|
30777
|
+
if (pageSize?.height != null) pgSz.attributes["w:h"] = String(inchesToTwips(pageSize.height));
|
|
30778
|
+
if (pgSz.attributes["w:w"] == null) pgSz.attributes["w:w"] = DEFAULT_SECTION_PROPS_TWIPS.pageSize.width;
|
|
30779
|
+
if (pgSz.attributes["w:h"] == null) pgSz.attributes["w:h"] = DEFAULT_SECTION_PROPS_TWIPS.pageSize.height;
|
|
30780
|
+
const pageMargins = converter?.pageStyles?.pageMargins;
|
|
30781
|
+
const pgMar = ensureChild("w:pgMar");
|
|
30782
|
+
if (pageMargins) {
|
|
30783
|
+
Object.entries(pageMargins).forEach(([key2, value]) => {
|
|
30784
|
+
const converted = inchesToTwips(value);
|
|
30785
|
+
if (converted != null) pgMar.attributes[`w:${key2}`] = String(converted);
|
|
30786
|
+
});
|
|
30787
|
+
}
|
|
30788
|
+
Object.entries(DEFAULT_SECTION_PROPS_TWIPS.pageMargins).forEach(([key2, value]) => {
|
|
30789
|
+
const attrKey = `w:${key2}`;
|
|
30790
|
+
if (pgMar.attributes[attrKey] == null) pgMar.attributes[attrKey] = value;
|
|
30791
|
+
});
|
|
30792
|
+
return sectPr;
|
|
30793
|
+
};
|
|
30614
30794
|
const isLineBreakOnlyRun = (node) => {
|
|
30615
30795
|
if (!node) return false;
|
|
30616
30796
|
if (node.type === "lineBreak" || node.type === "hardBreak") return true;
|
|
@@ -30663,28 +30843,30 @@ function exportSchemaToJson(params2) {
|
|
|
30663
30843
|
return handler2(params2);
|
|
30664
30844
|
}
|
|
30665
30845
|
function translateBodyNode(params2) {
|
|
30666
|
-
let sectPr = params2.bodyNode?.elements
|
|
30846
|
+
let sectPr = params2.bodyNode?.elements?.find((n) => n.name === "w:sectPr");
|
|
30847
|
+
if (!sectPr) {
|
|
30848
|
+
sectPr = {
|
|
30849
|
+
type: "element",
|
|
30850
|
+
name: "w:sectPr",
|
|
30851
|
+
elements: []
|
|
30852
|
+
};
|
|
30853
|
+
} else if (!sectPr.elements) {
|
|
30854
|
+
sectPr = { ...sectPr, elements: [] };
|
|
30855
|
+
}
|
|
30856
|
+
sectPr = ensureSectionLayoutDefaults(sectPr, params2.converter);
|
|
30667
30857
|
if (params2.converter) {
|
|
30668
|
-
const hasHeader = sectPr
|
|
30858
|
+
const hasHeader = sectPr.elements?.some((n) => n.name === "w:headerReference");
|
|
30669
30859
|
const hasDefaultHeader = params2.converter.headerIds?.default;
|
|
30670
30860
|
if (!hasHeader && hasDefaultHeader && !params2.editor.options.isHeaderOrFooter) {
|
|
30671
30861
|
const defaultHeader = generateDefaultHeaderFooter("header", params2.converter.headerIds?.default);
|
|
30672
30862
|
sectPr.elements.push(defaultHeader);
|
|
30673
30863
|
}
|
|
30674
|
-
const hasFooter = sectPr
|
|
30864
|
+
const hasFooter = sectPr.elements?.some((n) => n.name === "w:footerReference");
|
|
30675
30865
|
const hasDefaultFooter = params2.converter.footerIds?.default;
|
|
30676
30866
|
if (!hasFooter && hasDefaultFooter && !params2.editor.options.isHeaderOrFooter) {
|
|
30677
30867
|
const defaultFooter = generateDefaultHeaderFooter("footer", params2.converter.footerIds?.default);
|
|
30678
30868
|
sectPr.elements.push(defaultFooter);
|
|
30679
30869
|
}
|
|
30680
|
-
const newMargins = params2.converter.pageStyles.pageMargins;
|
|
30681
|
-
const sectPrMargins = sectPr.elements.find((n) => n.name === "w:pgMar");
|
|
30682
|
-
const { attributes } = sectPrMargins;
|
|
30683
|
-
Object.entries(newMargins).forEach(([key2, value]) => {
|
|
30684
|
-
const convertedValue = inchesToTwips(value);
|
|
30685
|
-
attributes[`w:${key2}`] = convertedValue;
|
|
30686
|
-
});
|
|
30687
|
-
sectPrMargins.attributes = attributes;
|
|
30688
30870
|
}
|
|
30689
30871
|
const elements = translateChildNodes(params2);
|
|
30690
30872
|
if (params2.isHeaderFooter) {
|
|
@@ -32111,8 +32293,15 @@ const handlePictNode = (params2) => {
|
|
|
32111
32293
|
return { nodes: [], consumed: 0 };
|
|
32112
32294
|
}
|
|
32113
32295
|
const [pNode] = nodes;
|
|
32114
|
-
const
|
|
32115
|
-
|
|
32296
|
+
const runs = pNode.elements?.filter((el) => el.name === "w:r") || [];
|
|
32297
|
+
let pict = null;
|
|
32298
|
+
for (const run2 of runs) {
|
|
32299
|
+
const foundPict = run2.elements?.find((el) => el.name === "w:pict");
|
|
32300
|
+
if (foundPict) {
|
|
32301
|
+
pict = foundPict;
|
|
32302
|
+
break;
|
|
32303
|
+
}
|
|
32304
|
+
}
|
|
32116
32305
|
if (!pict) {
|
|
32117
32306
|
return { nodes: [], consumed: 0 };
|
|
32118
32307
|
}
|
|
@@ -32699,6 +32888,7 @@ const createDocumentJson = (docx, converter, editor) => {
|
|
|
32699
32888
|
const nodeListHandler = defaultNodeListHandler();
|
|
32700
32889
|
const bodyNode = json.elements[0].elements.find((el) => el.name === "w:body");
|
|
32701
32890
|
if (bodyNode) {
|
|
32891
|
+
ensureSectionProperties(bodyNode);
|
|
32702
32892
|
const node = bodyNode;
|
|
32703
32893
|
const contentElements = node.elements?.filter((n) => n.name !== "w:sectPr") ?? [];
|
|
32704
32894
|
const content = pruneIgnoredNodes(contentElements);
|
|
@@ -32932,6 +33122,59 @@ function getDocumentStyles(node, docx, converter, editor) {
|
|
|
32932
33122
|
styles.alternateHeaders = isAlternatingHeadersOddEven(docx);
|
|
32933
33123
|
return styles;
|
|
32934
33124
|
}
|
|
33125
|
+
const DEFAULT_SECTION_PROPS = Object.freeze({
|
|
33126
|
+
pageSize: Object.freeze({ width: "12240", height: "15840" }),
|
|
33127
|
+
pageMargins: Object.freeze({
|
|
33128
|
+
top: "1440",
|
|
33129
|
+
right: "1440",
|
|
33130
|
+
bottom: "1440",
|
|
33131
|
+
left: "1440",
|
|
33132
|
+
header: "720",
|
|
33133
|
+
footer: "720",
|
|
33134
|
+
gutter: "0"
|
|
33135
|
+
})
|
|
33136
|
+
});
|
|
33137
|
+
function ensureSectionProperties(bodyNode, converter) {
|
|
33138
|
+
if (!bodyNode.elements) bodyNode.elements = [];
|
|
33139
|
+
let sectPr = bodyNode.elements.find((el) => el.name === "w:sectPr");
|
|
33140
|
+
if (!sectPr) {
|
|
33141
|
+
sectPr = {
|
|
33142
|
+
type: "element",
|
|
33143
|
+
name: "w:sectPr",
|
|
33144
|
+
elements: []
|
|
33145
|
+
};
|
|
33146
|
+
bodyNode.elements.push(sectPr);
|
|
33147
|
+
} else if (!sectPr.elements) {
|
|
33148
|
+
sectPr.elements = [];
|
|
33149
|
+
}
|
|
33150
|
+
const ensureChild = (name, factory) => {
|
|
33151
|
+
let child = sectPr.elements.find((el) => el.name === name);
|
|
33152
|
+
if (!child) {
|
|
33153
|
+
child = factory();
|
|
33154
|
+
sectPr.elements.push(child);
|
|
33155
|
+
} else if (!child.attributes) {
|
|
33156
|
+
child.attributes = {};
|
|
33157
|
+
}
|
|
33158
|
+
return child;
|
|
33159
|
+
};
|
|
33160
|
+
const pgSz = ensureChild("w:pgSz", () => ({
|
|
33161
|
+
type: "element",
|
|
33162
|
+
name: "w:pgSz",
|
|
33163
|
+
attributes: {}
|
|
33164
|
+
}));
|
|
33165
|
+
pgSz.attributes["w:w"] = pgSz.attributes["w:w"] ?? DEFAULT_SECTION_PROPS.pageSize.width;
|
|
33166
|
+
pgSz.attributes["w:h"] = pgSz.attributes["w:h"] ?? DEFAULT_SECTION_PROPS.pageSize.height;
|
|
33167
|
+
const pgMar = ensureChild("w:pgMar", () => ({
|
|
33168
|
+
type: "element",
|
|
33169
|
+
name: "w:pgMar",
|
|
33170
|
+
attributes: {}
|
|
33171
|
+
}));
|
|
33172
|
+
Object.entries(DEFAULT_SECTION_PROPS.pageMargins).forEach(([key2, value]) => {
|
|
33173
|
+
const attrKey = `w:${key2}`;
|
|
33174
|
+
if (pgMar.attributes[attrKey] == null) pgMar.attributes[attrKey] = value;
|
|
33175
|
+
});
|
|
33176
|
+
return sectPr;
|
|
33177
|
+
}
|
|
32935
33178
|
function getStyleDefinitions(docx) {
|
|
32936
33179
|
const styles = docx["word/styles.xml"];
|
|
32937
33180
|
if (!styles) return [];
|
|
@@ -33124,6 +33367,36 @@ const FONT_FAMILY_FALLBACKS = Object.freeze({
|
|
|
33124
33367
|
auto: "sans-serif"
|
|
33125
33368
|
});
|
|
33126
33369
|
const DEFAULT_GENERIC_FALLBACK = "sans-serif";
|
|
33370
|
+
const DEFAULT_FONT_SIZE_PT = 10;
|
|
33371
|
+
const collectRunDefaultProperties = (runProps, { allowOverrideTypeface = true, allowOverrideSize = true, themeResolver, state: state2 }) => {
|
|
33372
|
+
if (!runProps?.elements?.length || !state2) return;
|
|
33373
|
+
const fontsNode = runProps.elements.find((el) => el.name === "w:rFonts");
|
|
33374
|
+
if (fontsNode?.attributes) {
|
|
33375
|
+
const themeName = fontsNode.attributes["w:asciiTheme"];
|
|
33376
|
+
if (themeName) {
|
|
33377
|
+
const themeInfo = themeResolver?.(themeName) || {};
|
|
33378
|
+
if ((allowOverrideTypeface || !state2.typeface) && themeInfo.typeface) state2.typeface = themeInfo.typeface;
|
|
33379
|
+
if ((allowOverrideTypeface || !state2.panose) && themeInfo.panose) state2.panose = themeInfo.panose;
|
|
33380
|
+
}
|
|
33381
|
+
const ascii = fontsNode.attributes["w:ascii"];
|
|
33382
|
+
if ((allowOverrideTypeface || !state2.typeface) && ascii) {
|
|
33383
|
+
state2.typeface = ascii;
|
|
33384
|
+
}
|
|
33385
|
+
}
|
|
33386
|
+
const sizeNode = runProps.elements.find((el) => el.name === "w:sz");
|
|
33387
|
+
if (sizeNode?.attributes?.["w:val"]) {
|
|
33388
|
+
const sizeTwips = Number(sizeNode.attributes["w:val"]);
|
|
33389
|
+
if (Number.isFinite(sizeTwips)) {
|
|
33390
|
+
if (state2.fallbackSzTwips === void 0) state2.fallbackSzTwips = sizeTwips;
|
|
33391
|
+
const sizePt = sizeTwips / 2;
|
|
33392
|
+
if (allowOverrideSize || state2.fontSizePt === void 0) state2.fontSizePt = sizePt;
|
|
33393
|
+
}
|
|
33394
|
+
}
|
|
33395
|
+
const kernNode = runProps.elements.find((el) => el.name === "w:kern");
|
|
33396
|
+
if (kernNode?.attributes?.["w:val"]) {
|
|
33397
|
+
if (allowOverrideSize || state2.kern === void 0) state2.kern = kernNode.attributes["w:val"];
|
|
33398
|
+
}
|
|
33399
|
+
};
|
|
33127
33400
|
const _SuperConverter = class _SuperConverter2 {
|
|
33128
33401
|
constructor(params2 = null) {
|
|
33129
33402
|
__privateAdd$2(this, _SuperConverter_instances);
|
|
@@ -33251,49 +33524,45 @@ const _SuperConverter = class _SuperConverter2 {
|
|
|
33251
33524
|
}
|
|
33252
33525
|
getDocumentDefaultStyles() {
|
|
33253
33526
|
const styles = this.convertedXml["word/styles.xml"];
|
|
33254
|
-
|
|
33255
|
-
const
|
|
33256
|
-
|
|
33257
|
-
|
|
33258
|
-
const
|
|
33259
|
-
const
|
|
33260
|
-
|
|
33261
|
-
|
|
33262
|
-
|
|
33263
|
-
|
|
33264
|
-
|
|
33265
|
-
|
|
33266
|
-
|
|
33267
|
-
|
|
33268
|
-
|
|
33269
|
-
|
|
33270
|
-
|
|
33271
|
-
|
|
33272
|
-
|
|
33273
|
-
|
|
33274
|
-
|
|
33275
|
-
|
|
33276
|
-
|
|
33277
|
-
|
|
33278
|
-
|
|
33279
|
-
|
|
33280
|
-
|
|
33281
|
-
|
|
33282
|
-
|
|
33283
|
-
|
|
33284
|
-
|
|
33285
|
-
|
|
33286
|
-
|
|
33287
|
-
|
|
33288
|
-
|
|
33289
|
-
|
|
33290
|
-
|
|
33291
|
-
|
|
33292
|
-
|
|
33293
|
-
const kern = rElements.find((el) => el.name === "w:kern")?.attributes["w:val"];
|
|
33294
|
-
const fontFamilyCss = _SuperConverter2.toCssFontFamily(typeface, this.convertedXml);
|
|
33295
|
-
return { fontSizePt, kern, typeface, panose, fontFamilyCss };
|
|
33296
|
-
}
|
|
33527
|
+
const styleRoot = styles?.elements?.[0];
|
|
33528
|
+
const styleElements = styleRoot?.elements || [];
|
|
33529
|
+
if (!styleElements.length) return {};
|
|
33530
|
+
const defaults = styleElements.find((el) => el.name === "w:docDefaults");
|
|
33531
|
+
const normalStyle = styleElements.find((el) => el.name === "w:style" && el.attributes?.["w:styleId"] === "Normal");
|
|
33532
|
+
const defaultsState = {
|
|
33533
|
+
typeface: void 0,
|
|
33534
|
+
panose: void 0,
|
|
33535
|
+
fontSizePt: void 0,
|
|
33536
|
+
kern: void 0,
|
|
33537
|
+
fallbackSzTwips: void 0
|
|
33538
|
+
};
|
|
33539
|
+
const docDefaultRun = defaults?.elements?.find((el) => el.name === "w:rPrDefault");
|
|
33540
|
+
const docDefaultProps = docDefaultRun?.elements?.find((el) => el.name === "w:rPr") ?? docDefaultRun;
|
|
33541
|
+
collectRunDefaultProperties(docDefaultProps, {
|
|
33542
|
+
allowOverrideTypeface: true,
|
|
33543
|
+
allowOverrideSize: true,
|
|
33544
|
+
themeResolver: (theme) => this.getThemeInfo(theme),
|
|
33545
|
+
state: defaultsState
|
|
33546
|
+
});
|
|
33547
|
+
const normalRunProps = normalStyle?.elements?.find((el) => el.name === "w:rPr") ?? null;
|
|
33548
|
+
collectRunDefaultProperties(normalRunProps, {
|
|
33549
|
+
allowOverrideTypeface: true,
|
|
33550
|
+
allowOverrideSize: true,
|
|
33551
|
+
themeResolver: (theme) => this.getThemeInfo(theme),
|
|
33552
|
+
state: defaultsState
|
|
33553
|
+
});
|
|
33554
|
+
if (defaultsState.fontSizePt === void 0) {
|
|
33555
|
+
if (Number.isFinite(defaultsState.fallbackSzTwips)) defaultsState.fontSizePt = defaultsState.fallbackSzTwips / 2;
|
|
33556
|
+
else defaultsState.fontSizePt = DEFAULT_FONT_SIZE_PT;
|
|
33557
|
+
}
|
|
33558
|
+
const fontFamilyCss = defaultsState.typeface ? _SuperConverter2.toCssFontFamily(defaultsState.typeface, this.convertedXml) : void 0;
|
|
33559
|
+
const result = {};
|
|
33560
|
+
if (defaultsState.fontSizePt !== void 0) result.fontSizePt = defaultsState.fontSizePt;
|
|
33561
|
+
if (defaultsState.kern !== void 0) result.kern = defaultsState.kern;
|
|
33562
|
+
if (defaultsState.typeface) result.typeface = defaultsState.typeface;
|
|
33563
|
+
if (defaultsState.panose) result.panose = defaultsState.panose;
|
|
33564
|
+
if (fontFamilyCss) result.fontFamilyCss = fontFamilyCss;
|
|
33565
|
+
return result;
|
|
33297
33566
|
}
|
|
33298
33567
|
getDocumentFonts() {
|
|
33299
33568
|
const fontTable = this.convertedXml["word/fontTable.xml"];
|
|
@@ -36160,14 +36429,19 @@ class DocxZipper {
|
|
|
36160
36429
|
/**
|
|
36161
36430
|
* Update [Content_Types].xml with extensions of new Image annotations
|
|
36162
36431
|
*/
|
|
36163
|
-
async updateContentTypes(docx, media, fromJson) {
|
|
36432
|
+
async updateContentTypes(docx, media, fromJson, updatedDocs = {}) {
|
|
36433
|
+
const additionalPartNames = Object.keys(updatedDocs || {});
|
|
36164
36434
|
const newMediaTypes = Object.keys(media).map((name) => {
|
|
36165
36435
|
return this.getFileExtension(name);
|
|
36166
36436
|
}).filter(Boolean);
|
|
36167
36437
|
const contentTypesPath = "[Content_Types].xml";
|
|
36168
36438
|
let contentTypesXml;
|
|
36169
36439
|
if (fromJson) {
|
|
36170
|
-
|
|
36440
|
+
if (Array.isArray(docx.files)) {
|
|
36441
|
+
contentTypesXml = docx.files.find((file) => file.name === contentTypesPath)?.content || "";
|
|
36442
|
+
} else {
|
|
36443
|
+
contentTypesXml = docx.files?.[contentTypesPath] || "";
|
|
36444
|
+
}
|
|
36171
36445
|
} else contentTypesXml = await docx.file(contentTypesPath).async("string");
|
|
36172
36446
|
let typesString = "";
|
|
36173
36447
|
const defaultMediaTypes = getContentTypesFromXml(contentTypesXml);
|
|
@@ -36193,24 +36467,39 @@ class DocxZipper {
|
|
|
36193
36467
|
const hasCommentsExtensible = types2.elements?.some(
|
|
36194
36468
|
(el) => el.name === "Override" && el.attributes.PartName === "/word/commentsExtensible.xml"
|
|
36195
36469
|
);
|
|
36196
|
-
|
|
36470
|
+
const hasFile = (filename) => {
|
|
36471
|
+
if (!docx?.files) return false;
|
|
36472
|
+
if (!fromJson) return Boolean(docx.files[filename]);
|
|
36473
|
+
if (Array.isArray(docx.files)) return docx.files.some((file) => file.name === filename);
|
|
36474
|
+
return Boolean(docx.files[filename]);
|
|
36475
|
+
};
|
|
36476
|
+
if (hasFile("word/comments.xml")) {
|
|
36197
36477
|
const commentsDef = `<Override PartName="/word/comments.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.comments+xml" />`;
|
|
36198
36478
|
if (!hasComments) typesString += commentsDef;
|
|
36199
36479
|
}
|
|
36200
|
-
if (
|
|
36480
|
+
if (hasFile("word/commentsExtended.xml")) {
|
|
36201
36481
|
const commentsExtendedDef = `<Override PartName="/word/commentsExtended.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.commentsExtended+xml" />`;
|
|
36202
36482
|
if (!hasCommentsExtended) typesString += commentsExtendedDef;
|
|
36203
36483
|
}
|
|
36204
|
-
if (
|
|
36484
|
+
if (hasFile("word/commentsIds.xml")) {
|
|
36205
36485
|
const commentsIdsDef = `<Override PartName="/word/commentsIds.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.commentsIds+xml" />`;
|
|
36206
36486
|
if (!hasCommentsIds) typesString += commentsIdsDef;
|
|
36207
36487
|
}
|
|
36208
|
-
if (
|
|
36488
|
+
if (hasFile("word/commentsExtensible.xml")) {
|
|
36209
36489
|
const commentsExtendedDef = `<Override PartName="/word/commentsExtensible.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.commentsExtensible+xml" />`;
|
|
36210
36490
|
if (!hasCommentsExtensible) typesString += commentsExtendedDef;
|
|
36211
36491
|
}
|
|
36212
|
-
|
|
36213
|
-
|
|
36492
|
+
const partNames = new Set(additionalPartNames);
|
|
36493
|
+
if (docx?.files) {
|
|
36494
|
+
if (fromJson && Array.isArray(docx.files)) {
|
|
36495
|
+
docx.files.forEach((file) => partNames.add(file.name));
|
|
36496
|
+
} else {
|
|
36497
|
+
Object.keys(docx.files).forEach((key2) => partNames.add(key2));
|
|
36498
|
+
}
|
|
36499
|
+
}
|
|
36500
|
+
partNames.forEach((name) => {
|
|
36501
|
+
if (name.includes(".rels")) return;
|
|
36502
|
+
if (!name.includes("header") && !name.includes("footer")) return;
|
|
36214
36503
|
const hasExtensible = types2.elements?.some(
|
|
36215
36504
|
(el) => el.name === "Override" && el.attributes.PartName === `/${name}`
|
|
36216
36505
|
);
|
|
@@ -36221,7 +36510,48 @@ class DocxZipper {
|
|
|
36221
36510
|
}
|
|
36222
36511
|
});
|
|
36223
36512
|
const beginningString = '<Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types">';
|
|
36224
|
-
|
|
36513
|
+
let updatedContentTypesXml = contentTypesXml.replace(beginningString, `${beginningString}${typesString}`);
|
|
36514
|
+
let relationshipsXml = updatedDocs["word/_rels/document.xml.rels"];
|
|
36515
|
+
if (!relationshipsXml) {
|
|
36516
|
+
if (fromJson) {
|
|
36517
|
+
if (Array.isArray(docx.files)) {
|
|
36518
|
+
relationshipsXml = docx.files.find((file) => file.name === "word/_rels/document.xml.rels")?.content;
|
|
36519
|
+
} else {
|
|
36520
|
+
relationshipsXml = docx.files?.["word/_rels/document.xml.rels"];
|
|
36521
|
+
}
|
|
36522
|
+
} else {
|
|
36523
|
+
relationshipsXml = await docx.file("word/_rels/document.xml.rels")?.async("string");
|
|
36524
|
+
}
|
|
36525
|
+
}
|
|
36526
|
+
if (relationshipsXml) {
|
|
36527
|
+
try {
|
|
36528
|
+
const relJson = xmljs.xml2js(relationshipsXml, { compact: false });
|
|
36529
|
+
const relationships = relJson.elements?.find((el) => el.name === "Relationships");
|
|
36530
|
+
relationships?.elements?.forEach((rel) => {
|
|
36531
|
+
const type2 = rel.attributes?.Type;
|
|
36532
|
+
const target = rel.attributes?.Target;
|
|
36533
|
+
if (!type2 || !target) return;
|
|
36534
|
+
const isHeader = type2.includes("/header");
|
|
36535
|
+
const isFooter = type2.includes("/footer");
|
|
36536
|
+
if (!isHeader && !isFooter) return;
|
|
36537
|
+
let sanitizedTarget = target.replace(/^\.\//, "");
|
|
36538
|
+
if (sanitizedTarget.startsWith("../")) sanitizedTarget = sanitizedTarget.slice(3);
|
|
36539
|
+
if (sanitizedTarget.startsWith("/")) sanitizedTarget = sanitizedTarget.slice(1);
|
|
36540
|
+
const partName = sanitizedTarget.startsWith("word/") ? sanitizedTarget : `word/${sanitizedTarget}`;
|
|
36541
|
+
partNames.add(partName);
|
|
36542
|
+
});
|
|
36543
|
+
} catch (error) {
|
|
36544
|
+
console.warn("Failed to parse document relationships while updating content types", error);
|
|
36545
|
+
}
|
|
36546
|
+
}
|
|
36547
|
+
partNames.forEach((name) => {
|
|
36548
|
+
if (name.includes(".rels")) return;
|
|
36549
|
+
if (!name.includes("header") && !name.includes("footer")) return;
|
|
36550
|
+
if (updatedContentTypesXml.includes(`PartName="/${name}"`)) return;
|
|
36551
|
+
const type2 = name.includes("header") ? "header" : "footer";
|
|
36552
|
+
const extendedDef = `<Override PartName="/${name}" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.${type2}+xml"/>`;
|
|
36553
|
+
updatedContentTypesXml = updatedContentTypesXml.replace("</Types>", `${extendedDef}</Types>`);
|
|
36554
|
+
});
|
|
36225
36555
|
if (fromJson) return updatedContentTypesXml;
|
|
36226
36556
|
docx.file(contentTypesPath, updatedContentTypesXml);
|
|
36227
36557
|
}
|
|
@@ -36262,7 +36592,7 @@ class DocxZipper {
|
|
|
36262
36592
|
for (const [fontName, fontUintArray] of Object.entries(fonts)) {
|
|
36263
36593
|
zip.file(fontName, fontUintArray);
|
|
36264
36594
|
}
|
|
36265
|
-
await this.updateContentTypes(zip, media);
|
|
36595
|
+
await this.updateContentTypes(zip, media, false, updatedDocs);
|
|
36266
36596
|
return zip;
|
|
36267
36597
|
}
|
|
36268
36598
|
/**
|
|
@@ -36288,7 +36618,7 @@ class DocxZipper {
|
|
|
36288
36618
|
Object.keys(media).forEach((path) => {
|
|
36289
36619
|
unzippedOriginalDocx.file(path, media[path]);
|
|
36290
36620
|
});
|
|
36291
|
-
await this.updateContentTypes(unzippedOriginalDocx, media);
|
|
36621
|
+
await this.updateContentTypes(unzippedOriginalDocx, media, false, updatedDocs);
|
|
36292
36622
|
return unzippedOriginalDocx;
|
|
36293
36623
|
}
|
|
36294
36624
|
}
|
|
@@ -36303,7 +36633,7 @@ var __privateGet$1 = (obj, member, getter) => (__accessCheck$1(obj, member, "rea
|
|
|
36303
36633
|
var __privateAdd$1 = (obj, member, value) => member.has(obj) ? __typeError$1("Cannot add the same private member more than once") : member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
|
|
36304
36634
|
var __privateSet = (obj, member, value, setter) => (__accessCheck$1(obj, member, "write to private field"), member.set(obj, value), value);
|
|
36305
36635
|
var __privateMethod$1 = (obj, member, method) => (__accessCheck$1(obj, member, "access private method"), method);
|
|
36306
|
-
var _Attribute_static, getGlobalAttributes_fn, getNodeAndMarksAttributes_fn, _Schema_static, createNodesSchema_fn, createMarksSchema_fn, _events, _ExtensionService_instances, setupExtensions_fn, attachEditorEvents_fn, _editor, _stateValidators, _xmlValidators, _requiredNodeTypes, _requiredMarkTypes, _SuperValidator_instances, initializeValidators_fn, collectValidatorRequirements_fn, analyzeDocument_fn, _commandService, _Editor_instances, initContainerElement_fn, init_fn, initRichText_fn, onFocus_fn, checkHeadless_fn, registerCopyHandler_fn, insertNewFileData_fn, registerPluginByNameIfNotExists_fn, createExtensionService_fn, createCommandService_fn, createConverter_fn, initMedia_fn, initFonts_fn, createSchema_fn, generatePmData_fn, createView_fn, onCollaborationReady_fn, initComments_fn, initPagination_fn, dispatchTransaction_fn, handleNodeSelection_fn, prepareDocumentForImport_fn, prepareDocumentForExport_fn, endCollaboration_fn, validateDocumentInit_fn, validateDocumentExport_fn, initDevTools_fn,
|
|
36636
|
+
var _Attribute_static, getGlobalAttributes_fn, getNodeAndMarksAttributes_fn, _Schema_static, createNodesSchema_fn, createMarksSchema_fn, _events, _ExtensionService_instances, setupExtensions_fn, attachEditorEvents_fn, _editor, _stateValidators, _xmlValidators, _requiredNodeTypes, _requiredMarkTypes, _SuperValidator_instances, initializeValidators_fn, collectValidatorRequirements_fn, analyzeDocument_fn, _commandService, _Editor_instances, initContainerElement_fn, init_fn, initRichText_fn, onFocus_fn, checkHeadless_fn, registerCopyHandler_fn, insertNewFileData_fn, registerPluginByNameIfNotExists_fn, createExtensionService_fn, createCommandService_fn, createConverter_fn, initMedia_fn, initFonts_fn, createSchema_fn, generatePmData_fn, createView_fn, onCollaborationReady_fn, initComments_fn, initPagination_fn, dispatchTransaction_fn, handleNodeSelection_fn, prepareDocumentForImport_fn, prepareDocumentForExport_fn, endCollaboration_fn, validateDocumentInit_fn, validateDocumentExport_fn, initDevTools_fn, _DocumentSectionView_instances, init_fn2, addToolTip_fn, _ListItemNodeView_instances, init_fn3, _FieldAnnotationView_instances, createAnnotation_fn, _AutoPageNumberNodeView_instances, renderDom_fn, scheduleUpdateNodeStyle_fn;
|
|
36307
36637
|
var GOOD_LEAF_SIZE = 200;
|
|
36308
36638
|
var RopeSequence = function RopeSequence2() {
|
|
36309
36639
|
};
|
|
@@ -47946,9 +48276,11 @@ const toggleHeaderFooterEditMode = ({ editor, focusedSectionEditor, isEditMode,
|
|
|
47946
48276
|
item.editor.view.dom.setAttribute("documentmode", documentMode);
|
|
47947
48277
|
});
|
|
47948
48278
|
if (isEditMode) {
|
|
47949
|
-
const pm =
|
|
47950
|
-
pm
|
|
47951
|
-
|
|
48279
|
+
const pm = editor.view?.dom || editor.options.element?.querySelector?.(".ProseMirror");
|
|
48280
|
+
if (pm) {
|
|
48281
|
+
pm.classList.add("header-footer-edit");
|
|
48282
|
+
pm.setAttribute("aria-readonly", true);
|
|
48283
|
+
}
|
|
47952
48284
|
}
|
|
47953
48285
|
if (focusedSectionEditor) {
|
|
47954
48286
|
focusedSectionEditor.view.focus();
|
|
@@ -48376,28 +48708,25 @@ const handleTrackedChangeTransaction = (trackedChangeMeta, trackedChanges, newEd
|
|
|
48376
48708
|
if (emitParams) editor.emit("commentsUpdate", emitParams);
|
|
48377
48709
|
return newTrackedChanges;
|
|
48378
48710
|
};
|
|
48379
|
-
const getTrackedChangeText = ({ state: state2,
|
|
48711
|
+
const getTrackedChangeText = ({ state: state2, nodes, mark, marks, trackedChangeType, isDeletionInsertion }) => {
|
|
48380
48712
|
let trackedChangeText = "";
|
|
48381
48713
|
let deletionText = "";
|
|
48382
48714
|
if (trackedChangeType === TrackInsertMarkName) {
|
|
48383
|
-
trackedChangeText = node
|
|
48715
|
+
trackedChangeText = nodes.reduce((acc, node) => {
|
|
48716
|
+
if (!node.marks.find((nodeMark) => nodeMark.type.name === mark.type.name)) return acc;
|
|
48717
|
+
acc += node?.text || node?.textContent || "";
|
|
48718
|
+
return acc;
|
|
48719
|
+
}, "");
|
|
48384
48720
|
}
|
|
48385
48721
|
if (trackedChangeType === TrackFormatMarkName) {
|
|
48386
48722
|
trackedChangeText = translateFormatChangesToEnglish(mark.attrs);
|
|
48387
48723
|
}
|
|
48388
48724
|
if (trackedChangeType === TrackDeleteMarkName || isDeletionInsertion) {
|
|
48389
|
-
deletionText = node
|
|
48390
|
-
|
|
48391
|
-
|
|
48392
|
-
|
|
48393
|
-
|
|
48394
|
-
const changeMarks = marks2.filter((mark2) => TRACK_CHANGE_MARKS.includes(mark2.type.name));
|
|
48395
|
-
if (!changeMarks.length) return false;
|
|
48396
|
-
const hasMatchingId = changeMarks.find((mark2) => mark2.attrs.id === id);
|
|
48397
|
-
if (hasMatchingId) return true;
|
|
48398
|
-
});
|
|
48399
|
-
deletionText = deletionNode?.node.text ?? "";
|
|
48400
|
-
}
|
|
48725
|
+
deletionText = nodes.reduce((acc, node) => {
|
|
48726
|
+
if (!node.marks.find((nodeMark) => nodeMark.type.name === TrackDeleteMarkName)) return acc;
|
|
48727
|
+
acc += node?.text || node?.textContent || "";
|
|
48728
|
+
return acc;
|
|
48729
|
+
}, "");
|
|
48401
48730
|
}
|
|
48402
48731
|
return {
|
|
48403
48732
|
deletionText,
|
|
@@ -48412,18 +48741,17 @@ const createOrUpdateTrackedChangeComment = ({ event, marks, deletionNodes, nodes
|
|
|
48412
48741
|
const id = attrs.id;
|
|
48413
48742
|
const node = nodes[0];
|
|
48414
48743
|
const isDeletionInsertion = !!(marks.insertedMark && marks.deletionMark);
|
|
48415
|
-
let
|
|
48744
|
+
let nodesWithMark = [];
|
|
48416
48745
|
newEditorState.doc.descendants((node2) => {
|
|
48417
48746
|
const { marks: marks2 = [] } = node2;
|
|
48418
48747
|
const changeMarks = marks2.filter((mark) => TRACK_CHANGE_MARKS.includes(mark.type.name));
|
|
48419
48748
|
if (!changeMarks.length) return;
|
|
48420
48749
|
const hasMatchingId = changeMarks.find((mark) => mark.attrs.id === id);
|
|
48421
|
-
if (hasMatchingId)
|
|
48422
|
-
if (existingNode) return false;
|
|
48750
|
+
if (hasMatchingId) nodesWithMark.push(node2);
|
|
48423
48751
|
});
|
|
48424
48752
|
const { deletionText, trackedChangeText } = getTrackedChangeText({
|
|
48425
48753
|
state: newEditorState,
|
|
48426
|
-
|
|
48754
|
+
nodes: nodesWithMark.length ? nodesWithMark : [node],
|
|
48427
48755
|
mark: trackedMark,
|
|
48428
48756
|
marks,
|
|
48429
48757
|
trackedChangeType,
|
|
@@ -48453,14 +48781,6 @@ const createOrUpdateTrackedChangeComment = ({ event, marks, deletionNodes, nodes
|
|
|
48453
48781
|
else if (event === "update") params2.event = comments_module_events.UPDATE;
|
|
48454
48782
|
return params2;
|
|
48455
48783
|
};
|
|
48456
|
-
function findNode$1(node, predicate) {
|
|
48457
|
-
let found2 = null;
|
|
48458
|
-
node.descendants((node2, pos) => {
|
|
48459
|
-
if (predicate(node2)) found2 = { node: node2, pos };
|
|
48460
|
-
if (found2) return false;
|
|
48461
|
-
});
|
|
48462
|
-
return found2;
|
|
48463
|
-
}
|
|
48464
48784
|
function findRangeById(doc2, id) {
|
|
48465
48785
|
let from2 = null, to = null;
|
|
48466
48786
|
doc2.descendants((node, pos) => {
|
|
@@ -48978,6 +49298,7 @@ const generateTableIfNecessary = ({ tableNode, annotationValues, tr, state: stat
|
|
|
48978
49298
|
const mappedRowStart = tr.mapping.map(absoluteRowStart);
|
|
48979
49299
|
const rowEnd = mappedRowStart + rowNode.nodeSize;
|
|
48980
49300
|
tr.replaceWith(mappedRowStart, rowEnd, Fragment.from(newRows));
|
|
49301
|
+
tr.setMeta("tableGeneration", true);
|
|
48981
49302
|
} catch (error) {
|
|
48982
49303
|
console.error("Error during row generation:", error);
|
|
48983
49304
|
throw error;
|
|
@@ -49382,7 +49703,7 @@ function findFieldAnnotationsBetween(from2, to, doc2) {
|
|
|
49382
49703
|
}
|
|
49383
49704
|
function findRemovedFieldAnnotations(tr) {
|
|
49384
49705
|
let removedNodes = [];
|
|
49385
|
-
if (!tr.steps.length || tr.meta && !Object.keys(tr.meta).every((meta) => ["inputType", "uiEvent", "paste"].includes(meta)) || ["historyUndo", "historyRedo"].includes(tr.getMeta("inputType")) || ["drop"].includes(tr.getMeta("uiEvent")) || tr.getMeta("fieldAnnotationUpdate") === true) {
|
|
49706
|
+
if (!tr.steps.length || tr.meta && !Object.keys(tr.meta).every((meta) => ["inputType", "uiEvent", "paste"].includes(meta)) || ["historyUndo", "historyRedo"].includes(tr.getMeta("inputType")) || ["drop"].includes(tr.getMeta("uiEvent")) || tr.getMeta("fieldAnnotationUpdate") === true || tr.getMeta("tableGeneration") === true) {
|
|
49386
49707
|
return removedNodes;
|
|
49387
49708
|
}
|
|
49388
49709
|
const hasDeletion = transactionDeletedAnything(tr);
|
|
@@ -50560,7 +50881,7 @@ const _Editor = class _Editor2 extends EventEmitter$1 {
|
|
|
50560
50881
|
setDocumentMode(documentMode) {
|
|
50561
50882
|
let cleanedMode = documentMode?.toLowerCase() || "editing";
|
|
50562
50883
|
if (!this.extensionService || !this.state) return;
|
|
50563
|
-
const pm =
|
|
50884
|
+
const pm = this.view?.dom || this.options.element?.querySelector?.(".ProseMirror");
|
|
50564
50885
|
if (this.options.role === "viewer") cleanedMode = "viewing";
|
|
50565
50886
|
if (this.options.role === "suggester" && cleanedMode === "editing") cleanedMode = "suggesting";
|
|
50566
50887
|
if (cleanedMode === "viewing") {
|
|
@@ -51048,7 +51369,8 @@ const _Editor = class _Editor2 extends EventEmitter$1 {
|
|
|
51048
51369
|
files: this.options.content
|
|
51049
51370
|
},
|
|
51050
51371
|
media,
|
|
51051
|
-
true
|
|
51372
|
+
true,
|
|
51373
|
+
updatedDocs
|
|
51052
51374
|
);
|
|
51053
51375
|
return updatedDocs;
|
|
51054
51376
|
}
|
|
@@ -51534,9 +51856,11 @@ createView_fn = function(element) {
|
|
|
51534
51856
|
isEditMode: false,
|
|
51535
51857
|
documentMode: this.options.documentMode
|
|
51536
51858
|
});
|
|
51537
|
-
const pm =
|
|
51538
|
-
pm
|
|
51539
|
-
|
|
51859
|
+
const pm = this.view?.dom || this.options.element?.querySelector?.(".ProseMirror");
|
|
51860
|
+
if (pm) {
|
|
51861
|
+
pm.classList.remove("header-footer-edit");
|
|
51862
|
+
pm.setAttribute("aria-readonly", false);
|
|
51863
|
+
}
|
|
51540
51864
|
}
|
|
51541
51865
|
setWordSelection(view, pos);
|
|
51542
51866
|
}
|
|
@@ -53084,522 +53408,1536 @@ const SlashMenu = Extension.create({
|
|
|
53084
53408
|
return this.editor.options.isHeadless ? [] : [slashMenuPlugin];
|
|
53085
53409
|
}
|
|
53086
53410
|
});
|
|
53087
|
-
|
|
53088
|
-
|
|
53089
|
-
|
|
53090
|
-
|
|
53091
|
-
|
|
53092
|
-
|
|
53093
|
-
|
|
53094
|
-
|
|
53095
|
-
|
|
53096
|
-
|
|
53097
|
-
|
|
53098
|
-
|
|
53099
|
-
|
|
53100
|
-
|
|
53101
|
-
|
|
53102
|
-
|
|
53103
|
-
|
|
53104
|
-
|
|
53105
|
-
|
|
53106
|
-
|
|
53107
|
-
|
|
53108
|
-
|
|
53109
|
-
|
|
53110
|
-
|
|
53111
|
-
|
|
53112
|
-
|
|
53113
|
-
|
|
53114
|
-
|
|
53115
|
-
|
|
53116
|
-
|
|
53117
|
-
|
|
53118
|
-
|
|
53119
|
-
|
|
53120
|
-
|
|
53121
|
-
|
|
53122
|
-
|
|
53123
|
-
|
|
53124
|
-
|
|
53125
|
-
|
|
53126
|
-
|
|
53127
|
-
|
|
53128
|
-
|
|
53129
|
-
|
|
53130
|
-
|
|
53131
|
-
|
|
53132
|
-
|
|
53133
|
-
|
|
53134
|
-
|
|
53135
|
-
|
|
53411
|
+
class StructuredContentViewBase {
|
|
53412
|
+
constructor(props) {
|
|
53413
|
+
__publicField$1(this, "node");
|
|
53414
|
+
__publicField$1(this, "view");
|
|
53415
|
+
__publicField$1(this, "getPos");
|
|
53416
|
+
__publicField$1(this, "decorations");
|
|
53417
|
+
__publicField$1(this, "innerDecorations");
|
|
53418
|
+
__publicField$1(this, "editor");
|
|
53419
|
+
__publicField$1(this, "extension");
|
|
53420
|
+
__publicField$1(this, "htmlAttributes");
|
|
53421
|
+
__publicField$1(this, "root");
|
|
53422
|
+
__publicField$1(this, "isDragging", false);
|
|
53423
|
+
this.node = props.node;
|
|
53424
|
+
this.view = props.editor.view;
|
|
53425
|
+
this.getPos = props.getPos;
|
|
53426
|
+
this.decorations = props.decorations;
|
|
53427
|
+
this.innerDecorations = props.innerDecorations;
|
|
53428
|
+
this.editor = props.editor;
|
|
53429
|
+
this.extension = props.extension;
|
|
53430
|
+
this.htmlAttributes = props.htmlAttributes;
|
|
53431
|
+
this.mount(props);
|
|
53432
|
+
}
|
|
53433
|
+
mount() {
|
|
53434
|
+
return;
|
|
53435
|
+
}
|
|
53436
|
+
get dom() {
|
|
53437
|
+
return this.root;
|
|
53438
|
+
}
|
|
53439
|
+
get contentDOM() {
|
|
53440
|
+
return null;
|
|
53441
|
+
}
|
|
53442
|
+
update(node, decorations, innerDecorations) {
|
|
53443
|
+
if (node.type !== this.node.type) {
|
|
53444
|
+
return false;
|
|
53445
|
+
}
|
|
53446
|
+
this.node = node;
|
|
53447
|
+
this.decorations = decorations;
|
|
53448
|
+
this.innerDecorations = innerDecorations;
|
|
53449
|
+
this.updateHTMLAttributes();
|
|
53450
|
+
return true;
|
|
53451
|
+
}
|
|
53452
|
+
stopEvent(event) {
|
|
53453
|
+
if (!this.dom) return false;
|
|
53454
|
+
const target = event.target;
|
|
53455
|
+
const isInElement = this.dom.contains(target) && !this.contentDOM?.contains(target);
|
|
53456
|
+
if (!isInElement) return false;
|
|
53457
|
+
const isDragEvent = event.type.startsWith("drag");
|
|
53458
|
+
const isDropEvent = event.type === "drop";
|
|
53459
|
+
const isInput = ["INPUT", "BUTTON", "SELECT", "TEXTAREA"].includes(target.tagName) || target.isContentEditable;
|
|
53460
|
+
if (isInput && !isDropEvent && !isDragEvent) return true;
|
|
53461
|
+
const { isEditable } = this.editor;
|
|
53462
|
+
const { isDragging } = this;
|
|
53463
|
+
const isDraggable = !!this.node.type.spec.draggable;
|
|
53464
|
+
const isSelectable = NodeSelection.isSelectable(this.node);
|
|
53465
|
+
const isCopyEvent = event.type === "copy";
|
|
53466
|
+
const isPasteEvent = event.type === "paste";
|
|
53467
|
+
const isCutEvent = event.type === "cut";
|
|
53468
|
+
const isClickEvent = event.type === "mousedown";
|
|
53469
|
+
if (!isDraggable && isSelectable && isDragEvent && event.target === this.dom) {
|
|
53470
|
+
event.preventDefault();
|
|
53471
|
+
}
|
|
53472
|
+
if (isDraggable && isDragEvent && !isDragging && event.target === this.dom) {
|
|
53473
|
+
event.preventDefault();
|
|
53474
|
+
return false;
|
|
53475
|
+
}
|
|
53476
|
+
if (isDraggable && isEditable && !isDragging && isClickEvent) {
|
|
53477
|
+
const dragHandle = target.closest("[data-drag-handle]");
|
|
53478
|
+
const isValidDragHandle = dragHandle && (this.dom === dragHandle || this.dom.contains(dragHandle));
|
|
53479
|
+
if (isValidDragHandle) {
|
|
53480
|
+
this.isDragging = true;
|
|
53481
|
+
document.addEventListener(
|
|
53482
|
+
"dragend",
|
|
53483
|
+
() => {
|
|
53484
|
+
this.isDragging = false;
|
|
53485
|
+
},
|
|
53486
|
+
{ once: true }
|
|
53487
|
+
);
|
|
53488
|
+
document.addEventListener(
|
|
53489
|
+
"drop",
|
|
53490
|
+
() => {
|
|
53491
|
+
this.isDragging = false;
|
|
53492
|
+
},
|
|
53493
|
+
{ once: true }
|
|
53494
|
+
);
|
|
53495
|
+
document.addEventListener(
|
|
53496
|
+
"mouseup",
|
|
53497
|
+
() => {
|
|
53498
|
+
this.isDragging = false;
|
|
53499
|
+
},
|
|
53500
|
+
{ once: true }
|
|
53501
|
+
);
|
|
53136
53502
|
}
|
|
53137
|
-
}
|
|
53503
|
+
}
|
|
53504
|
+
if (isDragging || isDropEvent || isCopyEvent || isPasteEvent || isCutEvent || isClickEvent && isSelectable) {
|
|
53505
|
+
return false;
|
|
53506
|
+
}
|
|
53507
|
+
return true;
|
|
53138
53508
|
}
|
|
53139
|
-
|
|
53140
|
-
|
|
53141
|
-
|
|
53142
|
-
|
|
53143
|
-
|
|
53144
|
-
|
|
53145
|
-
return
|
|
53509
|
+
ignoreMutation(mutation) {
|
|
53510
|
+
if (!this.dom || !this.contentDOM) return true;
|
|
53511
|
+
if (this.node.isLeaf || this.node.isAtom) return true;
|
|
53512
|
+
if (mutation.type === "selection") return false;
|
|
53513
|
+
if (this.contentDOM === mutation.target && mutation.type === "attributes") return true;
|
|
53514
|
+
if (this.contentDOM.contains(mutation.target)) return false;
|
|
53515
|
+
return true;
|
|
53146
53516
|
}
|
|
53147
|
-
|
|
53148
|
-
|
|
53149
|
-
|
|
53150
|
-
|
|
53151
|
-
|
|
53152
|
-
|
|
53153
|
-
|
|
53517
|
+
destroy() {
|
|
53518
|
+
this.dom.remove();
|
|
53519
|
+
this.contentDOM?.remove();
|
|
53520
|
+
}
|
|
53521
|
+
updateAttributes(attrs) {
|
|
53522
|
+
const pos = this.getPos();
|
|
53523
|
+
if (typeof pos !== "number") {
|
|
53524
|
+
return;
|
|
53525
|
+
}
|
|
53526
|
+
return this.view.dispatch(
|
|
53527
|
+
this.view.state.tr.setNodeMarkup(pos, void 0, {
|
|
53528
|
+
...this.node.attrs,
|
|
53529
|
+
...attrs
|
|
53530
|
+
})
|
|
53531
|
+
);
|
|
53532
|
+
}
|
|
53533
|
+
updateHTMLAttributes() {
|
|
53534
|
+
const { extensionService } = this.editor;
|
|
53535
|
+
const { attributes } = extensionService;
|
|
53536
|
+
const extensionAttrs = attributes.filter((i) => i.type === this.node.type.name);
|
|
53537
|
+
this.htmlAttributes = Attribute2.getAttributesToRender(this.node, extensionAttrs);
|
|
53538
|
+
}
|
|
53539
|
+
createDragHandle() {
|
|
53540
|
+
const dragHandle = document.createElement("span");
|
|
53541
|
+
dragHandle.classList.add("sd-structured-content-draggable");
|
|
53542
|
+
dragHandle.draggable = true;
|
|
53543
|
+
dragHandle.contentEditable = "false";
|
|
53544
|
+
dragHandle.dataset.dragHandle = "";
|
|
53545
|
+
const textElement = document.createElement("span");
|
|
53546
|
+
textElement.textContent = this.node.attrs.alias || "Structured content";
|
|
53547
|
+
dragHandle.append(textElement);
|
|
53548
|
+
return dragHandle;
|
|
53549
|
+
}
|
|
53550
|
+
onDragStart(event) {
|
|
53551
|
+
const { view } = this.editor;
|
|
53552
|
+
const target = event.target;
|
|
53553
|
+
const dragHandle = target.nodeType === 3 ? target.parentElement?.closest("[data-drag-handle]") : target.closest("[data-drag-handle]");
|
|
53554
|
+
if (!this.dom || this.contentDOM?.contains(target) || !dragHandle) {
|
|
53555
|
+
return;
|
|
53556
|
+
}
|
|
53557
|
+
let x = 0;
|
|
53558
|
+
let y2 = 0;
|
|
53559
|
+
if (this.dom !== dragHandle) {
|
|
53560
|
+
const domBox = this.dom.getBoundingClientRect();
|
|
53561
|
+
const handleBox = dragHandle.getBoundingClientRect();
|
|
53562
|
+
const offsetX = event.offsetX ?? event.nativeEvent?.offsetX;
|
|
53563
|
+
const offsetY = event.offsetY ?? event.nativeEvent?.offsetY;
|
|
53564
|
+
x = handleBox.x - domBox.x + offsetX;
|
|
53565
|
+
y2 = handleBox.y - domBox.y + offsetY;
|
|
53566
|
+
}
|
|
53567
|
+
event.dataTransfer?.setDragImage(this.dom, x, y2);
|
|
53568
|
+
const pos = this.getPos();
|
|
53569
|
+
if (typeof pos !== "number") {
|
|
53570
|
+
return;
|
|
53571
|
+
}
|
|
53572
|
+
const selection = NodeSelection.create(view.state.doc, pos);
|
|
53573
|
+
const transaction = view.state.tr.setSelection(selection);
|
|
53154
53574
|
view.dispatch(transaction);
|
|
53155
|
-
});
|
|
53156
|
-
if (handled) {
|
|
53157
|
-
tr.setMeta("preventDispatch", true);
|
|
53158
53575
|
}
|
|
53159
|
-
|
|
53160
|
-
|
|
53161
|
-
|
|
53162
|
-
|
|
53163
|
-
|
|
53164
|
-
|
|
53576
|
+
}
|
|
53577
|
+
class StructuredContentInlineView extends StructuredContentViewBase {
|
|
53578
|
+
constructor(props) {
|
|
53579
|
+
super(props);
|
|
53580
|
+
}
|
|
53581
|
+
mount() {
|
|
53582
|
+
this.buildView();
|
|
53583
|
+
}
|
|
53584
|
+
get contentDOM() {
|
|
53585
|
+
const contentElement = this.dom?.querySelector(`.${structuredContentInnerClass$1}`);
|
|
53586
|
+
return contentElement || null;
|
|
53587
|
+
}
|
|
53588
|
+
createElement() {
|
|
53589
|
+
const element = document.createElement("span");
|
|
53590
|
+
element.classList.add(structuredContentClass$1);
|
|
53591
|
+
element.setAttribute("data-structured-content", "");
|
|
53592
|
+
const contentElement = document.createElement("span");
|
|
53593
|
+
contentElement.classList.add(structuredContentInnerClass$1);
|
|
53594
|
+
element.append(contentElement);
|
|
53595
|
+
const domAttrs = Attribute2.mergeAttributes(this.htmlAttributes);
|
|
53596
|
+
updateDOMAttributes(element, { ...domAttrs });
|
|
53597
|
+
return { element, contentElement };
|
|
53598
|
+
}
|
|
53599
|
+
buildView() {
|
|
53600
|
+
const { element } = this.createElement();
|
|
53601
|
+
const dragHandle = this.createDragHandle();
|
|
53602
|
+
element.prepend(dragHandle);
|
|
53603
|
+
element.addEventListener("dragstart", (e) => this.onDragStart(e));
|
|
53604
|
+
this.root = element;
|
|
53605
|
+
}
|
|
53606
|
+
updateView() {
|
|
53607
|
+
const domAttrs = Attribute2.mergeAttributes(this.htmlAttributes);
|
|
53608
|
+
updateDOMAttributes(this.dom, { ...domAttrs });
|
|
53609
|
+
}
|
|
53610
|
+
update(node, decorations, innerDecorations) {
|
|
53611
|
+
const result = super.update(node, decorations, innerDecorations);
|
|
53612
|
+
if (!result) return false;
|
|
53613
|
+
this.updateView();
|
|
53614
|
+
return true;
|
|
53615
|
+
}
|
|
53616
|
+
}
|
|
53617
|
+
const structuredContentClass$1 = "sd-structured-content";
|
|
53618
|
+
const structuredContentInnerClass$1 = "sd-structured-content__content";
|
|
53619
|
+
const StructuredContent = Node$1.create({
|
|
53620
|
+
name: "structuredContent",
|
|
53621
|
+
group: "inline structuredContent",
|
|
53165
53622
|
inline: true,
|
|
53166
53623
|
content: "inline*",
|
|
53167
|
-
|
|
53168
|
-
|
|
53624
|
+
isolating: true,
|
|
53625
|
+
atom: false,
|
|
53626
|
+
// false - has editable content.
|
|
53627
|
+
draggable: true,
|
|
53169
53628
|
addOptions() {
|
|
53170
53629
|
return {
|
|
53171
53630
|
htmlAttributes: {
|
|
53172
|
-
|
|
53631
|
+
class: structuredContentClass$1,
|
|
53632
|
+
"aria-label": "Structured content node"
|
|
53173
53633
|
}
|
|
53174
53634
|
};
|
|
53175
53635
|
},
|
|
53176
53636
|
addAttributes() {
|
|
53177
53637
|
return {
|
|
53178
|
-
|
|
53638
|
+
id: {
|
|
53179
53639
|
default: null,
|
|
53180
|
-
|
|
53181
|
-
|
|
53640
|
+
parseDOM: (elem) => elem.getAttribute("data-id"),
|
|
53641
|
+
renderDOM: (attrs) => {
|
|
53642
|
+
if (!attrs.id) return {};
|
|
53643
|
+
return { "data-id": attrs.id };
|
|
53644
|
+
}
|
|
53182
53645
|
},
|
|
53183
|
-
|
|
53646
|
+
tag: {
|
|
53184
53647
|
default: null,
|
|
53185
|
-
|
|
53186
|
-
|
|
53648
|
+
parseDOM: (elem) => elem.getAttribute("data-tag"),
|
|
53649
|
+
renderDOM: (attrs) => {
|
|
53650
|
+
if (!attrs.tag) return {};
|
|
53651
|
+
return { "data-tag": attrs.tag };
|
|
53652
|
+
}
|
|
53187
53653
|
},
|
|
53188
|
-
|
|
53654
|
+
alias: {
|
|
53189
53655
|
default: null,
|
|
53190
|
-
|
|
53191
|
-
|
|
53656
|
+
parseDOM: (elem) => elem.getAttribute("data-alias"),
|
|
53657
|
+
renderDOM: (attrs) => {
|
|
53658
|
+
if (!attrs.alias) return {};
|
|
53659
|
+
return { "data-alias": attrs.alias };
|
|
53660
|
+
}
|
|
53192
53661
|
},
|
|
53193
|
-
|
|
53194
|
-
|
|
53195
|
-
rendered: false,
|
|
53196
|
-
keepOnSplit: true
|
|
53662
|
+
sdtPr: {
|
|
53663
|
+
rendered: false
|
|
53197
53664
|
}
|
|
53198
53665
|
};
|
|
53199
53666
|
},
|
|
53200
|
-
addCommands() {
|
|
53201
|
-
return {
|
|
53202
|
-
splitRun
|
|
53203
|
-
};
|
|
53204
|
-
},
|
|
53205
53667
|
parseDOM() {
|
|
53206
|
-
return [{ tag: "span[data-
|
|
53668
|
+
return [{ tag: "span[data-structured-content]" }];
|
|
53207
53669
|
},
|
|
53208
53670
|
renderDOM({ htmlAttributes }) {
|
|
53209
|
-
|
|
53210
|
-
|
|
53211
|
-
|
|
53212
|
-
|
|
53213
|
-
|
|
53214
|
-
|
|
53215
|
-
|
|
53216
|
-
group: "block list",
|
|
53217
|
-
selectable: false,
|
|
53218
|
-
content() {
|
|
53219
|
-
return `${this.options.itemTypeName}+`;
|
|
53671
|
+
return [
|
|
53672
|
+
"span",
|
|
53673
|
+
Attribute2.mergeAttributes(this.options.htmlAttributes, htmlAttributes, {
|
|
53674
|
+
"data-structured-content": ""
|
|
53675
|
+
}),
|
|
53676
|
+
0
|
|
53677
|
+
];
|
|
53220
53678
|
},
|
|
53221
|
-
|
|
53222
|
-
return {
|
|
53223
|
-
|
|
53224
|
-
htmlAttributes: {
|
|
53225
|
-
"aria-label": "Bullet list node"
|
|
53226
|
-
},
|
|
53227
|
-
keepMarks: true,
|
|
53228
|
-
keepAttributes: false
|
|
53679
|
+
addNodeView() {
|
|
53680
|
+
return (props) => {
|
|
53681
|
+
return new StructuredContentInlineView({ ...props });
|
|
53229
53682
|
};
|
|
53230
|
-
},
|
|
53231
|
-
parseDOM() {
|
|
53232
|
-
return [{ tag: "ul" }];
|
|
53233
|
-
},
|
|
53234
|
-
renderDOM({ htmlAttributes }) {
|
|
53235
|
-
const attributes = Attribute2.mergeAttributes(this.options.htmlAttributes, htmlAttributes);
|
|
53236
|
-
return ["ul", attributes, 0];
|
|
53237
|
-
},
|
|
53238
|
-
addAttributes() {
|
|
53239
|
-
return {
|
|
53240
|
-
"list-style-type": {
|
|
53241
|
-
default: "bullet",
|
|
53242
|
-
rendered: false
|
|
53243
|
-
},
|
|
53244
|
-
listId: {
|
|
53245
|
-
rendered: false
|
|
53246
|
-
},
|
|
53247
|
-
sdBlockId: {
|
|
53248
|
-
default: null,
|
|
53249
|
-
keepOnSplit: false,
|
|
53250
|
-
parseDOM: (elem) => elem.getAttribute("data-sd-block-id"),
|
|
53251
|
-
renderDOM: (attrs) => {
|
|
53252
|
-
return attrs.sdBlockId ? { "data-sd-block-id": attrs.sdBlockId } : {};
|
|
53253
|
-
}
|
|
53254
|
-
},
|
|
53255
|
-
attributes: {
|
|
53256
|
-
rendered: false,
|
|
53257
|
-
keepOnSplit: true
|
|
53258
|
-
}
|
|
53259
|
-
};
|
|
53260
|
-
},
|
|
53261
|
-
addCommands() {
|
|
53262
|
-
return {
|
|
53263
|
-
/**
|
|
53264
|
-
* Toggle a bullet list at the current selection
|
|
53265
|
-
* @category Command
|
|
53266
|
-
* @example
|
|
53267
|
-
* // Toggle bullet list on selected text
|
|
53268
|
-
* editor.commands.toggleBulletList()
|
|
53269
|
-
* @note Converts selected paragraphs to list items or removes list formatting
|
|
53270
|
-
*/
|
|
53271
|
-
toggleBulletList: () => (params2) => {
|
|
53272
|
-
return toggleList(this.type)(params2);
|
|
53273
|
-
}
|
|
53274
|
-
};
|
|
53275
|
-
},
|
|
53276
|
-
addShortcuts() {
|
|
53277
|
-
return {
|
|
53278
|
-
"Mod-Shift-8": () => {
|
|
53279
|
-
return this.editor.commands.toggleBulletList();
|
|
53280
|
-
}
|
|
53281
|
-
};
|
|
53282
|
-
},
|
|
53283
|
-
addInputRules() {
|
|
53284
|
-
return [
|
|
53285
|
-
new InputRule({
|
|
53286
|
-
match: inputRegex$1,
|
|
53287
|
-
handler: ({ state: state2, range: range2 }) => {
|
|
53288
|
-
const $pos = state2.selection.$from;
|
|
53289
|
-
const listItemType = state2.schema.nodes.listItem;
|
|
53290
|
-
for (let depth = $pos.depth; depth >= 0; depth--) {
|
|
53291
|
-
if ($pos.node(depth).type === listItemType) {
|
|
53292
|
-
return null;
|
|
53293
|
-
}
|
|
53294
|
-
}
|
|
53295
|
-
const { tr } = state2;
|
|
53296
|
-
tr.delete(range2.from, range2.to);
|
|
53297
|
-
ListHelpers.createNewList({
|
|
53298
|
-
listType: this.type,
|
|
53299
|
-
tr,
|
|
53300
|
-
editor: this.editor
|
|
53301
|
-
});
|
|
53302
|
-
}
|
|
53303
|
-
})
|
|
53304
|
-
];
|
|
53305
53683
|
}
|
|
53306
53684
|
});
|
|
53307
|
-
|
|
53308
|
-
|
|
53309
|
-
|
|
53310
|
-
|
|
53311
|
-
|
|
53312
|
-
|
|
53313
|
-
|
|
53314
|
-
|
|
53685
|
+
class StructuredContentBlockView extends StructuredContentViewBase {
|
|
53686
|
+
constructor(props) {
|
|
53687
|
+
super(props);
|
|
53688
|
+
}
|
|
53689
|
+
mount() {
|
|
53690
|
+
this.buildView();
|
|
53691
|
+
}
|
|
53692
|
+
get contentDOM() {
|
|
53693
|
+
const contentElement = this.dom?.querySelector(`.${structuredContentInnerClass}`);
|
|
53694
|
+
return contentElement || null;
|
|
53695
|
+
}
|
|
53696
|
+
createElement() {
|
|
53697
|
+
const element = document.createElement("div");
|
|
53698
|
+
element.classList.add(structuredContentClass);
|
|
53699
|
+
element.setAttribute("data-structured-content-block", "");
|
|
53700
|
+
const contentElement = document.createElement("div");
|
|
53701
|
+
contentElement.classList.add(structuredContentInnerClass);
|
|
53702
|
+
element.append(contentElement);
|
|
53703
|
+
const domAttrs = Attribute2.mergeAttributes(this.htmlAttributes);
|
|
53704
|
+
updateDOMAttributes(element, { ...domAttrs });
|
|
53705
|
+
return { element, contentElement };
|
|
53706
|
+
}
|
|
53707
|
+
buildView() {
|
|
53708
|
+
const { element } = this.createElement();
|
|
53709
|
+
const dragHandle = this.createDragHandle();
|
|
53710
|
+
element.prepend(dragHandle);
|
|
53711
|
+
element.addEventListener("dragstart", (e) => this.onDragStart(e));
|
|
53712
|
+
this.root = element;
|
|
53713
|
+
}
|
|
53714
|
+
updateView() {
|
|
53715
|
+
const domAttrs = Attribute2.mergeAttributes(this.htmlAttributes);
|
|
53716
|
+
updateDOMAttributes(this.dom, { ...domAttrs });
|
|
53717
|
+
}
|
|
53718
|
+
update(node, decorations, innerDecorations) {
|
|
53719
|
+
const result = super.update(node, decorations, innerDecorations);
|
|
53720
|
+
if (!result) return false;
|
|
53721
|
+
this.updateView();
|
|
53722
|
+
return true;
|
|
53723
|
+
}
|
|
53724
|
+
}
|
|
53725
|
+
const structuredContentClass = "sd-structured-content-block";
|
|
53726
|
+
const structuredContentInnerClass = "sd-structured-content-block__content";
|
|
53727
|
+
const StructuredContentBlock = Node$1.create({
|
|
53728
|
+
name: "structuredContentBlock",
|
|
53729
|
+
group: "block structuredContent",
|
|
53730
|
+
content: "block*",
|
|
53731
|
+
isolating: true,
|
|
53732
|
+
atom: false,
|
|
53733
|
+
// false - has editable content.
|
|
53734
|
+
draggable: true,
|
|
53315
53735
|
addOptions() {
|
|
53316
53736
|
return {
|
|
53317
|
-
itemTypeName: "listItem",
|
|
53318
53737
|
htmlAttributes: {
|
|
53319
|
-
|
|
53320
|
-
|
|
53321
|
-
|
|
53322
|
-
keepAttributes: false,
|
|
53323
|
-
listStyleTypes: ["decimal", "lowerAlpha", "lowerRoman"]
|
|
53738
|
+
class: structuredContentClass,
|
|
53739
|
+
"aria-label": "Structured content block node"
|
|
53740
|
+
}
|
|
53324
53741
|
};
|
|
53325
53742
|
},
|
|
53326
53743
|
addAttributes() {
|
|
53327
53744
|
return {
|
|
53328
|
-
|
|
53329
|
-
default: 1,
|
|
53330
|
-
parseDOM: (element) => {
|
|
53331
|
-
return element.hasAttribute("start") ? parseInt(element.getAttribute("start") || "", 10) : 1;
|
|
53332
|
-
},
|
|
53333
|
-
renderDOM: (attrs) => {
|
|
53334
|
-
return {
|
|
53335
|
-
start: attrs.order
|
|
53336
|
-
};
|
|
53337
|
-
}
|
|
53338
|
-
},
|
|
53339
|
-
sdBlockId: {
|
|
53745
|
+
id: {
|
|
53340
53746
|
default: null,
|
|
53341
|
-
|
|
53342
|
-
parseDOM: (elem) => elem.getAttribute("data-sd-block-id"),
|
|
53747
|
+
parseDOM: (elem) => elem.getAttribute("data-id"),
|
|
53343
53748
|
renderDOM: (attrs) => {
|
|
53344
|
-
|
|
53749
|
+
if (!attrs.id) return {};
|
|
53750
|
+
return { "data-id": attrs.id };
|
|
53345
53751
|
}
|
|
53346
53752
|
},
|
|
53347
|
-
|
|
53753
|
+
tag: {
|
|
53348
53754
|
default: null,
|
|
53349
|
-
parseDOM: (elem) => elem.getAttribute("data-
|
|
53755
|
+
parseDOM: (elem) => elem.getAttribute("data-tag"),
|
|
53350
53756
|
renderDOM: (attrs) => {
|
|
53351
|
-
if (!attrs.
|
|
53352
|
-
return {
|
|
53353
|
-
"data-sync-id": attrs.syncId
|
|
53354
|
-
};
|
|
53757
|
+
if (!attrs.tag) return {};
|
|
53758
|
+
return { "data-tag": attrs.tag };
|
|
53355
53759
|
}
|
|
53356
|
-
// rendered: false,
|
|
53357
53760
|
},
|
|
53358
|
-
|
|
53359
|
-
|
|
53360
|
-
parseDOM: (elem) => elem.getAttribute("data-
|
|
53761
|
+
alias: {
|
|
53762
|
+
default: null,
|
|
53763
|
+
parseDOM: (elem) => elem.getAttribute("data-alias"),
|
|
53361
53764
|
renderDOM: (attrs) => {
|
|
53362
|
-
if (!attrs.
|
|
53363
|
-
return {
|
|
53364
|
-
"data-list-id": attrs.listId
|
|
53365
|
-
};
|
|
53765
|
+
if (!attrs.alias) return {};
|
|
53766
|
+
return { "data-alias": attrs.alias };
|
|
53366
53767
|
}
|
|
53367
53768
|
},
|
|
53368
|
-
|
|
53369
|
-
default: "decimal",
|
|
53769
|
+
sdtPr: {
|
|
53370
53770
|
rendered: false
|
|
53371
|
-
},
|
|
53372
|
-
attributes: {
|
|
53373
|
-
rendered: false,
|
|
53374
|
-
keepOnSplit: true
|
|
53375
53771
|
}
|
|
53376
53772
|
};
|
|
53377
53773
|
},
|
|
53378
53774
|
parseDOM() {
|
|
53379
|
-
return [{ tag: "
|
|
53775
|
+
return [{ tag: "div[data-structured-content-block]" }];
|
|
53380
53776
|
},
|
|
53381
53777
|
renderDOM({ htmlAttributes }) {
|
|
53382
|
-
|
|
53383
|
-
|
|
53778
|
+
return [
|
|
53779
|
+
"div",
|
|
53780
|
+
Attribute2.mergeAttributes(this.options.htmlAttributes, htmlAttributes, {
|
|
53781
|
+
"data-structured-content-block": ""
|
|
53782
|
+
}),
|
|
53783
|
+
0
|
|
53784
|
+
];
|
|
53384
53785
|
},
|
|
53786
|
+
addNodeView() {
|
|
53787
|
+
return (props) => {
|
|
53788
|
+
return new StructuredContentBlockView({ ...props });
|
|
53789
|
+
};
|
|
53790
|
+
}
|
|
53791
|
+
});
|
|
53792
|
+
function getStructuredContentTagsById(idOrIds, state2) {
|
|
53793
|
+
const result = findChildren$5(state2.doc, (node) => {
|
|
53794
|
+
const isStructuredContent = ["structuredContent", "structuredContentBlock"].includes(node.type.name);
|
|
53795
|
+
if (Array.isArray(idOrIds)) {
|
|
53796
|
+
return isStructuredContent && idOrIds.includes(node.attrs.id);
|
|
53797
|
+
} else {
|
|
53798
|
+
return isStructuredContent && node.attrs.id === idOrIds;
|
|
53799
|
+
}
|
|
53800
|
+
});
|
|
53801
|
+
return result;
|
|
53802
|
+
}
|
|
53803
|
+
function getStructuredContentTags(state2) {
|
|
53804
|
+
const result = findChildren$5(state2.doc, (node) => {
|
|
53805
|
+
return node.type.name === "structuredContent" || node.type.name === "structuredContentBlock";
|
|
53806
|
+
});
|
|
53807
|
+
return result;
|
|
53808
|
+
}
|
|
53809
|
+
function getStructuredContentInlineTags(state2) {
|
|
53810
|
+
const result = findChildren$5(state2.doc, (node) => node.type.name === "structuredContent");
|
|
53811
|
+
return result;
|
|
53812
|
+
}
|
|
53813
|
+
function getStructuredContentBlockTags(state2) {
|
|
53814
|
+
const result = findChildren$5(state2.doc, (node) => node.type.name === "structuredContentBlock");
|
|
53815
|
+
return result;
|
|
53816
|
+
}
|
|
53817
|
+
const structuredContentHelpers = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
53818
|
+
__proto__: null,
|
|
53819
|
+
getStructuredContentBlockTags,
|
|
53820
|
+
getStructuredContentInlineTags,
|
|
53821
|
+
getStructuredContentTags,
|
|
53822
|
+
getStructuredContentTagsById
|
|
53823
|
+
}, Symbol.toStringTag, { value: "Module" }));
|
|
53824
|
+
const STRUCTURED_CONTENT_NAMES = ["structuredContent", "structuredContentBlock"];
|
|
53825
|
+
const StructuredContentCommands = Extension.create({
|
|
53826
|
+
name: "structuredContentCommands",
|
|
53385
53827
|
addCommands() {
|
|
53386
53828
|
return {
|
|
53387
53829
|
/**
|
|
53388
|
-
*
|
|
53830
|
+
* Inserts a structured content inline at selection.
|
|
53389
53831
|
* @category Command
|
|
53390
|
-
* @
|
|
53391
|
-
* editor.commands.toggleOrderedList()
|
|
53392
|
-
* @note Converts selection to ordered list or back to paragraphs
|
|
53832
|
+
* @param {StructuredContentInlineInsert} options
|
|
53393
53833
|
*/
|
|
53394
|
-
|
|
53395
|
-
|
|
53834
|
+
insertStructuredContentInline: (options = {}) => ({ editor, dispatch, state: state2, tr }) => {
|
|
53835
|
+
const { schema } = editor;
|
|
53836
|
+
let { from: from2, to } = state2.selection;
|
|
53837
|
+
if (dispatch) {
|
|
53838
|
+
const selectionText = state2.doc.textBetween(from2, to);
|
|
53839
|
+
let content = null;
|
|
53840
|
+
if (selectionText) {
|
|
53841
|
+
content = schema.text(selectionText);
|
|
53842
|
+
}
|
|
53843
|
+
if (options.text) {
|
|
53844
|
+
content = schema.text(options.text);
|
|
53845
|
+
}
|
|
53846
|
+
if (options.json) {
|
|
53847
|
+
content = schema.nodeFromJSON(options.json);
|
|
53848
|
+
}
|
|
53849
|
+
if (!content) {
|
|
53850
|
+
content = schema.text(" ");
|
|
53851
|
+
}
|
|
53852
|
+
const attrs = {
|
|
53853
|
+
...options.attrs,
|
|
53854
|
+
id: options.attrs?.id || randomId(),
|
|
53855
|
+
tag: "inline_text_sdt",
|
|
53856
|
+
alias: options.attrs?.alias || "Structured content"
|
|
53857
|
+
};
|
|
53858
|
+
const node = schema.nodes.structuredContent.create(attrs, content, null);
|
|
53859
|
+
const parent = findParentNode((node2) => node2.type.name === "structuredContent")(state2.selection);
|
|
53860
|
+
if (parent) {
|
|
53861
|
+
const insertPos = parent.pos + parent.node.nodeSize;
|
|
53862
|
+
from2 = to = insertPos;
|
|
53863
|
+
}
|
|
53864
|
+
tr.replaceWith(from2, to, node);
|
|
53865
|
+
}
|
|
53866
|
+
return true;
|
|
53396
53867
|
},
|
|
53397
53868
|
/**
|
|
53398
|
-
*
|
|
53869
|
+
* Inserts a structured content block at selection.
|
|
53399
53870
|
* @category Command
|
|
53400
|
-
* @param {
|
|
53401
|
-
* @param {number} pos - Starting position
|
|
53402
|
-
* @example
|
|
53403
|
-
* editor.commands.restartListNodes(nodes, position)
|
|
53404
|
-
* @note Resets list numbering for specified nodes
|
|
53871
|
+
* @param {StructuredContentBlockInsert} options
|
|
53405
53872
|
*/
|
|
53406
|
-
|
|
53407
|
-
|
|
53408
|
-
|
|
53409
|
-
|
|
53410
|
-
|
|
53411
|
-
|
|
53873
|
+
insertStructuredContentBlock: (options = {}) => ({ editor, dispatch, state: state2, tr }) => {
|
|
53874
|
+
const { schema } = editor;
|
|
53875
|
+
let { from: from2, to } = state2.selection;
|
|
53876
|
+
if (dispatch) {
|
|
53877
|
+
const selectionContent = state2.selection.content();
|
|
53878
|
+
let content = null;
|
|
53879
|
+
if (selectionContent.size) {
|
|
53880
|
+
content = selectionContent.content;
|
|
53881
|
+
}
|
|
53882
|
+
if (options.html) {
|
|
53883
|
+
const html = htmlHandler(options.html, editor);
|
|
53884
|
+
const doc2 = DOMParser$1.fromSchema(schema).parse(html);
|
|
53885
|
+
content = doc2.content;
|
|
53886
|
+
}
|
|
53887
|
+
if (options.json) {
|
|
53888
|
+
content = schema.nodeFromJSON(options.json);
|
|
53889
|
+
}
|
|
53890
|
+
if (!content) {
|
|
53891
|
+
content = schema.nodeFromJSON({ type: "paragraph", content: [] });
|
|
53892
|
+
}
|
|
53893
|
+
const attrs = {
|
|
53894
|
+
...options.attrs,
|
|
53895
|
+
id: options.attrs?.id || randomId(),
|
|
53896
|
+
tag: "block_table_sdt",
|
|
53897
|
+
alias: options.attrs?.alias || "Structured content"
|
|
53412
53898
|
};
|
|
53413
|
-
|
|
53414
|
-
|
|
53415
|
-
|
|
53416
|
-
|
|
53417
|
-
|
|
53418
|
-
|
|
53419
|
-
tr.
|
|
53420
|
-
}
|
|
53899
|
+
const node = schema.nodes.structuredContentBlock.create(attrs, content, null);
|
|
53900
|
+
const parent = findParentNode((node2) => node2.type.name === "structuredContentBlock")(state2.selection);
|
|
53901
|
+
if (parent) {
|
|
53902
|
+
const insertPos = parent.pos + parent.node.nodeSize;
|
|
53903
|
+
from2 = to = insertPos;
|
|
53904
|
+
}
|
|
53905
|
+
tr.replaceRangeWith(from2, to, node);
|
|
53906
|
+
}
|
|
53421
53907
|
return true;
|
|
53422
53908
|
},
|
|
53423
53909
|
/**
|
|
53424
|
-
*
|
|
53910
|
+
* Updates a structured content attributes or content.
|
|
53911
|
+
* If the updated node does not match the schema, it will not be updated.
|
|
53425
53912
|
* @category Command
|
|
53426
|
-
* @
|
|
53427
|
-
*
|
|
53428
|
-
* @note Cycles through decimal -> lowerAlpha -> lowerRoman based on depth
|
|
53913
|
+
* @param {string} id
|
|
53914
|
+
* @param {StructuredContentUpdate} options
|
|
53429
53915
|
*/
|
|
53430
|
-
|
|
53431
|
-
|
|
53432
|
-
if (!
|
|
53916
|
+
updateStructuredContentById: (id, options = {}) => ({ editor, dispatch, state: state2, tr }) => {
|
|
53917
|
+
const structuredContentTags = getStructuredContentTagsById(id, state2);
|
|
53918
|
+
if (!structuredContentTags.length) {
|
|
53433
53919
|
return true;
|
|
53434
53920
|
}
|
|
53921
|
+
const { schema } = editor;
|
|
53435
53922
|
if (dispatch) {
|
|
53436
|
-
|
|
53437
|
-
|
|
53438
|
-
|
|
53439
|
-
|
|
53440
|
-
let
|
|
53441
|
-
if (
|
|
53442
|
-
|
|
53443
|
-
|
|
53444
|
-
|
|
53445
|
-
|
|
53446
|
-
|
|
53447
|
-
|
|
53923
|
+
const structuredContent = structuredContentTags[0];
|
|
53924
|
+
const { pos, node } = structuredContent;
|
|
53925
|
+
const posFrom = pos;
|
|
53926
|
+
const posTo = pos + node.nodeSize;
|
|
53927
|
+
let content = null;
|
|
53928
|
+
if (options.text) {
|
|
53929
|
+
content = schema.text(options.text);
|
|
53930
|
+
}
|
|
53931
|
+
if (options.html) {
|
|
53932
|
+
const html = htmlHandler(options.html, editor);
|
|
53933
|
+
const doc2 = DOMParser$1.fromSchema(schema).parse(html);
|
|
53934
|
+
content = doc2.content;
|
|
53935
|
+
}
|
|
53936
|
+
if (options.json) {
|
|
53937
|
+
content = schema.nodeFromJSON(options.json);
|
|
53448
53938
|
}
|
|
53939
|
+
if (!content) {
|
|
53940
|
+
content = node.content;
|
|
53941
|
+
}
|
|
53942
|
+
const updatedNode = node.type.create({ ...node.attrs, ...options.attrs }, content, node.marks);
|
|
53943
|
+
try {
|
|
53944
|
+
updatedNode.check();
|
|
53945
|
+
} catch {
|
|
53946
|
+
console.error("Updated node does not conform to the schema");
|
|
53947
|
+
return false;
|
|
53948
|
+
}
|
|
53949
|
+
tr.replaceWith(posFrom, posTo, updatedNode);
|
|
53950
|
+
}
|
|
53951
|
+
return true;
|
|
53952
|
+
},
|
|
53953
|
+
/**
|
|
53954
|
+
* Removes a structured content.
|
|
53955
|
+
* @category Command
|
|
53956
|
+
* @param {Array<{ node: Node, pos: number }>} structuredContentTags
|
|
53957
|
+
*/
|
|
53958
|
+
deleteStructuredContent: (structuredContentTags) => ({ dispatch, tr }) => {
|
|
53959
|
+
if (!structuredContentTags.length) {
|
|
53960
|
+
return true;
|
|
53961
|
+
}
|
|
53962
|
+
if (dispatch) {
|
|
53963
|
+
structuredContentTags.forEach((structuredContent) => {
|
|
53964
|
+
const { pos, node } = structuredContent;
|
|
53965
|
+
const posFrom = tr.mapping.map(pos);
|
|
53966
|
+
const posTo = tr.mapping.map(pos + node.nodeSize);
|
|
53967
|
+
const currentNode = tr.doc.nodeAt(posFrom);
|
|
53968
|
+
if (currentNode && node.eq(currentNode)) {
|
|
53969
|
+
tr.delete(posFrom, posTo);
|
|
53970
|
+
}
|
|
53971
|
+
});
|
|
53972
|
+
}
|
|
53973
|
+
return true;
|
|
53974
|
+
},
|
|
53975
|
+
/**
|
|
53976
|
+
* Removes a structured content by ID.
|
|
53977
|
+
* @category Command
|
|
53978
|
+
* @param {string | string[]} idOrIds
|
|
53979
|
+
*/
|
|
53980
|
+
deleteStructuredContentById: (idOrIds) => ({ dispatch, state: state2, tr }) => {
|
|
53981
|
+
const structuredContentTags = getStructuredContentTagsById(idOrIds, state2);
|
|
53982
|
+
if (!structuredContentTags.length) {
|
|
53983
|
+
return true;
|
|
53984
|
+
}
|
|
53985
|
+
if (dispatch) {
|
|
53986
|
+
structuredContentTags.forEach((structuredContent) => {
|
|
53987
|
+
const { pos, node } = structuredContent;
|
|
53988
|
+
const posFrom = tr.mapping.map(pos);
|
|
53989
|
+
const posTo = tr.mapping.map(pos + node.nodeSize);
|
|
53990
|
+
const currentNode = tr.doc.nodeAt(posFrom);
|
|
53991
|
+
if (currentNode && node.eq(currentNode)) {
|
|
53992
|
+
tr.delete(posFrom, posTo);
|
|
53993
|
+
}
|
|
53994
|
+
});
|
|
53995
|
+
}
|
|
53996
|
+
return true;
|
|
53997
|
+
},
|
|
53998
|
+
/**
|
|
53999
|
+
* Removes a structured content at cursor, preserving its content.
|
|
54000
|
+
* @category Command
|
|
54001
|
+
*/
|
|
54002
|
+
deleteStructuredContentAtSelection: () => ({ editor, dispatch, state: state2, tr }) => {
|
|
54003
|
+
const predicate = (node) => STRUCTURED_CONTENT_NAMES.includes(node.type.name);
|
|
54004
|
+
const structuredContent = findParentNode(predicate)(state2.selection);
|
|
54005
|
+
if (!structuredContent) {
|
|
54006
|
+
return true;
|
|
54007
|
+
}
|
|
54008
|
+
if (dispatch) {
|
|
54009
|
+
const { node, pos } = structuredContent;
|
|
54010
|
+
const posFrom = pos;
|
|
54011
|
+
const posTo = posFrom + node.nodeSize;
|
|
54012
|
+
const content = node.content;
|
|
54013
|
+
tr.replaceWith(posFrom, posTo, content);
|
|
53449
54014
|
}
|
|
53450
54015
|
return true;
|
|
53451
54016
|
}
|
|
53452
54017
|
};
|
|
53453
54018
|
},
|
|
53454
|
-
|
|
54019
|
+
addHelpers() {
|
|
53455
54020
|
return {
|
|
53456
|
-
|
|
53457
|
-
return this.editor.commands.toggleOrderedList();
|
|
53458
|
-
}
|
|
54021
|
+
...structuredContentHelpers
|
|
53459
54022
|
};
|
|
53460
|
-
},
|
|
53461
|
-
addInputRules() {
|
|
53462
|
-
return [
|
|
53463
|
-
new InputRule({
|
|
53464
|
-
match: inputRegex,
|
|
53465
|
-
handler: ({ state: state2, range: range2 }) => {
|
|
53466
|
-
const $pos = state2.selection.$from;
|
|
53467
|
-
const listItemType = state2.schema.nodes.listItem;
|
|
53468
|
-
for (let depth = $pos.depth; depth >= 0; depth--) {
|
|
53469
|
-
if ($pos.node(depth).type === listItemType) {
|
|
53470
|
-
return null;
|
|
53471
|
-
}
|
|
53472
|
-
}
|
|
53473
|
-
const { tr } = state2;
|
|
53474
|
-
tr.delete(range2.from, range2.to);
|
|
53475
|
-
ListHelpers.createNewList({
|
|
53476
|
-
listType: this.type,
|
|
53477
|
-
tr,
|
|
53478
|
-
editor: this.editor
|
|
53479
|
-
});
|
|
53480
|
-
}
|
|
53481
|
-
})
|
|
53482
|
-
];
|
|
53483
54023
|
}
|
|
53484
54024
|
});
|
|
53485
|
-
const
|
|
53486
|
-
|
|
53487
|
-
return handler2 ? handler2(listLevel, lvlText, customFormat) : null;
|
|
53488
|
-
};
|
|
53489
|
-
const handleDecimal = (path, lvlText) => generateNumbering(path, lvlText, String);
|
|
53490
|
-
const handleRoman = (path, lvlText) => generateNumbering(path, lvlText, intToRoman);
|
|
53491
|
-
const handleLowerRoman = (path, lvlText) => handleRoman(path, lvlText).toLowerCase();
|
|
53492
|
-
const handleLowerAlpha = (path, lvlText) => handleAlpha(path, lvlText).toLowerCase();
|
|
53493
|
-
const handleAlpha = (path, lvlText) => generateNumbering(path, lvlText, (p) => intToAlpha(p));
|
|
53494
|
-
const handleOrdinal = (path, lvlText) => generateNumbering(path, lvlText, ordinalFormatter);
|
|
53495
|
-
const handleCustom = (path, lvlText, customFormat) => generateFromCustom(path, lvlText, customFormat);
|
|
53496
|
-
const handleJapaneseCounting = (path, lvlText) => generateNumbering(path, lvlText, intToJapaneseCounting);
|
|
53497
|
-
const listIndexMap = {
|
|
53498
|
-
decimal: handleDecimal,
|
|
53499
|
-
lowerRoman: handleLowerRoman,
|
|
53500
|
-
upperRoman: handleRoman,
|
|
53501
|
-
lowerLetter: handleLowerAlpha,
|
|
53502
|
-
upperLetter: handleAlpha,
|
|
53503
|
-
ordinal: handleOrdinal,
|
|
53504
|
-
custom: handleCustom,
|
|
53505
|
-
japaneseCounting: handleJapaneseCounting
|
|
53506
|
-
};
|
|
53507
|
-
const createNumbering = (values, lvlText) => {
|
|
53508
|
-
return values.reduce((acc, value, index2) => {
|
|
53509
|
-
return value > 9 ? acc.replace(/^0/, "").replace(`%${index2 + 1}`, value) : acc.replace(`%${index2 + 1}`, value);
|
|
53510
|
-
}, lvlText);
|
|
53511
|
-
};
|
|
53512
|
-
const generateNumbering = (path, lvlText, formatter) => {
|
|
53513
|
-
const formattedValues = path.map(formatter);
|
|
53514
|
-
return createNumbering(formattedValues, lvlText);
|
|
54025
|
+
const randomId = () => {
|
|
54026
|
+
return Math.floor(Math.random() * 4294967295).toString();
|
|
53515
54027
|
};
|
|
53516
|
-
|
|
53517
|
-
|
|
53518
|
-
|
|
53519
|
-
|
|
53520
|
-
|
|
53521
|
-
|
|
54028
|
+
class DocumentSectionView {
|
|
54029
|
+
constructor(node, getPos, decorations, editor) {
|
|
54030
|
+
__privateAdd$1(this, _DocumentSectionView_instances);
|
|
54031
|
+
this.node = node;
|
|
54032
|
+
this.editor = editor;
|
|
54033
|
+
this.decorations = decorations;
|
|
54034
|
+
this.view = editor.view;
|
|
54035
|
+
this.getPos = getPos;
|
|
54036
|
+
__privateMethod$1(this, _DocumentSectionView_instances, init_fn2).call(this);
|
|
54037
|
+
}
|
|
54038
|
+
}
|
|
54039
|
+
_DocumentSectionView_instances = /* @__PURE__ */ new WeakSet();
|
|
54040
|
+
init_fn2 = function() {
|
|
54041
|
+
const { attrs } = this.node;
|
|
54042
|
+
const { id, title, description } = attrs;
|
|
54043
|
+
this.dom = document.createElement("div");
|
|
54044
|
+
this.dom.className = "sd-document-section-block";
|
|
54045
|
+
this.dom.setAttribute("data-id", id);
|
|
54046
|
+
this.dom.setAttribute("data-title", title);
|
|
54047
|
+
this.dom.setAttribute("data-description", description);
|
|
54048
|
+
this.dom.setAttribute("aria-label", "Document section");
|
|
54049
|
+
__privateMethod$1(this, _DocumentSectionView_instances, addToolTip_fn).call(this);
|
|
54050
|
+
this.contentDOM = document.createElement("div");
|
|
54051
|
+
this.contentDOM.className = "sd-document-section-block-content";
|
|
54052
|
+
this.contentDOM.setAttribute("contenteditable", "true");
|
|
54053
|
+
this.dom.appendChild(this.contentDOM);
|
|
53522
54054
|
};
|
|
53523
|
-
|
|
53524
|
-
|
|
53525
|
-
|
|
53526
|
-
|
|
53527
|
-
const
|
|
53528
|
-
|
|
53529
|
-
|
|
53530
|
-
|
|
54055
|
+
addToolTip_fn = function() {
|
|
54056
|
+
const { title } = this.node.attrs;
|
|
54057
|
+
this.infoDiv = document.createElement("div");
|
|
54058
|
+
this.infoDiv.className = "sd-document-section-block-info";
|
|
54059
|
+
const textSpan = document.createElement("span");
|
|
54060
|
+
textSpan.textContent = title || "Document section";
|
|
54061
|
+
this.infoDiv.appendChild(textSpan);
|
|
54062
|
+
this.infoDiv.setAttribute("contenteditable", "false");
|
|
54063
|
+
this.dom.appendChild(this.infoDiv);
|
|
53531
54064
|
};
|
|
53532
|
-
const
|
|
53533
|
-
|
|
53534
|
-
|
|
53535
|
-
|
|
53536
|
-
|
|
53537
|
-
|
|
53538
|
-
|
|
53539
|
-
|
|
53540
|
-
|
|
53541
|
-
{ value: 40, numeral: "XL" },
|
|
53542
|
-
{ value: 10, numeral: "X" },
|
|
53543
|
-
{ value: 9, numeral: "IX" },
|
|
53544
|
-
{ value: 5, numeral: "V" },
|
|
53545
|
-
{ value: 4, numeral: "IV" },
|
|
53546
|
-
{ value: 1, numeral: "I" }
|
|
53547
|
-
];
|
|
53548
|
-
let result = "";
|
|
53549
|
-
for (const { value, numeral } of romanNumeralMap) {
|
|
53550
|
-
while (num >= value) {
|
|
53551
|
-
result += numeral;
|
|
53552
|
-
num -= value;
|
|
54065
|
+
const getAllSections = (editor) => {
|
|
54066
|
+
if (!editor) return [];
|
|
54067
|
+
const type2 = editor.schema.nodes.documentSection;
|
|
54068
|
+
if (!type2) return [];
|
|
54069
|
+
const sections = [];
|
|
54070
|
+
const { state: state2 } = editor;
|
|
54071
|
+
state2.doc.descendants((node, pos) => {
|
|
54072
|
+
if (node.type.name === type2.name) {
|
|
54073
|
+
sections.push({ node, pos });
|
|
53553
54074
|
}
|
|
53554
|
-
}
|
|
53555
|
-
return
|
|
54075
|
+
});
|
|
54076
|
+
return sections;
|
|
53556
54077
|
};
|
|
53557
|
-
const
|
|
53558
|
-
|
|
53559
|
-
const
|
|
53560
|
-
|
|
53561
|
-
|
|
53562
|
-
|
|
53563
|
-
|
|
53564
|
-
|
|
54078
|
+
const exportSectionsToHTML = (editor) => {
|
|
54079
|
+
const sections = getAllSections(editor);
|
|
54080
|
+
const processedSections = /* @__PURE__ */ new Set();
|
|
54081
|
+
const result = [];
|
|
54082
|
+
sections.forEach(({ node }) => {
|
|
54083
|
+
const { attrs } = node;
|
|
54084
|
+
const { id, title, description } = attrs;
|
|
54085
|
+
if (processedSections.has(id)) return;
|
|
54086
|
+
processedSections.add(id);
|
|
54087
|
+
const html = getHTMLFromNode(node, editor);
|
|
54088
|
+
result.push({
|
|
54089
|
+
id,
|
|
54090
|
+
title,
|
|
54091
|
+
description,
|
|
54092
|
+
html
|
|
54093
|
+
});
|
|
54094
|
+
});
|
|
53565
54095
|
return result;
|
|
53566
54096
|
};
|
|
53567
|
-
const
|
|
53568
|
-
const
|
|
53569
|
-
const
|
|
53570
|
-
|
|
53571
|
-
|
|
53572
|
-
let
|
|
53573
|
-
|
|
53574
|
-
|
|
53575
|
-
|
|
53576
|
-
|
|
53577
|
-
|
|
53578
|
-
|
|
53579
|
-
|
|
53580
|
-
|
|
53581
|
-
|
|
53582
|
-
|
|
53583
|
-
|
|
53584
|
-
|
|
53585
|
-
|
|
53586
|
-
|
|
53587
|
-
|
|
53588
|
-
|
|
53589
|
-
|
|
53590
|
-
|
|
53591
|
-
}
|
|
54097
|
+
const getHTMLFromNode = (node, editor) => {
|
|
54098
|
+
const tempDocument = document.implementation.createHTMLDocument();
|
|
54099
|
+
const container = tempDocument.createElement("div");
|
|
54100
|
+
const fragment = DOMSerializer.fromSchema(editor.schema).serializeFragment(node.content);
|
|
54101
|
+
container.appendChild(fragment);
|
|
54102
|
+
let html = container.innerHTML;
|
|
54103
|
+
return html;
|
|
54104
|
+
};
|
|
54105
|
+
const exportSectionsToJSON = (editor) => {
|
|
54106
|
+
const sections = getAllSections(editor);
|
|
54107
|
+
const processedSections = /* @__PURE__ */ new Set();
|
|
54108
|
+
const result = [];
|
|
54109
|
+
sections.forEach(({ node }) => {
|
|
54110
|
+
const { attrs } = node;
|
|
54111
|
+
const { id, title, description } = attrs;
|
|
54112
|
+
if (processedSections.has(id)) return;
|
|
54113
|
+
processedSections.add(id);
|
|
54114
|
+
result.push({
|
|
54115
|
+
id,
|
|
54116
|
+
title,
|
|
54117
|
+
description,
|
|
54118
|
+
content: node.toJSON()
|
|
54119
|
+
});
|
|
54120
|
+
});
|
|
53592
54121
|
return result;
|
|
53593
54122
|
};
|
|
53594
|
-
const
|
|
53595
|
-
const
|
|
53596
|
-
|
|
53597
|
-
if (
|
|
53598
|
-
|
|
53599
|
-
|
|
53600
|
-
|
|
53601
|
-
|
|
54123
|
+
const getLinkedSectionEditor = (id, options, editor) => {
|
|
54124
|
+
const sections = getAllSections(editor);
|
|
54125
|
+
const section = sections.find((s) => s.node.attrs.id === id);
|
|
54126
|
+
if (!section) return null;
|
|
54127
|
+
const child = editor.createChildEditor({
|
|
54128
|
+
...options,
|
|
54129
|
+
onUpdate: ({ editor: childEditor, transaction }) => {
|
|
54130
|
+
const isFromtLinkedParent = transaction.getMeta("fromLinkedParent");
|
|
54131
|
+
if (isFromtLinkedParent) return;
|
|
54132
|
+
const updatedContent = childEditor.state.doc.content;
|
|
54133
|
+
const sectionNode = getAllSections(editor)?.find((s) => s.node.attrs.id === id);
|
|
54134
|
+
if (!sectionNode) return;
|
|
54135
|
+
const { pos, node } = sectionNode;
|
|
54136
|
+
const newNode = node.type.create(node.attrs, updatedContent, node.marks);
|
|
54137
|
+
const tr = editor.state.tr.replaceWith(pos, pos + node.nodeSize, newNode);
|
|
54138
|
+
tr.setMeta("fromLinkedChild", true);
|
|
54139
|
+
editor.view.dispatch(tr);
|
|
54140
|
+
}
|
|
54141
|
+
});
|
|
54142
|
+
editor.on("update", ({ transaction }) => {
|
|
54143
|
+
const isFromLinkedChild = transaction.getMeta("fromLinkedChild");
|
|
54144
|
+
if (isFromLinkedChild) return;
|
|
54145
|
+
const sectionNode = getAllSections(editor)?.find((s) => s.node.attrs.id === id);
|
|
54146
|
+
if (!sectionNode) return;
|
|
54147
|
+
const sectionContent = sectionNode.node.content;
|
|
54148
|
+
const json = {
|
|
54149
|
+
type: "doc",
|
|
54150
|
+
content: sectionContent.content.map((node) => node.toJSON())
|
|
54151
|
+
};
|
|
54152
|
+
const childTr = child.state.tr;
|
|
54153
|
+
childTr.setMeta("fromLinkedParent", true);
|
|
54154
|
+
childTr.replaceWith(0, child.state.doc.content.size, child.schema.nodeFromJSON(json));
|
|
54155
|
+
child.view.dispatch(childTr);
|
|
54156
|
+
});
|
|
54157
|
+
return child;
|
|
54158
|
+
};
|
|
54159
|
+
const SectionHelpers = {
|
|
54160
|
+
getAllSections,
|
|
54161
|
+
exportSectionsToHTML,
|
|
54162
|
+
exportSectionsToJSON,
|
|
54163
|
+
getLinkedSectionEditor
|
|
54164
|
+
};
|
|
54165
|
+
const DocumentSection = Node$1.create({
|
|
54166
|
+
name: "documentSection",
|
|
54167
|
+
group: "block",
|
|
54168
|
+
content: "block*",
|
|
54169
|
+
atom: true,
|
|
54170
|
+
isolating: true,
|
|
54171
|
+
addOptions() {
|
|
54172
|
+
return {
|
|
54173
|
+
htmlAttributes: {
|
|
54174
|
+
class: "sd-document-section-block",
|
|
54175
|
+
"aria-label": "Structured content block"
|
|
54176
|
+
}
|
|
54177
|
+
};
|
|
54178
|
+
},
|
|
54179
|
+
parseDOM() {
|
|
54180
|
+
return [
|
|
54181
|
+
{
|
|
54182
|
+
tag: "div.sd-document-section-block",
|
|
54183
|
+
priority: 60
|
|
54184
|
+
}
|
|
54185
|
+
];
|
|
54186
|
+
},
|
|
54187
|
+
renderDOM({ htmlAttributes }) {
|
|
54188
|
+
return ["div", Attribute2.mergeAttributes(this.options.htmlAttributes, htmlAttributes), 0];
|
|
54189
|
+
},
|
|
54190
|
+
addAttributes() {
|
|
54191
|
+
return {
|
|
54192
|
+
id: {},
|
|
54193
|
+
sdBlockId: {
|
|
54194
|
+
default: null,
|
|
54195
|
+
keepOnSplit: false,
|
|
54196
|
+
parseDOM: (elem) => elem.getAttribute("data-sd-block-id"),
|
|
54197
|
+
renderDOM: (attrs) => {
|
|
54198
|
+
return attrs.sdBlockId ? { "data-sd-block-id": attrs.sdBlockId } : {};
|
|
54199
|
+
}
|
|
54200
|
+
},
|
|
54201
|
+
title: {},
|
|
54202
|
+
description: {},
|
|
54203
|
+
sectionType: {},
|
|
54204
|
+
isLocked: { default: false }
|
|
54205
|
+
};
|
|
54206
|
+
},
|
|
54207
|
+
addNodeView() {
|
|
54208
|
+
return ({ node, editor, getPos, decorations }) => {
|
|
54209
|
+
return new DocumentSectionView(node, getPos, decorations, editor);
|
|
54210
|
+
};
|
|
54211
|
+
},
|
|
54212
|
+
addCommands() {
|
|
54213
|
+
return {
|
|
54214
|
+
/**
|
|
54215
|
+
* Create a lockable content section
|
|
54216
|
+
* @category Command
|
|
54217
|
+
* @param {SectionCreate} [options={}] - Section configuration
|
|
54218
|
+
* @example
|
|
54219
|
+
* editor.commands.createDocumentSection({
|
|
54220
|
+
* id: 1,
|
|
54221
|
+
* title: 'Terms & Conditions',
|
|
54222
|
+
* isLocked: true,
|
|
54223
|
+
* html: '<p>Legal content...</p>'
|
|
54224
|
+
* })
|
|
54225
|
+
*/
|
|
54226
|
+
createDocumentSection: (options = {}) => ({ tr, state: state2, dispatch, editor }) => {
|
|
54227
|
+
const { selection } = state2;
|
|
54228
|
+
let { from: from2, to } = selection;
|
|
54229
|
+
let content = selection.content().content;
|
|
54230
|
+
const { html: optionsHTML, json: optionsJSON } = options;
|
|
54231
|
+
if (optionsHTML) {
|
|
54232
|
+
const html = htmlHandler(optionsHTML, this.editor);
|
|
54233
|
+
const doc2 = DOMParser$1.fromSchema(this.editor.schema).parse(html);
|
|
54234
|
+
content = doc2.content;
|
|
54235
|
+
}
|
|
54236
|
+
if (optionsJSON) {
|
|
54237
|
+
content = this.editor.schema.nodeFromJSON(optionsJSON);
|
|
54238
|
+
}
|
|
54239
|
+
if (!content?.content?.length) {
|
|
54240
|
+
content = this.editor.schema.nodeFromJSON({ type: "paragraph", content: [] });
|
|
54241
|
+
}
|
|
54242
|
+
if (!options.id) {
|
|
54243
|
+
const allSections = SectionHelpers.getAllSections(editor);
|
|
54244
|
+
options.id = allSections.length + 1;
|
|
54245
|
+
}
|
|
54246
|
+
if (!options.title) {
|
|
54247
|
+
options.title = "Document section";
|
|
54248
|
+
}
|
|
54249
|
+
const node = this.type.createAndFill(options, content);
|
|
54250
|
+
if (!node) return false;
|
|
54251
|
+
const isAlreadyInSdtBlock = findParentNode((node2) => node2.type.name === "documentSection")(selection);
|
|
54252
|
+
if (isAlreadyInSdtBlock && isAlreadyInSdtBlock.node) {
|
|
54253
|
+
const insertPos2 = isAlreadyInSdtBlock.pos + isAlreadyInSdtBlock.node.nodeSize;
|
|
54254
|
+
from2 = insertPos2;
|
|
54255
|
+
to = insertPos2;
|
|
54256
|
+
}
|
|
54257
|
+
tr.replaceRangeWith(from2, to, node);
|
|
54258
|
+
const nodeEnd = from2 + node.nodeSize;
|
|
54259
|
+
let shouldInsertParagraph = true;
|
|
54260
|
+
let insertPos = nodeEnd;
|
|
54261
|
+
if (nodeEnd >= tr.doc.content.size) {
|
|
54262
|
+
insertPos = tr.doc.content.size;
|
|
54263
|
+
if (insertPos > 0) {
|
|
54264
|
+
const $endPos = tr.doc.resolve(insertPos);
|
|
54265
|
+
if ($endPos.nodeBefore && $endPos.nodeBefore.type.name === "paragraph") {
|
|
54266
|
+
shouldInsertParagraph = false;
|
|
54267
|
+
}
|
|
54268
|
+
}
|
|
54269
|
+
}
|
|
54270
|
+
if (shouldInsertParagraph) {
|
|
54271
|
+
const emptyParagraph = tr.doc.type.schema.nodes.paragraph.create();
|
|
54272
|
+
tr.insert(insertPos, emptyParagraph);
|
|
54273
|
+
}
|
|
54274
|
+
if (dispatch) {
|
|
54275
|
+
tr.setMeta("documentSection", { action: "create" });
|
|
54276
|
+
dispatch(tr);
|
|
54277
|
+
setTimeout(() => {
|
|
54278
|
+
try {
|
|
54279
|
+
const currentState = editor.state;
|
|
54280
|
+
const docSize = currentState.doc.content.size;
|
|
54281
|
+
let targetPos = from2 + node.nodeSize;
|
|
54282
|
+
if (shouldInsertParagraph) {
|
|
54283
|
+
targetPos += 1;
|
|
54284
|
+
}
|
|
54285
|
+
targetPos = Math.min(targetPos, docSize);
|
|
54286
|
+
if (targetPos < docSize && targetPos > 0) {
|
|
54287
|
+
const newSelection = Selection.near(currentState.doc.resolve(targetPos));
|
|
54288
|
+
const newTr = currentState.tr.setSelection(newSelection);
|
|
54289
|
+
editor.view.dispatch(newTr);
|
|
54290
|
+
}
|
|
54291
|
+
} catch (e) {
|
|
54292
|
+
console.warn("Could not set delayed selection:", e);
|
|
54293
|
+
}
|
|
54294
|
+
}, 0);
|
|
54295
|
+
}
|
|
54296
|
+
return true;
|
|
54297
|
+
},
|
|
54298
|
+
/**
|
|
54299
|
+
* Remove section wrapper at cursor, preserving its content
|
|
54300
|
+
* @category Command
|
|
54301
|
+
* @example
|
|
54302
|
+
* editor.commands.removeSectionAtSelection()
|
|
54303
|
+
* @note Content stays in document, only section wrapper is removed
|
|
54304
|
+
*/
|
|
54305
|
+
removeSectionAtSelection: () => ({ tr, dispatch }) => {
|
|
54306
|
+
const sdtNode = findParentNode((node2) => node2.type.name === "documentSection")(tr.selection);
|
|
54307
|
+
if (!sdtNode) return false;
|
|
54308
|
+
const { node, pos } = sdtNode;
|
|
54309
|
+
const nodeStart = pos;
|
|
54310
|
+
const nodeEnd = nodeStart + node.nodeSize;
|
|
54311
|
+
const contentToPreserve = node.content;
|
|
54312
|
+
tr.delete(nodeStart, nodeEnd);
|
|
54313
|
+
if (contentToPreserve.size > 0) {
|
|
54314
|
+
tr.insert(nodeStart, contentToPreserve);
|
|
54315
|
+
}
|
|
54316
|
+
const newPos = Math.min(nodeStart, tr.doc.content.size);
|
|
54317
|
+
tr.setSelection(Selection.near(tr.doc.resolve(newPos)));
|
|
54318
|
+
if (dispatch) {
|
|
54319
|
+
tr.setMeta("documentSection", { action: "delete" });
|
|
54320
|
+
dispatch(tr);
|
|
54321
|
+
}
|
|
54322
|
+
return true;
|
|
54323
|
+
},
|
|
54324
|
+
/**
|
|
54325
|
+
* Delete section and all its content
|
|
54326
|
+
* @category Command
|
|
54327
|
+
* @param {number} id - Section to delete
|
|
54328
|
+
* @example
|
|
54329
|
+
* editor.commands.removeSectionById(123)
|
|
54330
|
+
*/
|
|
54331
|
+
removeSectionById: (id) => ({ tr, dispatch }) => {
|
|
54332
|
+
const sections = SectionHelpers.getAllSections(this.editor);
|
|
54333
|
+
const sectionToRemove = sections.find(({ node: node2 }) => node2.attrs.id === id);
|
|
54334
|
+
if (!sectionToRemove) return false;
|
|
54335
|
+
const { pos, node } = sectionToRemove;
|
|
54336
|
+
const nodeStart = pos;
|
|
54337
|
+
const nodeEnd = nodeStart + node.nodeSize;
|
|
54338
|
+
tr.delete(nodeStart, nodeEnd);
|
|
54339
|
+
if (dispatch) {
|
|
54340
|
+
tr.setMeta("documentSection", { action: "delete", id });
|
|
54341
|
+
dispatch(tr);
|
|
54342
|
+
}
|
|
54343
|
+
return true;
|
|
54344
|
+
},
|
|
54345
|
+
/**
|
|
54346
|
+
* Lock section against edits
|
|
54347
|
+
* @category Command
|
|
54348
|
+
* @param {number} id - Section to lock
|
|
54349
|
+
* @example
|
|
54350
|
+
* editor.commands.lockSectionById(123)
|
|
54351
|
+
*/
|
|
54352
|
+
lockSectionById: (id) => ({ tr, dispatch }) => {
|
|
54353
|
+
const sections = SectionHelpers.getAllSections(this.editor);
|
|
54354
|
+
const sectionToLock = sections.find(({ node }) => node.attrs.id === id);
|
|
54355
|
+
if (!sectionToLock) return false;
|
|
54356
|
+
tr.setNodeMarkup(sectionToLock.pos, null, { ...sectionToLock.node.attrs, isLocked: true });
|
|
54357
|
+
if (dispatch) {
|
|
54358
|
+
tr.setMeta("documentSection", { action: "lock", id });
|
|
54359
|
+
dispatch(tr);
|
|
54360
|
+
}
|
|
54361
|
+
return true;
|
|
54362
|
+
},
|
|
54363
|
+
/**
|
|
54364
|
+
* Modify section attributes or content
|
|
54365
|
+
* @category Command
|
|
54366
|
+
* @param {SectionUpdate} options - Changes to apply
|
|
54367
|
+
* @example
|
|
54368
|
+
* editor.commands.updateSectionById({ id: 123, attrs: { isLocked: false } })
|
|
54369
|
+
* editor.commands.updateSectionById({ id: 123, html: '<p>New content</p>' })
|
|
54370
|
+
* editor.commands.updateSectionById({
|
|
54371
|
+
* id: 123,
|
|
54372
|
+
* html: '<p>Updated</p>',
|
|
54373
|
+
* attrs: { title: 'New Title' }
|
|
54374
|
+
* })
|
|
54375
|
+
*/
|
|
54376
|
+
updateSectionById: ({ id, html, json, attrs }) => ({ tr, dispatch, editor }) => {
|
|
54377
|
+
const sections = SectionHelpers.getAllSections(editor || this.editor);
|
|
54378
|
+
const sectionToUpdate = sections.find(({ node: node2 }) => node2.attrs.id === id);
|
|
54379
|
+
if (!sectionToUpdate) return false;
|
|
54380
|
+
const { pos, node } = sectionToUpdate;
|
|
54381
|
+
let newContent = null;
|
|
54382
|
+
if (html) {
|
|
54383
|
+
const htmlDoc = htmlHandler(html, editor || this.editor);
|
|
54384
|
+
const doc2 = DOMParser$1.fromSchema((editor || this.editor).schema).parse(htmlDoc);
|
|
54385
|
+
newContent = doc2.content;
|
|
54386
|
+
}
|
|
54387
|
+
if (json) {
|
|
54388
|
+
newContent = (editor || this.editor).schema.nodeFromJSON(json);
|
|
54389
|
+
}
|
|
54390
|
+
if (!newContent) {
|
|
54391
|
+
newContent = node.content;
|
|
54392
|
+
}
|
|
54393
|
+
const updatedNode = node.type.create({ ...node.attrs, ...attrs }, newContent, node.marks);
|
|
54394
|
+
tr.replaceWith(pos, pos + node.nodeSize, updatedNode);
|
|
54395
|
+
if (dispatch) {
|
|
54396
|
+
tr.setMeta("documentSection", { action: "update", id, attrs });
|
|
54397
|
+
dispatch(tr);
|
|
54398
|
+
}
|
|
54399
|
+
return true;
|
|
54400
|
+
}
|
|
54401
|
+
};
|
|
54402
|
+
},
|
|
54403
|
+
addHelpers() {
|
|
54404
|
+
return {
|
|
54405
|
+
...SectionHelpers
|
|
54406
|
+
};
|
|
54407
|
+
}
|
|
54408
|
+
});
|
|
54409
|
+
const Document = Node$1.create({
|
|
54410
|
+
name: "doc",
|
|
54411
|
+
topNode: true,
|
|
54412
|
+
content: "block+",
|
|
54413
|
+
parseDOM() {
|
|
54414
|
+
return [{ tag: "doc" }];
|
|
54415
|
+
},
|
|
54416
|
+
renderDOM() {
|
|
54417
|
+
return ["doc", 0];
|
|
54418
|
+
},
|
|
54419
|
+
addAttributes() {
|
|
54420
|
+
return {
|
|
54421
|
+
attributes: {
|
|
54422
|
+
rendered: false,
|
|
54423
|
+
"aria-label": "Document node"
|
|
54424
|
+
}
|
|
54425
|
+
};
|
|
54426
|
+
},
|
|
54427
|
+
addCommands() {
|
|
54428
|
+
return {
|
|
54429
|
+
/**
|
|
54430
|
+
* Get document statistics
|
|
54431
|
+
* @category Command
|
|
54432
|
+
* @example
|
|
54433
|
+
* // Get word and character count
|
|
54434
|
+
* const stats = editor.commands.getDocumentStats()
|
|
54435
|
+
* console.log(`${stats.words} words, ${stats.characters} characters`)
|
|
54436
|
+
* @note Returns word count, character count, and paragraph count
|
|
54437
|
+
*/
|
|
54438
|
+
getDocumentStats: () => ({ editor }) => {
|
|
54439
|
+
const text = editor.getText();
|
|
54440
|
+
const words = text.split(/\s+/).filter((word) => word.length > 0).length;
|
|
54441
|
+
const characters = text.length;
|
|
54442
|
+
const paragraphs = editor.state.doc.content.childCount;
|
|
54443
|
+
return {
|
|
54444
|
+
words,
|
|
54445
|
+
characters,
|
|
54446
|
+
paragraphs
|
|
54447
|
+
};
|
|
54448
|
+
},
|
|
54449
|
+
/**
|
|
54450
|
+
* Clear entire document
|
|
54451
|
+
* @category Command
|
|
54452
|
+
* @example
|
|
54453
|
+
* editor.commands.clearDocument()
|
|
54454
|
+
* @note Replaces all content with an empty paragraph
|
|
54455
|
+
*/
|
|
54456
|
+
clearDocument: () => ({ commands: commands2 }) => {
|
|
54457
|
+
return commands2.setContent("<p></p>");
|
|
54458
|
+
}
|
|
54459
|
+
};
|
|
54460
|
+
}
|
|
54461
|
+
});
|
|
54462
|
+
const Text = Node$1.create({
|
|
54463
|
+
name: "text",
|
|
54464
|
+
group: "inline",
|
|
54465
|
+
inline: true,
|
|
54466
|
+
addOptions() {
|
|
54467
|
+
return {};
|
|
54468
|
+
}
|
|
54469
|
+
});
|
|
54470
|
+
const splitRun = () => (props) => {
|
|
54471
|
+
const { state: state2, view, tr } = props;
|
|
54472
|
+
const { $from, empty: empty2 } = state2.selection;
|
|
54473
|
+
if (!empty2) return false;
|
|
54474
|
+
if ($from.parent.type.name !== "run") return false;
|
|
54475
|
+
const handled = splitBlock(state2, (transaction) => {
|
|
54476
|
+
view.dispatch(transaction);
|
|
54477
|
+
});
|
|
54478
|
+
if (handled) {
|
|
54479
|
+
tr.setMeta("preventDispatch", true);
|
|
54480
|
+
}
|
|
54481
|
+
return handled;
|
|
54482
|
+
};
|
|
54483
|
+
const Run = OxmlNode.create({
|
|
54484
|
+
name: "run",
|
|
54485
|
+
oXmlName: "w:r",
|
|
54486
|
+
group: "inline",
|
|
54487
|
+
inline: true,
|
|
54488
|
+
content: "inline*",
|
|
54489
|
+
selectable: false,
|
|
54490
|
+
childToAttributes: ["runProperties"],
|
|
54491
|
+
addOptions() {
|
|
54492
|
+
return {
|
|
54493
|
+
htmlAttributes: {
|
|
54494
|
+
"data-run": "1"
|
|
54495
|
+
}
|
|
54496
|
+
};
|
|
54497
|
+
},
|
|
54498
|
+
addAttributes() {
|
|
54499
|
+
return {
|
|
54500
|
+
runProperties: {
|
|
54501
|
+
default: null,
|
|
54502
|
+
rendered: false,
|
|
54503
|
+
keepOnSplit: true
|
|
54504
|
+
},
|
|
54505
|
+
rsidR: {
|
|
54506
|
+
default: null,
|
|
54507
|
+
rendered: false,
|
|
54508
|
+
keepOnSplit: true
|
|
54509
|
+
},
|
|
54510
|
+
rsidRPr: {
|
|
54511
|
+
default: null,
|
|
54512
|
+
rendered: false,
|
|
54513
|
+
keepOnSplit: true
|
|
54514
|
+
},
|
|
54515
|
+
rsidDel: {
|
|
54516
|
+
default: null,
|
|
54517
|
+
rendered: false,
|
|
54518
|
+
keepOnSplit: true
|
|
54519
|
+
}
|
|
54520
|
+
};
|
|
54521
|
+
},
|
|
54522
|
+
addCommands() {
|
|
54523
|
+
return {
|
|
54524
|
+
splitRun
|
|
54525
|
+
};
|
|
54526
|
+
},
|
|
54527
|
+
parseDOM() {
|
|
54528
|
+
return [{ tag: "span[data-run]" }];
|
|
54529
|
+
},
|
|
54530
|
+
renderDOM({ htmlAttributes }) {
|
|
54531
|
+
const base2 = Attribute2.mergeAttributes(this.options.htmlAttributes, htmlAttributes);
|
|
54532
|
+
return ["span", base2, 0];
|
|
54533
|
+
}
|
|
54534
|
+
});
|
|
54535
|
+
const inputRegex$1 = /^\s*([-+*])\s$/;
|
|
54536
|
+
const BulletList = Node$1.create({
|
|
54537
|
+
name: "bulletList",
|
|
54538
|
+
group: "block list",
|
|
54539
|
+
selectable: false,
|
|
54540
|
+
content() {
|
|
54541
|
+
return `${this.options.itemTypeName}+`;
|
|
54542
|
+
},
|
|
54543
|
+
addOptions() {
|
|
54544
|
+
return {
|
|
54545
|
+
itemTypeName: "listItem",
|
|
54546
|
+
htmlAttributes: {
|
|
54547
|
+
"aria-label": "Bullet list node"
|
|
54548
|
+
},
|
|
54549
|
+
keepMarks: true,
|
|
54550
|
+
keepAttributes: false
|
|
54551
|
+
};
|
|
54552
|
+
},
|
|
54553
|
+
parseDOM() {
|
|
54554
|
+
return [{ tag: "ul" }];
|
|
54555
|
+
},
|
|
54556
|
+
renderDOM({ htmlAttributes }) {
|
|
54557
|
+
const attributes = Attribute2.mergeAttributes(this.options.htmlAttributes, htmlAttributes);
|
|
54558
|
+
return ["ul", attributes, 0];
|
|
54559
|
+
},
|
|
54560
|
+
addAttributes() {
|
|
54561
|
+
return {
|
|
54562
|
+
"list-style-type": {
|
|
54563
|
+
default: "bullet",
|
|
54564
|
+
rendered: false
|
|
54565
|
+
},
|
|
54566
|
+
listId: {
|
|
54567
|
+
rendered: false
|
|
54568
|
+
},
|
|
54569
|
+
sdBlockId: {
|
|
54570
|
+
default: null,
|
|
54571
|
+
keepOnSplit: false,
|
|
54572
|
+
parseDOM: (elem) => elem.getAttribute("data-sd-block-id"),
|
|
54573
|
+
renderDOM: (attrs) => {
|
|
54574
|
+
return attrs.sdBlockId ? { "data-sd-block-id": attrs.sdBlockId } : {};
|
|
54575
|
+
}
|
|
54576
|
+
},
|
|
54577
|
+
attributes: {
|
|
54578
|
+
rendered: false,
|
|
54579
|
+
keepOnSplit: true
|
|
54580
|
+
}
|
|
54581
|
+
};
|
|
54582
|
+
},
|
|
54583
|
+
addCommands() {
|
|
54584
|
+
return {
|
|
54585
|
+
/**
|
|
54586
|
+
* Toggle a bullet list at the current selection
|
|
54587
|
+
* @category Command
|
|
54588
|
+
* @example
|
|
54589
|
+
* // Toggle bullet list on selected text
|
|
54590
|
+
* editor.commands.toggleBulletList()
|
|
54591
|
+
* @note Converts selected paragraphs to list items or removes list formatting
|
|
54592
|
+
*/
|
|
54593
|
+
toggleBulletList: () => (params2) => {
|
|
54594
|
+
return toggleList(this.type)(params2);
|
|
54595
|
+
}
|
|
54596
|
+
};
|
|
54597
|
+
},
|
|
54598
|
+
addShortcuts() {
|
|
54599
|
+
return {
|
|
54600
|
+
"Mod-Shift-8": () => {
|
|
54601
|
+
return this.editor.commands.toggleBulletList();
|
|
54602
|
+
}
|
|
54603
|
+
};
|
|
54604
|
+
},
|
|
54605
|
+
addInputRules() {
|
|
54606
|
+
return [
|
|
54607
|
+
new InputRule({
|
|
54608
|
+
match: inputRegex$1,
|
|
54609
|
+
handler: ({ state: state2, range: range2 }) => {
|
|
54610
|
+
const $pos = state2.selection.$from;
|
|
54611
|
+
const listItemType = state2.schema.nodes.listItem;
|
|
54612
|
+
for (let depth = $pos.depth; depth >= 0; depth--) {
|
|
54613
|
+
if ($pos.node(depth).type === listItemType) {
|
|
54614
|
+
return null;
|
|
54615
|
+
}
|
|
54616
|
+
}
|
|
54617
|
+
const { tr } = state2;
|
|
54618
|
+
tr.delete(range2.from, range2.to);
|
|
54619
|
+
ListHelpers.createNewList({
|
|
54620
|
+
listType: this.type,
|
|
54621
|
+
tr,
|
|
54622
|
+
editor: this.editor
|
|
54623
|
+
});
|
|
54624
|
+
}
|
|
54625
|
+
})
|
|
54626
|
+
];
|
|
54627
|
+
}
|
|
54628
|
+
});
|
|
54629
|
+
const inputRegex = /^(\d+)\.\s$/;
|
|
54630
|
+
const OrderedList = Node$1.create({
|
|
54631
|
+
name: "orderedList",
|
|
54632
|
+
group: "block list",
|
|
54633
|
+
selectable: false,
|
|
54634
|
+
content() {
|
|
54635
|
+
return `${this.options.itemTypeName}+`;
|
|
54636
|
+
},
|
|
54637
|
+
addOptions() {
|
|
54638
|
+
return {
|
|
54639
|
+
itemTypeName: "listItem",
|
|
54640
|
+
htmlAttributes: {
|
|
54641
|
+
"aria-label": "Ordered list node"
|
|
54642
|
+
},
|
|
54643
|
+
keepMarks: true,
|
|
54644
|
+
keepAttributes: false,
|
|
54645
|
+
listStyleTypes: ["decimal", "lowerAlpha", "lowerRoman"]
|
|
54646
|
+
};
|
|
54647
|
+
},
|
|
54648
|
+
addAttributes() {
|
|
54649
|
+
return {
|
|
54650
|
+
order: {
|
|
54651
|
+
default: 1,
|
|
54652
|
+
parseDOM: (element) => {
|
|
54653
|
+
return element.hasAttribute("start") ? parseInt(element.getAttribute("start") || "", 10) : 1;
|
|
54654
|
+
},
|
|
54655
|
+
renderDOM: (attrs) => {
|
|
54656
|
+
return {
|
|
54657
|
+
start: attrs.order
|
|
54658
|
+
};
|
|
54659
|
+
}
|
|
54660
|
+
},
|
|
54661
|
+
sdBlockId: {
|
|
54662
|
+
default: null,
|
|
54663
|
+
keepOnSplit: false,
|
|
54664
|
+
parseDOM: (elem) => elem.getAttribute("data-sd-block-id"),
|
|
54665
|
+
renderDOM: (attrs) => {
|
|
54666
|
+
return attrs.sdBlockId ? { "data-sd-block-id": attrs.sdBlockId } : {};
|
|
54667
|
+
}
|
|
54668
|
+
},
|
|
54669
|
+
syncId: {
|
|
54670
|
+
default: null,
|
|
54671
|
+
parseDOM: (elem) => elem.getAttribute("data-sync-id"),
|
|
54672
|
+
renderDOM: (attrs) => {
|
|
54673
|
+
if (!attrs.syncId) return {};
|
|
54674
|
+
return {
|
|
54675
|
+
"data-sync-id": attrs.syncId
|
|
54676
|
+
};
|
|
54677
|
+
}
|
|
54678
|
+
// rendered: false,
|
|
54679
|
+
},
|
|
54680
|
+
listId: {
|
|
54681
|
+
keepOnSplit: true,
|
|
54682
|
+
parseDOM: (elem) => elem.getAttribute("data-list-id"),
|
|
54683
|
+
renderDOM: (attrs) => {
|
|
54684
|
+
if (!attrs.listId) return {};
|
|
54685
|
+
return {
|
|
54686
|
+
"data-list-id": attrs.listId
|
|
54687
|
+
};
|
|
54688
|
+
}
|
|
54689
|
+
},
|
|
54690
|
+
"list-style-type": {
|
|
54691
|
+
default: "decimal",
|
|
54692
|
+
rendered: false
|
|
54693
|
+
},
|
|
54694
|
+
attributes: {
|
|
54695
|
+
rendered: false,
|
|
54696
|
+
keepOnSplit: true
|
|
54697
|
+
}
|
|
54698
|
+
};
|
|
54699
|
+
},
|
|
54700
|
+
parseDOM() {
|
|
54701
|
+
return [{ tag: "ol" }];
|
|
54702
|
+
},
|
|
54703
|
+
renderDOM({ htmlAttributes }) {
|
|
54704
|
+
const { start: start2, ...restAttributes } = htmlAttributes;
|
|
54705
|
+
return start2 === 1 ? ["ol", Attribute2.mergeAttributes(this.options.htmlAttributes, restAttributes), 0] : ["ol", Attribute2.mergeAttributes(this.options.htmlAttributes, htmlAttributes), 0];
|
|
54706
|
+
},
|
|
54707
|
+
addCommands() {
|
|
54708
|
+
return {
|
|
54709
|
+
/**
|
|
54710
|
+
* Toggle ordered list formatting
|
|
54711
|
+
* @category Command
|
|
54712
|
+
* @example
|
|
54713
|
+
* editor.commands.toggleOrderedList()
|
|
54714
|
+
* @note Converts selection to ordered list or back to paragraphs
|
|
54715
|
+
*/
|
|
54716
|
+
toggleOrderedList: () => (params2) => {
|
|
54717
|
+
return toggleList(this.type)(params2);
|
|
54718
|
+
},
|
|
54719
|
+
/**
|
|
54720
|
+
* Restart list node numbering
|
|
54721
|
+
* @category Command
|
|
54722
|
+
* @param {Array} followingNodes - Nodes to restart
|
|
54723
|
+
* @param {number} pos - Starting position
|
|
54724
|
+
* @example
|
|
54725
|
+
* editor.commands.restartListNodes(nodes, position)
|
|
54726
|
+
* @note Resets list numbering for specified nodes
|
|
54727
|
+
*/
|
|
54728
|
+
restartListNodes: (followingNodes, pos) => ({ tr }) => {
|
|
54729
|
+
let currentNodePos = pos;
|
|
54730
|
+
const nodes = followingNodes.map((node) => {
|
|
54731
|
+
const resultNode = {
|
|
54732
|
+
node,
|
|
54733
|
+
pos: currentNodePos
|
|
54734
|
+
};
|
|
54735
|
+
currentNodePos += node.nodeSize;
|
|
54736
|
+
return resultNode;
|
|
54737
|
+
});
|
|
54738
|
+
nodes.forEach((item) => {
|
|
54739
|
+
const { pos: pos2 } = item;
|
|
54740
|
+
const newPos = tr.mapping.map(pos2);
|
|
54741
|
+
tr.setNodeMarkup(newPos, void 0, {});
|
|
54742
|
+
});
|
|
54743
|
+
return true;
|
|
54744
|
+
},
|
|
54745
|
+
/**
|
|
54746
|
+
* Update ordered list style type based on nesting level
|
|
54747
|
+
* @category Command
|
|
54748
|
+
* @example
|
|
54749
|
+
* editor.commands.updateOrderedListStyleType()
|
|
54750
|
+
* @note Cycles through decimal -> lowerAlpha -> lowerRoman based on depth
|
|
54751
|
+
*/
|
|
54752
|
+
updateOrderedListStyleType: () => ({ dispatch, tr }) => {
|
|
54753
|
+
let list = findParentNode((node) => node.type.name === this.name)(tr.selection);
|
|
54754
|
+
if (!list) {
|
|
54755
|
+
return true;
|
|
54756
|
+
}
|
|
54757
|
+
if (dispatch) {
|
|
54758
|
+
let listLevel = (list.depth - 1) / 2;
|
|
54759
|
+
let listStyleTypes = this.options.listStyleTypes;
|
|
54760
|
+
let listStyle = listStyleTypes[listLevel % listStyleTypes.length];
|
|
54761
|
+
let currentListStyle = list.node.attrs["list-style-type"];
|
|
54762
|
+
let nodeAtPos = tr.doc.nodeAt(list.pos);
|
|
54763
|
+
if (currentListStyle !== listStyle && nodeAtPos.eq(list.node)) {
|
|
54764
|
+
tr.setNodeMarkup(list.pos, void 0, {
|
|
54765
|
+
...list.node.attrs,
|
|
54766
|
+
...{
|
|
54767
|
+
"list-style-type": listStyle
|
|
54768
|
+
}
|
|
54769
|
+
});
|
|
54770
|
+
}
|
|
54771
|
+
}
|
|
54772
|
+
return true;
|
|
54773
|
+
}
|
|
54774
|
+
};
|
|
54775
|
+
},
|
|
54776
|
+
addShortcuts() {
|
|
54777
|
+
return {
|
|
54778
|
+
"Mod-Shift-7": () => {
|
|
54779
|
+
return this.editor.commands.toggleOrderedList();
|
|
54780
|
+
}
|
|
54781
|
+
};
|
|
54782
|
+
},
|
|
54783
|
+
addInputRules() {
|
|
54784
|
+
return [
|
|
54785
|
+
new InputRule({
|
|
54786
|
+
match: inputRegex,
|
|
54787
|
+
handler: ({ state: state2, range: range2 }) => {
|
|
54788
|
+
const $pos = state2.selection.$from;
|
|
54789
|
+
const listItemType = state2.schema.nodes.listItem;
|
|
54790
|
+
for (let depth = $pos.depth; depth >= 0; depth--) {
|
|
54791
|
+
if ($pos.node(depth).type === listItemType) {
|
|
54792
|
+
return null;
|
|
54793
|
+
}
|
|
54794
|
+
}
|
|
54795
|
+
const { tr } = state2;
|
|
54796
|
+
tr.delete(range2.from, range2.to);
|
|
54797
|
+
ListHelpers.createNewList({
|
|
54798
|
+
listType: this.type,
|
|
54799
|
+
tr,
|
|
54800
|
+
editor: this.editor
|
|
54801
|
+
});
|
|
54802
|
+
}
|
|
54803
|
+
})
|
|
54804
|
+
];
|
|
54805
|
+
}
|
|
54806
|
+
});
|
|
54807
|
+
const generateOrderedListIndex = ({ listLevel, lvlText, listNumberingType, customFormat }) => {
|
|
54808
|
+
const handler2 = listIndexMap[listNumberingType];
|
|
54809
|
+
return handler2 ? handler2(listLevel, lvlText, customFormat) : null;
|
|
54810
|
+
};
|
|
54811
|
+
const handleDecimal = (path, lvlText) => generateNumbering(path, lvlText, String);
|
|
54812
|
+
const handleRoman = (path, lvlText) => generateNumbering(path, lvlText, intToRoman);
|
|
54813
|
+
const handleLowerRoman = (path, lvlText) => handleRoman(path, lvlText).toLowerCase();
|
|
54814
|
+
const handleLowerAlpha = (path, lvlText) => handleAlpha(path, lvlText).toLowerCase();
|
|
54815
|
+
const handleAlpha = (path, lvlText) => generateNumbering(path, lvlText, (p) => intToAlpha(p));
|
|
54816
|
+
const handleOrdinal = (path, lvlText) => generateNumbering(path, lvlText, ordinalFormatter);
|
|
54817
|
+
const handleCustom = (path, lvlText, customFormat) => generateFromCustom(path, lvlText, customFormat);
|
|
54818
|
+
const handleJapaneseCounting = (path, lvlText) => generateNumbering(path, lvlText, intToJapaneseCounting);
|
|
54819
|
+
const listIndexMap = {
|
|
54820
|
+
decimal: handleDecimal,
|
|
54821
|
+
lowerRoman: handleLowerRoman,
|
|
54822
|
+
upperRoman: handleRoman,
|
|
54823
|
+
lowerLetter: handleLowerAlpha,
|
|
54824
|
+
upperLetter: handleAlpha,
|
|
54825
|
+
ordinal: handleOrdinal,
|
|
54826
|
+
custom: handleCustom,
|
|
54827
|
+
japaneseCounting: handleJapaneseCounting
|
|
54828
|
+
};
|
|
54829
|
+
const createNumbering = (values, lvlText) => {
|
|
54830
|
+
return values.reduce((acc, value, index2) => {
|
|
54831
|
+
return value > 9 ? acc.replace(/^0/, "").replace(`%${index2 + 1}`, value) : acc.replace(`%${index2 + 1}`, value);
|
|
54832
|
+
}, lvlText);
|
|
54833
|
+
};
|
|
54834
|
+
const generateNumbering = (path, lvlText, formatter) => {
|
|
54835
|
+
const formattedValues = path.map(formatter);
|
|
54836
|
+
return createNumbering(formattedValues, lvlText);
|
|
54837
|
+
};
|
|
54838
|
+
const ordinalFormatter = (level) => {
|
|
54839
|
+
const suffixes = ["th", "st", "nd", "rd"];
|
|
54840
|
+
const value = level % 100;
|
|
54841
|
+
const suffix2 = suffixes[(value - 20) % 10] || suffixes[value] || suffixes[0];
|
|
54842
|
+
const p = level + suffix2;
|
|
54843
|
+
return p;
|
|
54844
|
+
};
|
|
54845
|
+
const generateFromCustom = (path, lvlText, customFormat) => {
|
|
54846
|
+
if (customFormat !== "001, 002, 003, ...") return generateNumbering(path, lvlText, String);
|
|
54847
|
+
const match = customFormat.match(/(\d+)/);
|
|
54848
|
+
if (!match) throw new Error("Invalid format string: no numeric pattern found");
|
|
54849
|
+
const sample = match[1];
|
|
54850
|
+
const digitCount = sample.length;
|
|
54851
|
+
const index2 = path.pop();
|
|
54852
|
+
return String(index2).padStart(digitCount, "0");
|
|
53602
54853
|
};
|
|
54854
|
+
const intToRoman = (num) => {
|
|
54855
|
+
const romanNumeralMap = [
|
|
54856
|
+
{ value: 1e3, numeral: "M" },
|
|
54857
|
+
{ value: 900, numeral: "CM" },
|
|
54858
|
+
{ value: 500, numeral: "D" },
|
|
54859
|
+
{ value: 400, numeral: "CD" },
|
|
54860
|
+
{ value: 100, numeral: "C" },
|
|
54861
|
+
{ value: 90, numeral: "XC" },
|
|
54862
|
+
{ value: 50, numeral: "L" },
|
|
54863
|
+
{ value: 40, numeral: "XL" },
|
|
54864
|
+
{ value: 10, numeral: "X" },
|
|
54865
|
+
{ value: 9, numeral: "IX" },
|
|
54866
|
+
{ value: 5, numeral: "V" },
|
|
54867
|
+
{ value: 4, numeral: "IV" },
|
|
54868
|
+
{ value: 1, numeral: "I" }
|
|
54869
|
+
];
|
|
54870
|
+
let result = "";
|
|
54871
|
+
for (const { value, numeral } of romanNumeralMap) {
|
|
54872
|
+
while (num >= value) {
|
|
54873
|
+
result += numeral;
|
|
54874
|
+
num -= value;
|
|
54875
|
+
}
|
|
54876
|
+
}
|
|
54877
|
+
return result;
|
|
54878
|
+
};
|
|
54879
|
+
const intToAlpha = (num) => {
|
|
54880
|
+
let result = "";
|
|
54881
|
+
const alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
|
|
54882
|
+
while (num > 0) {
|
|
54883
|
+
let index2 = (num - 1) % 26;
|
|
54884
|
+
result = alphabet[index2] + result;
|
|
54885
|
+
num = Math.floor((num - 1) / 26);
|
|
54886
|
+
}
|
|
54887
|
+
return result;
|
|
54888
|
+
};
|
|
54889
|
+
const intToJapaneseCounting = (num) => {
|
|
54890
|
+
const digits = ["", "一", "二", "三", "四", "五", "六", "七", "八", "九"];
|
|
54891
|
+
const units = ["", "十", "百", "千"];
|
|
54892
|
+
if (num === 0) return "零";
|
|
54893
|
+
if (num < 10) return digits[num];
|
|
54894
|
+
let result = "";
|
|
54895
|
+
let tempNum = num;
|
|
54896
|
+
let unitIndex = 0;
|
|
54897
|
+
while (tempNum > 0) {
|
|
54898
|
+
const digit = tempNum % 10;
|
|
54899
|
+
if (digit !== 0) {
|
|
54900
|
+
const digitStr = digit === 1 && unitIndex > 0 ? "" : digits[digit];
|
|
54901
|
+
result = digitStr + (unitIndex > 0 ? units[unitIndex] : "") + result;
|
|
54902
|
+
} else if (result && tempNum > 0) {
|
|
54903
|
+
if (!result.startsWith("零") && tempNum % 100 !== 0) {
|
|
54904
|
+
result = "零" + result;
|
|
54905
|
+
}
|
|
54906
|
+
}
|
|
54907
|
+
tempNum = Math.floor(tempNum / 10);
|
|
54908
|
+
unitIndex++;
|
|
54909
|
+
if (unitIndex > 3) break;
|
|
54910
|
+
}
|
|
54911
|
+
if (num >= 10 && num < 20) {
|
|
54912
|
+
result = result.replace(/^一十/, "十");
|
|
54913
|
+
}
|
|
54914
|
+
return result;
|
|
54915
|
+
};
|
|
54916
|
+
const isKeyboardInvocation = (event) => {
|
|
54917
|
+
return event.type === "contextmenu" && typeof event.detail === "number" && event.detail === 0 && (event.button === 0 || event.button === void 0) && event.clientX === 0 && event.clientY === 0;
|
|
54918
|
+
};
|
|
54919
|
+
const prefersNativeMenu = (event) => {
|
|
54920
|
+
if (!event) return false;
|
|
54921
|
+
if (event.ctrlKey || event.metaKey) {
|
|
54922
|
+
return true;
|
|
54923
|
+
}
|
|
54924
|
+
return isKeyboardInvocation(event);
|
|
54925
|
+
};
|
|
54926
|
+
const shouldAllowNativeContextMenu = (event) => {
|
|
54927
|
+
return prefersNativeMenu(event);
|
|
54928
|
+
};
|
|
54929
|
+
const shouldBypassContextMenu = shouldAllowNativeContextMenu;
|
|
54930
|
+
const DEFAULT_SELECTION_STATE = Object.freeze({
|
|
54931
|
+
focused: false,
|
|
54932
|
+
preservedSelection: null,
|
|
54933
|
+
showVisualSelection: false,
|
|
54934
|
+
skipFocusReset: false
|
|
54935
|
+
});
|
|
54936
|
+
const normalizeSelectionState = (state2 = {}) => ({
|
|
54937
|
+
...DEFAULT_SELECTION_STATE,
|
|
54938
|
+
...state2
|
|
54939
|
+
});
|
|
54940
|
+
const CustomSelectionPluginKey = new PluginKey("CustomSelection");
|
|
53603
54941
|
const handleClickOutside = (event, editor) => {
|
|
53604
54942
|
const editorElem = editor?.options?.element;
|
|
53605
54943
|
if (!editorElem) return;
|
|
@@ -53636,11 +54974,7 @@ const CustomSelection = Extension.create({
|
|
|
53636
54974
|
const customSelectionPlugin = new Plugin({
|
|
53637
54975
|
key: CustomSelectionPluginKey,
|
|
53638
54976
|
state: {
|
|
53639
|
-
init: () => ({
|
|
53640
|
-
focused: false,
|
|
53641
|
-
preservedSelection: null,
|
|
53642
|
-
showVisualSelection: false
|
|
53643
|
-
}),
|
|
54977
|
+
init: () => ({ ...DEFAULT_SELECTION_STATE }),
|
|
53644
54978
|
apply: (tr, value) => {
|
|
53645
54979
|
const meta = getFocusMeta(tr);
|
|
53646
54980
|
if (meta !== void 0) {
|
|
@@ -53671,7 +55005,8 @@ const CustomSelection = Extension.create({
|
|
|
53671
55005
|
setFocusMeta(view.state.tr, {
|
|
53672
55006
|
focused: true,
|
|
53673
55007
|
preservedSelection: selection,
|
|
53674
|
-
showVisualSelection: true
|
|
55008
|
+
showVisualSelection: true,
|
|
55009
|
+
skipFocusReset: true
|
|
53675
55010
|
})
|
|
53676
55011
|
);
|
|
53677
55012
|
}
|
|
@@ -53692,7 +55027,8 @@ const CustomSelection = Extension.create({
|
|
|
53692
55027
|
setFocusMeta(view.state.tr, {
|
|
53693
55028
|
focused: true,
|
|
53694
55029
|
preservedSelection: selection2,
|
|
53695
|
-
showVisualSelection: true
|
|
55030
|
+
showVisualSelection: true,
|
|
55031
|
+
skipFocusReset: true
|
|
53696
55032
|
})
|
|
53697
55033
|
);
|
|
53698
55034
|
this.editor.setOptions({
|
|
@@ -53715,7 +55051,8 @@ const CustomSelection = Extension.create({
|
|
|
53715
55051
|
setFocusMeta(view.state.tr, {
|
|
53716
55052
|
focused: true,
|
|
53717
55053
|
preservedSelection: selection,
|
|
53718
|
-
showVisualSelection: true
|
|
55054
|
+
showVisualSelection: true,
|
|
55055
|
+
skipFocusReset: false
|
|
53719
55056
|
})
|
|
53720
55057
|
);
|
|
53721
55058
|
this.editor.setOptions({
|
|
@@ -53733,7 +55070,8 @@ const CustomSelection = Extension.create({
|
|
|
53733
55070
|
setFocusMeta(view.state.tr, {
|
|
53734
55071
|
focused: true,
|
|
53735
55072
|
preservedSelection: selection,
|
|
53736
|
-
showVisualSelection: true
|
|
55073
|
+
showVisualSelection: true,
|
|
55074
|
+
skipFocusReset: false
|
|
53737
55075
|
})
|
|
53738
55076
|
);
|
|
53739
55077
|
}
|
|
@@ -53744,7 +55082,8 @@ const CustomSelection = Extension.create({
|
|
|
53744
55082
|
setFocusMeta(view.state.tr, {
|
|
53745
55083
|
focused: false,
|
|
53746
55084
|
preservedSelection: null,
|
|
53747
|
-
showVisualSelection: false
|
|
55085
|
+
showVisualSelection: false,
|
|
55086
|
+
skipFocusReset: false
|
|
53748
55087
|
})
|
|
53749
55088
|
);
|
|
53750
55089
|
if (!selection.empty && !this.editor.options.element?.contains(target)) {
|
|
@@ -53761,12 +55100,20 @@ const CustomSelection = Extension.create({
|
|
|
53761
55100
|
const isElement2 = target instanceof Element;
|
|
53762
55101
|
const isToolbarBtn = isElement2 && isToolbarButton(target);
|
|
53763
55102
|
const isToolbarInp = isElement2 && isToolbarInput(target);
|
|
55103
|
+
const focusState = getFocusState(view.state);
|
|
55104
|
+
if (focusState?.skipFocusReset) {
|
|
55105
|
+
view.dispatch(
|
|
55106
|
+
setFocusMeta(view.state.tr, normalizeSelectionState({ ...focusState, skipFocusReset: false }))
|
|
55107
|
+
);
|
|
55108
|
+
return false;
|
|
55109
|
+
}
|
|
53764
55110
|
if (!isToolbarBtn && !isToolbarInp) {
|
|
53765
55111
|
view.dispatch(
|
|
53766
55112
|
setFocusMeta(view.state.tr, {
|
|
53767
55113
|
focused: false,
|
|
53768
55114
|
preservedSelection: null,
|
|
53769
|
-
showVisualSelection: false
|
|
55115
|
+
showVisualSelection: false,
|
|
55116
|
+
skipFocusReset: false
|
|
53770
55117
|
})
|
|
53771
55118
|
);
|
|
53772
55119
|
}
|
|
@@ -53777,12 +55124,16 @@ const CustomSelection = Extension.create({
|
|
|
53777
55124
|
const isToolbarBtn = isElement2 && isToolbarButton(target);
|
|
53778
55125
|
const isToolbarInp = isElement2 && isToolbarInput(target);
|
|
53779
55126
|
const state2 = getFocusState(view.state);
|
|
55127
|
+
if (state2?.skipFocusReset) {
|
|
55128
|
+
return false;
|
|
55129
|
+
}
|
|
53780
55130
|
if (isToolbarBtn || isToolbarInp) {
|
|
53781
55131
|
view.dispatch(
|
|
53782
55132
|
setFocusMeta(view.state.tr, {
|
|
53783
55133
|
focused: true,
|
|
53784
55134
|
preservedSelection: state2.preservedSelection || view.state.selection,
|
|
53785
|
-
showVisualSelection: true
|
|
55135
|
+
showVisualSelection: true,
|
|
55136
|
+
skipFocusReset: false
|
|
53786
55137
|
})
|
|
53787
55138
|
);
|
|
53788
55139
|
} else {
|
|
@@ -53790,7 +55141,8 @@ const CustomSelection = Extension.create({
|
|
|
53790
55141
|
setFocusMeta(view.state.tr, {
|
|
53791
55142
|
focused: false,
|
|
53792
55143
|
preservedSelection: null,
|
|
53793
|
-
showVisualSelection: false
|
|
55144
|
+
showVisualSelection: false,
|
|
55145
|
+
skipFocusReset: false
|
|
53794
55146
|
})
|
|
53795
55147
|
);
|
|
53796
55148
|
}
|
|
@@ -54636,7 +55988,7 @@ class ListItemNodeView {
|
|
|
54636
55988
|
this.decorations = decorations;
|
|
54637
55989
|
this.view = editor.view;
|
|
54638
55990
|
this.getPos = getPos;
|
|
54639
|
-
__privateMethod$1(this, _ListItemNodeView_instances,
|
|
55991
|
+
__privateMethod$1(this, _ListItemNodeView_instances, init_fn3).call(this);
|
|
54640
55992
|
activeListItemNodeViews.add(this);
|
|
54641
55993
|
}
|
|
54642
55994
|
refreshIndentStyling() {
|
|
@@ -54697,7 +56049,7 @@ class ListItemNodeView {
|
|
|
54697
56049
|
}
|
|
54698
56050
|
}
|
|
54699
56051
|
_ListItemNodeView_instances = /* @__PURE__ */ new WeakSet();
|
|
54700
|
-
|
|
56052
|
+
init_fn3 = function() {
|
|
54701
56053
|
const { attrs } = this.node;
|
|
54702
56054
|
const { listLevel, listNumberingType, lvlText, numId, level, customFormat } = attrs;
|
|
54703
56055
|
let orderMarker = "";
|
|
@@ -61813,977 +63165,328 @@ const PageNumber = Node$1.create({
|
|
|
61813
63165
|
rendered: false
|
|
61814
63166
|
}
|
|
61815
63167
|
};
|
|
61816
|
-
},
|
|
61817
|
-
addNodeView() {
|
|
61818
|
-
return ({ node, editor, getPos, decorations }) => {
|
|
61819
|
-
const htmlAttributes = this.options.htmlAttributes;
|
|
61820
|
-
return new AutoPageNumberNodeView(node, getPos, decorations, editor, htmlAttributes);
|
|
61821
|
-
};
|
|
61822
|
-
},
|
|
61823
|
-
parseDOM() {
|
|
61824
|
-
return [{ tag: 'span[data-id="auto-page-number"' }];
|
|
61825
|
-
},
|
|
61826
|
-
renderDOM({ htmlAttributes }) {
|
|
61827
|
-
return ["span", Attribute2.mergeAttributes(this.options.htmlAttributes, htmlAttributes)];
|
|
61828
|
-
},
|
|
61829
|
-
addCommands() {
|
|
61830
|
-
return {
|
|
61831
|
-
/**
|
|
61832
|
-
* Insert an automatic page number
|
|
61833
|
-
* @category Command
|
|
61834
|
-
* @returns {Function} Command function
|
|
61835
|
-
* @example
|
|
61836
|
-
* editor.commands.addAutoPageNumber()
|
|
61837
|
-
* @note Only works in header/footer contexts
|
|
61838
|
-
*/
|
|
61839
|
-
addAutoPageNumber: () => ({ tr, dispatch, state: state2, editor }) => {
|
|
61840
|
-
const { options } = editor;
|
|
61841
|
-
if (!options.isHeaderOrFooter) return false;
|
|
61842
|
-
const { schema } = state2;
|
|
61843
|
-
const pageNumberType = schema?.nodes?.["page-number"];
|
|
61844
|
-
if (!pageNumberType) return false;
|
|
61845
|
-
const pageNumberNodeJSON = { type: "page-number" };
|
|
61846
|
-
const pageNumberNode = schema.nodeFromJSON(pageNumberNodeJSON);
|
|
61847
|
-
if (dispatch) {
|
|
61848
|
-
tr.replaceSelectionWith(pageNumberNode, false);
|
|
61849
|
-
tr.setMeta("forceUpdatePagination", true);
|
|
61850
|
-
}
|
|
61851
|
-
return true;
|
|
61852
|
-
}
|
|
61853
|
-
};
|
|
61854
|
-
},
|
|
61855
|
-
addShortcuts() {
|
|
61856
|
-
return {
|
|
61857
|
-
"Mod-Shift-alt-p": () => this.editor.commands.addAutoPageNumber()
|
|
61858
|
-
};
|
|
61859
|
-
}
|
|
61860
|
-
});
|
|
61861
|
-
const TotalPageCount = Node$1.create({
|
|
61862
|
-
name: "total-page-number",
|
|
61863
|
-
group: "inline",
|
|
61864
|
-
inline: true,
|
|
61865
|
-
atom: true,
|
|
61866
|
-
draggable: false,
|
|
61867
|
-
selectable: false,
|
|
61868
|
-
content: "text*",
|
|
61869
|
-
addOptions() {
|
|
61870
|
-
return {
|
|
61871
|
-
htmlAttributes: {
|
|
61872
|
-
contenteditable: false,
|
|
61873
|
-
"data-id": "auto-total-pages",
|
|
61874
|
-
"aria-label": "Total page count node",
|
|
61875
|
-
class: "sd-editor-auto-total-pages"
|
|
61876
|
-
}
|
|
61877
|
-
};
|
|
61878
|
-
},
|
|
61879
|
-
addAttributes() {
|
|
61880
|
-
return {
|
|
61881
|
-
marksAsAttrs: {
|
|
61882
|
-
default: null,
|
|
61883
|
-
rendered: false
|
|
61884
|
-
}
|
|
61885
|
-
};
|
|
61886
|
-
},
|
|
61887
|
-
addNodeView() {
|
|
61888
|
-
return ({ node, editor, getPos, decorations }) => {
|
|
61889
|
-
const htmlAttributes = this.options.htmlAttributes;
|
|
61890
|
-
return new AutoPageNumberNodeView(node, getPos, decorations, editor, htmlAttributes);
|
|
61891
|
-
};
|
|
61892
|
-
},
|
|
61893
|
-
parseDOM() {
|
|
61894
|
-
return [{ tag: 'span[data-id="auto-total-pages"' }];
|
|
61895
|
-
},
|
|
61896
|
-
renderDOM({ htmlAttributes }) {
|
|
61897
|
-
return ["span", Attribute2.mergeAttributes(this.options.htmlAttributes, htmlAttributes), 0];
|
|
61898
|
-
},
|
|
61899
|
-
addCommands() {
|
|
61900
|
-
return {
|
|
61901
|
-
/**
|
|
61902
|
-
* Insert total page count
|
|
61903
|
-
* @category Command
|
|
61904
|
-
* @returns {Function} Command function
|
|
61905
|
-
* @example
|
|
61906
|
-
* editor.commands.addTotalPageCount()
|
|
61907
|
-
* @note Only works in header/footer contexts
|
|
61908
|
-
*/
|
|
61909
|
-
addTotalPageCount: () => ({ tr, dispatch, state: state2, editor }) => {
|
|
61910
|
-
const { options } = editor;
|
|
61911
|
-
if (!options.isHeaderOrFooter) return false;
|
|
61912
|
-
const { schema } = state2;
|
|
61913
|
-
const pageNumberType = schema.nodes?.["total-page-number"];
|
|
61914
|
-
if (!pageNumberType) return false;
|
|
61915
|
-
const currentPages = editor?.options?.parentEditor?.currentTotalPages || 1;
|
|
61916
|
-
const pageNumberNode = {
|
|
61917
|
-
type: "total-page-number",
|
|
61918
|
-
content: [{ type: "text", text: String(currentPages) }]
|
|
61919
|
-
};
|
|
61920
|
-
const pageNode = schema.nodeFromJSON(pageNumberNode);
|
|
61921
|
-
if (dispatch) {
|
|
61922
|
-
tr.replaceSelectionWith(pageNode, false);
|
|
61923
|
-
}
|
|
61924
|
-
return true;
|
|
61925
|
-
}
|
|
61926
|
-
};
|
|
61927
|
-
},
|
|
61928
|
-
addShortcuts() {
|
|
61929
|
-
return {
|
|
61930
|
-
"Mod-Shift-alt-c": () => this.editor.commands.addTotalPageCount()
|
|
61931
|
-
};
|
|
61932
|
-
}
|
|
61933
|
-
});
|
|
61934
|
-
const getNodeAttributes = (nodeName, editor) => {
|
|
61935
|
-
switch (nodeName) {
|
|
61936
|
-
case "page-number":
|
|
61937
|
-
return {
|
|
61938
|
-
text: editor.options.currentPageNumber || "1",
|
|
61939
|
-
className: "sd-editor-auto-page-number",
|
|
61940
|
-
dataId: "auto-page-number",
|
|
61941
|
-
ariaLabel: "Page number node"
|
|
61942
|
-
};
|
|
61943
|
-
case "total-page-number":
|
|
61944
|
-
return {
|
|
61945
|
-
text: editor.options.parentEditor?.currentTotalPages || "1",
|
|
61946
|
-
className: "sd-editor-auto-total-pages",
|
|
61947
|
-
dataId: "auto-total-pages",
|
|
61948
|
-
ariaLabel: "Total page count node"
|
|
61949
|
-
};
|
|
61950
|
-
default:
|
|
61951
|
-
return {};
|
|
61952
|
-
}
|
|
61953
|
-
};
|
|
61954
|
-
class AutoPageNumberNodeView {
|
|
61955
|
-
constructor(node, getPos, decorations, editor, htmlAttributes = {}) {
|
|
61956
|
-
__privateAdd$1(this, _AutoPageNumberNodeView_instances);
|
|
61957
|
-
this.node = node;
|
|
61958
|
-
this.editor = editor;
|
|
61959
|
-
this.view = editor.view;
|
|
61960
|
-
this.getPos = getPos;
|
|
61961
|
-
this.editor = editor;
|
|
61962
|
-
this.dom = __privateMethod$1(this, _AutoPageNumberNodeView_instances, renderDom_fn).call(this, node, htmlAttributes);
|
|
61963
|
-
}
|
|
61964
|
-
update(node) {
|
|
61965
|
-
const incomingType = node?.type?.name;
|
|
61966
|
-
const currentType = this.node?.type?.name;
|
|
61967
|
-
if (!incomingType || incomingType !== currentType) return false;
|
|
61968
|
-
this.node = node;
|
|
61969
|
-
return true;
|
|
61970
|
-
}
|
|
61971
|
-
}
|
|
61972
|
-
_AutoPageNumberNodeView_instances = /* @__PURE__ */ new WeakSet();
|
|
61973
|
-
renderDom_fn = function(node, htmlAttributes) {
|
|
61974
|
-
const attrs = getNodeAttributes(this.node.type.name, this.editor);
|
|
61975
|
-
const content = document.createTextNode(String(attrs.text));
|
|
61976
|
-
const nodeContent = document.createElement("span");
|
|
61977
|
-
nodeContent.className = attrs.className;
|
|
61978
|
-
nodeContent.setAttribute("data-id", attrs.dataId);
|
|
61979
|
-
nodeContent.setAttribute("aria-label", attrs.ariaLabel);
|
|
61980
|
-
const currentPos = this.getPos();
|
|
61981
|
-
const { styles, marks } = getMarksFromNeighbors(currentPos, this.view);
|
|
61982
|
-
__privateMethod$1(this, _AutoPageNumberNodeView_instances, scheduleUpdateNodeStyle_fn).call(this, currentPos, marks);
|
|
61983
|
-
Object.assign(nodeContent.style, styles);
|
|
61984
|
-
nodeContent.appendChild(content);
|
|
61985
|
-
Object.entries(htmlAttributes).forEach(([key2, value]) => {
|
|
61986
|
-
if (value) nodeContent.setAttribute(key2, value);
|
|
61987
|
-
});
|
|
61988
|
-
return nodeContent;
|
|
61989
|
-
};
|
|
61990
|
-
scheduleUpdateNodeStyle_fn = function(pos, marks) {
|
|
61991
|
-
setTimeout(() => {
|
|
61992
|
-
const { state: state2 } = this.editor;
|
|
61993
|
-
const { dispatch } = this.view;
|
|
61994
|
-
const node = state2.doc.nodeAt(pos);
|
|
61995
|
-
if (!node || node.isText) return;
|
|
61996
|
-
const currentMarks = node.attrs.marksAsAttrs || [];
|
|
61997
|
-
const newMarks = marks.map((m2) => ({ type: m2.type.name, attrs: m2.attrs }));
|
|
61998
|
-
const isEqual = JSON.stringify(currentMarks) === JSON.stringify(newMarks);
|
|
61999
|
-
if (isEqual) return;
|
|
62000
|
-
const newAttrs = {
|
|
62001
|
-
...node.attrs,
|
|
62002
|
-
marksAsAttrs: newMarks
|
|
62003
|
-
};
|
|
62004
|
-
const tr = state2.tr.setNodeMarkup(pos, void 0, newAttrs);
|
|
62005
|
-
dispatch(tr);
|
|
62006
|
-
}, 0);
|
|
62007
|
-
};
|
|
62008
|
-
const getMarksFromNeighbors = (currentPos, view) => {
|
|
62009
|
-
const $pos = view.state.doc.resolve(currentPos);
|
|
62010
|
-
const styles = {};
|
|
62011
|
-
const marks = [];
|
|
62012
|
-
const before = $pos.nodeBefore;
|
|
62013
|
-
if (before) {
|
|
62014
|
-
Object.assign(styles, processMarks(before.marks));
|
|
62015
|
-
marks.push(...before.marks);
|
|
62016
|
-
}
|
|
62017
|
-
const after = $pos.nodeAfter;
|
|
62018
|
-
if (after) {
|
|
62019
|
-
Object.assign(styles, { ...styles, ...processMarks(after.marks) });
|
|
62020
|
-
marks.push(...after.marks);
|
|
62021
|
-
}
|
|
62022
|
-
return {
|
|
62023
|
-
styles,
|
|
62024
|
-
marks
|
|
62025
|
-
};
|
|
62026
|
-
};
|
|
62027
|
-
const processMarks = (marks) => {
|
|
62028
|
-
const styles = {};
|
|
62029
|
-
marks.forEach((mark) => {
|
|
62030
|
-
const { type: type2, attrs } = mark;
|
|
62031
|
-
switch (type2.name) {
|
|
62032
|
-
case "textStyle":
|
|
62033
|
-
if (attrs.fontFamily) styles["font-family"] = attrs.fontFamily;
|
|
62034
|
-
if (attrs.fontSize) styles["font-size"] = attrs.fontSize;
|
|
62035
|
-
if (attrs.color) styles["color"] = attrs.color;
|
|
62036
|
-
if (attrs.backgroundColor) styles["background-color"] = attrs.backgroundColor;
|
|
62037
|
-
break;
|
|
62038
|
-
case "bold":
|
|
62039
|
-
styles["font-weight"] = "bold";
|
|
62040
|
-
break;
|
|
62041
|
-
case "italic":
|
|
62042
|
-
styles["font-style"] = "italic";
|
|
62043
|
-
break;
|
|
62044
|
-
case "underline":
|
|
62045
|
-
styles["text-decoration"] = (styles["text-decoration"] || "") + " underline";
|
|
62046
|
-
break;
|
|
62047
|
-
case "strike":
|
|
62048
|
-
styles["text-decoration"] = (styles["text-decoration"] || "") + " line-through";
|
|
62049
|
-
break;
|
|
62050
|
-
default:
|
|
62051
|
-
if (attrs?.style) {
|
|
62052
|
-
Object.entries(attrs.style).forEach(([key2, value]) => {
|
|
62053
|
-
styles[key2] = value;
|
|
62054
|
-
});
|
|
62055
|
-
}
|
|
62056
|
-
break;
|
|
62057
|
-
}
|
|
62058
|
-
});
|
|
62059
|
-
return styles;
|
|
62060
|
-
};
|
|
62061
|
-
const ShapeContainer = Node$1.create({
|
|
62062
|
-
name: "shapeContainer",
|
|
62063
|
-
group: "block",
|
|
62064
|
-
content: "block+",
|
|
62065
|
-
isolating: true,
|
|
62066
|
-
addOptions() {
|
|
62067
|
-
return {
|
|
62068
|
-
htmlAttributes: {
|
|
62069
|
-
class: "sd-editor-shape-container",
|
|
62070
|
-
"aria-label": "Shape container node"
|
|
62071
|
-
}
|
|
62072
|
-
};
|
|
62073
|
-
},
|
|
62074
|
-
addAttributes() {
|
|
62075
|
-
return {
|
|
62076
|
-
fillcolor: {
|
|
62077
|
-
renderDOM: (attrs) => {
|
|
62078
|
-
if (!attrs.fillcolor) return {};
|
|
62079
|
-
return {
|
|
62080
|
-
style: `background-color: ${attrs.fillcolor}`
|
|
62081
|
-
};
|
|
62082
|
-
}
|
|
62083
|
-
},
|
|
62084
|
-
sdBlockId: {
|
|
62085
|
-
default: null,
|
|
62086
|
-
keepOnSplit: false,
|
|
62087
|
-
parseDOM: (elem) => elem.getAttribute("data-sd-block-id"),
|
|
62088
|
-
renderDOM: (attrs) => {
|
|
62089
|
-
return attrs.sdBlockId ? { "data-sd-block-id": attrs.sdBlockId } : {};
|
|
62090
|
-
}
|
|
62091
|
-
},
|
|
62092
|
-
style: {
|
|
62093
|
-
renderDOM: (attrs) => {
|
|
62094
|
-
if (!attrs.style) return {};
|
|
62095
|
-
return {
|
|
62096
|
-
style: attrs.style
|
|
62097
|
-
};
|
|
62098
|
-
}
|
|
62099
|
-
},
|
|
62100
|
-
wrapAttributes: {
|
|
62101
|
-
rendered: false
|
|
62102
|
-
},
|
|
62103
|
-
attributes: {
|
|
62104
|
-
rendered: false
|
|
62105
|
-
}
|
|
62106
|
-
};
|
|
62107
|
-
},
|
|
62108
|
-
parseDOM() {
|
|
62109
|
-
return [
|
|
62110
|
-
{
|
|
62111
|
-
tag: `div[data-type="${this.name}"]`
|
|
62112
|
-
}
|
|
62113
|
-
];
|
|
62114
|
-
},
|
|
62115
|
-
renderDOM({ htmlAttributes }) {
|
|
62116
|
-
return [
|
|
62117
|
-
"div",
|
|
62118
|
-
Attribute2.mergeAttributes(this.options.htmlAttributes, htmlAttributes, { "data-type": this.name }),
|
|
62119
|
-
0
|
|
62120
|
-
];
|
|
62121
|
-
}
|
|
62122
|
-
});
|
|
62123
|
-
const ShapeTextbox = Node$1.create({
|
|
62124
|
-
name: "shapeTextbox",
|
|
62125
|
-
group: "block",
|
|
62126
|
-
content: "paragraph* block*",
|
|
62127
|
-
isolating: true,
|
|
62128
|
-
addOptions() {
|
|
62129
|
-
return {
|
|
62130
|
-
htmlAttributes: {
|
|
62131
|
-
class: "sd-editor-shape-textbox",
|
|
62132
|
-
"aria-label": "Shape textbox node"
|
|
62133
|
-
}
|
|
62134
|
-
};
|
|
62135
|
-
},
|
|
62136
|
-
addAttributes() {
|
|
62137
|
-
return {
|
|
62138
|
-
sdBlockId: {
|
|
62139
|
-
default: null,
|
|
62140
|
-
keepOnSplit: false,
|
|
62141
|
-
parseDOM: (elem) => elem.getAttribute("data-sd-block-id"),
|
|
62142
|
-
renderDOM: (attrs) => {
|
|
62143
|
-
return attrs.sdBlockId ? { "data-sd-block-id": attrs.sdBlockId } : {};
|
|
62144
|
-
}
|
|
62145
|
-
},
|
|
62146
|
-
attributes: {
|
|
62147
|
-
rendered: false
|
|
62148
|
-
}
|
|
62149
|
-
};
|
|
62150
|
-
},
|
|
62151
|
-
parseDOM() {
|
|
62152
|
-
return [
|
|
62153
|
-
{
|
|
62154
|
-
tag: `div[data-type="${this.name}"]`
|
|
62155
|
-
}
|
|
62156
|
-
];
|
|
62157
|
-
},
|
|
62158
|
-
renderDOM({ htmlAttributes }) {
|
|
62159
|
-
return [
|
|
62160
|
-
"div",
|
|
62161
|
-
Attribute2.mergeAttributes(this.options.htmlAttributes, htmlAttributes, { "data-type": this.name }),
|
|
62162
|
-
0
|
|
62163
|
-
];
|
|
62164
|
-
}
|
|
62165
|
-
});
|
|
62166
|
-
const ContentBlock = Node$1.create({
|
|
62167
|
-
name: "contentBlock",
|
|
62168
|
-
group: "inline",
|
|
62169
|
-
content: "",
|
|
62170
|
-
isolating: true,
|
|
62171
|
-
atom: true,
|
|
62172
|
-
inline: true,
|
|
62173
|
-
addOptions() {
|
|
62174
|
-
return {
|
|
62175
|
-
htmlAttributes: {
|
|
62176
|
-
contenteditable: false
|
|
62177
|
-
}
|
|
62178
|
-
};
|
|
62179
|
-
},
|
|
62180
|
-
addAttributes() {
|
|
62181
|
-
return {
|
|
62182
|
-
horizontalRule: {
|
|
62183
|
-
default: false,
|
|
62184
|
-
renderDOM: ({ horizontalRule }) => {
|
|
62185
|
-
if (!horizontalRule) return {};
|
|
62186
|
-
return { "data-horizontal-rule": "true" };
|
|
62187
|
-
}
|
|
62188
|
-
},
|
|
62189
|
-
size: {
|
|
62190
|
-
default: null,
|
|
62191
|
-
renderDOM: ({ size: size2 }) => {
|
|
62192
|
-
if (!size2) return {};
|
|
62193
|
-
let style2 = "";
|
|
62194
|
-
if (size2.top) style2 += `top: ${size2.top}px; `;
|
|
62195
|
-
if (size2.left) style2 += `left: ${size2.left}px; `;
|
|
62196
|
-
if (size2.width) style2 += `width: ${size2.width.toString().endsWith("%") ? size2.width : `${size2.width}px`}; `;
|
|
62197
|
-
if (size2.height)
|
|
62198
|
-
style2 += `height: ${size2.height.toString().endsWith("%") ? size2.height : `${size2.height}px`}; `;
|
|
62199
|
-
return { style: style2 };
|
|
62200
|
-
}
|
|
62201
|
-
},
|
|
62202
|
-
background: {
|
|
62203
|
-
default: null,
|
|
62204
|
-
renderDOM: (attrs) => {
|
|
62205
|
-
if (!attrs.background) return {};
|
|
62206
|
-
return {
|
|
62207
|
-
style: `background-color: ${attrs.background}`
|
|
62208
|
-
};
|
|
62209
|
-
}
|
|
62210
|
-
},
|
|
62211
|
-
drawingContent: {
|
|
62212
|
-
rendered: false
|
|
62213
|
-
},
|
|
62214
|
-
attributes: {
|
|
62215
|
-
rendered: false
|
|
62216
|
-
}
|
|
63168
|
+
},
|
|
63169
|
+
addNodeView() {
|
|
63170
|
+
return ({ node, editor, getPos, decorations }) => {
|
|
63171
|
+
const htmlAttributes = this.options.htmlAttributes;
|
|
63172
|
+
return new AutoPageNumberNodeView(node, getPos, decorations, editor, htmlAttributes);
|
|
62217
63173
|
};
|
|
62218
63174
|
},
|
|
62219
63175
|
parseDOM() {
|
|
62220
|
-
return [
|
|
62221
|
-
{
|
|
62222
|
-
tag: `div[data-type="${this.name}"]`
|
|
62223
|
-
}
|
|
62224
|
-
];
|
|
63176
|
+
return [{ tag: 'span[data-id="auto-page-number"' }];
|
|
62225
63177
|
},
|
|
62226
63178
|
renderDOM({ htmlAttributes }) {
|
|
62227
|
-
return ["
|
|
63179
|
+
return ["span", Attribute2.mergeAttributes(this.options.htmlAttributes, htmlAttributes)];
|
|
62228
63180
|
},
|
|
62229
63181
|
addCommands() {
|
|
62230
63182
|
return {
|
|
62231
63183
|
/**
|
|
62232
|
-
* Insert
|
|
62233
|
-
* @category Command
|
|
62234
|
-
* @example
|
|
62235
|
-
* editor.commands.insertHorizontalRule()
|
|
62236
|
-
* @note Creates a visual separator between content sections
|
|
62237
|
-
*/
|
|
62238
|
-
insertHorizontalRule: () => ({ commands: commands2 }) => {
|
|
62239
|
-
return commands2.insertContent({
|
|
62240
|
-
type: this.name,
|
|
62241
|
-
attrs: {
|
|
62242
|
-
horizontalRule: true,
|
|
62243
|
-
size: { width: "100%", height: 2 },
|
|
62244
|
-
background: "#e5e7eb"
|
|
62245
|
-
}
|
|
62246
|
-
});
|
|
62247
|
-
},
|
|
62248
|
-
/**
|
|
62249
|
-
* Insert a content block
|
|
63184
|
+
* Insert an automatic page number
|
|
62250
63185
|
* @category Command
|
|
62251
|
-
* @
|
|
62252
|
-
* @example
|
|
62253
|
-
* // Insert a spacer block
|
|
62254
|
-
* editor.commands.insertContentBlock({ size: { height: 20 } })
|
|
62255
|
-
*
|
|
63186
|
+
* @returns {Function} Command function
|
|
62256
63187
|
* @example
|
|
62257
|
-
*
|
|
62258
|
-
*
|
|
62259
|
-
* size: { width: '50%', height: 3 },
|
|
62260
|
-
* background: '#3b82f6'
|
|
62261
|
-
* })
|
|
62262
|
-
* @note Used for spacing, dividers, and special inline content
|
|
63188
|
+
* editor.commands.addAutoPageNumber()
|
|
63189
|
+
* @note Only works in header/footer contexts
|
|
62263
63190
|
*/
|
|
62264
|
-
|
|
62265
|
-
|
|
62266
|
-
|
|
62267
|
-
|
|
62268
|
-
|
|
63191
|
+
addAutoPageNumber: () => ({ tr, dispatch, state: state2, editor }) => {
|
|
63192
|
+
const { options } = editor;
|
|
63193
|
+
if (!options.isHeaderOrFooter) return false;
|
|
63194
|
+
const { schema } = state2;
|
|
63195
|
+
const pageNumberType = schema?.nodes?.["page-number"];
|
|
63196
|
+
if (!pageNumberType) return false;
|
|
63197
|
+
const pageNumberNodeJSON = { type: "page-number" };
|
|
63198
|
+
const pageNumberNode = schema.nodeFromJSON(pageNumberNodeJSON);
|
|
63199
|
+
if (dispatch) {
|
|
63200
|
+
tr.replaceSelectionWith(pageNumberNode, false);
|
|
63201
|
+
tr.setMeta("forceUpdatePagination", true);
|
|
63202
|
+
}
|
|
63203
|
+
return true;
|
|
62269
63204
|
}
|
|
62270
63205
|
};
|
|
63206
|
+
},
|
|
63207
|
+
addShortcuts() {
|
|
63208
|
+
return {
|
|
63209
|
+
"Mod-Shift-alt-p": () => this.editor.commands.addAutoPageNumber()
|
|
63210
|
+
};
|
|
62271
63211
|
}
|
|
62272
63212
|
});
|
|
62273
|
-
|
|
62274
|
-
|
|
62275
|
-
|
|
62276
|
-
__publicField$1(this, "view");
|
|
62277
|
-
__publicField$1(this, "getPos");
|
|
62278
|
-
__publicField$1(this, "decorations");
|
|
62279
|
-
__publicField$1(this, "innerDecorations");
|
|
62280
|
-
__publicField$1(this, "editor");
|
|
62281
|
-
__publicField$1(this, "extension");
|
|
62282
|
-
__publicField$1(this, "htmlAttributes");
|
|
62283
|
-
__publicField$1(this, "root");
|
|
62284
|
-
__publicField$1(this, "isDragging", false);
|
|
62285
|
-
this.node = props.node;
|
|
62286
|
-
this.view = props.editor.view;
|
|
62287
|
-
this.getPos = props.getPos;
|
|
62288
|
-
this.decorations = props.decorations;
|
|
62289
|
-
this.innerDecorations = props.innerDecorations;
|
|
62290
|
-
this.editor = props.editor;
|
|
62291
|
-
this.extension = props.extension;
|
|
62292
|
-
this.htmlAttributes = props.htmlAttributes;
|
|
62293
|
-
this.mount(props);
|
|
62294
|
-
}
|
|
62295
|
-
mount() {
|
|
62296
|
-
return;
|
|
62297
|
-
}
|
|
62298
|
-
get dom() {
|
|
62299
|
-
return this.root;
|
|
62300
|
-
}
|
|
62301
|
-
get contentDOM() {
|
|
62302
|
-
return null;
|
|
62303
|
-
}
|
|
62304
|
-
update(node, decorations, innerDecorations) {
|
|
62305
|
-
if (node.type !== this.node.type) {
|
|
62306
|
-
return false;
|
|
62307
|
-
}
|
|
62308
|
-
this.node = node;
|
|
62309
|
-
this.decorations = decorations;
|
|
62310
|
-
this.innerDecorations = innerDecorations;
|
|
62311
|
-
this.updateHTMLAttributes();
|
|
62312
|
-
return true;
|
|
62313
|
-
}
|
|
62314
|
-
stopEvent(event) {
|
|
62315
|
-
if (!this.dom) return false;
|
|
62316
|
-
const target = event.target;
|
|
62317
|
-
const isInElement = this.dom.contains(target) && !this.contentDOM?.contains(target);
|
|
62318
|
-
if (!isInElement) return false;
|
|
62319
|
-
const isDragEvent = event.type.startsWith("drag");
|
|
62320
|
-
const isDropEvent = event.type === "drop";
|
|
62321
|
-
const isInput = ["INPUT", "BUTTON", "SELECT", "TEXTAREA"].includes(target.tagName) || target.isContentEditable;
|
|
62322
|
-
if (isInput && !isDropEvent && !isDragEvent) return true;
|
|
62323
|
-
const { isEditable } = this.editor;
|
|
62324
|
-
const { isDragging } = this;
|
|
62325
|
-
const isDraggable = !!this.node.type.spec.draggable;
|
|
62326
|
-
const isSelectable = NodeSelection.isSelectable(this.node);
|
|
62327
|
-
const isCopyEvent = event.type === "copy";
|
|
62328
|
-
const isPasteEvent = event.type === "paste";
|
|
62329
|
-
const isCutEvent = event.type === "cut";
|
|
62330
|
-
const isClickEvent = event.type === "mousedown";
|
|
62331
|
-
if (!isDraggable && isSelectable && isDragEvent && event.target === this.dom) {
|
|
62332
|
-
event.preventDefault();
|
|
62333
|
-
}
|
|
62334
|
-
if (isDraggable && isDragEvent && !isDragging && event.target === this.dom) {
|
|
62335
|
-
event.preventDefault();
|
|
62336
|
-
return false;
|
|
62337
|
-
}
|
|
62338
|
-
if (isDraggable && isEditable && !isDragging && isClickEvent) {
|
|
62339
|
-
const dragHandle = target.closest("[data-drag-handle]");
|
|
62340
|
-
const isValidDragHandle = dragHandle && (this.dom === dragHandle || this.dom.contains(dragHandle));
|
|
62341
|
-
if (isValidDragHandle) {
|
|
62342
|
-
this.isDragging = true;
|
|
62343
|
-
document.addEventListener(
|
|
62344
|
-
"dragend",
|
|
62345
|
-
() => {
|
|
62346
|
-
this.isDragging = false;
|
|
62347
|
-
},
|
|
62348
|
-
{ once: true }
|
|
62349
|
-
);
|
|
62350
|
-
document.addEventListener(
|
|
62351
|
-
"drop",
|
|
62352
|
-
() => {
|
|
62353
|
-
this.isDragging = false;
|
|
62354
|
-
},
|
|
62355
|
-
{ once: true }
|
|
62356
|
-
);
|
|
62357
|
-
document.addEventListener(
|
|
62358
|
-
"mouseup",
|
|
62359
|
-
() => {
|
|
62360
|
-
this.isDragging = false;
|
|
62361
|
-
},
|
|
62362
|
-
{ once: true }
|
|
62363
|
-
);
|
|
62364
|
-
}
|
|
62365
|
-
}
|
|
62366
|
-
if (isDragging || isDropEvent || isCopyEvent || isPasteEvent || isCutEvent || isClickEvent && isSelectable) {
|
|
62367
|
-
return false;
|
|
62368
|
-
}
|
|
62369
|
-
return true;
|
|
62370
|
-
}
|
|
62371
|
-
ignoreMutation(mutation) {
|
|
62372
|
-
if (!this.dom || !this.contentDOM) return true;
|
|
62373
|
-
if (this.node.isLeaf || this.node.isAtom) return true;
|
|
62374
|
-
if (mutation.type === "selection") return false;
|
|
62375
|
-
if (this.contentDOM === mutation.target && mutation.type === "attributes") return true;
|
|
62376
|
-
if (this.contentDOM.contains(mutation.target)) return false;
|
|
62377
|
-
return true;
|
|
62378
|
-
}
|
|
62379
|
-
destroy() {
|
|
62380
|
-
this.dom.remove();
|
|
62381
|
-
this.contentDOM?.remove();
|
|
62382
|
-
}
|
|
62383
|
-
updateAttributes(attrs) {
|
|
62384
|
-
const pos = this.getPos();
|
|
62385
|
-
if (typeof pos !== "number") {
|
|
62386
|
-
return;
|
|
62387
|
-
}
|
|
62388
|
-
return this.view.dispatch(
|
|
62389
|
-
this.view.state.tr.setNodeMarkup(pos, void 0, {
|
|
62390
|
-
...this.node.attrs,
|
|
62391
|
-
...attrs
|
|
62392
|
-
})
|
|
62393
|
-
);
|
|
62394
|
-
}
|
|
62395
|
-
updateHTMLAttributes() {
|
|
62396
|
-
const { extensionService } = this.editor;
|
|
62397
|
-
const { attributes } = extensionService;
|
|
62398
|
-
const extensionAttrs = attributes.filter((i) => i.type === this.node.type.name);
|
|
62399
|
-
this.htmlAttributes = Attribute2.getAttributesToRender(this.node, extensionAttrs);
|
|
62400
|
-
}
|
|
62401
|
-
createDragHandle() {
|
|
62402
|
-
const dragHandle = document.createElement("span");
|
|
62403
|
-
dragHandle.classList.add("sd-structured-content-draggable");
|
|
62404
|
-
dragHandle.draggable = true;
|
|
62405
|
-
dragHandle.contentEditable = "false";
|
|
62406
|
-
dragHandle.dataset.dragHandle = "";
|
|
62407
|
-
const textElement = document.createElement("span");
|
|
62408
|
-
textElement.textContent = "Structured content";
|
|
62409
|
-
dragHandle.append(textElement);
|
|
62410
|
-
return dragHandle;
|
|
62411
|
-
}
|
|
62412
|
-
onDragStart(event) {
|
|
62413
|
-
const { view } = this.editor;
|
|
62414
|
-
const target = event.target;
|
|
62415
|
-
const dragHandle = target.nodeType === 3 ? target.parentElement?.closest("[data-drag-handle]") : target.closest("[data-drag-handle]");
|
|
62416
|
-
if (!this.dom || this.contentDOM?.contains(target) || !dragHandle) {
|
|
62417
|
-
return;
|
|
62418
|
-
}
|
|
62419
|
-
let x = 0;
|
|
62420
|
-
let y2 = 0;
|
|
62421
|
-
if (this.dom !== dragHandle) {
|
|
62422
|
-
const domBox = this.dom.getBoundingClientRect();
|
|
62423
|
-
const handleBox = dragHandle.getBoundingClientRect();
|
|
62424
|
-
const offsetX = event.offsetX ?? event.nativeEvent?.offsetX;
|
|
62425
|
-
const offsetY = event.offsetY ?? event.nativeEvent?.offsetY;
|
|
62426
|
-
x = handleBox.x - domBox.x + offsetX;
|
|
62427
|
-
y2 = handleBox.y - domBox.y + offsetY;
|
|
62428
|
-
}
|
|
62429
|
-
event.dataTransfer?.setDragImage(this.dom, x, y2);
|
|
62430
|
-
const pos = this.getPos();
|
|
62431
|
-
if (typeof pos !== "number") {
|
|
62432
|
-
return;
|
|
62433
|
-
}
|
|
62434
|
-
const selection = NodeSelection.create(view.state.doc, pos);
|
|
62435
|
-
const transaction = view.state.tr.setSelection(selection);
|
|
62436
|
-
view.dispatch(transaction);
|
|
62437
|
-
}
|
|
62438
|
-
}
|
|
62439
|
-
class StructuredContentInlineView extends StructuredContentViewBase {
|
|
62440
|
-
constructor(props) {
|
|
62441
|
-
super(props);
|
|
62442
|
-
}
|
|
62443
|
-
mount() {
|
|
62444
|
-
this.buildView();
|
|
62445
|
-
}
|
|
62446
|
-
get contentDOM() {
|
|
62447
|
-
const contentElement = this.dom?.querySelector(`.${structuredContentInnerClass$1}`);
|
|
62448
|
-
return contentElement || null;
|
|
62449
|
-
}
|
|
62450
|
-
createElement() {
|
|
62451
|
-
const element = document.createElement("span");
|
|
62452
|
-
element.classList.add(structuredContentClass$1);
|
|
62453
|
-
element.setAttribute("data-structured-content", "");
|
|
62454
|
-
const contentElement = document.createElement("span");
|
|
62455
|
-
contentElement.classList.add(structuredContentInnerClass$1);
|
|
62456
|
-
element.append(contentElement);
|
|
62457
|
-
const domAttrs = Attribute2.mergeAttributes(this.htmlAttributes);
|
|
62458
|
-
updateDOMAttributes(element, { ...domAttrs });
|
|
62459
|
-
return { element, contentElement };
|
|
62460
|
-
}
|
|
62461
|
-
buildView() {
|
|
62462
|
-
const { element } = this.createElement();
|
|
62463
|
-
const dragHandle = this.createDragHandle();
|
|
62464
|
-
element.prepend(dragHandle);
|
|
62465
|
-
element.addEventListener("dragstart", (e) => this.onDragStart(e));
|
|
62466
|
-
this.root = element;
|
|
62467
|
-
}
|
|
62468
|
-
updateView() {
|
|
62469
|
-
const domAttrs = Attribute2.mergeAttributes(this.htmlAttributes);
|
|
62470
|
-
updateDOMAttributes(this.dom, { ...domAttrs });
|
|
62471
|
-
}
|
|
62472
|
-
update(node, decorations, innerDecorations) {
|
|
62473
|
-
const result = super.update(node, decorations, innerDecorations);
|
|
62474
|
-
if (!result) return false;
|
|
62475
|
-
this.updateView();
|
|
62476
|
-
return true;
|
|
62477
|
-
}
|
|
62478
|
-
}
|
|
62479
|
-
const structuredContentClass$1 = "sd-structured-content";
|
|
62480
|
-
const structuredContentInnerClass$1 = "sd-structured-content__content";
|
|
62481
|
-
const StructuredContent = Node$1.create({
|
|
62482
|
-
name: "structuredContent",
|
|
62483
|
-
group: "inline structuredContent",
|
|
63213
|
+
const TotalPageCount = Node$1.create({
|
|
63214
|
+
name: "total-page-number",
|
|
63215
|
+
group: "inline",
|
|
62484
63216
|
inline: true,
|
|
62485
|
-
|
|
62486
|
-
|
|
62487
|
-
|
|
62488
|
-
|
|
62489
|
-
draggable: true,
|
|
63217
|
+
atom: true,
|
|
63218
|
+
draggable: false,
|
|
63219
|
+
selectable: false,
|
|
63220
|
+
content: "text*",
|
|
62490
63221
|
addOptions() {
|
|
62491
63222
|
return {
|
|
62492
63223
|
htmlAttributes: {
|
|
62493
|
-
|
|
62494
|
-
"
|
|
63224
|
+
contenteditable: false,
|
|
63225
|
+
"data-id": "auto-total-pages",
|
|
63226
|
+
"aria-label": "Total page count node",
|
|
63227
|
+
class: "sd-editor-auto-total-pages"
|
|
62495
63228
|
}
|
|
62496
63229
|
};
|
|
62497
63230
|
},
|
|
62498
63231
|
addAttributes() {
|
|
62499
63232
|
return {
|
|
62500
|
-
|
|
63233
|
+
marksAsAttrs: {
|
|
62501
63234
|
default: null,
|
|
62502
|
-
parseDOM: (elem) => elem.getAttribute("data-id"),
|
|
62503
|
-
renderDOM: (attrs) => {
|
|
62504
|
-
if (!attrs.id) return {};
|
|
62505
|
-
return { "data-id": attrs.id };
|
|
62506
|
-
}
|
|
62507
|
-
},
|
|
62508
|
-
sdtPr: {
|
|
62509
63235
|
rendered: false
|
|
62510
63236
|
}
|
|
62511
63237
|
};
|
|
62512
63238
|
},
|
|
63239
|
+
addNodeView() {
|
|
63240
|
+
return ({ node, editor, getPos, decorations }) => {
|
|
63241
|
+
const htmlAttributes = this.options.htmlAttributes;
|
|
63242
|
+
return new AutoPageNumberNodeView(node, getPos, decorations, editor, htmlAttributes);
|
|
63243
|
+
};
|
|
63244
|
+
},
|
|
62513
63245
|
parseDOM() {
|
|
62514
|
-
return [{ tag:
|
|
63246
|
+
return [{ tag: 'span[data-id="auto-total-pages"' }];
|
|
62515
63247
|
},
|
|
62516
63248
|
renderDOM({ htmlAttributes }) {
|
|
62517
|
-
return [
|
|
62518
|
-
"span",
|
|
62519
|
-
Attribute2.mergeAttributes(this.options.htmlAttributes, htmlAttributes, {
|
|
62520
|
-
"data-structured-content": ""
|
|
62521
|
-
}),
|
|
62522
|
-
0
|
|
62523
|
-
];
|
|
63249
|
+
return ["span", Attribute2.mergeAttributes(this.options.htmlAttributes, htmlAttributes), 0];
|
|
62524
63250
|
},
|
|
62525
|
-
|
|
62526
|
-
return
|
|
62527
|
-
|
|
63251
|
+
addCommands() {
|
|
63252
|
+
return {
|
|
63253
|
+
/**
|
|
63254
|
+
* Insert total page count
|
|
63255
|
+
* @category Command
|
|
63256
|
+
* @returns {Function} Command function
|
|
63257
|
+
* @example
|
|
63258
|
+
* editor.commands.addTotalPageCount()
|
|
63259
|
+
* @note Only works in header/footer contexts
|
|
63260
|
+
*/
|
|
63261
|
+
addTotalPageCount: () => ({ tr, dispatch, state: state2, editor }) => {
|
|
63262
|
+
const { options } = editor;
|
|
63263
|
+
if (!options.isHeaderOrFooter) return false;
|
|
63264
|
+
const { schema } = state2;
|
|
63265
|
+
const pageNumberType = schema.nodes?.["total-page-number"];
|
|
63266
|
+
if (!pageNumberType) return false;
|
|
63267
|
+
const currentPages = editor?.options?.parentEditor?.currentTotalPages || 1;
|
|
63268
|
+
const pageNumberNode = {
|
|
63269
|
+
type: "total-page-number",
|
|
63270
|
+
content: [{ type: "text", text: String(currentPages) }]
|
|
63271
|
+
};
|
|
63272
|
+
const pageNode = schema.nodeFromJSON(pageNumberNode);
|
|
63273
|
+
if (dispatch) {
|
|
63274
|
+
tr.replaceSelectionWith(pageNode, false);
|
|
63275
|
+
}
|
|
63276
|
+
return true;
|
|
63277
|
+
}
|
|
63278
|
+
};
|
|
63279
|
+
},
|
|
63280
|
+
addShortcuts() {
|
|
63281
|
+
return {
|
|
63282
|
+
"Mod-Shift-alt-c": () => this.editor.commands.addTotalPageCount()
|
|
62528
63283
|
};
|
|
62529
63284
|
}
|
|
62530
63285
|
});
|
|
62531
|
-
|
|
62532
|
-
|
|
62533
|
-
|
|
62534
|
-
|
|
62535
|
-
|
|
62536
|
-
|
|
62537
|
-
|
|
62538
|
-
|
|
62539
|
-
|
|
62540
|
-
|
|
62541
|
-
|
|
62542
|
-
|
|
62543
|
-
|
|
62544
|
-
|
|
62545
|
-
|
|
62546
|
-
|
|
62547
|
-
|
|
62548
|
-
|
|
62549
|
-
const domAttrs = Attribute2.mergeAttributes(this.htmlAttributes);
|
|
62550
|
-
updateDOMAttributes(element, { ...domAttrs });
|
|
62551
|
-
return { element, contentElement };
|
|
62552
|
-
}
|
|
62553
|
-
buildView() {
|
|
62554
|
-
const { element } = this.createElement();
|
|
62555
|
-
const dragHandle = this.createDragHandle();
|
|
62556
|
-
element.prepend(dragHandle);
|
|
62557
|
-
element.addEventListener("dragstart", (e) => this.onDragStart(e));
|
|
62558
|
-
this.root = element;
|
|
63286
|
+
const getNodeAttributes = (nodeName, editor) => {
|
|
63287
|
+
switch (nodeName) {
|
|
63288
|
+
case "page-number":
|
|
63289
|
+
return {
|
|
63290
|
+
text: editor.options.currentPageNumber || "1",
|
|
63291
|
+
className: "sd-editor-auto-page-number",
|
|
63292
|
+
dataId: "auto-page-number",
|
|
63293
|
+
ariaLabel: "Page number node"
|
|
63294
|
+
};
|
|
63295
|
+
case "total-page-number":
|
|
63296
|
+
return {
|
|
63297
|
+
text: editor.options.parentEditor?.currentTotalPages || "1",
|
|
63298
|
+
className: "sd-editor-auto-total-pages",
|
|
63299
|
+
dataId: "auto-total-pages",
|
|
63300
|
+
ariaLabel: "Total page count node"
|
|
63301
|
+
};
|
|
63302
|
+
default:
|
|
63303
|
+
return {};
|
|
62559
63304
|
}
|
|
62560
|
-
|
|
62561
|
-
|
|
62562
|
-
|
|
63305
|
+
};
|
|
63306
|
+
class AutoPageNumberNodeView {
|
|
63307
|
+
constructor(node, getPos, decorations, editor, htmlAttributes = {}) {
|
|
63308
|
+
__privateAdd$1(this, _AutoPageNumberNodeView_instances);
|
|
63309
|
+
this.node = node;
|
|
63310
|
+
this.editor = editor;
|
|
63311
|
+
this.view = editor.view;
|
|
63312
|
+
this.getPos = getPos;
|
|
63313
|
+
this.editor = editor;
|
|
63314
|
+
this.dom = __privateMethod$1(this, _AutoPageNumberNodeView_instances, renderDom_fn).call(this, node, htmlAttributes);
|
|
62563
63315
|
}
|
|
62564
|
-
update(node
|
|
62565
|
-
const
|
|
62566
|
-
|
|
62567
|
-
|
|
63316
|
+
update(node) {
|
|
63317
|
+
const incomingType = node?.type?.name;
|
|
63318
|
+
const currentType = this.node?.type?.name;
|
|
63319
|
+
if (!incomingType || incomingType !== currentType) return false;
|
|
63320
|
+
this.node = node;
|
|
62568
63321
|
return true;
|
|
62569
63322
|
}
|
|
62570
63323
|
}
|
|
62571
|
-
|
|
62572
|
-
|
|
62573
|
-
const
|
|
62574
|
-
|
|
62575
|
-
|
|
62576
|
-
|
|
63324
|
+
_AutoPageNumberNodeView_instances = /* @__PURE__ */ new WeakSet();
|
|
63325
|
+
renderDom_fn = function(node, htmlAttributes) {
|
|
63326
|
+
const attrs = getNodeAttributes(this.node.type.name, this.editor);
|
|
63327
|
+
const content = document.createTextNode(String(attrs.text));
|
|
63328
|
+
const nodeContent = document.createElement("span");
|
|
63329
|
+
nodeContent.className = attrs.className;
|
|
63330
|
+
nodeContent.setAttribute("data-id", attrs.dataId);
|
|
63331
|
+
nodeContent.setAttribute("aria-label", attrs.ariaLabel);
|
|
63332
|
+
const currentPos = this.getPos();
|
|
63333
|
+
const { styles, marks } = getMarksFromNeighbors(currentPos, this.view);
|
|
63334
|
+
__privateMethod$1(this, _AutoPageNumberNodeView_instances, scheduleUpdateNodeStyle_fn).call(this, currentPos, marks);
|
|
63335
|
+
Object.assign(nodeContent.style, styles);
|
|
63336
|
+
nodeContent.appendChild(content);
|
|
63337
|
+
Object.entries(htmlAttributes).forEach(([key2, value]) => {
|
|
63338
|
+
if (value) nodeContent.setAttribute(key2, value);
|
|
63339
|
+
});
|
|
63340
|
+
return nodeContent;
|
|
63341
|
+
};
|
|
63342
|
+
scheduleUpdateNodeStyle_fn = function(pos, marks) {
|
|
63343
|
+
setTimeout(() => {
|
|
63344
|
+
const { state: state2 } = this.editor;
|
|
63345
|
+
const { dispatch } = this.view;
|
|
63346
|
+
const node = state2.doc.nodeAt(pos);
|
|
63347
|
+
if (!node || node.isText) return;
|
|
63348
|
+
const currentMarks = node.attrs.marksAsAttrs || [];
|
|
63349
|
+
const newMarks = marks.map((m2) => ({ type: m2.type.name, attrs: m2.attrs }));
|
|
63350
|
+
const isEqual = JSON.stringify(currentMarks) === JSON.stringify(newMarks);
|
|
63351
|
+
if (isEqual) return;
|
|
63352
|
+
const newAttrs = {
|
|
63353
|
+
...node.attrs,
|
|
63354
|
+
marksAsAttrs: newMarks
|
|
63355
|
+
};
|
|
63356
|
+
const tr = state2.tr.setNodeMarkup(pos, void 0, newAttrs);
|
|
63357
|
+
dispatch(tr);
|
|
63358
|
+
}, 0);
|
|
63359
|
+
};
|
|
63360
|
+
const getMarksFromNeighbors = (currentPos, view) => {
|
|
63361
|
+
const $pos = view.state.doc.resolve(currentPos);
|
|
63362
|
+
const styles = {};
|
|
63363
|
+
const marks = [];
|
|
63364
|
+
const before = $pos.nodeBefore;
|
|
63365
|
+
if (before) {
|
|
63366
|
+
Object.assign(styles, processMarks(before.marks));
|
|
63367
|
+
marks.push(...before.marks);
|
|
63368
|
+
}
|
|
63369
|
+
const after = $pos.nodeAfter;
|
|
63370
|
+
if (after) {
|
|
63371
|
+
Object.assign(styles, { ...styles, ...processMarks(after.marks) });
|
|
63372
|
+
marks.push(...after.marks);
|
|
63373
|
+
}
|
|
63374
|
+
return {
|
|
63375
|
+
styles,
|
|
63376
|
+
marks
|
|
63377
|
+
};
|
|
63378
|
+
};
|
|
63379
|
+
const processMarks = (marks) => {
|
|
63380
|
+
const styles = {};
|
|
63381
|
+
marks.forEach((mark) => {
|
|
63382
|
+
const { type: type2, attrs } = mark;
|
|
63383
|
+
switch (type2.name) {
|
|
63384
|
+
case "textStyle":
|
|
63385
|
+
if (attrs.fontFamily) styles["font-family"] = attrs.fontFamily;
|
|
63386
|
+
if (attrs.fontSize) styles["font-size"] = attrs.fontSize;
|
|
63387
|
+
if (attrs.color) styles["color"] = attrs.color;
|
|
63388
|
+
if (attrs.backgroundColor) styles["background-color"] = attrs.backgroundColor;
|
|
63389
|
+
break;
|
|
63390
|
+
case "bold":
|
|
63391
|
+
styles["font-weight"] = "bold";
|
|
63392
|
+
break;
|
|
63393
|
+
case "italic":
|
|
63394
|
+
styles["font-style"] = "italic";
|
|
63395
|
+
break;
|
|
63396
|
+
case "underline":
|
|
63397
|
+
styles["text-decoration"] = (styles["text-decoration"] || "") + " underline";
|
|
63398
|
+
break;
|
|
63399
|
+
case "strike":
|
|
63400
|
+
styles["text-decoration"] = (styles["text-decoration"] || "") + " line-through";
|
|
63401
|
+
break;
|
|
63402
|
+
default:
|
|
63403
|
+
if (attrs?.style) {
|
|
63404
|
+
Object.entries(attrs.style).forEach(([key2, value]) => {
|
|
63405
|
+
styles[key2] = value;
|
|
63406
|
+
});
|
|
63407
|
+
}
|
|
63408
|
+
break;
|
|
63409
|
+
}
|
|
63410
|
+
});
|
|
63411
|
+
return styles;
|
|
63412
|
+
};
|
|
63413
|
+
const ShapeContainer = Node$1.create({
|
|
63414
|
+
name: "shapeContainer",
|
|
63415
|
+
group: "block",
|
|
63416
|
+
content: "block+",
|
|
62577
63417
|
isolating: true,
|
|
62578
|
-
atom: false,
|
|
62579
|
-
// false - has editable content.
|
|
62580
|
-
draggable: true,
|
|
62581
63418
|
addOptions() {
|
|
62582
63419
|
return {
|
|
62583
63420
|
htmlAttributes: {
|
|
62584
|
-
class:
|
|
62585
|
-
"aria-label": "
|
|
63421
|
+
class: "sd-editor-shape-container",
|
|
63422
|
+
"aria-label": "Shape container node"
|
|
62586
63423
|
}
|
|
62587
63424
|
};
|
|
62588
63425
|
},
|
|
62589
63426
|
addAttributes() {
|
|
62590
63427
|
return {
|
|
62591
|
-
|
|
63428
|
+
fillcolor: {
|
|
63429
|
+
renderDOM: (attrs) => {
|
|
63430
|
+
if (!attrs.fillcolor) return {};
|
|
63431
|
+
return {
|
|
63432
|
+
style: `background-color: ${attrs.fillcolor}`
|
|
63433
|
+
};
|
|
63434
|
+
}
|
|
63435
|
+
},
|
|
63436
|
+
sdBlockId: {
|
|
62592
63437
|
default: null,
|
|
62593
|
-
|
|
63438
|
+
keepOnSplit: false,
|
|
63439
|
+
parseDOM: (elem) => elem.getAttribute("data-sd-block-id"),
|
|
62594
63440
|
renderDOM: (attrs) => {
|
|
62595
|
-
|
|
62596
|
-
return { "data-id": attrs.id };
|
|
63441
|
+
return attrs.sdBlockId ? { "data-sd-block-id": attrs.sdBlockId } : {};
|
|
62597
63442
|
}
|
|
62598
63443
|
},
|
|
62599
|
-
|
|
63444
|
+
style: {
|
|
63445
|
+
renderDOM: (attrs) => {
|
|
63446
|
+
if (!attrs.style) return {};
|
|
63447
|
+
return {
|
|
63448
|
+
style: attrs.style
|
|
63449
|
+
};
|
|
63450
|
+
}
|
|
63451
|
+
},
|
|
63452
|
+
wrapAttributes: {
|
|
63453
|
+
rendered: false
|
|
63454
|
+
},
|
|
63455
|
+
attributes: {
|
|
62600
63456
|
rendered: false
|
|
62601
63457
|
}
|
|
62602
63458
|
};
|
|
62603
63459
|
},
|
|
62604
63460
|
parseDOM() {
|
|
62605
|
-
return [
|
|
63461
|
+
return [
|
|
63462
|
+
{
|
|
63463
|
+
tag: `div[data-type="${this.name}"]`
|
|
63464
|
+
}
|
|
63465
|
+
];
|
|
62606
63466
|
},
|
|
62607
63467
|
renderDOM({ htmlAttributes }) {
|
|
62608
63468
|
return [
|
|
62609
63469
|
"div",
|
|
62610
|
-
Attribute2.mergeAttributes(this.options.htmlAttributes, htmlAttributes, {
|
|
62611
|
-
"data-structured-content-block": ""
|
|
62612
|
-
}),
|
|
63470
|
+
Attribute2.mergeAttributes(this.options.htmlAttributes, htmlAttributes, { "data-type": this.name }),
|
|
62613
63471
|
0
|
|
62614
63472
|
];
|
|
62615
|
-
},
|
|
62616
|
-
addNodeView() {
|
|
62617
|
-
return (props) => {
|
|
62618
|
-
return new StructuredContentBlockView({ ...props });
|
|
62619
|
-
};
|
|
62620
63473
|
}
|
|
62621
63474
|
});
|
|
62622
|
-
|
|
62623
|
-
|
|
62624
|
-
__privateAdd$1(this, _DocumentSectionView_instances);
|
|
62625
|
-
this.node = node;
|
|
62626
|
-
this.editor = editor;
|
|
62627
|
-
this.decorations = decorations;
|
|
62628
|
-
this.view = editor.view;
|
|
62629
|
-
this.getPos = getPos;
|
|
62630
|
-
__privateMethod$1(this, _DocumentSectionView_instances, init_fn3).call(this);
|
|
62631
|
-
}
|
|
62632
|
-
}
|
|
62633
|
-
_DocumentSectionView_instances = /* @__PURE__ */ new WeakSet();
|
|
62634
|
-
init_fn3 = function() {
|
|
62635
|
-
const { attrs } = this.node;
|
|
62636
|
-
const { id, title, description } = attrs;
|
|
62637
|
-
this.dom = document.createElement("div");
|
|
62638
|
-
this.dom.className = "sd-document-section-block";
|
|
62639
|
-
this.dom.setAttribute("data-id", id);
|
|
62640
|
-
this.dom.setAttribute("data-title", title);
|
|
62641
|
-
this.dom.setAttribute("data-description", description);
|
|
62642
|
-
this.dom.setAttribute("aria-label", "Document section");
|
|
62643
|
-
__privateMethod$1(this, _DocumentSectionView_instances, addToolTip_fn).call(this);
|
|
62644
|
-
this.contentDOM = document.createElement("div");
|
|
62645
|
-
this.contentDOM.className = "sd-document-section-block-content";
|
|
62646
|
-
this.contentDOM.setAttribute("contenteditable", "true");
|
|
62647
|
-
this.dom.appendChild(this.contentDOM);
|
|
62648
|
-
};
|
|
62649
|
-
addToolTip_fn = function() {
|
|
62650
|
-
const { title } = this.node.attrs;
|
|
62651
|
-
this.infoDiv = document.createElement("div");
|
|
62652
|
-
this.infoDiv.className = "sd-document-section-block-info";
|
|
62653
|
-
const textSpan = document.createElement("span");
|
|
62654
|
-
textSpan.textContent = title || "Document section";
|
|
62655
|
-
this.infoDiv.appendChild(textSpan);
|
|
62656
|
-
this.infoDiv.setAttribute("contenteditable", "false");
|
|
62657
|
-
this.dom.appendChild(this.infoDiv);
|
|
62658
|
-
};
|
|
62659
|
-
const getAllSections = (editor) => {
|
|
62660
|
-
if (!editor) return [];
|
|
62661
|
-
const type2 = editor.schema.nodes.documentSection;
|
|
62662
|
-
if (!type2) return [];
|
|
62663
|
-
const sections = [];
|
|
62664
|
-
const { state: state2 } = editor;
|
|
62665
|
-
state2.doc.descendants((node, pos) => {
|
|
62666
|
-
if (node.type.name === type2.name) {
|
|
62667
|
-
sections.push({ node, pos });
|
|
62668
|
-
}
|
|
62669
|
-
});
|
|
62670
|
-
return sections;
|
|
62671
|
-
};
|
|
62672
|
-
const exportSectionsToHTML = (editor) => {
|
|
62673
|
-
const sections = getAllSections(editor);
|
|
62674
|
-
const processedSections = /* @__PURE__ */ new Set();
|
|
62675
|
-
const result = [];
|
|
62676
|
-
sections.forEach(({ node }) => {
|
|
62677
|
-
const { attrs } = node;
|
|
62678
|
-
const { id, title, description } = attrs;
|
|
62679
|
-
if (processedSections.has(id)) return;
|
|
62680
|
-
processedSections.add(id);
|
|
62681
|
-
const html = getHTMLFromNode(node, editor);
|
|
62682
|
-
result.push({
|
|
62683
|
-
id,
|
|
62684
|
-
title,
|
|
62685
|
-
description,
|
|
62686
|
-
html
|
|
62687
|
-
});
|
|
62688
|
-
});
|
|
62689
|
-
return result;
|
|
62690
|
-
};
|
|
62691
|
-
const getHTMLFromNode = (node, editor) => {
|
|
62692
|
-
const tempDocument = document.implementation.createHTMLDocument();
|
|
62693
|
-
const container = tempDocument.createElement("div");
|
|
62694
|
-
const fragment = DOMSerializer.fromSchema(editor.schema).serializeFragment(node.content);
|
|
62695
|
-
container.appendChild(fragment);
|
|
62696
|
-
let html = container.innerHTML;
|
|
62697
|
-
return html;
|
|
62698
|
-
};
|
|
62699
|
-
const exportSectionsToJSON = (editor) => {
|
|
62700
|
-
const sections = getAllSections(editor);
|
|
62701
|
-
const processedSections = /* @__PURE__ */ new Set();
|
|
62702
|
-
const result = [];
|
|
62703
|
-
sections.forEach(({ node }) => {
|
|
62704
|
-
const { attrs } = node;
|
|
62705
|
-
const { id, title, description } = attrs;
|
|
62706
|
-
if (processedSections.has(id)) return;
|
|
62707
|
-
processedSections.add(id);
|
|
62708
|
-
result.push({
|
|
62709
|
-
id,
|
|
62710
|
-
title,
|
|
62711
|
-
description,
|
|
62712
|
-
content: node.toJSON()
|
|
62713
|
-
});
|
|
62714
|
-
});
|
|
62715
|
-
return result;
|
|
62716
|
-
};
|
|
62717
|
-
const getLinkedSectionEditor = (id, options, editor) => {
|
|
62718
|
-
const sections = getAllSections(editor);
|
|
62719
|
-
const section = sections.find((s) => s.node.attrs.id === id);
|
|
62720
|
-
if (!section) return null;
|
|
62721
|
-
const child = editor.createChildEditor({
|
|
62722
|
-
...options,
|
|
62723
|
-
onUpdate: ({ editor: childEditor, transaction }) => {
|
|
62724
|
-
const isFromtLinkedParent = transaction.getMeta("fromLinkedParent");
|
|
62725
|
-
if (isFromtLinkedParent) return;
|
|
62726
|
-
const updatedContent = childEditor.state.doc.content;
|
|
62727
|
-
const sectionNode = getAllSections(editor)?.find((s) => s.node.attrs.id === id);
|
|
62728
|
-
if (!sectionNode) return;
|
|
62729
|
-
const { pos, node } = sectionNode;
|
|
62730
|
-
const newNode = node.type.create(node.attrs, updatedContent, node.marks);
|
|
62731
|
-
const tr = editor.state.tr.replaceWith(pos, pos + node.nodeSize, newNode);
|
|
62732
|
-
tr.setMeta("fromLinkedChild", true);
|
|
62733
|
-
editor.view.dispatch(tr);
|
|
62734
|
-
}
|
|
62735
|
-
});
|
|
62736
|
-
editor.on("update", ({ transaction }) => {
|
|
62737
|
-
const isFromLinkedChild = transaction.getMeta("fromLinkedChild");
|
|
62738
|
-
if (isFromLinkedChild) return;
|
|
62739
|
-
const sectionNode = getAllSections(editor)?.find((s) => s.node.attrs.id === id);
|
|
62740
|
-
if (!sectionNode) return;
|
|
62741
|
-
const sectionContent = sectionNode.node.content;
|
|
62742
|
-
const json = {
|
|
62743
|
-
type: "doc",
|
|
62744
|
-
content: sectionContent.content.map((node) => node.toJSON())
|
|
62745
|
-
};
|
|
62746
|
-
const childTr = child.state.tr;
|
|
62747
|
-
childTr.setMeta("fromLinkedParent", true);
|
|
62748
|
-
childTr.replaceWith(0, child.state.doc.content.size, child.schema.nodeFromJSON(json));
|
|
62749
|
-
child.view.dispatch(childTr);
|
|
62750
|
-
});
|
|
62751
|
-
return child;
|
|
62752
|
-
};
|
|
62753
|
-
const SectionHelpers = {
|
|
62754
|
-
getAllSections,
|
|
62755
|
-
exportSectionsToHTML,
|
|
62756
|
-
exportSectionsToJSON,
|
|
62757
|
-
getLinkedSectionEditor
|
|
62758
|
-
};
|
|
62759
|
-
const DocumentSection = Node$1.create({
|
|
62760
|
-
name: "documentSection",
|
|
63475
|
+
const ShapeTextbox = Node$1.create({
|
|
63476
|
+
name: "shapeTextbox",
|
|
62761
63477
|
group: "block",
|
|
62762
|
-
content: "block*",
|
|
62763
|
-
atom: true,
|
|
63478
|
+
content: "paragraph* block*",
|
|
62764
63479
|
isolating: true,
|
|
62765
63480
|
addOptions() {
|
|
62766
63481
|
return {
|
|
62767
63482
|
htmlAttributes: {
|
|
62768
|
-
class: "sd-
|
|
62769
|
-
"aria-label": "
|
|
63483
|
+
class: "sd-editor-shape-textbox",
|
|
63484
|
+
"aria-label": "Shape textbox node"
|
|
62770
63485
|
}
|
|
62771
63486
|
};
|
|
62772
63487
|
},
|
|
62773
|
-
parseDOM() {
|
|
62774
|
-
return [
|
|
62775
|
-
{
|
|
62776
|
-
tag: "div.sd-document-section-block",
|
|
62777
|
-
priority: 60
|
|
62778
|
-
}
|
|
62779
|
-
];
|
|
62780
|
-
},
|
|
62781
|
-
renderDOM({ htmlAttributes }) {
|
|
62782
|
-
return ["div", Attribute2.mergeAttributes(this.options.htmlAttributes, htmlAttributes), 0];
|
|
62783
|
-
},
|
|
62784
63488
|
addAttributes() {
|
|
62785
63489
|
return {
|
|
62786
|
-
id: {},
|
|
62787
63490
|
sdBlockId: {
|
|
62788
63491
|
default: null,
|
|
62789
63492
|
keepOnSplit: false,
|
|
@@ -62792,212 +63495,131 @@ const DocumentSection = Node$1.create({
|
|
|
62792
63495
|
return attrs.sdBlockId ? { "data-sd-block-id": attrs.sdBlockId } : {};
|
|
62793
63496
|
}
|
|
62794
63497
|
},
|
|
62795
|
-
|
|
62796
|
-
|
|
62797
|
-
|
|
62798
|
-
isLocked: { default: false }
|
|
63498
|
+
attributes: {
|
|
63499
|
+
rendered: false
|
|
63500
|
+
}
|
|
62799
63501
|
};
|
|
62800
63502
|
},
|
|
62801
|
-
|
|
62802
|
-
return
|
|
62803
|
-
|
|
63503
|
+
parseDOM() {
|
|
63504
|
+
return [
|
|
63505
|
+
{
|
|
63506
|
+
tag: `div[data-type="${this.name}"]`
|
|
63507
|
+
}
|
|
63508
|
+
];
|
|
63509
|
+
},
|
|
63510
|
+
renderDOM({ htmlAttributes }) {
|
|
63511
|
+
return [
|
|
63512
|
+
"div",
|
|
63513
|
+
Attribute2.mergeAttributes(this.options.htmlAttributes, htmlAttributes, { "data-type": this.name }),
|
|
63514
|
+
0
|
|
63515
|
+
];
|
|
63516
|
+
}
|
|
63517
|
+
});
|
|
63518
|
+
const ContentBlock = Node$1.create({
|
|
63519
|
+
name: "contentBlock",
|
|
63520
|
+
group: "inline",
|
|
63521
|
+
content: "",
|
|
63522
|
+
isolating: true,
|
|
63523
|
+
atom: true,
|
|
63524
|
+
inline: true,
|
|
63525
|
+
addOptions() {
|
|
63526
|
+
return {
|
|
63527
|
+
htmlAttributes: {
|
|
63528
|
+
contenteditable: false
|
|
63529
|
+
}
|
|
62804
63530
|
};
|
|
62805
63531
|
},
|
|
62806
|
-
|
|
63532
|
+
addAttributes() {
|
|
62807
63533
|
return {
|
|
62808
|
-
|
|
62809
|
-
|
|
62810
|
-
|
|
62811
|
-
|
|
62812
|
-
|
|
62813
|
-
* editor.commands.createDocumentSection({
|
|
62814
|
-
* id: 1,
|
|
62815
|
-
* title: 'Terms & Conditions',
|
|
62816
|
-
* isLocked: true,
|
|
62817
|
-
* html: '<p>Legal content...</p>'
|
|
62818
|
-
* })
|
|
62819
|
-
*/
|
|
62820
|
-
createDocumentSection: (options = {}) => ({ tr, state: state2, dispatch, editor }) => {
|
|
62821
|
-
const { selection } = state2;
|
|
62822
|
-
let { from: from2, to } = selection;
|
|
62823
|
-
let content = selection.content().content;
|
|
62824
|
-
const { html: optionsHTML, json: optionsJSON } = options;
|
|
62825
|
-
if (optionsHTML) {
|
|
62826
|
-
const html = htmlHandler(optionsHTML, this.editor);
|
|
62827
|
-
const doc2 = DOMParser$1.fromSchema(this.editor.schema).parse(html);
|
|
62828
|
-
content = doc2.content;
|
|
62829
|
-
}
|
|
62830
|
-
if (optionsJSON) {
|
|
62831
|
-
content = this.editor.schema.nodeFromJSON(optionsJSON);
|
|
62832
|
-
}
|
|
62833
|
-
if (!content?.content?.length) {
|
|
62834
|
-
content = this.editor.schema.nodeFromJSON({ type: "paragraph", content: [] });
|
|
62835
|
-
}
|
|
62836
|
-
if (!options.id) {
|
|
62837
|
-
const allSections = SectionHelpers.getAllSections(editor);
|
|
62838
|
-
options.id = allSections.length + 1;
|
|
62839
|
-
}
|
|
62840
|
-
if (!options.title) {
|
|
62841
|
-
options.title = "Document section";
|
|
62842
|
-
}
|
|
62843
|
-
const node = this.type.createAndFill(options, content);
|
|
62844
|
-
if (!node) return false;
|
|
62845
|
-
const isAlreadyInSdtBlock = findParentNode((node2) => node2.type.name === "documentSection")(selection);
|
|
62846
|
-
if (isAlreadyInSdtBlock && isAlreadyInSdtBlock.node) {
|
|
62847
|
-
const insertPos2 = isAlreadyInSdtBlock.pos + isAlreadyInSdtBlock.node.nodeSize;
|
|
62848
|
-
from2 = insertPos2;
|
|
62849
|
-
to = insertPos2;
|
|
62850
|
-
}
|
|
62851
|
-
tr.replaceRangeWith(from2, to, node);
|
|
62852
|
-
const nodeEnd = from2 + node.nodeSize;
|
|
62853
|
-
let shouldInsertParagraph = true;
|
|
62854
|
-
let insertPos = nodeEnd;
|
|
62855
|
-
if (nodeEnd >= tr.doc.content.size) {
|
|
62856
|
-
insertPos = tr.doc.content.size;
|
|
62857
|
-
if (insertPos > 0) {
|
|
62858
|
-
const $endPos = tr.doc.resolve(insertPos);
|
|
62859
|
-
if ($endPos.nodeBefore && $endPos.nodeBefore.type.name === "paragraph") {
|
|
62860
|
-
shouldInsertParagraph = false;
|
|
62861
|
-
}
|
|
62862
|
-
}
|
|
62863
|
-
}
|
|
62864
|
-
if (shouldInsertParagraph) {
|
|
62865
|
-
const emptyParagraph = tr.doc.type.schema.nodes.paragraph.create();
|
|
62866
|
-
tr.insert(insertPos, emptyParagraph);
|
|
62867
|
-
}
|
|
62868
|
-
if (dispatch) {
|
|
62869
|
-
tr.setMeta("documentSection", { action: "create" });
|
|
62870
|
-
dispatch(tr);
|
|
62871
|
-
setTimeout(() => {
|
|
62872
|
-
try {
|
|
62873
|
-
const currentState = editor.state;
|
|
62874
|
-
const docSize = currentState.doc.content.size;
|
|
62875
|
-
let targetPos = from2 + node.nodeSize;
|
|
62876
|
-
if (shouldInsertParagraph) {
|
|
62877
|
-
targetPos += 1;
|
|
62878
|
-
}
|
|
62879
|
-
targetPos = Math.min(targetPos, docSize);
|
|
62880
|
-
if (targetPos < docSize && targetPos > 0) {
|
|
62881
|
-
const newSelection = Selection.near(currentState.doc.resolve(targetPos));
|
|
62882
|
-
const newTr = currentState.tr.setSelection(newSelection);
|
|
62883
|
-
editor.view.dispatch(newTr);
|
|
62884
|
-
}
|
|
62885
|
-
} catch (e) {
|
|
62886
|
-
console.warn("Could not set delayed selection:", e);
|
|
62887
|
-
}
|
|
62888
|
-
}, 0);
|
|
63534
|
+
horizontalRule: {
|
|
63535
|
+
default: false,
|
|
63536
|
+
renderDOM: ({ horizontalRule }) => {
|
|
63537
|
+
if (!horizontalRule) return {};
|
|
63538
|
+
return { "data-horizontal-rule": "true" };
|
|
62889
63539
|
}
|
|
62890
|
-
return true;
|
|
62891
63540
|
},
|
|
62892
|
-
|
|
62893
|
-
|
|
62894
|
-
|
|
62895
|
-
|
|
62896
|
-
|
|
62897
|
-
|
|
62898
|
-
|
|
62899
|
-
|
|
62900
|
-
|
|
62901
|
-
|
|
62902
|
-
|
|
62903
|
-
const nodeStart = pos;
|
|
62904
|
-
const nodeEnd = nodeStart + node.nodeSize;
|
|
62905
|
-
const contentToPreserve = node.content;
|
|
62906
|
-
tr.delete(nodeStart, nodeEnd);
|
|
62907
|
-
if (contentToPreserve.size > 0) {
|
|
62908
|
-
tr.insert(nodeStart, contentToPreserve);
|
|
62909
|
-
}
|
|
62910
|
-
const newPos = Math.min(nodeStart, tr.doc.content.size);
|
|
62911
|
-
tr.setSelection(Selection.near(tr.doc.resolve(newPos)));
|
|
62912
|
-
if (dispatch) {
|
|
62913
|
-
tr.setMeta("documentSection", { action: "delete" });
|
|
62914
|
-
dispatch(tr);
|
|
63541
|
+
size: {
|
|
63542
|
+
default: null,
|
|
63543
|
+
renderDOM: ({ size: size2 }) => {
|
|
63544
|
+
if (!size2) return {};
|
|
63545
|
+
let style2 = "";
|
|
63546
|
+
if (size2.top) style2 += `top: ${size2.top}px; `;
|
|
63547
|
+
if (size2.left) style2 += `left: ${size2.left}px; `;
|
|
63548
|
+
if (size2.width) style2 += `width: ${size2.width.toString().endsWith("%") ? size2.width : `${size2.width}px`}; `;
|
|
63549
|
+
if (size2.height)
|
|
63550
|
+
style2 += `height: ${size2.height.toString().endsWith("%") ? size2.height : `${size2.height}px`}; `;
|
|
63551
|
+
return { style: style2 };
|
|
62915
63552
|
}
|
|
62916
|
-
return true;
|
|
62917
63553
|
},
|
|
62918
|
-
|
|
62919
|
-
|
|
62920
|
-
|
|
62921
|
-
|
|
62922
|
-
|
|
62923
|
-
|
|
62924
|
-
|
|
62925
|
-
removeSectionById: (id) => ({ tr, dispatch }) => {
|
|
62926
|
-
const sections = SectionHelpers.getAllSections(this.editor);
|
|
62927
|
-
const sectionToRemove = sections.find(({ node: node2 }) => node2.attrs.id === id);
|
|
62928
|
-
if (!sectionToRemove) return false;
|
|
62929
|
-
const { pos, node } = sectionToRemove;
|
|
62930
|
-
const nodeStart = pos;
|
|
62931
|
-
const nodeEnd = nodeStart + node.nodeSize;
|
|
62932
|
-
tr.delete(nodeStart, nodeEnd);
|
|
62933
|
-
if (dispatch) {
|
|
62934
|
-
tr.setMeta("documentSection", { action: "delete", id });
|
|
62935
|
-
dispatch(tr);
|
|
63554
|
+
background: {
|
|
63555
|
+
default: null,
|
|
63556
|
+
renderDOM: (attrs) => {
|
|
63557
|
+
if (!attrs.background) return {};
|
|
63558
|
+
return {
|
|
63559
|
+
style: `background-color: ${attrs.background}`
|
|
63560
|
+
};
|
|
62936
63561
|
}
|
|
62937
|
-
return true;
|
|
62938
63562
|
},
|
|
63563
|
+
drawingContent: {
|
|
63564
|
+
rendered: false
|
|
63565
|
+
},
|
|
63566
|
+
attributes: {
|
|
63567
|
+
rendered: false
|
|
63568
|
+
}
|
|
63569
|
+
};
|
|
63570
|
+
},
|
|
63571
|
+
parseDOM() {
|
|
63572
|
+
return [
|
|
63573
|
+
{
|
|
63574
|
+
tag: `div[data-type="${this.name}"]`
|
|
63575
|
+
}
|
|
63576
|
+
];
|
|
63577
|
+
},
|
|
63578
|
+
renderDOM({ htmlAttributes }) {
|
|
63579
|
+
return ["div", Attribute2.mergeAttributes(this.options.htmlAttributes, htmlAttributes, { "data-type": this.name })];
|
|
63580
|
+
},
|
|
63581
|
+
addCommands() {
|
|
63582
|
+
return {
|
|
62939
63583
|
/**
|
|
62940
|
-
*
|
|
63584
|
+
* Insert a horizontal rule
|
|
62941
63585
|
* @category Command
|
|
62942
|
-
* @param {number} id - Section to lock
|
|
62943
63586
|
* @example
|
|
62944
|
-
* editor.commands.
|
|
63587
|
+
* editor.commands.insertHorizontalRule()
|
|
63588
|
+
* @note Creates a visual separator between content sections
|
|
62945
63589
|
*/
|
|
62946
|
-
|
|
62947
|
-
|
|
62948
|
-
|
|
62949
|
-
|
|
62950
|
-
|
|
62951
|
-
|
|
62952
|
-
|
|
62953
|
-
|
|
62954
|
-
}
|
|
62955
|
-
return true;
|
|
63590
|
+
insertHorizontalRule: () => ({ commands: commands2 }) => {
|
|
63591
|
+
return commands2.insertContent({
|
|
63592
|
+
type: this.name,
|
|
63593
|
+
attrs: {
|
|
63594
|
+
horizontalRule: true,
|
|
63595
|
+
size: { width: "100%", height: 2 },
|
|
63596
|
+
background: "#e5e7eb"
|
|
63597
|
+
}
|
|
63598
|
+
});
|
|
62956
63599
|
},
|
|
62957
63600
|
/**
|
|
62958
|
-
*
|
|
63601
|
+
* Insert a content block
|
|
62959
63602
|
* @category Command
|
|
62960
|
-
* @param {
|
|
63603
|
+
* @param {ContentBlockConfig} config - Block configuration
|
|
62961
63604
|
* @example
|
|
62962
|
-
*
|
|
62963
|
-
* editor.commands.
|
|
62964
|
-
*
|
|
62965
|
-
*
|
|
62966
|
-
*
|
|
62967
|
-
*
|
|
63605
|
+
* // Insert a spacer block
|
|
63606
|
+
* editor.commands.insertContentBlock({ size: { height: 20 } })
|
|
63607
|
+
*
|
|
63608
|
+
* @example
|
|
63609
|
+
* // Insert a colored divider
|
|
63610
|
+
* editor.commands.insertContentBlock({
|
|
63611
|
+
* size: { width: '50%', height: 3 },
|
|
63612
|
+
* background: '#3b82f6'
|
|
62968
63613
|
* })
|
|
63614
|
+
* @note Used for spacing, dividers, and special inline content
|
|
62969
63615
|
*/
|
|
62970
|
-
|
|
62971
|
-
|
|
62972
|
-
|
|
62973
|
-
|
|
62974
|
-
|
|
62975
|
-
let newContent = null;
|
|
62976
|
-
if (html) {
|
|
62977
|
-
const htmlDoc = htmlHandler(html, editor || this.editor);
|
|
62978
|
-
const doc2 = DOMParser$1.fromSchema((editor || this.editor).schema).parse(htmlDoc);
|
|
62979
|
-
newContent = doc2.content;
|
|
62980
|
-
}
|
|
62981
|
-
if (json) {
|
|
62982
|
-
newContent = (editor || this.editor).schema.nodeFromJSON(json);
|
|
62983
|
-
}
|
|
62984
|
-
if (!newContent) {
|
|
62985
|
-
newContent = node.content;
|
|
62986
|
-
}
|
|
62987
|
-
const updatedNode = node.type.create({ ...node.attrs, ...attrs }, newContent, node.marks);
|
|
62988
|
-
tr.replaceWith(pos, pos + node.nodeSize, updatedNode);
|
|
62989
|
-
if (dispatch) {
|
|
62990
|
-
tr.setMeta("documentSection", { action: "update", id, attrs });
|
|
62991
|
-
dispatch(tr);
|
|
62992
|
-
}
|
|
62993
|
-
return true;
|
|
63616
|
+
insertContentBlock: (config2) => ({ commands: commands2 }) => {
|
|
63617
|
+
return commands2.insertContent({
|
|
63618
|
+
type: this.name,
|
|
63619
|
+
attrs: config2
|
|
63620
|
+
});
|
|
62994
63621
|
}
|
|
62995
63622
|
};
|
|
62996
|
-
},
|
|
62997
|
-
addHelpers() {
|
|
62998
|
-
return {
|
|
62999
|
-
...SectionHelpers
|
|
63000
|
-
};
|
|
63001
63623
|
}
|
|
63002
63624
|
});
|
|
63003
63625
|
const { findChildren } = helpers;
|
|
@@ -69565,7 +70187,8 @@ const nodeResizer = (nodeNames = ["image"], editor) => {
|
|
|
69565
70187
|
const prevSelection = prevState.selection;
|
|
69566
70188
|
if (selection.from !== prevSelection.from || selection.to !== prevSelection.to) {
|
|
69567
70189
|
setTimeout(() => {
|
|
69568
|
-
const
|
|
70190
|
+
const searchRoot = editorView?.dom;
|
|
70191
|
+
const selectedResizableWrapper = searchRoot?.querySelector(".sd-editor-resizable-wrapper");
|
|
69569
70192
|
if (selectedResizableWrapper) {
|
|
69570
70193
|
showResizeHandles(view2, selectedResizableWrapper);
|
|
69571
70194
|
} else {
|
|
@@ -69846,6 +70469,7 @@ const getStarterExtensions = () => {
|
|
|
69846
70469
|
Search,
|
|
69847
70470
|
StructuredContent,
|
|
69848
70471
|
StructuredContentBlock,
|
|
70472
|
+
StructuredContentCommands,
|
|
69849
70473
|
DocumentSection,
|
|
69850
70474
|
NodeResizer,
|
|
69851
70475
|
CustomSelection,
|
|
@@ -83101,7 +83725,7 @@ class SuperToolbar extends EventEmitter2 {
|
|
|
83101
83725
|
if (!argument) return;
|
|
83102
83726
|
item.onActivate({ zoom: argument });
|
|
83103
83727
|
this.emit("superdoc-command", { item, argument });
|
|
83104
|
-
const layers =
|
|
83728
|
+
const layers = this.superdoc.element?.querySelector(".layers");
|
|
83105
83729
|
if (!layers) return;
|
|
83106
83730
|
const isMobileDevice = typeof screen.orientation !== "undefined";
|
|
83107
83731
|
const isSmallScreen = window.matchMedia("(max-width: 834px)").matches;
|
|
@@ -84163,14 +84787,6 @@ function getStructureFromResolvedPos(state2, pos) {
|
|
|
84163
84787
|
return null;
|
|
84164
84788
|
}
|
|
84165
84789
|
}
|
|
84166
|
-
const shouldBypassContextMenu = (event) => {
|
|
84167
|
-
if (!event) return false;
|
|
84168
|
-
if (event.ctrlKey || event.metaKey) {
|
|
84169
|
-
return true;
|
|
84170
|
-
}
|
|
84171
|
-
const isKeyboardInvocation = event.type === "contextmenu" && typeof event.detail === "number" && event.detail === 0 && (event.button === 0 || event.button === void 0) && event.clientX === 0 && event.clientY === 0;
|
|
84172
|
-
return Boolean(isKeyboardInvocation);
|
|
84173
|
-
};
|
|
84174
84790
|
const isModuleEnabled = (editorOptions, moduleName) => {
|
|
84175
84791
|
switch (moduleName) {
|
|
84176
84792
|
case "ai":
|