@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
|
@@ -24839,17 +24839,16 @@ const getParagraphSpacing = (node, docx, styleId = "", marks = [], options = {})
|
|
|
24839
24839
|
};
|
|
24840
24840
|
const getDefaultParagraphStyle = (docx, styleId = "") => {
|
|
24841
24841
|
const styles = docx["word/styles.xml"];
|
|
24842
|
-
|
|
24842
|
+
const rootElements = styles?.elements?.[0]?.elements;
|
|
24843
|
+
if (!rootElements?.length) {
|
|
24843
24844
|
return {};
|
|
24844
24845
|
}
|
|
24845
|
-
const defaults =
|
|
24846
|
-
const pDefault = defaults
|
|
24846
|
+
const defaults = rootElements.find((el) => el.name === "w:docDefaults");
|
|
24847
|
+
const pDefault = defaults?.elements?.find((el) => el.name === "w:pPrDefault") || {};
|
|
24847
24848
|
const pPrDefault = pDefault?.elements?.find((el) => el.name === "w:pPr");
|
|
24848
24849
|
const pPrDefaultSpacingTag = pPrDefault?.elements?.find((el) => el.name === "w:spacing") || {};
|
|
24849
24850
|
const pPrDefaultIndentTag = pPrDefault?.elements?.find((el) => el.name === "w:ind") || {};
|
|
24850
|
-
const stylesNormal =
|
|
24851
|
-
(el) => el.name === "w:style" && el.attributes["w:styleId"] === "Normal"
|
|
24852
|
-
);
|
|
24851
|
+
const stylesNormal = rootElements.find((el) => el.name === "w:style" && el.attributes["w:styleId"] === "Normal");
|
|
24853
24852
|
const pPrNormal = stylesNormal?.elements?.find((el) => el.name === "w:pPr");
|
|
24854
24853
|
const pPrNormalSpacingTag = pPrNormal?.elements?.find((el) => el.name === "w:spacing") || {};
|
|
24855
24854
|
const pPrNormalIndentTag = pPrNormal?.elements?.find((el) => el.name === "w:ind") || {};
|
|
@@ -24858,9 +24857,7 @@ const getDefaultParagraphStyle = (docx, styleId = "") => {
|
|
|
24858
24857
|
let pPrStyleIdIndentTag = {};
|
|
24859
24858
|
let pPrStyleJc = {};
|
|
24860
24859
|
if (styleId) {
|
|
24861
|
-
const stylesById =
|
|
24862
|
-
(el) => el.name === "w:style" && el.attributes["w:styleId"] === styleId
|
|
24863
|
-
);
|
|
24860
|
+
const stylesById = rootElements.find((el) => el.name === "w:style" && el.attributes["w:styleId"] === styleId);
|
|
24864
24861
|
const pPrById = stylesById?.elements?.find((el) => el.name === "w:pPr");
|
|
24865
24862
|
pPrStyleIdSpacingTag = pPrById?.elements?.find((el) => el.name === "w:spacing") || {};
|
|
24866
24863
|
pPrStyleIdIndentTag = pPrById?.elements?.find((el) => el.name === "w:ind") || {};
|
|
@@ -27163,6 +27160,68 @@ const config$a = {
|
|
|
27163
27160
|
decode: decode$h
|
|
27164
27161
|
};
|
|
27165
27162
|
const translator$a = NodeTranslator.from(config$a);
|
|
27163
|
+
const DEFAULT_PAGE_WIDTH_TWIPS = 12240;
|
|
27164
|
+
const DEFAULT_PAGE_MARGIN_TWIPS = 1440;
|
|
27165
|
+
const DEFAULT_CONTENT_WIDTH_TWIPS = DEFAULT_PAGE_WIDTH_TWIPS - 2 * DEFAULT_PAGE_MARGIN_TWIPS;
|
|
27166
|
+
const MIN_COLUMN_WIDTH_TWIPS = pixelsToTwips(10);
|
|
27167
|
+
const pctToPercent = (value) => {
|
|
27168
|
+
if (value == null) return null;
|
|
27169
|
+
return value / 50;
|
|
27170
|
+
};
|
|
27171
|
+
const resolveContentWidthTwips = () => DEFAULT_CONTENT_WIDTH_TWIPS;
|
|
27172
|
+
const resolveMeasurementWidthPx = (measurement) => {
|
|
27173
|
+
if (!measurement || typeof measurement.value !== "number" || measurement.value <= 0) return null;
|
|
27174
|
+
const { value, type: type2 } = measurement;
|
|
27175
|
+
if (!type2 || type2 === "auto") return null;
|
|
27176
|
+
if (type2 === "dxa") return twipsToPixels(value);
|
|
27177
|
+
if (type2 === "pct") {
|
|
27178
|
+
const percent2 = pctToPercent(value);
|
|
27179
|
+
if (percent2 == null || percent2 <= 0) return null;
|
|
27180
|
+
const widthTwips = resolveContentWidthTwips() * percent2 / 100;
|
|
27181
|
+
return twipsToPixels(widthTwips);
|
|
27182
|
+
}
|
|
27183
|
+
return null;
|
|
27184
|
+
};
|
|
27185
|
+
const countColumnsInRow = (row) => {
|
|
27186
|
+
if (!row?.elements?.length) return 0;
|
|
27187
|
+
return row.elements.reduce((count, element) => {
|
|
27188
|
+
if (element.name !== "w:tc") return count;
|
|
27189
|
+
const tcPr = element.elements?.find((el) => el.name === "w:tcPr");
|
|
27190
|
+
const gridSpan = tcPr?.elements?.find((el) => el.name === "w:gridSpan");
|
|
27191
|
+
const spanValue = parseInt(gridSpan?.attributes?.["w:val"] || "1", 10);
|
|
27192
|
+
return count + (Number.isFinite(spanValue) && spanValue > 0 ? spanValue : 1);
|
|
27193
|
+
}, 0);
|
|
27194
|
+
};
|
|
27195
|
+
const clampColumnWidthTwips = (value) => Math.max(Math.round(value), MIN_COLUMN_WIDTH_TWIPS);
|
|
27196
|
+
const createFallbackGrid = (columnCount, columnWidthTwips) => Array.from({ length: columnCount }, () => ({ col: clampColumnWidthTwips(columnWidthTwips) }));
|
|
27197
|
+
const buildFallbackGridForTable = ({ params: params2, rows, tableWidth, tableWidthMeasurement }) => {
|
|
27198
|
+
const firstRow = rows.find((row) => row.elements?.some((el) => el.name === "w:tc"));
|
|
27199
|
+
const columnCount = countColumnsInRow(firstRow);
|
|
27200
|
+
if (!columnCount) return null;
|
|
27201
|
+
const schemaDefaultPx = getSchemaDefaultColumnWidthPx(
|
|
27202
|
+
/** @type {any} */
|
|
27203
|
+
params2
|
|
27204
|
+
);
|
|
27205
|
+
const minimumColumnWidthPx = Number.isFinite(schemaDefaultPx) && schemaDefaultPx > 0 ? schemaDefaultPx : DEFAULT_COLUMN_WIDTH_PX;
|
|
27206
|
+
let totalWidthPx;
|
|
27207
|
+
if (tableWidthMeasurement) {
|
|
27208
|
+
const resolved = resolveMeasurementWidthPx(tableWidthMeasurement);
|
|
27209
|
+
if (resolved != null) totalWidthPx = resolved;
|
|
27210
|
+
}
|
|
27211
|
+
if (totalWidthPx == null && tableWidth?.width && tableWidth.width > 0) {
|
|
27212
|
+
totalWidthPx = tableWidth.width;
|
|
27213
|
+
}
|
|
27214
|
+
if (totalWidthPx == null) {
|
|
27215
|
+
totalWidthPx = minimumColumnWidthPx * columnCount;
|
|
27216
|
+
}
|
|
27217
|
+
const rawColumnWidthPx = Math.max(totalWidthPx / columnCount, minimumColumnWidthPx);
|
|
27218
|
+
const columnWidthTwips = clampColumnWidthTwips(pixelsToTwips(rawColumnWidthPx));
|
|
27219
|
+
const fallbackColumnWidthPx = twipsToPixels(columnWidthTwips);
|
|
27220
|
+
return {
|
|
27221
|
+
grid: createFallbackGrid(columnCount, columnWidthTwips),
|
|
27222
|
+
columnWidths: Array(columnCount).fill(fallbackColumnWidthPx)
|
|
27223
|
+
};
|
|
27224
|
+
};
|
|
27166
27225
|
const XML_NODE_NAME$9 = "w:tbl";
|
|
27167
27226
|
const SD_NODE_NAME$9 = "table";
|
|
27168
27227
|
const encode$g = (params2, encodedAttrs) => {
|
|
@@ -27182,7 +27241,6 @@ const encode$g = (params2, encodedAttrs) => {
|
|
|
27182
27241
|
"justification",
|
|
27183
27242
|
"tableLayout",
|
|
27184
27243
|
["tableIndent", ({ value, type: type2 }) => ({ width: twipsToPixels(value), type: type2 })],
|
|
27185
|
-
["tableWidth", ({ value, type: type2 }) => ({ width: twipsToPixels(value), type: type2 })],
|
|
27186
27244
|
["tableCellSpacing", ({ value, type: type2 }) => ({ w: String(value), type: type2 })]
|
|
27187
27245
|
].forEach((prop) => {
|
|
27188
27246
|
let key2;
|
|
@@ -27200,6 +27258,21 @@ const encode$g = (params2, encodedAttrs) => {
|
|
|
27200
27258
|
if (encodedAttrs.tableCellSpacing) {
|
|
27201
27259
|
encodedAttrs["borderCollapse"] = "separate";
|
|
27202
27260
|
}
|
|
27261
|
+
if (encodedAttrs.tableProperties?.tableWidth) {
|
|
27262
|
+
const tableWidthMeasurement = encodedAttrs.tableProperties.tableWidth;
|
|
27263
|
+
const widthPx = twipsToPixels(tableWidthMeasurement.value);
|
|
27264
|
+
if (widthPx != null) {
|
|
27265
|
+
encodedAttrs.tableWidth = {
|
|
27266
|
+
width: widthPx,
|
|
27267
|
+
type: tableWidthMeasurement.type
|
|
27268
|
+
};
|
|
27269
|
+
} else if (tableWidthMeasurement.type === "auto") {
|
|
27270
|
+
encodedAttrs.tableWidth = {
|
|
27271
|
+
width: 0,
|
|
27272
|
+
type: tableWidthMeasurement.type
|
|
27273
|
+
};
|
|
27274
|
+
}
|
|
27275
|
+
}
|
|
27203
27276
|
const { borders, rowBorders } = _processTableBorders(encodedAttrs.tableProperties?.borders || {});
|
|
27204
27277
|
const referencedStyles = _getReferencedTableStyles(encodedAttrs.tableStyleId, params2);
|
|
27205
27278
|
if (referencedStyles?.cellMargins && !encodedAttrs.tableProperties?.cellMargins) {
|
|
@@ -27213,7 +27286,19 @@ const encode$g = (params2, encodedAttrs) => {
|
|
|
27213
27286
|
const borderRowData = Object.assign({}, referencedStyles?.rowBorders || {}, rowBorders || {});
|
|
27214
27287
|
encodedAttrs["borders"] = borderData;
|
|
27215
27288
|
const tblStyleTag = tblPr?.elements?.find((el) => el.name === "w:tblStyle");
|
|
27216
|
-
|
|
27289
|
+
let columnWidths = Array.isArray(encodedAttrs["grid"]) ? encodedAttrs["grid"].map((item) => twipsToPixels(item.col)) : [];
|
|
27290
|
+
if (!columnWidths.length) {
|
|
27291
|
+
const fallback = buildFallbackGridForTable({
|
|
27292
|
+
params: params2,
|
|
27293
|
+
rows,
|
|
27294
|
+
tableWidth: encodedAttrs.tableWidth,
|
|
27295
|
+
tableWidthMeasurement: encodedAttrs.tableProperties?.tableWidth
|
|
27296
|
+
});
|
|
27297
|
+
if (fallback) {
|
|
27298
|
+
encodedAttrs.grid = fallback.grid;
|
|
27299
|
+
columnWidths = fallback.columnWidths;
|
|
27300
|
+
}
|
|
27301
|
+
}
|
|
27217
27302
|
const content = [];
|
|
27218
27303
|
rows.forEach((row) => {
|
|
27219
27304
|
const result = translator$G.encode({
|
|
@@ -28075,6 +28160,9 @@ function handleStructuredContentNode(params2) {
|
|
|
28075
28160
|
const node = nodes[0];
|
|
28076
28161
|
const sdtPr = node.elements.find((el) => el.name === "w:sdtPr");
|
|
28077
28162
|
const sdtContent = node.elements.find((el) => el.name === "w:sdtContent");
|
|
28163
|
+
const id = sdtPr?.elements?.find((el) => el.name === "w:id");
|
|
28164
|
+
const tag = sdtPr?.elements?.find((el) => el.name === "w:tag");
|
|
28165
|
+
const alias = sdtPr?.elements?.find((el) => el.name === "w:alias");
|
|
28078
28166
|
if (!sdtContent) {
|
|
28079
28167
|
return null;
|
|
28080
28168
|
}
|
|
@@ -28086,15 +28174,16 @@ function handleStructuredContentNode(params2) {
|
|
|
28086
28174
|
nodes: sdtContent.elements,
|
|
28087
28175
|
path: [...params2.path || [], sdtContent]
|
|
28088
28176
|
});
|
|
28089
|
-
|
|
28090
|
-
|
|
28091
|
-
sdtContentType = "structuredContentBlock";
|
|
28092
|
-
}
|
|
28177
|
+
const isBlockNode2 = paragraph || table;
|
|
28178
|
+
const sdtContentType = isBlockNode2 ? "structuredContentBlock" : "structuredContent";
|
|
28093
28179
|
let result = {
|
|
28094
28180
|
type: sdtContentType,
|
|
28095
28181
|
content: translatedContent,
|
|
28096
28182
|
marks,
|
|
28097
28183
|
attrs: {
|
|
28184
|
+
id: id?.attributes?.["w:val"] || null,
|
|
28185
|
+
tag: tag?.attributes?.["w:val"] || null,
|
|
28186
|
+
alias: alias?.attributes?.["w:val"] || null,
|
|
28098
28187
|
sdtPr
|
|
28099
28188
|
}
|
|
28100
28189
|
};
|
|
@@ -30352,21 +30441,55 @@ const generateSdtPrTagForDocumentSection = (id, title, tag) => {
|
|
|
30352
30441
|
};
|
|
30353
30442
|
function translateStructuredContent(params2) {
|
|
30354
30443
|
const { node } = params2;
|
|
30355
|
-
const { attrs = {} } = node;
|
|
30356
30444
|
const childContent = translateChildNodes({ ...params2, nodes: node.content });
|
|
30357
|
-
const
|
|
30358
|
-
|
|
30359
|
-
|
|
30360
|
-
elements: childContent
|
|
30361
|
-
}
|
|
30362
|
-
];
|
|
30363
|
-
nodeElements.unshift(attrs.sdtPr);
|
|
30445
|
+
const sdtContent = { name: "w:sdtContent", elements: childContent };
|
|
30446
|
+
const sdtPr = generateSdtPrTagForStructuredContent({ node });
|
|
30447
|
+
const nodeElements = [sdtPr, sdtContent];
|
|
30364
30448
|
const result = {
|
|
30365
30449
|
name: "w:sdt",
|
|
30366
30450
|
elements: nodeElements
|
|
30367
30451
|
};
|
|
30368
30452
|
return result;
|
|
30369
30453
|
}
|
|
30454
|
+
function generateSdtPrTagForStructuredContent({ node }) {
|
|
30455
|
+
const { attrs = {} } = node;
|
|
30456
|
+
const id = {
|
|
30457
|
+
name: "w:id",
|
|
30458
|
+
type: "element",
|
|
30459
|
+
attributes: { "w:val": attrs.id }
|
|
30460
|
+
};
|
|
30461
|
+
const alias = {
|
|
30462
|
+
name: "w:alias",
|
|
30463
|
+
type: "element",
|
|
30464
|
+
attributes: { "w:val": attrs.alias }
|
|
30465
|
+
};
|
|
30466
|
+
const tag = {
|
|
30467
|
+
name: "w:tag",
|
|
30468
|
+
type: "element",
|
|
30469
|
+
attributes: { "w:val": attrs.tag }
|
|
30470
|
+
};
|
|
30471
|
+
const resultElements = [];
|
|
30472
|
+
if (attrs.id) resultElements.push(id);
|
|
30473
|
+
if (attrs.alias) resultElements.push(alias);
|
|
30474
|
+
if (attrs.tag) resultElements.push(tag);
|
|
30475
|
+
if (attrs.sdtPr) {
|
|
30476
|
+
const elements = attrs.sdtPr.elements || [];
|
|
30477
|
+
const elementsToExclude = ["w:id", "w:alias", "w:tag"];
|
|
30478
|
+
const restElements = elements.filter((el) => !elementsToExclude.includes(el.name));
|
|
30479
|
+
const result2 = {
|
|
30480
|
+
name: "w:sdtPr",
|
|
30481
|
+
type: "element",
|
|
30482
|
+
elements: [...resultElements, ...restElements]
|
|
30483
|
+
};
|
|
30484
|
+
return result2;
|
|
30485
|
+
}
|
|
30486
|
+
const result = {
|
|
30487
|
+
name: "w:sdtPr",
|
|
30488
|
+
type: "element",
|
|
30489
|
+
elements: resultElements
|
|
30490
|
+
};
|
|
30491
|
+
return result;
|
|
30492
|
+
}
|
|
30370
30493
|
const XML_NODE_NAME$3 = "w:sdt";
|
|
30371
30494
|
const SD_NODE_NAME$3 = ["fieldAnnotation", "structuredContent", "structuredContentBlock", "documentSection"];
|
|
30372
30495
|
const validXmlAttributes$3 = [];
|
|
@@ -30594,6 +30717,63 @@ const config = {
|
|
|
30594
30717
|
attributes: validXmlAttributes
|
|
30595
30718
|
};
|
|
30596
30719
|
const translator = NodeTranslator.from(config);
|
|
30720
|
+
const DEFAULT_SECTION_PROPS_TWIPS = Object.freeze({
|
|
30721
|
+
pageSize: Object.freeze({ width: "12240", height: "15840" }),
|
|
30722
|
+
pageMargins: Object.freeze({
|
|
30723
|
+
top: "1440",
|
|
30724
|
+
right: "1440",
|
|
30725
|
+
bottom: "1440",
|
|
30726
|
+
left: "1440",
|
|
30727
|
+
header: "720",
|
|
30728
|
+
footer: "720",
|
|
30729
|
+
gutter: "0"
|
|
30730
|
+
})
|
|
30731
|
+
});
|
|
30732
|
+
const ensureSectionLayoutDefaults = (sectPr, converter) => {
|
|
30733
|
+
if (!sectPr) {
|
|
30734
|
+
return {
|
|
30735
|
+
type: "element",
|
|
30736
|
+
name: "w:sectPr",
|
|
30737
|
+
elements: []
|
|
30738
|
+
};
|
|
30739
|
+
}
|
|
30740
|
+
if (!sectPr.elements) sectPr.elements = [];
|
|
30741
|
+
const ensureChild = (name) => {
|
|
30742
|
+
let child = sectPr.elements.find((n) => n.name === name);
|
|
30743
|
+
if (!child) {
|
|
30744
|
+
child = {
|
|
30745
|
+
type: "element",
|
|
30746
|
+
name,
|
|
30747
|
+
elements: [],
|
|
30748
|
+
attributes: {}
|
|
30749
|
+
};
|
|
30750
|
+
sectPr.elements.push(child);
|
|
30751
|
+
} else {
|
|
30752
|
+
if (!child.elements) child.elements = [];
|
|
30753
|
+
if (!child.attributes) child.attributes = {};
|
|
30754
|
+
}
|
|
30755
|
+
return child;
|
|
30756
|
+
};
|
|
30757
|
+
const pageSize = converter?.pageStyles?.pageSize;
|
|
30758
|
+
const pgSz = ensureChild("w:pgSz");
|
|
30759
|
+
if (pageSize?.width != null) pgSz.attributes["w:w"] = String(inchesToTwips(pageSize.width));
|
|
30760
|
+
if (pageSize?.height != null) pgSz.attributes["w:h"] = String(inchesToTwips(pageSize.height));
|
|
30761
|
+
if (pgSz.attributes["w:w"] == null) pgSz.attributes["w:w"] = DEFAULT_SECTION_PROPS_TWIPS.pageSize.width;
|
|
30762
|
+
if (pgSz.attributes["w:h"] == null) pgSz.attributes["w:h"] = DEFAULT_SECTION_PROPS_TWIPS.pageSize.height;
|
|
30763
|
+
const pageMargins = converter?.pageStyles?.pageMargins;
|
|
30764
|
+
const pgMar = ensureChild("w:pgMar");
|
|
30765
|
+
if (pageMargins) {
|
|
30766
|
+
Object.entries(pageMargins).forEach(([key2, value]) => {
|
|
30767
|
+
const converted = inchesToTwips(value);
|
|
30768
|
+
if (converted != null) pgMar.attributes[`w:${key2}`] = String(converted);
|
|
30769
|
+
});
|
|
30770
|
+
}
|
|
30771
|
+
Object.entries(DEFAULT_SECTION_PROPS_TWIPS.pageMargins).forEach(([key2, value]) => {
|
|
30772
|
+
const attrKey = `w:${key2}`;
|
|
30773
|
+
if (pgMar.attributes[attrKey] == null) pgMar.attributes[attrKey] = value;
|
|
30774
|
+
});
|
|
30775
|
+
return sectPr;
|
|
30776
|
+
};
|
|
30597
30777
|
const isLineBreakOnlyRun = (node) => {
|
|
30598
30778
|
if (!node) return false;
|
|
30599
30779
|
if (node.type === "lineBreak" || node.type === "hardBreak") return true;
|
|
@@ -30646,28 +30826,30 @@ function exportSchemaToJson(params2) {
|
|
|
30646
30826
|
return handler2(params2);
|
|
30647
30827
|
}
|
|
30648
30828
|
function translateBodyNode(params2) {
|
|
30649
|
-
let sectPr = params2.bodyNode?.elements
|
|
30829
|
+
let sectPr = params2.bodyNode?.elements?.find((n) => n.name === "w:sectPr");
|
|
30830
|
+
if (!sectPr) {
|
|
30831
|
+
sectPr = {
|
|
30832
|
+
type: "element",
|
|
30833
|
+
name: "w:sectPr",
|
|
30834
|
+
elements: []
|
|
30835
|
+
};
|
|
30836
|
+
} else if (!sectPr.elements) {
|
|
30837
|
+
sectPr = { ...sectPr, elements: [] };
|
|
30838
|
+
}
|
|
30839
|
+
sectPr = ensureSectionLayoutDefaults(sectPr, params2.converter);
|
|
30650
30840
|
if (params2.converter) {
|
|
30651
|
-
const hasHeader = sectPr
|
|
30841
|
+
const hasHeader = sectPr.elements?.some((n) => n.name === "w:headerReference");
|
|
30652
30842
|
const hasDefaultHeader = params2.converter.headerIds?.default;
|
|
30653
30843
|
if (!hasHeader && hasDefaultHeader && !params2.editor.options.isHeaderOrFooter) {
|
|
30654
30844
|
const defaultHeader = generateDefaultHeaderFooter("header", params2.converter.headerIds?.default);
|
|
30655
30845
|
sectPr.elements.push(defaultHeader);
|
|
30656
30846
|
}
|
|
30657
|
-
const hasFooter = sectPr
|
|
30847
|
+
const hasFooter = sectPr.elements?.some((n) => n.name === "w:footerReference");
|
|
30658
30848
|
const hasDefaultFooter = params2.converter.footerIds?.default;
|
|
30659
30849
|
if (!hasFooter && hasDefaultFooter && !params2.editor.options.isHeaderOrFooter) {
|
|
30660
30850
|
const defaultFooter = generateDefaultHeaderFooter("footer", params2.converter.footerIds?.default);
|
|
30661
30851
|
sectPr.elements.push(defaultFooter);
|
|
30662
30852
|
}
|
|
30663
|
-
const newMargins = params2.converter.pageStyles.pageMargins;
|
|
30664
|
-
const sectPrMargins = sectPr.elements.find((n) => n.name === "w:pgMar");
|
|
30665
|
-
const { attributes } = sectPrMargins;
|
|
30666
|
-
Object.entries(newMargins).forEach(([key2, value]) => {
|
|
30667
|
-
const convertedValue = inchesToTwips(value);
|
|
30668
|
-
attributes[`w:${key2}`] = convertedValue;
|
|
30669
|
-
});
|
|
30670
|
-
sectPrMargins.attributes = attributes;
|
|
30671
30853
|
}
|
|
30672
30854
|
const elements = translateChildNodes(params2);
|
|
30673
30855
|
if (params2.isHeaderFooter) {
|
|
@@ -32094,8 +32276,15 @@ const handlePictNode = (params2) => {
|
|
|
32094
32276
|
return { nodes: [], consumed: 0 };
|
|
32095
32277
|
}
|
|
32096
32278
|
const [pNode] = nodes;
|
|
32097
|
-
const
|
|
32098
|
-
|
|
32279
|
+
const runs = pNode.elements?.filter((el) => el.name === "w:r") || [];
|
|
32280
|
+
let pict = null;
|
|
32281
|
+
for (const run2 of runs) {
|
|
32282
|
+
const foundPict = run2.elements?.find((el) => el.name === "w:pict");
|
|
32283
|
+
if (foundPict) {
|
|
32284
|
+
pict = foundPict;
|
|
32285
|
+
break;
|
|
32286
|
+
}
|
|
32287
|
+
}
|
|
32099
32288
|
if (!pict) {
|
|
32100
32289
|
return { nodes: [], consumed: 0 };
|
|
32101
32290
|
}
|
|
@@ -32682,6 +32871,7 @@ const createDocumentJson = (docx, converter, editor) => {
|
|
|
32682
32871
|
const nodeListHandler = defaultNodeListHandler();
|
|
32683
32872
|
const bodyNode = json.elements[0].elements.find((el) => el.name === "w:body");
|
|
32684
32873
|
if (bodyNode) {
|
|
32874
|
+
ensureSectionProperties(bodyNode);
|
|
32685
32875
|
const node = bodyNode;
|
|
32686
32876
|
const contentElements = node.elements?.filter((n) => n.name !== "w:sectPr") ?? [];
|
|
32687
32877
|
const content = pruneIgnoredNodes(contentElements);
|
|
@@ -32915,6 +33105,59 @@ function getDocumentStyles(node, docx, converter, editor) {
|
|
|
32915
33105
|
styles.alternateHeaders = isAlternatingHeadersOddEven(docx);
|
|
32916
33106
|
return styles;
|
|
32917
33107
|
}
|
|
33108
|
+
const DEFAULT_SECTION_PROPS = Object.freeze({
|
|
33109
|
+
pageSize: Object.freeze({ width: "12240", height: "15840" }),
|
|
33110
|
+
pageMargins: Object.freeze({
|
|
33111
|
+
top: "1440",
|
|
33112
|
+
right: "1440",
|
|
33113
|
+
bottom: "1440",
|
|
33114
|
+
left: "1440",
|
|
33115
|
+
header: "720",
|
|
33116
|
+
footer: "720",
|
|
33117
|
+
gutter: "0"
|
|
33118
|
+
})
|
|
33119
|
+
});
|
|
33120
|
+
function ensureSectionProperties(bodyNode, converter) {
|
|
33121
|
+
if (!bodyNode.elements) bodyNode.elements = [];
|
|
33122
|
+
let sectPr = bodyNode.elements.find((el) => el.name === "w:sectPr");
|
|
33123
|
+
if (!sectPr) {
|
|
33124
|
+
sectPr = {
|
|
33125
|
+
type: "element",
|
|
33126
|
+
name: "w:sectPr",
|
|
33127
|
+
elements: []
|
|
33128
|
+
};
|
|
33129
|
+
bodyNode.elements.push(sectPr);
|
|
33130
|
+
} else if (!sectPr.elements) {
|
|
33131
|
+
sectPr.elements = [];
|
|
33132
|
+
}
|
|
33133
|
+
const ensureChild = (name, factory) => {
|
|
33134
|
+
let child = sectPr.elements.find((el) => el.name === name);
|
|
33135
|
+
if (!child) {
|
|
33136
|
+
child = factory();
|
|
33137
|
+
sectPr.elements.push(child);
|
|
33138
|
+
} else if (!child.attributes) {
|
|
33139
|
+
child.attributes = {};
|
|
33140
|
+
}
|
|
33141
|
+
return child;
|
|
33142
|
+
};
|
|
33143
|
+
const pgSz = ensureChild("w:pgSz", () => ({
|
|
33144
|
+
type: "element",
|
|
33145
|
+
name: "w:pgSz",
|
|
33146
|
+
attributes: {}
|
|
33147
|
+
}));
|
|
33148
|
+
pgSz.attributes["w:w"] = pgSz.attributes["w:w"] ?? DEFAULT_SECTION_PROPS.pageSize.width;
|
|
33149
|
+
pgSz.attributes["w:h"] = pgSz.attributes["w:h"] ?? DEFAULT_SECTION_PROPS.pageSize.height;
|
|
33150
|
+
const pgMar = ensureChild("w:pgMar", () => ({
|
|
33151
|
+
type: "element",
|
|
33152
|
+
name: "w:pgMar",
|
|
33153
|
+
attributes: {}
|
|
33154
|
+
}));
|
|
33155
|
+
Object.entries(DEFAULT_SECTION_PROPS.pageMargins).forEach(([key2, value]) => {
|
|
33156
|
+
const attrKey = `w:${key2}`;
|
|
33157
|
+
if (pgMar.attributes[attrKey] == null) pgMar.attributes[attrKey] = value;
|
|
33158
|
+
});
|
|
33159
|
+
return sectPr;
|
|
33160
|
+
}
|
|
32918
33161
|
function getStyleDefinitions(docx) {
|
|
32919
33162
|
const styles = docx["word/styles.xml"];
|
|
32920
33163
|
if (!styles) return [];
|
|
@@ -33107,6 +33350,36 @@ const FONT_FAMILY_FALLBACKS = Object.freeze({
|
|
|
33107
33350
|
auto: "sans-serif"
|
|
33108
33351
|
});
|
|
33109
33352
|
const DEFAULT_GENERIC_FALLBACK = "sans-serif";
|
|
33353
|
+
const DEFAULT_FONT_SIZE_PT = 10;
|
|
33354
|
+
const collectRunDefaultProperties = (runProps, { allowOverrideTypeface = true, allowOverrideSize = true, themeResolver, state: state2 }) => {
|
|
33355
|
+
if (!runProps?.elements?.length || !state2) return;
|
|
33356
|
+
const fontsNode = runProps.elements.find((el) => el.name === "w:rFonts");
|
|
33357
|
+
if (fontsNode?.attributes) {
|
|
33358
|
+
const themeName = fontsNode.attributes["w:asciiTheme"];
|
|
33359
|
+
if (themeName) {
|
|
33360
|
+
const themeInfo = themeResolver?.(themeName) || {};
|
|
33361
|
+
if ((allowOverrideTypeface || !state2.typeface) && themeInfo.typeface) state2.typeface = themeInfo.typeface;
|
|
33362
|
+
if ((allowOverrideTypeface || !state2.panose) && themeInfo.panose) state2.panose = themeInfo.panose;
|
|
33363
|
+
}
|
|
33364
|
+
const ascii = fontsNode.attributes["w:ascii"];
|
|
33365
|
+
if ((allowOverrideTypeface || !state2.typeface) && ascii) {
|
|
33366
|
+
state2.typeface = ascii;
|
|
33367
|
+
}
|
|
33368
|
+
}
|
|
33369
|
+
const sizeNode = runProps.elements.find((el) => el.name === "w:sz");
|
|
33370
|
+
if (sizeNode?.attributes?.["w:val"]) {
|
|
33371
|
+
const sizeTwips = Number(sizeNode.attributes["w:val"]);
|
|
33372
|
+
if (Number.isFinite(sizeTwips)) {
|
|
33373
|
+
if (state2.fallbackSzTwips === void 0) state2.fallbackSzTwips = sizeTwips;
|
|
33374
|
+
const sizePt = sizeTwips / 2;
|
|
33375
|
+
if (allowOverrideSize || state2.fontSizePt === void 0) state2.fontSizePt = sizePt;
|
|
33376
|
+
}
|
|
33377
|
+
}
|
|
33378
|
+
const kernNode = runProps.elements.find((el) => el.name === "w:kern");
|
|
33379
|
+
if (kernNode?.attributes?.["w:val"]) {
|
|
33380
|
+
if (allowOverrideSize || state2.kern === void 0) state2.kern = kernNode.attributes["w:val"];
|
|
33381
|
+
}
|
|
33382
|
+
};
|
|
33110
33383
|
const _SuperConverter = class _SuperConverter2 {
|
|
33111
33384
|
constructor(params2 = null) {
|
|
33112
33385
|
__privateAdd$2(this, _SuperConverter_instances);
|
|
@@ -33234,49 +33507,45 @@ const _SuperConverter = class _SuperConverter2 {
|
|
|
33234
33507
|
}
|
|
33235
33508
|
getDocumentDefaultStyles() {
|
|
33236
33509
|
const styles = this.convertedXml["word/styles.xml"];
|
|
33237
|
-
|
|
33238
|
-
const
|
|
33239
|
-
|
|
33240
|
-
|
|
33241
|
-
const
|
|
33242
|
-
const
|
|
33243
|
-
|
|
33244
|
-
|
|
33245
|
-
|
|
33246
|
-
|
|
33247
|
-
|
|
33248
|
-
|
|
33249
|
-
|
|
33250
|
-
|
|
33251
|
-
|
|
33252
|
-
|
|
33253
|
-
|
|
33254
|
-
|
|
33255
|
-
|
|
33256
|
-
|
|
33257
|
-
|
|
33258
|
-
|
|
33259
|
-
|
|
33260
|
-
|
|
33261
|
-
|
|
33262
|
-
|
|
33263
|
-
|
|
33264
|
-
|
|
33265
|
-
|
|
33266
|
-
|
|
33267
|
-
|
|
33268
|
-
|
|
33269
|
-
|
|
33270
|
-
|
|
33271
|
-
|
|
33272
|
-
|
|
33273
|
-
|
|
33274
|
-
|
|
33275
|
-
|
|
33276
|
-
const kern = rElements.find((el) => el.name === "w:kern")?.attributes["w:val"];
|
|
33277
|
-
const fontFamilyCss = _SuperConverter2.toCssFontFamily(typeface, this.convertedXml);
|
|
33278
|
-
return { fontSizePt, kern, typeface, panose, fontFamilyCss };
|
|
33279
|
-
}
|
|
33510
|
+
const styleRoot = styles?.elements?.[0];
|
|
33511
|
+
const styleElements = styleRoot?.elements || [];
|
|
33512
|
+
if (!styleElements.length) return {};
|
|
33513
|
+
const defaults = styleElements.find((el) => el.name === "w:docDefaults");
|
|
33514
|
+
const normalStyle = styleElements.find((el) => el.name === "w:style" && el.attributes?.["w:styleId"] === "Normal");
|
|
33515
|
+
const defaultsState = {
|
|
33516
|
+
typeface: void 0,
|
|
33517
|
+
panose: void 0,
|
|
33518
|
+
fontSizePt: void 0,
|
|
33519
|
+
kern: void 0,
|
|
33520
|
+
fallbackSzTwips: void 0
|
|
33521
|
+
};
|
|
33522
|
+
const docDefaultRun = defaults?.elements?.find((el) => el.name === "w:rPrDefault");
|
|
33523
|
+
const docDefaultProps = docDefaultRun?.elements?.find((el) => el.name === "w:rPr") ?? docDefaultRun;
|
|
33524
|
+
collectRunDefaultProperties(docDefaultProps, {
|
|
33525
|
+
allowOverrideTypeface: true,
|
|
33526
|
+
allowOverrideSize: true,
|
|
33527
|
+
themeResolver: (theme) => this.getThemeInfo(theme),
|
|
33528
|
+
state: defaultsState
|
|
33529
|
+
});
|
|
33530
|
+
const normalRunProps = normalStyle?.elements?.find((el) => el.name === "w:rPr") ?? null;
|
|
33531
|
+
collectRunDefaultProperties(normalRunProps, {
|
|
33532
|
+
allowOverrideTypeface: true,
|
|
33533
|
+
allowOverrideSize: true,
|
|
33534
|
+
themeResolver: (theme) => this.getThemeInfo(theme),
|
|
33535
|
+
state: defaultsState
|
|
33536
|
+
});
|
|
33537
|
+
if (defaultsState.fontSizePt === void 0) {
|
|
33538
|
+
if (Number.isFinite(defaultsState.fallbackSzTwips)) defaultsState.fontSizePt = defaultsState.fallbackSzTwips / 2;
|
|
33539
|
+
else defaultsState.fontSizePt = DEFAULT_FONT_SIZE_PT;
|
|
33540
|
+
}
|
|
33541
|
+
const fontFamilyCss = defaultsState.typeface ? _SuperConverter2.toCssFontFamily(defaultsState.typeface, this.convertedXml) : void 0;
|
|
33542
|
+
const result = {};
|
|
33543
|
+
if (defaultsState.fontSizePt !== void 0) result.fontSizePt = defaultsState.fontSizePt;
|
|
33544
|
+
if (defaultsState.kern !== void 0) result.kern = defaultsState.kern;
|
|
33545
|
+
if (defaultsState.typeface) result.typeface = defaultsState.typeface;
|
|
33546
|
+
if (defaultsState.panose) result.panose = defaultsState.panose;
|
|
33547
|
+
if (fontFamilyCss) result.fontFamilyCss = fontFamilyCss;
|
|
33548
|
+
return result;
|
|
33280
33549
|
}
|
|
33281
33550
|
getDocumentFonts() {
|
|
33282
33551
|
const fontTable = this.convertedXml["word/fontTable.xml"];
|
|
@@ -36143,14 +36412,19 @@ class DocxZipper {
|
|
|
36143
36412
|
/**
|
|
36144
36413
|
* Update [Content_Types].xml with extensions of new Image annotations
|
|
36145
36414
|
*/
|
|
36146
|
-
async updateContentTypes(docx, media, fromJson) {
|
|
36415
|
+
async updateContentTypes(docx, media, fromJson, updatedDocs = {}) {
|
|
36416
|
+
const additionalPartNames = Object.keys(updatedDocs || {});
|
|
36147
36417
|
const newMediaTypes = Object.keys(media).map((name) => {
|
|
36148
36418
|
return this.getFileExtension(name);
|
|
36149
36419
|
}).filter(Boolean);
|
|
36150
36420
|
const contentTypesPath = "[Content_Types].xml";
|
|
36151
36421
|
let contentTypesXml;
|
|
36152
36422
|
if (fromJson) {
|
|
36153
|
-
|
|
36423
|
+
if (Array.isArray(docx.files)) {
|
|
36424
|
+
contentTypesXml = docx.files.find((file) => file.name === contentTypesPath)?.content || "";
|
|
36425
|
+
} else {
|
|
36426
|
+
contentTypesXml = docx.files?.[contentTypesPath] || "";
|
|
36427
|
+
}
|
|
36154
36428
|
} else contentTypesXml = await docx.file(contentTypesPath).async("string");
|
|
36155
36429
|
let typesString = "";
|
|
36156
36430
|
const defaultMediaTypes = getContentTypesFromXml(contentTypesXml);
|
|
@@ -36176,24 +36450,39 @@ class DocxZipper {
|
|
|
36176
36450
|
const hasCommentsExtensible = types2.elements?.some(
|
|
36177
36451
|
(el) => el.name === "Override" && el.attributes.PartName === "/word/commentsExtensible.xml"
|
|
36178
36452
|
);
|
|
36179
|
-
|
|
36453
|
+
const hasFile = (filename) => {
|
|
36454
|
+
if (!docx?.files) return false;
|
|
36455
|
+
if (!fromJson) return Boolean(docx.files[filename]);
|
|
36456
|
+
if (Array.isArray(docx.files)) return docx.files.some((file) => file.name === filename);
|
|
36457
|
+
return Boolean(docx.files[filename]);
|
|
36458
|
+
};
|
|
36459
|
+
if (hasFile("word/comments.xml")) {
|
|
36180
36460
|
const commentsDef = `<Override PartName="/word/comments.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.comments+xml" />`;
|
|
36181
36461
|
if (!hasComments) typesString += commentsDef;
|
|
36182
36462
|
}
|
|
36183
|
-
if (
|
|
36463
|
+
if (hasFile("word/commentsExtended.xml")) {
|
|
36184
36464
|
const commentsExtendedDef = `<Override PartName="/word/commentsExtended.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.commentsExtended+xml" />`;
|
|
36185
36465
|
if (!hasCommentsExtended) typesString += commentsExtendedDef;
|
|
36186
36466
|
}
|
|
36187
|
-
if (
|
|
36467
|
+
if (hasFile("word/commentsIds.xml")) {
|
|
36188
36468
|
const commentsIdsDef = `<Override PartName="/word/commentsIds.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.commentsIds+xml" />`;
|
|
36189
36469
|
if (!hasCommentsIds) typesString += commentsIdsDef;
|
|
36190
36470
|
}
|
|
36191
|
-
if (
|
|
36471
|
+
if (hasFile("word/commentsExtensible.xml")) {
|
|
36192
36472
|
const commentsExtendedDef = `<Override PartName="/word/commentsExtensible.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.commentsExtensible+xml" />`;
|
|
36193
36473
|
if (!hasCommentsExtensible) typesString += commentsExtendedDef;
|
|
36194
36474
|
}
|
|
36195
|
-
|
|
36196
|
-
|
|
36475
|
+
const partNames = new Set(additionalPartNames);
|
|
36476
|
+
if (docx?.files) {
|
|
36477
|
+
if (fromJson && Array.isArray(docx.files)) {
|
|
36478
|
+
docx.files.forEach((file) => partNames.add(file.name));
|
|
36479
|
+
} else {
|
|
36480
|
+
Object.keys(docx.files).forEach((key2) => partNames.add(key2));
|
|
36481
|
+
}
|
|
36482
|
+
}
|
|
36483
|
+
partNames.forEach((name) => {
|
|
36484
|
+
if (name.includes(".rels")) return;
|
|
36485
|
+
if (!name.includes("header") && !name.includes("footer")) return;
|
|
36197
36486
|
const hasExtensible = types2.elements?.some(
|
|
36198
36487
|
(el) => el.name === "Override" && el.attributes.PartName === `/${name}`
|
|
36199
36488
|
);
|
|
@@ -36204,7 +36493,48 @@ class DocxZipper {
|
|
|
36204
36493
|
}
|
|
36205
36494
|
});
|
|
36206
36495
|
const beginningString = '<Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types">';
|
|
36207
|
-
|
|
36496
|
+
let updatedContentTypesXml = contentTypesXml.replace(beginningString, `${beginningString}${typesString}`);
|
|
36497
|
+
let relationshipsXml = updatedDocs["word/_rels/document.xml.rels"];
|
|
36498
|
+
if (!relationshipsXml) {
|
|
36499
|
+
if (fromJson) {
|
|
36500
|
+
if (Array.isArray(docx.files)) {
|
|
36501
|
+
relationshipsXml = docx.files.find((file) => file.name === "word/_rels/document.xml.rels")?.content;
|
|
36502
|
+
} else {
|
|
36503
|
+
relationshipsXml = docx.files?.["word/_rels/document.xml.rels"];
|
|
36504
|
+
}
|
|
36505
|
+
} else {
|
|
36506
|
+
relationshipsXml = await docx.file("word/_rels/document.xml.rels")?.async("string");
|
|
36507
|
+
}
|
|
36508
|
+
}
|
|
36509
|
+
if (relationshipsXml) {
|
|
36510
|
+
try {
|
|
36511
|
+
const relJson = xmljs.xml2js(relationshipsXml, { compact: false });
|
|
36512
|
+
const relationships = relJson.elements?.find((el) => el.name === "Relationships");
|
|
36513
|
+
relationships?.elements?.forEach((rel) => {
|
|
36514
|
+
const type2 = rel.attributes?.Type;
|
|
36515
|
+
const target = rel.attributes?.Target;
|
|
36516
|
+
if (!type2 || !target) return;
|
|
36517
|
+
const isHeader = type2.includes("/header");
|
|
36518
|
+
const isFooter = type2.includes("/footer");
|
|
36519
|
+
if (!isHeader && !isFooter) return;
|
|
36520
|
+
let sanitizedTarget = target.replace(/^\.\//, "");
|
|
36521
|
+
if (sanitizedTarget.startsWith("../")) sanitizedTarget = sanitizedTarget.slice(3);
|
|
36522
|
+
if (sanitizedTarget.startsWith("/")) sanitizedTarget = sanitizedTarget.slice(1);
|
|
36523
|
+
const partName = sanitizedTarget.startsWith("word/") ? sanitizedTarget : `word/${sanitizedTarget}`;
|
|
36524
|
+
partNames.add(partName);
|
|
36525
|
+
});
|
|
36526
|
+
} catch (error) {
|
|
36527
|
+
console.warn("Failed to parse document relationships while updating content types", error);
|
|
36528
|
+
}
|
|
36529
|
+
}
|
|
36530
|
+
partNames.forEach((name) => {
|
|
36531
|
+
if (name.includes(".rels")) return;
|
|
36532
|
+
if (!name.includes("header") && !name.includes("footer")) return;
|
|
36533
|
+
if (updatedContentTypesXml.includes(`PartName="/${name}"`)) return;
|
|
36534
|
+
const type2 = name.includes("header") ? "header" : "footer";
|
|
36535
|
+
const extendedDef = `<Override PartName="/${name}" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.${type2}+xml"/>`;
|
|
36536
|
+
updatedContentTypesXml = updatedContentTypesXml.replace("</Types>", `${extendedDef}</Types>`);
|
|
36537
|
+
});
|
|
36208
36538
|
if (fromJson) return updatedContentTypesXml;
|
|
36209
36539
|
docx.file(contentTypesPath, updatedContentTypesXml);
|
|
36210
36540
|
}
|
|
@@ -36245,7 +36575,7 @@ class DocxZipper {
|
|
|
36245
36575
|
for (const [fontName, fontUintArray] of Object.entries(fonts)) {
|
|
36246
36576
|
zip.file(fontName, fontUintArray);
|
|
36247
36577
|
}
|
|
36248
|
-
await this.updateContentTypes(zip, media);
|
|
36578
|
+
await this.updateContentTypes(zip, media, false, updatedDocs);
|
|
36249
36579
|
return zip;
|
|
36250
36580
|
}
|
|
36251
36581
|
/**
|
|
@@ -36271,7 +36601,7 @@ class DocxZipper {
|
|
|
36271
36601
|
Object.keys(media).forEach((path) => {
|
|
36272
36602
|
unzippedOriginalDocx.file(path, media[path]);
|
|
36273
36603
|
});
|
|
36274
|
-
await this.updateContentTypes(unzippedOriginalDocx, media);
|
|
36604
|
+
await this.updateContentTypes(unzippedOriginalDocx, media, false, updatedDocs);
|
|
36275
36605
|
return unzippedOriginalDocx;
|
|
36276
36606
|
}
|
|
36277
36607
|
}
|
|
@@ -36286,7 +36616,7 @@ var __privateGet$1 = (obj, member, getter) => (__accessCheck$1(obj, member, "rea
|
|
|
36286
36616
|
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);
|
|
36287
36617
|
var __privateSet = (obj, member, value, setter) => (__accessCheck$1(obj, member, "write to private field"), member.set(obj, value), value);
|
|
36288
36618
|
var __privateMethod$1 = (obj, member, method) => (__accessCheck$1(obj, member, "access private method"), method);
|
|
36289
|
-
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,
|
|
36619
|
+
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;
|
|
36290
36620
|
var GOOD_LEAF_SIZE = 200;
|
|
36291
36621
|
var RopeSequence = function RopeSequence2() {
|
|
36292
36622
|
};
|
|
@@ -47929,9 +48259,11 @@ const toggleHeaderFooterEditMode = ({ editor, focusedSectionEditor, isEditMode,
|
|
|
47929
48259
|
item.editor.view.dom.setAttribute("documentmode", documentMode);
|
|
47930
48260
|
});
|
|
47931
48261
|
if (isEditMode) {
|
|
47932
|
-
const pm =
|
|
47933
|
-
pm
|
|
47934
|
-
|
|
48262
|
+
const pm = editor.view?.dom || editor.options.element?.querySelector?.(".ProseMirror");
|
|
48263
|
+
if (pm) {
|
|
48264
|
+
pm.classList.add("header-footer-edit");
|
|
48265
|
+
pm.setAttribute("aria-readonly", true);
|
|
48266
|
+
}
|
|
47935
48267
|
}
|
|
47936
48268
|
if (focusedSectionEditor) {
|
|
47937
48269
|
focusedSectionEditor.view.focus();
|
|
@@ -48359,28 +48691,25 @@ const handleTrackedChangeTransaction = (trackedChangeMeta, trackedChanges, newEd
|
|
|
48359
48691
|
if (emitParams) editor.emit("commentsUpdate", emitParams);
|
|
48360
48692
|
return newTrackedChanges;
|
|
48361
48693
|
};
|
|
48362
|
-
const getTrackedChangeText = ({ state: state2,
|
|
48694
|
+
const getTrackedChangeText = ({ state: state2, nodes, mark, marks, trackedChangeType, isDeletionInsertion }) => {
|
|
48363
48695
|
let trackedChangeText = "";
|
|
48364
48696
|
let deletionText = "";
|
|
48365
48697
|
if (trackedChangeType === TrackInsertMarkName) {
|
|
48366
|
-
trackedChangeText = node
|
|
48698
|
+
trackedChangeText = nodes.reduce((acc, node) => {
|
|
48699
|
+
if (!node.marks.find((nodeMark) => nodeMark.type.name === mark.type.name)) return acc;
|
|
48700
|
+
acc += node?.text || node?.textContent || "";
|
|
48701
|
+
return acc;
|
|
48702
|
+
}, "");
|
|
48367
48703
|
}
|
|
48368
48704
|
if (trackedChangeType === TrackFormatMarkName) {
|
|
48369
48705
|
trackedChangeText = translateFormatChangesToEnglish(mark.attrs);
|
|
48370
48706
|
}
|
|
48371
48707
|
if (trackedChangeType === TrackDeleteMarkName || isDeletionInsertion) {
|
|
48372
|
-
deletionText = node
|
|
48373
|
-
|
|
48374
|
-
|
|
48375
|
-
|
|
48376
|
-
|
|
48377
|
-
const changeMarks = marks2.filter((mark2) => TRACK_CHANGE_MARKS.includes(mark2.type.name));
|
|
48378
|
-
if (!changeMarks.length) return false;
|
|
48379
|
-
const hasMatchingId = changeMarks.find((mark2) => mark2.attrs.id === id);
|
|
48380
|
-
if (hasMatchingId) return true;
|
|
48381
|
-
});
|
|
48382
|
-
deletionText = deletionNode?.node.text ?? "";
|
|
48383
|
-
}
|
|
48708
|
+
deletionText = nodes.reduce((acc, node) => {
|
|
48709
|
+
if (!node.marks.find((nodeMark) => nodeMark.type.name === TrackDeleteMarkName)) return acc;
|
|
48710
|
+
acc += node?.text || node?.textContent || "";
|
|
48711
|
+
return acc;
|
|
48712
|
+
}, "");
|
|
48384
48713
|
}
|
|
48385
48714
|
return {
|
|
48386
48715
|
deletionText,
|
|
@@ -48395,18 +48724,17 @@ const createOrUpdateTrackedChangeComment = ({ event, marks, deletionNodes, nodes
|
|
|
48395
48724
|
const id = attrs.id;
|
|
48396
48725
|
const node = nodes[0];
|
|
48397
48726
|
const isDeletionInsertion = !!(marks.insertedMark && marks.deletionMark);
|
|
48398
|
-
let
|
|
48727
|
+
let nodesWithMark = [];
|
|
48399
48728
|
newEditorState.doc.descendants((node2) => {
|
|
48400
48729
|
const { marks: marks2 = [] } = node2;
|
|
48401
48730
|
const changeMarks = marks2.filter((mark) => TRACK_CHANGE_MARKS.includes(mark.type.name));
|
|
48402
48731
|
if (!changeMarks.length) return;
|
|
48403
48732
|
const hasMatchingId = changeMarks.find((mark) => mark.attrs.id === id);
|
|
48404
|
-
if (hasMatchingId)
|
|
48405
|
-
if (existingNode) return false;
|
|
48733
|
+
if (hasMatchingId) nodesWithMark.push(node2);
|
|
48406
48734
|
});
|
|
48407
48735
|
const { deletionText, trackedChangeText } = getTrackedChangeText({
|
|
48408
48736
|
state: newEditorState,
|
|
48409
|
-
|
|
48737
|
+
nodes: nodesWithMark.length ? nodesWithMark : [node],
|
|
48410
48738
|
mark: trackedMark,
|
|
48411
48739
|
marks,
|
|
48412
48740
|
trackedChangeType,
|
|
@@ -48436,14 +48764,6 @@ const createOrUpdateTrackedChangeComment = ({ event, marks, deletionNodes, nodes
|
|
|
48436
48764
|
else if (event === "update") params2.event = comments_module_events.UPDATE;
|
|
48437
48765
|
return params2;
|
|
48438
48766
|
};
|
|
48439
|
-
function findNode$1(node, predicate) {
|
|
48440
|
-
let found2 = null;
|
|
48441
|
-
node.descendants((node2, pos) => {
|
|
48442
|
-
if (predicate(node2)) found2 = { node: node2, pos };
|
|
48443
|
-
if (found2) return false;
|
|
48444
|
-
});
|
|
48445
|
-
return found2;
|
|
48446
|
-
}
|
|
48447
48767
|
function findRangeById(doc2, id) {
|
|
48448
48768
|
let from2 = null, to = null;
|
|
48449
48769
|
doc2.descendants((node, pos) => {
|
|
@@ -48961,6 +49281,7 @@ const generateTableIfNecessary = ({ tableNode, annotationValues, tr, state: stat
|
|
|
48961
49281
|
const mappedRowStart = tr.mapping.map(absoluteRowStart);
|
|
48962
49282
|
const rowEnd = mappedRowStart + rowNode.nodeSize;
|
|
48963
49283
|
tr.replaceWith(mappedRowStart, rowEnd, Fragment.from(newRows));
|
|
49284
|
+
tr.setMeta("tableGeneration", true);
|
|
48964
49285
|
} catch (error) {
|
|
48965
49286
|
console.error("Error during row generation:", error);
|
|
48966
49287
|
throw error;
|
|
@@ -49365,7 +49686,7 @@ function findFieldAnnotationsBetween(from2, to, doc2) {
|
|
|
49365
49686
|
}
|
|
49366
49687
|
function findRemovedFieldAnnotations(tr) {
|
|
49367
49688
|
let removedNodes = [];
|
|
49368
|
-
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) {
|
|
49689
|
+
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) {
|
|
49369
49690
|
return removedNodes;
|
|
49370
49691
|
}
|
|
49371
49692
|
const hasDeletion = transactionDeletedAnything(tr);
|
|
@@ -50543,7 +50864,7 @@ const _Editor = class _Editor2 extends EventEmitter$1 {
|
|
|
50543
50864
|
setDocumentMode(documentMode) {
|
|
50544
50865
|
let cleanedMode = documentMode?.toLowerCase() || "editing";
|
|
50545
50866
|
if (!this.extensionService || !this.state) return;
|
|
50546
|
-
const pm =
|
|
50867
|
+
const pm = this.view?.dom || this.options.element?.querySelector?.(".ProseMirror");
|
|
50547
50868
|
if (this.options.role === "viewer") cleanedMode = "viewing";
|
|
50548
50869
|
if (this.options.role === "suggester" && cleanedMode === "editing") cleanedMode = "suggesting";
|
|
50549
50870
|
if (cleanedMode === "viewing") {
|
|
@@ -51031,7 +51352,8 @@ const _Editor = class _Editor2 extends EventEmitter$1 {
|
|
|
51031
51352
|
files: this.options.content
|
|
51032
51353
|
},
|
|
51033
51354
|
media,
|
|
51034
|
-
true
|
|
51355
|
+
true,
|
|
51356
|
+
updatedDocs
|
|
51035
51357
|
);
|
|
51036
51358
|
return updatedDocs;
|
|
51037
51359
|
}
|
|
@@ -51517,9 +51839,11 @@ createView_fn = function(element) {
|
|
|
51517
51839
|
isEditMode: false,
|
|
51518
51840
|
documentMode: this.options.documentMode
|
|
51519
51841
|
});
|
|
51520
|
-
const pm =
|
|
51521
|
-
pm
|
|
51522
|
-
|
|
51842
|
+
const pm = this.view?.dom || this.options.element?.querySelector?.(".ProseMirror");
|
|
51843
|
+
if (pm) {
|
|
51844
|
+
pm.classList.remove("header-footer-edit");
|
|
51845
|
+
pm.setAttribute("aria-readonly", false);
|
|
51846
|
+
}
|
|
51523
51847
|
}
|
|
51524
51848
|
setWordSelection(view, pos);
|
|
51525
51849
|
}
|
|
@@ -53067,522 +53391,1536 @@ const SlashMenu = Extension.create({
|
|
|
53067
53391
|
return this.editor.options.isHeadless ? [] : [slashMenuPlugin];
|
|
53068
53392
|
}
|
|
53069
53393
|
});
|
|
53070
|
-
|
|
53071
|
-
|
|
53072
|
-
|
|
53073
|
-
|
|
53074
|
-
|
|
53075
|
-
|
|
53076
|
-
|
|
53077
|
-
|
|
53078
|
-
|
|
53079
|
-
|
|
53080
|
-
|
|
53081
|
-
|
|
53082
|
-
|
|
53083
|
-
|
|
53084
|
-
|
|
53085
|
-
|
|
53086
|
-
|
|
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
|
-
|
|
53394
|
+
class StructuredContentViewBase {
|
|
53395
|
+
constructor(props) {
|
|
53396
|
+
__publicField$1(this, "node");
|
|
53397
|
+
__publicField$1(this, "view");
|
|
53398
|
+
__publicField$1(this, "getPos");
|
|
53399
|
+
__publicField$1(this, "decorations");
|
|
53400
|
+
__publicField$1(this, "innerDecorations");
|
|
53401
|
+
__publicField$1(this, "editor");
|
|
53402
|
+
__publicField$1(this, "extension");
|
|
53403
|
+
__publicField$1(this, "htmlAttributes");
|
|
53404
|
+
__publicField$1(this, "root");
|
|
53405
|
+
__publicField$1(this, "isDragging", false);
|
|
53406
|
+
this.node = props.node;
|
|
53407
|
+
this.view = props.editor.view;
|
|
53408
|
+
this.getPos = props.getPos;
|
|
53409
|
+
this.decorations = props.decorations;
|
|
53410
|
+
this.innerDecorations = props.innerDecorations;
|
|
53411
|
+
this.editor = props.editor;
|
|
53412
|
+
this.extension = props.extension;
|
|
53413
|
+
this.htmlAttributes = props.htmlAttributes;
|
|
53414
|
+
this.mount(props);
|
|
53415
|
+
}
|
|
53416
|
+
mount() {
|
|
53417
|
+
return;
|
|
53418
|
+
}
|
|
53419
|
+
get dom() {
|
|
53420
|
+
return this.root;
|
|
53421
|
+
}
|
|
53422
|
+
get contentDOM() {
|
|
53423
|
+
return null;
|
|
53424
|
+
}
|
|
53425
|
+
update(node, decorations, innerDecorations) {
|
|
53426
|
+
if (node.type !== this.node.type) {
|
|
53427
|
+
return false;
|
|
53428
|
+
}
|
|
53429
|
+
this.node = node;
|
|
53430
|
+
this.decorations = decorations;
|
|
53431
|
+
this.innerDecorations = innerDecorations;
|
|
53432
|
+
this.updateHTMLAttributes();
|
|
53433
|
+
return true;
|
|
53434
|
+
}
|
|
53435
|
+
stopEvent(event) {
|
|
53436
|
+
if (!this.dom) return false;
|
|
53437
|
+
const target = event.target;
|
|
53438
|
+
const isInElement = this.dom.contains(target) && !this.contentDOM?.contains(target);
|
|
53439
|
+
if (!isInElement) return false;
|
|
53440
|
+
const isDragEvent = event.type.startsWith("drag");
|
|
53441
|
+
const isDropEvent = event.type === "drop";
|
|
53442
|
+
const isInput = ["INPUT", "BUTTON", "SELECT", "TEXTAREA"].includes(target.tagName) || target.isContentEditable;
|
|
53443
|
+
if (isInput && !isDropEvent && !isDragEvent) return true;
|
|
53444
|
+
const { isEditable } = this.editor;
|
|
53445
|
+
const { isDragging } = this;
|
|
53446
|
+
const isDraggable = !!this.node.type.spec.draggable;
|
|
53447
|
+
const isSelectable = NodeSelection.isSelectable(this.node);
|
|
53448
|
+
const isCopyEvent = event.type === "copy";
|
|
53449
|
+
const isPasteEvent = event.type === "paste";
|
|
53450
|
+
const isCutEvent = event.type === "cut";
|
|
53451
|
+
const isClickEvent = event.type === "mousedown";
|
|
53452
|
+
if (!isDraggable && isSelectable && isDragEvent && event.target === this.dom) {
|
|
53453
|
+
event.preventDefault();
|
|
53454
|
+
}
|
|
53455
|
+
if (isDraggable && isDragEvent && !isDragging && event.target === this.dom) {
|
|
53456
|
+
event.preventDefault();
|
|
53457
|
+
return false;
|
|
53458
|
+
}
|
|
53459
|
+
if (isDraggable && isEditable && !isDragging && isClickEvent) {
|
|
53460
|
+
const dragHandle = target.closest("[data-drag-handle]");
|
|
53461
|
+
const isValidDragHandle = dragHandle && (this.dom === dragHandle || this.dom.contains(dragHandle));
|
|
53462
|
+
if (isValidDragHandle) {
|
|
53463
|
+
this.isDragging = true;
|
|
53464
|
+
document.addEventListener(
|
|
53465
|
+
"dragend",
|
|
53466
|
+
() => {
|
|
53467
|
+
this.isDragging = false;
|
|
53468
|
+
},
|
|
53469
|
+
{ once: true }
|
|
53470
|
+
);
|
|
53471
|
+
document.addEventListener(
|
|
53472
|
+
"drop",
|
|
53473
|
+
() => {
|
|
53474
|
+
this.isDragging = false;
|
|
53475
|
+
},
|
|
53476
|
+
{ once: true }
|
|
53477
|
+
);
|
|
53478
|
+
document.addEventListener(
|
|
53479
|
+
"mouseup",
|
|
53480
|
+
() => {
|
|
53481
|
+
this.isDragging = false;
|
|
53482
|
+
},
|
|
53483
|
+
{ once: true }
|
|
53484
|
+
);
|
|
53119
53485
|
}
|
|
53120
|
-
}
|
|
53486
|
+
}
|
|
53487
|
+
if (isDragging || isDropEvent || isCopyEvent || isPasteEvent || isCutEvent || isClickEvent && isSelectable) {
|
|
53488
|
+
return false;
|
|
53489
|
+
}
|
|
53490
|
+
return true;
|
|
53121
53491
|
}
|
|
53122
|
-
|
|
53123
|
-
|
|
53124
|
-
|
|
53125
|
-
|
|
53126
|
-
|
|
53127
|
-
|
|
53128
|
-
return
|
|
53492
|
+
ignoreMutation(mutation) {
|
|
53493
|
+
if (!this.dom || !this.contentDOM) return true;
|
|
53494
|
+
if (this.node.isLeaf || this.node.isAtom) return true;
|
|
53495
|
+
if (mutation.type === "selection") return false;
|
|
53496
|
+
if (this.contentDOM === mutation.target && mutation.type === "attributes") return true;
|
|
53497
|
+
if (this.contentDOM.contains(mutation.target)) return false;
|
|
53498
|
+
return true;
|
|
53129
53499
|
}
|
|
53130
|
-
|
|
53131
|
-
|
|
53132
|
-
|
|
53133
|
-
|
|
53134
|
-
|
|
53135
|
-
|
|
53136
|
-
|
|
53500
|
+
destroy() {
|
|
53501
|
+
this.dom.remove();
|
|
53502
|
+
this.contentDOM?.remove();
|
|
53503
|
+
}
|
|
53504
|
+
updateAttributes(attrs) {
|
|
53505
|
+
const pos = this.getPos();
|
|
53506
|
+
if (typeof pos !== "number") {
|
|
53507
|
+
return;
|
|
53508
|
+
}
|
|
53509
|
+
return this.view.dispatch(
|
|
53510
|
+
this.view.state.tr.setNodeMarkup(pos, void 0, {
|
|
53511
|
+
...this.node.attrs,
|
|
53512
|
+
...attrs
|
|
53513
|
+
})
|
|
53514
|
+
);
|
|
53515
|
+
}
|
|
53516
|
+
updateHTMLAttributes() {
|
|
53517
|
+
const { extensionService } = this.editor;
|
|
53518
|
+
const { attributes } = extensionService;
|
|
53519
|
+
const extensionAttrs = attributes.filter((i) => i.type === this.node.type.name);
|
|
53520
|
+
this.htmlAttributes = Attribute2.getAttributesToRender(this.node, extensionAttrs);
|
|
53521
|
+
}
|
|
53522
|
+
createDragHandle() {
|
|
53523
|
+
const dragHandle = document.createElement("span");
|
|
53524
|
+
dragHandle.classList.add("sd-structured-content-draggable");
|
|
53525
|
+
dragHandle.draggable = true;
|
|
53526
|
+
dragHandle.contentEditable = "false";
|
|
53527
|
+
dragHandle.dataset.dragHandle = "";
|
|
53528
|
+
const textElement = document.createElement("span");
|
|
53529
|
+
textElement.textContent = this.node.attrs.alias || "Structured content";
|
|
53530
|
+
dragHandle.append(textElement);
|
|
53531
|
+
return dragHandle;
|
|
53532
|
+
}
|
|
53533
|
+
onDragStart(event) {
|
|
53534
|
+
const { view } = this.editor;
|
|
53535
|
+
const target = event.target;
|
|
53536
|
+
const dragHandle = target.nodeType === 3 ? target.parentElement?.closest("[data-drag-handle]") : target.closest("[data-drag-handle]");
|
|
53537
|
+
if (!this.dom || this.contentDOM?.contains(target) || !dragHandle) {
|
|
53538
|
+
return;
|
|
53539
|
+
}
|
|
53540
|
+
let x = 0;
|
|
53541
|
+
let y2 = 0;
|
|
53542
|
+
if (this.dom !== dragHandle) {
|
|
53543
|
+
const domBox = this.dom.getBoundingClientRect();
|
|
53544
|
+
const handleBox = dragHandle.getBoundingClientRect();
|
|
53545
|
+
const offsetX = event.offsetX ?? event.nativeEvent?.offsetX;
|
|
53546
|
+
const offsetY = event.offsetY ?? event.nativeEvent?.offsetY;
|
|
53547
|
+
x = handleBox.x - domBox.x + offsetX;
|
|
53548
|
+
y2 = handleBox.y - domBox.y + offsetY;
|
|
53549
|
+
}
|
|
53550
|
+
event.dataTransfer?.setDragImage(this.dom, x, y2);
|
|
53551
|
+
const pos = this.getPos();
|
|
53552
|
+
if (typeof pos !== "number") {
|
|
53553
|
+
return;
|
|
53554
|
+
}
|
|
53555
|
+
const selection = NodeSelection.create(view.state.doc, pos);
|
|
53556
|
+
const transaction = view.state.tr.setSelection(selection);
|
|
53137
53557
|
view.dispatch(transaction);
|
|
53138
|
-
});
|
|
53139
|
-
if (handled) {
|
|
53140
|
-
tr.setMeta("preventDispatch", true);
|
|
53141
53558
|
}
|
|
53142
|
-
|
|
53143
|
-
|
|
53144
|
-
|
|
53145
|
-
|
|
53146
|
-
|
|
53147
|
-
|
|
53559
|
+
}
|
|
53560
|
+
class StructuredContentInlineView extends StructuredContentViewBase {
|
|
53561
|
+
constructor(props) {
|
|
53562
|
+
super(props);
|
|
53563
|
+
}
|
|
53564
|
+
mount() {
|
|
53565
|
+
this.buildView();
|
|
53566
|
+
}
|
|
53567
|
+
get contentDOM() {
|
|
53568
|
+
const contentElement = this.dom?.querySelector(`.${structuredContentInnerClass$1}`);
|
|
53569
|
+
return contentElement || null;
|
|
53570
|
+
}
|
|
53571
|
+
createElement() {
|
|
53572
|
+
const element = document.createElement("span");
|
|
53573
|
+
element.classList.add(structuredContentClass$1);
|
|
53574
|
+
element.setAttribute("data-structured-content", "");
|
|
53575
|
+
const contentElement = document.createElement("span");
|
|
53576
|
+
contentElement.classList.add(structuredContentInnerClass$1);
|
|
53577
|
+
element.append(contentElement);
|
|
53578
|
+
const domAttrs = Attribute2.mergeAttributes(this.htmlAttributes);
|
|
53579
|
+
updateDOMAttributes(element, { ...domAttrs });
|
|
53580
|
+
return { element, contentElement };
|
|
53581
|
+
}
|
|
53582
|
+
buildView() {
|
|
53583
|
+
const { element } = this.createElement();
|
|
53584
|
+
const dragHandle = this.createDragHandle();
|
|
53585
|
+
element.prepend(dragHandle);
|
|
53586
|
+
element.addEventListener("dragstart", (e) => this.onDragStart(e));
|
|
53587
|
+
this.root = element;
|
|
53588
|
+
}
|
|
53589
|
+
updateView() {
|
|
53590
|
+
const domAttrs = Attribute2.mergeAttributes(this.htmlAttributes);
|
|
53591
|
+
updateDOMAttributes(this.dom, { ...domAttrs });
|
|
53592
|
+
}
|
|
53593
|
+
update(node, decorations, innerDecorations) {
|
|
53594
|
+
const result = super.update(node, decorations, innerDecorations);
|
|
53595
|
+
if (!result) return false;
|
|
53596
|
+
this.updateView();
|
|
53597
|
+
return true;
|
|
53598
|
+
}
|
|
53599
|
+
}
|
|
53600
|
+
const structuredContentClass$1 = "sd-structured-content";
|
|
53601
|
+
const structuredContentInnerClass$1 = "sd-structured-content__content";
|
|
53602
|
+
const StructuredContent = Node$1.create({
|
|
53603
|
+
name: "structuredContent",
|
|
53604
|
+
group: "inline structuredContent",
|
|
53148
53605
|
inline: true,
|
|
53149
53606
|
content: "inline*",
|
|
53150
|
-
|
|
53151
|
-
|
|
53607
|
+
isolating: true,
|
|
53608
|
+
atom: false,
|
|
53609
|
+
// false - has editable content.
|
|
53610
|
+
draggable: true,
|
|
53152
53611
|
addOptions() {
|
|
53153
53612
|
return {
|
|
53154
53613
|
htmlAttributes: {
|
|
53155
|
-
|
|
53614
|
+
class: structuredContentClass$1,
|
|
53615
|
+
"aria-label": "Structured content node"
|
|
53156
53616
|
}
|
|
53157
53617
|
};
|
|
53158
53618
|
},
|
|
53159
53619
|
addAttributes() {
|
|
53160
53620
|
return {
|
|
53161
|
-
|
|
53621
|
+
id: {
|
|
53162
53622
|
default: null,
|
|
53163
|
-
|
|
53164
|
-
|
|
53623
|
+
parseDOM: (elem) => elem.getAttribute("data-id"),
|
|
53624
|
+
renderDOM: (attrs) => {
|
|
53625
|
+
if (!attrs.id) return {};
|
|
53626
|
+
return { "data-id": attrs.id };
|
|
53627
|
+
}
|
|
53165
53628
|
},
|
|
53166
|
-
|
|
53629
|
+
tag: {
|
|
53167
53630
|
default: null,
|
|
53168
|
-
|
|
53169
|
-
|
|
53631
|
+
parseDOM: (elem) => elem.getAttribute("data-tag"),
|
|
53632
|
+
renderDOM: (attrs) => {
|
|
53633
|
+
if (!attrs.tag) return {};
|
|
53634
|
+
return { "data-tag": attrs.tag };
|
|
53635
|
+
}
|
|
53170
53636
|
},
|
|
53171
|
-
|
|
53637
|
+
alias: {
|
|
53172
53638
|
default: null,
|
|
53173
|
-
|
|
53174
|
-
|
|
53639
|
+
parseDOM: (elem) => elem.getAttribute("data-alias"),
|
|
53640
|
+
renderDOM: (attrs) => {
|
|
53641
|
+
if (!attrs.alias) return {};
|
|
53642
|
+
return { "data-alias": attrs.alias };
|
|
53643
|
+
}
|
|
53175
53644
|
},
|
|
53176
|
-
|
|
53177
|
-
|
|
53178
|
-
rendered: false,
|
|
53179
|
-
keepOnSplit: true
|
|
53645
|
+
sdtPr: {
|
|
53646
|
+
rendered: false
|
|
53180
53647
|
}
|
|
53181
53648
|
};
|
|
53182
53649
|
},
|
|
53183
|
-
addCommands() {
|
|
53184
|
-
return {
|
|
53185
|
-
splitRun
|
|
53186
|
-
};
|
|
53187
|
-
},
|
|
53188
53650
|
parseDOM() {
|
|
53189
|
-
return [{ tag: "span[data-
|
|
53651
|
+
return [{ tag: "span[data-structured-content]" }];
|
|
53190
53652
|
},
|
|
53191
53653
|
renderDOM({ htmlAttributes }) {
|
|
53192
|
-
|
|
53193
|
-
|
|
53194
|
-
|
|
53195
|
-
|
|
53196
|
-
|
|
53197
|
-
|
|
53198
|
-
|
|
53199
|
-
group: "block list",
|
|
53200
|
-
selectable: false,
|
|
53201
|
-
content() {
|
|
53202
|
-
return `${this.options.itemTypeName}+`;
|
|
53654
|
+
return [
|
|
53655
|
+
"span",
|
|
53656
|
+
Attribute2.mergeAttributes(this.options.htmlAttributes, htmlAttributes, {
|
|
53657
|
+
"data-structured-content": ""
|
|
53658
|
+
}),
|
|
53659
|
+
0
|
|
53660
|
+
];
|
|
53203
53661
|
},
|
|
53204
|
-
|
|
53205
|
-
return {
|
|
53206
|
-
|
|
53207
|
-
htmlAttributes: {
|
|
53208
|
-
"aria-label": "Bullet list node"
|
|
53209
|
-
},
|
|
53210
|
-
keepMarks: true,
|
|
53211
|
-
keepAttributes: false
|
|
53662
|
+
addNodeView() {
|
|
53663
|
+
return (props) => {
|
|
53664
|
+
return new StructuredContentInlineView({ ...props });
|
|
53212
53665
|
};
|
|
53213
|
-
},
|
|
53214
|
-
parseDOM() {
|
|
53215
|
-
return [{ tag: "ul" }];
|
|
53216
|
-
},
|
|
53217
|
-
renderDOM({ htmlAttributes }) {
|
|
53218
|
-
const attributes = Attribute2.mergeAttributes(this.options.htmlAttributes, htmlAttributes);
|
|
53219
|
-
return ["ul", attributes, 0];
|
|
53220
|
-
},
|
|
53221
|
-
addAttributes() {
|
|
53222
|
-
return {
|
|
53223
|
-
"list-style-type": {
|
|
53224
|
-
default: "bullet",
|
|
53225
|
-
rendered: false
|
|
53226
|
-
},
|
|
53227
|
-
listId: {
|
|
53228
|
-
rendered: false
|
|
53229
|
-
},
|
|
53230
|
-
sdBlockId: {
|
|
53231
|
-
default: null,
|
|
53232
|
-
keepOnSplit: false,
|
|
53233
|
-
parseDOM: (elem) => elem.getAttribute("data-sd-block-id"),
|
|
53234
|
-
renderDOM: (attrs) => {
|
|
53235
|
-
return attrs.sdBlockId ? { "data-sd-block-id": attrs.sdBlockId } : {};
|
|
53236
|
-
}
|
|
53237
|
-
},
|
|
53238
|
-
attributes: {
|
|
53239
|
-
rendered: false,
|
|
53240
|
-
keepOnSplit: true
|
|
53241
|
-
}
|
|
53242
|
-
};
|
|
53243
|
-
},
|
|
53244
|
-
addCommands() {
|
|
53245
|
-
return {
|
|
53246
|
-
/**
|
|
53247
|
-
* Toggle a bullet list at the current selection
|
|
53248
|
-
* @category Command
|
|
53249
|
-
* @example
|
|
53250
|
-
* // Toggle bullet list on selected text
|
|
53251
|
-
* editor.commands.toggleBulletList()
|
|
53252
|
-
* @note Converts selected paragraphs to list items or removes list formatting
|
|
53253
|
-
*/
|
|
53254
|
-
toggleBulletList: () => (params2) => {
|
|
53255
|
-
return toggleList(this.type)(params2);
|
|
53256
|
-
}
|
|
53257
|
-
};
|
|
53258
|
-
},
|
|
53259
|
-
addShortcuts() {
|
|
53260
|
-
return {
|
|
53261
|
-
"Mod-Shift-8": () => {
|
|
53262
|
-
return this.editor.commands.toggleBulletList();
|
|
53263
|
-
}
|
|
53264
|
-
};
|
|
53265
|
-
},
|
|
53266
|
-
addInputRules() {
|
|
53267
|
-
return [
|
|
53268
|
-
new InputRule({
|
|
53269
|
-
match: inputRegex$1,
|
|
53270
|
-
handler: ({ state: state2, range: range2 }) => {
|
|
53271
|
-
const $pos = state2.selection.$from;
|
|
53272
|
-
const listItemType = state2.schema.nodes.listItem;
|
|
53273
|
-
for (let depth = $pos.depth; depth >= 0; depth--) {
|
|
53274
|
-
if ($pos.node(depth).type === listItemType) {
|
|
53275
|
-
return null;
|
|
53276
|
-
}
|
|
53277
|
-
}
|
|
53278
|
-
const { tr } = state2;
|
|
53279
|
-
tr.delete(range2.from, range2.to);
|
|
53280
|
-
ListHelpers.createNewList({
|
|
53281
|
-
listType: this.type,
|
|
53282
|
-
tr,
|
|
53283
|
-
editor: this.editor
|
|
53284
|
-
});
|
|
53285
|
-
}
|
|
53286
|
-
})
|
|
53287
|
-
];
|
|
53288
53666
|
}
|
|
53289
53667
|
});
|
|
53290
|
-
|
|
53291
|
-
|
|
53292
|
-
|
|
53293
|
-
|
|
53294
|
-
|
|
53295
|
-
|
|
53296
|
-
|
|
53297
|
-
|
|
53668
|
+
class StructuredContentBlockView extends StructuredContentViewBase {
|
|
53669
|
+
constructor(props) {
|
|
53670
|
+
super(props);
|
|
53671
|
+
}
|
|
53672
|
+
mount() {
|
|
53673
|
+
this.buildView();
|
|
53674
|
+
}
|
|
53675
|
+
get contentDOM() {
|
|
53676
|
+
const contentElement = this.dom?.querySelector(`.${structuredContentInnerClass}`);
|
|
53677
|
+
return contentElement || null;
|
|
53678
|
+
}
|
|
53679
|
+
createElement() {
|
|
53680
|
+
const element = document.createElement("div");
|
|
53681
|
+
element.classList.add(structuredContentClass);
|
|
53682
|
+
element.setAttribute("data-structured-content-block", "");
|
|
53683
|
+
const contentElement = document.createElement("div");
|
|
53684
|
+
contentElement.classList.add(structuredContentInnerClass);
|
|
53685
|
+
element.append(contentElement);
|
|
53686
|
+
const domAttrs = Attribute2.mergeAttributes(this.htmlAttributes);
|
|
53687
|
+
updateDOMAttributes(element, { ...domAttrs });
|
|
53688
|
+
return { element, contentElement };
|
|
53689
|
+
}
|
|
53690
|
+
buildView() {
|
|
53691
|
+
const { element } = this.createElement();
|
|
53692
|
+
const dragHandle = this.createDragHandle();
|
|
53693
|
+
element.prepend(dragHandle);
|
|
53694
|
+
element.addEventListener("dragstart", (e) => this.onDragStart(e));
|
|
53695
|
+
this.root = element;
|
|
53696
|
+
}
|
|
53697
|
+
updateView() {
|
|
53698
|
+
const domAttrs = Attribute2.mergeAttributes(this.htmlAttributes);
|
|
53699
|
+
updateDOMAttributes(this.dom, { ...domAttrs });
|
|
53700
|
+
}
|
|
53701
|
+
update(node, decorations, innerDecorations) {
|
|
53702
|
+
const result = super.update(node, decorations, innerDecorations);
|
|
53703
|
+
if (!result) return false;
|
|
53704
|
+
this.updateView();
|
|
53705
|
+
return true;
|
|
53706
|
+
}
|
|
53707
|
+
}
|
|
53708
|
+
const structuredContentClass = "sd-structured-content-block";
|
|
53709
|
+
const structuredContentInnerClass = "sd-structured-content-block__content";
|
|
53710
|
+
const StructuredContentBlock = Node$1.create({
|
|
53711
|
+
name: "structuredContentBlock",
|
|
53712
|
+
group: "block structuredContent",
|
|
53713
|
+
content: "block*",
|
|
53714
|
+
isolating: true,
|
|
53715
|
+
atom: false,
|
|
53716
|
+
// false - has editable content.
|
|
53717
|
+
draggable: true,
|
|
53298
53718
|
addOptions() {
|
|
53299
53719
|
return {
|
|
53300
|
-
itemTypeName: "listItem",
|
|
53301
53720
|
htmlAttributes: {
|
|
53302
|
-
|
|
53303
|
-
|
|
53304
|
-
|
|
53305
|
-
keepAttributes: false,
|
|
53306
|
-
listStyleTypes: ["decimal", "lowerAlpha", "lowerRoman"]
|
|
53721
|
+
class: structuredContentClass,
|
|
53722
|
+
"aria-label": "Structured content block node"
|
|
53723
|
+
}
|
|
53307
53724
|
};
|
|
53308
53725
|
},
|
|
53309
53726
|
addAttributes() {
|
|
53310
53727
|
return {
|
|
53311
|
-
|
|
53312
|
-
default: 1,
|
|
53313
|
-
parseDOM: (element) => {
|
|
53314
|
-
return element.hasAttribute("start") ? parseInt(element.getAttribute("start") || "", 10) : 1;
|
|
53315
|
-
},
|
|
53316
|
-
renderDOM: (attrs) => {
|
|
53317
|
-
return {
|
|
53318
|
-
start: attrs.order
|
|
53319
|
-
};
|
|
53320
|
-
}
|
|
53321
|
-
},
|
|
53322
|
-
sdBlockId: {
|
|
53728
|
+
id: {
|
|
53323
53729
|
default: null,
|
|
53324
|
-
|
|
53325
|
-
parseDOM: (elem) => elem.getAttribute("data-sd-block-id"),
|
|
53730
|
+
parseDOM: (elem) => elem.getAttribute("data-id"),
|
|
53326
53731
|
renderDOM: (attrs) => {
|
|
53327
|
-
|
|
53732
|
+
if (!attrs.id) return {};
|
|
53733
|
+
return { "data-id": attrs.id };
|
|
53328
53734
|
}
|
|
53329
53735
|
},
|
|
53330
|
-
|
|
53736
|
+
tag: {
|
|
53331
53737
|
default: null,
|
|
53332
|
-
parseDOM: (elem) => elem.getAttribute("data-
|
|
53738
|
+
parseDOM: (elem) => elem.getAttribute("data-tag"),
|
|
53333
53739
|
renderDOM: (attrs) => {
|
|
53334
|
-
if (!attrs.
|
|
53335
|
-
return {
|
|
53336
|
-
"data-sync-id": attrs.syncId
|
|
53337
|
-
};
|
|
53740
|
+
if (!attrs.tag) return {};
|
|
53741
|
+
return { "data-tag": attrs.tag };
|
|
53338
53742
|
}
|
|
53339
|
-
// rendered: false,
|
|
53340
53743
|
},
|
|
53341
|
-
|
|
53342
|
-
|
|
53343
|
-
parseDOM: (elem) => elem.getAttribute("data-
|
|
53744
|
+
alias: {
|
|
53745
|
+
default: null,
|
|
53746
|
+
parseDOM: (elem) => elem.getAttribute("data-alias"),
|
|
53344
53747
|
renderDOM: (attrs) => {
|
|
53345
|
-
if (!attrs.
|
|
53346
|
-
return {
|
|
53347
|
-
"data-list-id": attrs.listId
|
|
53348
|
-
};
|
|
53748
|
+
if (!attrs.alias) return {};
|
|
53749
|
+
return { "data-alias": attrs.alias };
|
|
53349
53750
|
}
|
|
53350
53751
|
},
|
|
53351
|
-
|
|
53352
|
-
default: "decimal",
|
|
53752
|
+
sdtPr: {
|
|
53353
53753
|
rendered: false
|
|
53354
|
-
},
|
|
53355
|
-
attributes: {
|
|
53356
|
-
rendered: false,
|
|
53357
|
-
keepOnSplit: true
|
|
53358
53754
|
}
|
|
53359
53755
|
};
|
|
53360
53756
|
},
|
|
53361
53757
|
parseDOM() {
|
|
53362
|
-
return [{ tag: "
|
|
53758
|
+
return [{ tag: "div[data-structured-content-block]" }];
|
|
53363
53759
|
},
|
|
53364
53760
|
renderDOM({ htmlAttributes }) {
|
|
53365
|
-
|
|
53366
|
-
|
|
53761
|
+
return [
|
|
53762
|
+
"div",
|
|
53763
|
+
Attribute2.mergeAttributes(this.options.htmlAttributes, htmlAttributes, {
|
|
53764
|
+
"data-structured-content-block": ""
|
|
53765
|
+
}),
|
|
53766
|
+
0
|
|
53767
|
+
];
|
|
53367
53768
|
},
|
|
53769
|
+
addNodeView() {
|
|
53770
|
+
return (props) => {
|
|
53771
|
+
return new StructuredContentBlockView({ ...props });
|
|
53772
|
+
};
|
|
53773
|
+
}
|
|
53774
|
+
});
|
|
53775
|
+
function getStructuredContentTagsById(idOrIds, state2) {
|
|
53776
|
+
const result = findChildren$5(state2.doc, (node) => {
|
|
53777
|
+
const isStructuredContent = ["structuredContent", "structuredContentBlock"].includes(node.type.name);
|
|
53778
|
+
if (Array.isArray(idOrIds)) {
|
|
53779
|
+
return isStructuredContent && idOrIds.includes(node.attrs.id);
|
|
53780
|
+
} else {
|
|
53781
|
+
return isStructuredContent && node.attrs.id === idOrIds;
|
|
53782
|
+
}
|
|
53783
|
+
});
|
|
53784
|
+
return result;
|
|
53785
|
+
}
|
|
53786
|
+
function getStructuredContentTags(state2) {
|
|
53787
|
+
const result = findChildren$5(state2.doc, (node) => {
|
|
53788
|
+
return node.type.name === "structuredContent" || node.type.name === "structuredContentBlock";
|
|
53789
|
+
});
|
|
53790
|
+
return result;
|
|
53791
|
+
}
|
|
53792
|
+
function getStructuredContentInlineTags(state2) {
|
|
53793
|
+
const result = findChildren$5(state2.doc, (node) => node.type.name === "structuredContent");
|
|
53794
|
+
return result;
|
|
53795
|
+
}
|
|
53796
|
+
function getStructuredContentBlockTags(state2) {
|
|
53797
|
+
const result = findChildren$5(state2.doc, (node) => node.type.name === "structuredContentBlock");
|
|
53798
|
+
return result;
|
|
53799
|
+
}
|
|
53800
|
+
const structuredContentHelpers = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
53801
|
+
__proto__: null,
|
|
53802
|
+
getStructuredContentBlockTags,
|
|
53803
|
+
getStructuredContentInlineTags,
|
|
53804
|
+
getStructuredContentTags,
|
|
53805
|
+
getStructuredContentTagsById
|
|
53806
|
+
}, Symbol.toStringTag, { value: "Module" }));
|
|
53807
|
+
const STRUCTURED_CONTENT_NAMES = ["structuredContent", "structuredContentBlock"];
|
|
53808
|
+
const StructuredContentCommands = Extension.create({
|
|
53809
|
+
name: "structuredContentCommands",
|
|
53368
53810
|
addCommands() {
|
|
53369
53811
|
return {
|
|
53370
53812
|
/**
|
|
53371
|
-
*
|
|
53813
|
+
* Inserts a structured content inline at selection.
|
|
53372
53814
|
* @category Command
|
|
53373
|
-
* @
|
|
53374
|
-
* editor.commands.toggleOrderedList()
|
|
53375
|
-
* @note Converts selection to ordered list or back to paragraphs
|
|
53815
|
+
* @param {StructuredContentInlineInsert} options
|
|
53376
53816
|
*/
|
|
53377
|
-
|
|
53378
|
-
|
|
53817
|
+
insertStructuredContentInline: (options = {}) => ({ editor, dispatch, state: state2, tr }) => {
|
|
53818
|
+
const { schema } = editor;
|
|
53819
|
+
let { from: from2, to } = state2.selection;
|
|
53820
|
+
if (dispatch) {
|
|
53821
|
+
const selectionText = state2.doc.textBetween(from2, to);
|
|
53822
|
+
let content = null;
|
|
53823
|
+
if (selectionText) {
|
|
53824
|
+
content = schema.text(selectionText);
|
|
53825
|
+
}
|
|
53826
|
+
if (options.text) {
|
|
53827
|
+
content = schema.text(options.text);
|
|
53828
|
+
}
|
|
53829
|
+
if (options.json) {
|
|
53830
|
+
content = schema.nodeFromJSON(options.json);
|
|
53831
|
+
}
|
|
53832
|
+
if (!content) {
|
|
53833
|
+
content = schema.text(" ");
|
|
53834
|
+
}
|
|
53835
|
+
const attrs = {
|
|
53836
|
+
...options.attrs,
|
|
53837
|
+
id: options.attrs?.id || randomId(),
|
|
53838
|
+
tag: "inline_text_sdt",
|
|
53839
|
+
alias: options.attrs?.alias || "Structured content"
|
|
53840
|
+
};
|
|
53841
|
+
const node = schema.nodes.structuredContent.create(attrs, content, null);
|
|
53842
|
+
const parent = findParentNode((node2) => node2.type.name === "structuredContent")(state2.selection);
|
|
53843
|
+
if (parent) {
|
|
53844
|
+
const insertPos = parent.pos + parent.node.nodeSize;
|
|
53845
|
+
from2 = to = insertPos;
|
|
53846
|
+
}
|
|
53847
|
+
tr.replaceWith(from2, to, node);
|
|
53848
|
+
}
|
|
53849
|
+
return true;
|
|
53379
53850
|
},
|
|
53380
53851
|
/**
|
|
53381
|
-
*
|
|
53852
|
+
* Inserts a structured content block at selection.
|
|
53382
53853
|
* @category Command
|
|
53383
|
-
* @param {
|
|
53384
|
-
* @param {number} pos - Starting position
|
|
53385
|
-
* @example
|
|
53386
|
-
* editor.commands.restartListNodes(nodes, position)
|
|
53387
|
-
* @note Resets list numbering for specified nodes
|
|
53854
|
+
* @param {StructuredContentBlockInsert} options
|
|
53388
53855
|
*/
|
|
53389
|
-
|
|
53390
|
-
|
|
53391
|
-
|
|
53392
|
-
|
|
53393
|
-
|
|
53394
|
-
|
|
53856
|
+
insertStructuredContentBlock: (options = {}) => ({ editor, dispatch, state: state2, tr }) => {
|
|
53857
|
+
const { schema } = editor;
|
|
53858
|
+
let { from: from2, to } = state2.selection;
|
|
53859
|
+
if (dispatch) {
|
|
53860
|
+
const selectionContent = state2.selection.content();
|
|
53861
|
+
let content = null;
|
|
53862
|
+
if (selectionContent.size) {
|
|
53863
|
+
content = selectionContent.content;
|
|
53864
|
+
}
|
|
53865
|
+
if (options.html) {
|
|
53866
|
+
const html = htmlHandler(options.html, editor);
|
|
53867
|
+
const doc2 = DOMParser$1.fromSchema(schema).parse(html);
|
|
53868
|
+
content = doc2.content;
|
|
53869
|
+
}
|
|
53870
|
+
if (options.json) {
|
|
53871
|
+
content = schema.nodeFromJSON(options.json);
|
|
53872
|
+
}
|
|
53873
|
+
if (!content) {
|
|
53874
|
+
content = schema.nodeFromJSON({ type: "paragraph", content: [] });
|
|
53875
|
+
}
|
|
53876
|
+
const attrs = {
|
|
53877
|
+
...options.attrs,
|
|
53878
|
+
id: options.attrs?.id || randomId(),
|
|
53879
|
+
tag: "block_table_sdt",
|
|
53880
|
+
alias: options.attrs?.alias || "Structured content"
|
|
53395
53881
|
};
|
|
53396
|
-
|
|
53397
|
-
|
|
53398
|
-
|
|
53399
|
-
|
|
53400
|
-
|
|
53401
|
-
|
|
53402
|
-
tr.
|
|
53403
|
-
}
|
|
53882
|
+
const node = schema.nodes.structuredContentBlock.create(attrs, content, null);
|
|
53883
|
+
const parent = findParentNode((node2) => node2.type.name === "structuredContentBlock")(state2.selection);
|
|
53884
|
+
if (parent) {
|
|
53885
|
+
const insertPos = parent.pos + parent.node.nodeSize;
|
|
53886
|
+
from2 = to = insertPos;
|
|
53887
|
+
}
|
|
53888
|
+
tr.replaceRangeWith(from2, to, node);
|
|
53889
|
+
}
|
|
53404
53890
|
return true;
|
|
53405
53891
|
},
|
|
53406
53892
|
/**
|
|
53407
|
-
*
|
|
53893
|
+
* Updates a structured content attributes or content.
|
|
53894
|
+
* If the updated node does not match the schema, it will not be updated.
|
|
53408
53895
|
* @category Command
|
|
53409
|
-
* @
|
|
53410
|
-
*
|
|
53411
|
-
* @note Cycles through decimal -> lowerAlpha -> lowerRoman based on depth
|
|
53896
|
+
* @param {string} id
|
|
53897
|
+
* @param {StructuredContentUpdate} options
|
|
53412
53898
|
*/
|
|
53413
|
-
|
|
53414
|
-
|
|
53415
|
-
if (!
|
|
53899
|
+
updateStructuredContentById: (id, options = {}) => ({ editor, dispatch, state: state2, tr }) => {
|
|
53900
|
+
const structuredContentTags = getStructuredContentTagsById(id, state2);
|
|
53901
|
+
if (!structuredContentTags.length) {
|
|
53416
53902
|
return true;
|
|
53417
53903
|
}
|
|
53904
|
+
const { schema } = editor;
|
|
53418
53905
|
if (dispatch) {
|
|
53419
|
-
|
|
53420
|
-
|
|
53421
|
-
|
|
53422
|
-
|
|
53423
|
-
let
|
|
53424
|
-
if (
|
|
53425
|
-
|
|
53426
|
-
|
|
53427
|
-
|
|
53428
|
-
|
|
53429
|
-
|
|
53430
|
-
|
|
53906
|
+
const structuredContent = structuredContentTags[0];
|
|
53907
|
+
const { pos, node } = structuredContent;
|
|
53908
|
+
const posFrom = pos;
|
|
53909
|
+
const posTo = pos + node.nodeSize;
|
|
53910
|
+
let content = null;
|
|
53911
|
+
if (options.text) {
|
|
53912
|
+
content = schema.text(options.text);
|
|
53913
|
+
}
|
|
53914
|
+
if (options.html) {
|
|
53915
|
+
const html = htmlHandler(options.html, editor);
|
|
53916
|
+
const doc2 = DOMParser$1.fromSchema(schema).parse(html);
|
|
53917
|
+
content = doc2.content;
|
|
53918
|
+
}
|
|
53919
|
+
if (options.json) {
|
|
53920
|
+
content = schema.nodeFromJSON(options.json);
|
|
53431
53921
|
}
|
|
53922
|
+
if (!content) {
|
|
53923
|
+
content = node.content;
|
|
53924
|
+
}
|
|
53925
|
+
const updatedNode = node.type.create({ ...node.attrs, ...options.attrs }, content, node.marks);
|
|
53926
|
+
try {
|
|
53927
|
+
updatedNode.check();
|
|
53928
|
+
} catch {
|
|
53929
|
+
console.error("Updated node does not conform to the schema");
|
|
53930
|
+
return false;
|
|
53931
|
+
}
|
|
53932
|
+
tr.replaceWith(posFrom, posTo, updatedNode);
|
|
53933
|
+
}
|
|
53934
|
+
return true;
|
|
53935
|
+
},
|
|
53936
|
+
/**
|
|
53937
|
+
* Removes a structured content.
|
|
53938
|
+
* @category Command
|
|
53939
|
+
* @param {Array<{ node: Node, pos: number }>} structuredContentTags
|
|
53940
|
+
*/
|
|
53941
|
+
deleteStructuredContent: (structuredContentTags) => ({ dispatch, tr }) => {
|
|
53942
|
+
if (!structuredContentTags.length) {
|
|
53943
|
+
return true;
|
|
53944
|
+
}
|
|
53945
|
+
if (dispatch) {
|
|
53946
|
+
structuredContentTags.forEach((structuredContent) => {
|
|
53947
|
+
const { pos, node } = structuredContent;
|
|
53948
|
+
const posFrom = tr.mapping.map(pos);
|
|
53949
|
+
const posTo = tr.mapping.map(pos + node.nodeSize);
|
|
53950
|
+
const currentNode = tr.doc.nodeAt(posFrom);
|
|
53951
|
+
if (currentNode && node.eq(currentNode)) {
|
|
53952
|
+
tr.delete(posFrom, posTo);
|
|
53953
|
+
}
|
|
53954
|
+
});
|
|
53955
|
+
}
|
|
53956
|
+
return true;
|
|
53957
|
+
},
|
|
53958
|
+
/**
|
|
53959
|
+
* Removes a structured content by ID.
|
|
53960
|
+
* @category Command
|
|
53961
|
+
* @param {string | string[]} idOrIds
|
|
53962
|
+
*/
|
|
53963
|
+
deleteStructuredContentById: (idOrIds) => ({ dispatch, state: state2, tr }) => {
|
|
53964
|
+
const structuredContentTags = getStructuredContentTagsById(idOrIds, state2);
|
|
53965
|
+
if (!structuredContentTags.length) {
|
|
53966
|
+
return true;
|
|
53967
|
+
}
|
|
53968
|
+
if (dispatch) {
|
|
53969
|
+
structuredContentTags.forEach((structuredContent) => {
|
|
53970
|
+
const { pos, node } = structuredContent;
|
|
53971
|
+
const posFrom = tr.mapping.map(pos);
|
|
53972
|
+
const posTo = tr.mapping.map(pos + node.nodeSize);
|
|
53973
|
+
const currentNode = tr.doc.nodeAt(posFrom);
|
|
53974
|
+
if (currentNode && node.eq(currentNode)) {
|
|
53975
|
+
tr.delete(posFrom, posTo);
|
|
53976
|
+
}
|
|
53977
|
+
});
|
|
53978
|
+
}
|
|
53979
|
+
return true;
|
|
53980
|
+
},
|
|
53981
|
+
/**
|
|
53982
|
+
* Removes a structured content at cursor, preserving its content.
|
|
53983
|
+
* @category Command
|
|
53984
|
+
*/
|
|
53985
|
+
deleteStructuredContentAtSelection: () => ({ editor, dispatch, state: state2, tr }) => {
|
|
53986
|
+
const predicate = (node) => STRUCTURED_CONTENT_NAMES.includes(node.type.name);
|
|
53987
|
+
const structuredContent = findParentNode(predicate)(state2.selection);
|
|
53988
|
+
if (!structuredContent) {
|
|
53989
|
+
return true;
|
|
53990
|
+
}
|
|
53991
|
+
if (dispatch) {
|
|
53992
|
+
const { node, pos } = structuredContent;
|
|
53993
|
+
const posFrom = pos;
|
|
53994
|
+
const posTo = posFrom + node.nodeSize;
|
|
53995
|
+
const content = node.content;
|
|
53996
|
+
tr.replaceWith(posFrom, posTo, content);
|
|
53432
53997
|
}
|
|
53433
53998
|
return true;
|
|
53434
53999
|
}
|
|
53435
54000
|
};
|
|
53436
54001
|
},
|
|
53437
|
-
|
|
54002
|
+
addHelpers() {
|
|
53438
54003
|
return {
|
|
53439
|
-
|
|
53440
|
-
return this.editor.commands.toggleOrderedList();
|
|
53441
|
-
}
|
|
54004
|
+
...structuredContentHelpers
|
|
53442
54005
|
};
|
|
53443
|
-
},
|
|
53444
|
-
addInputRules() {
|
|
53445
|
-
return [
|
|
53446
|
-
new InputRule({
|
|
53447
|
-
match: inputRegex,
|
|
53448
|
-
handler: ({ state: state2, range: range2 }) => {
|
|
53449
|
-
const $pos = state2.selection.$from;
|
|
53450
|
-
const listItemType = state2.schema.nodes.listItem;
|
|
53451
|
-
for (let depth = $pos.depth; depth >= 0; depth--) {
|
|
53452
|
-
if ($pos.node(depth).type === listItemType) {
|
|
53453
|
-
return null;
|
|
53454
|
-
}
|
|
53455
|
-
}
|
|
53456
|
-
const { tr } = state2;
|
|
53457
|
-
tr.delete(range2.from, range2.to);
|
|
53458
|
-
ListHelpers.createNewList({
|
|
53459
|
-
listType: this.type,
|
|
53460
|
-
tr,
|
|
53461
|
-
editor: this.editor
|
|
53462
|
-
});
|
|
53463
|
-
}
|
|
53464
|
-
})
|
|
53465
|
-
];
|
|
53466
54006
|
}
|
|
53467
54007
|
});
|
|
53468
|
-
const
|
|
53469
|
-
|
|
53470
|
-
return handler2 ? handler2(listLevel, lvlText, customFormat) : null;
|
|
53471
|
-
};
|
|
53472
|
-
const handleDecimal = (path, lvlText) => generateNumbering(path, lvlText, String);
|
|
53473
|
-
const handleRoman = (path, lvlText) => generateNumbering(path, lvlText, intToRoman);
|
|
53474
|
-
const handleLowerRoman = (path, lvlText) => handleRoman(path, lvlText).toLowerCase();
|
|
53475
|
-
const handleLowerAlpha = (path, lvlText) => handleAlpha(path, lvlText).toLowerCase();
|
|
53476
|
-
const handleAlpha = (path, lvlText) => generateNumbering(path, lvlText, (p) => intToAlpha(p));
|
|
53477
|
-
const handleOrdinal = (path, lvlText) => generateNumbering(path, lvlText, ordinalFormatter);
|
|
53478
|
-
const handleCustom = (path, lvlText, customFormat) => generateFromCustom(path, lvlText, customFormat);
|
|
53479
|
-
const handleJapaneseCounting = (path, lvlText) => generateNumbering(path, lvlText, intToJapaneseCounting);
|
|
53480
|
-
const listIndexMap = {
|
|
53481
|
-
decimal: handleDecimal,
|
|
53482
|
-
lowerRoman: handleLowerRoman,
|
|
53483
|
-
upperRoman: handleRoman,
|
|
53484
|
-
lowerLetter: handleLowerAlpha,
|
|
53485
|
-
upperLetter: handleAlpha,
|
|
53486
|
-
ordinal: handleOrdinal,
|
|
53487
|
-
custom: handleCustom,
|
|
53488
|
-
japaneseCounting: handleJapaneseCounting
|
|
53489
|
-
};
|
|
53490
|
-
const createNumbering = (values, lvlText) => {
|
|
53491
|
-
return values.reduce((acc, value, index2) => {
|
|
53492
|
-
return value > 9 ? acc.replace(/^0/, "").replace(`%${index2 + 1}`, value) : acc.replace(`%${index2 + 1}`, value);
|
|
53493
|
-
}, lvlText);
|
|
53494
|
-
};
|
|
53495
|
-
const generateNumbering = (path, lvlText, formatter) => {
|
|
53496
|
-
const formattedValues = path.map(formatter);
|
|
53497
|
-
return createNumbering(formattedValues, lvlText);
|
|
54008
|
+
const randomId = () => {
|
|
54009
|
+
return Math.floor(Math.random() * 4294967295).toString();
|
|
53498
54010
|
};
|
|
53499
|
-
|
|
53500
|
-
|
|
53501
|
-
|
|
53502
|
-
|
|
53503
|
-
|
|
53504
|
-
|
|
54011
|
+
class DocumentSectionView {
|
|
54012
|
+
constructor(node, getPos, decorations, editor) {
|
|
54013
|
+
__privateAdd$1(this, _DocumentSectionView_instances);
|
|
54014
|
+
this.node = node;
|
|
54015
|
+
this.editor = editor;
|
|
54016
|
+
this.decorations = decorations;
|
|
54017
|
+
this.view = editor.view;
|
|
54018
|
+
this.getPos = getPos;
|
|
54019
|
+
__privateMethod$1(this, _DocumentSectionView_instances, init_fn2).call(this);
|
|
54020
|
+
}
|
|
54021
|
+
}
|
|
54022
|
+
_DocumentSectionView_instances = /* @__PURE__ */ new WeakSet();
|
|
54023
|
+
init_fn2 = function() {
|
|
54024
|
+
const { attrs } = this.node;
|
|
54025
|
+
const { id, title, description } = attrs;
|
|
54026
|
+
this.dom = document.createElement("div");
|
|
54027
|
+
this.dom.className = "sd-document-section-block";
|
|
54028
|
+
this.dom.setAttribute("data-id", id);
|
|
54029
|
+
this.dom.setAttribute("data-title", title);
|
|
54030
|
+
this.dom.setAttribute("data-description", description);
|
|
54031
|
+
this.dom.setAttribute("aria-label", "Document section");
|
|
54032
|
+
__privateMethod$1(this, _DocumentSectionView_instances, addToolTip_fn).call(this);
|
|
54033
|
+
this.contentDOM = document.createElement("div");
|
|
54034
|
+
this.contentDOM.className = "sd-document-section-block-content";
|
|
54035
|
+
this.contentDOM.setAttribute("contenteditable", "true");
|
|
54036
|
+
this.dom.appendChild(this.contentDOM);
|
|
53505
54037
|
};
|
|
53506
|
-
|
|
53507
|
-
|
|
53508
|
-
|
|
53509
|
-
|
|
53510
|
-
const
|
|
53511
|
-
|
|
53512
|
-
|
|
53513
|
-
|
|
54038
|
+
addToolTip_fn = function() {
|
|
54039
|
+
const { title } = this.node.attrs;
|
|
54040
|
+
this.infoDiv = document.createElement("div");
|
|
54041
|
+
this.infoDiv.className = "sd-document-section-block-info";
|
|
54042
|
+
const textSpan = document.createElement("span");
|
|
54043
|
+
textSpan.textContent = title || "Document section";
|
|
54044
|
+
this.infoDiv.appendChild(textSpan);
|
|
54045
|
+
this.infoDiv.setAttribute("contenteditable", "false");
|
|
54046
|
+
this.dom.appendChild(this.infoDiv);
|
|
53514
54047
|
};
|
|
53515
|
-
const
|
|
53516
|
-
|
|
53517
|
-
|
|
53518
|
-
|
|
53519
|
-
|
|
53520
|
-
|
|
53521
|
-
|
|
53522
|
-
|
|
53523
|
-
|
|
53524
|
-
{ value: 40, numeral: "XL" },
|
|
53525
|
-
{ value: 10, numeral: "X" },
|
|
53526
|
-
{ value: 9, numeral: "IX" },
|
|
53527
|
-
{ value: 5, numeral: "V" },
|
|
53528
|
-
{ value: 4, numeral: "IV" },
|
|
53529
|
-
{ value: 1, numeral: "I" }
|
|
53530
|
-
];
|
|
53531
|
-
let result = "";
|
|
53532
|
-
for (const { value, numeral } of romanNumeralMap) {
|
|
53533
|
-
while (num >= value) {
|
|
53534
|
-
result += numeral;
|
|
53535
|
-
num -= value;
|
|
54048
|
+
const getAllSections = (editor) => {
|
|
54049
|
+
if (!editor) return [];
|
|
54050
|
+
const type2 = editor.schema.nodes.documentSection;
|
|
54051
|
+
if (!type2) return [];
|
|
54052
|
+
const sections = [];
|
|
54053
|
+
const { state: state2 } = editor;
|
|
54054
|
+
state2.doc.descendants((node, pos) => {
|
|
54055
|
+
if (node.type.name === type2.name) {
|
|
54056
|
+
sections.push({ node, pos });
|
|
53536
54057
|
}
|
|
53537
|
-
}
|
|
53538
|
-
return
|
|
54058
|
+
});
|
|
54059
|
+
return sections;
|
|
53539
54060
|
};
|
|
53540
|
-
const
|
|
53541
|
-
|
|
53542
|
-
const
|
|
53543
|
-
|
|
53544
|
-
|
|
53545
|
-
|
|
53546
|
-
|
|
53547
|
-
|
|
54061
|
+
const exportSectionsToHTML = (editor) => {
|
|
54062
|
+
const sections = getAllSections(editor);
|
|
54063
|
+
const processedSections = /* @__PURE__ */ new Set();
|
|
54064
|
+
const result = [];
|
|
54065
|
+
sections.forEach(({ node }) => {
|
|
54066
|
+
const { attrs } = node;
|
|
54067
|
+
const { id, title, description } = attrs;
|
|
54068
|
+
if (processedSections.has(id)) return;
|
|
54069
|
+
processedSections.add(id);
|
|
54070
|
+
const html = getHTMLFromNode(node, editor);
|
|
54071
|
+
result.push({
|
|
54072
|
+
id,
|
|
54073
|
+
title,
|
|
54074
|
+
description,
|
|
54075
|
+
html
|
|
54076
|
+
});
|
|
54077
|
+
});
|
|
53548
54078
|
return result;
|
|
53549
54079
|
};
|
|
53550
|
-
const
|
|
53551
|
-
const
|
|
53552
|
-
const
|
|
53553
|
-
|
|
53554
|
-
|
|
53555
|
-
let
|
|
53556
|
-
|
|
53557
|
-
|
|
53558
|
-
|
|
53559
|
-
|
|
53560
|
-
|
|
53561
|
-
|
|
53562
|
-
|
|
53563
|
-
|
|
53564
|
-
|
|
53565
|
-
|
|
53566
|
-
|
|
53567
|
-
|
|
53568
|
-
|
|
53569
|
-
|
|
53570
|
-
|
|
53571
|
-
|
|
53572
|
-
|
|
53573
|
-
|
|
53574
|
-
}
|
|
54080
|
+
const getHTMLFromNode = (node, editor) => {
|
|
54081
|
+
const tempDocument = document.implementation.createHTMLDocument();
|
|
54082
|
+
const container = tempDocument.createElement("div");
|
|
54083
|
+
const fragment = DOMSerializer.fromSchema(editor.schema).serializeFragment(node.content);
|
|
54084
|
+
container.appendChild(fragment);
|
|
54085
|
+
let html = container.innerHTML;
|
|
54086
|
+
return html;
|
|
54087
|
+
};
|
|
54088
|
+
const exportSectionsToJSON = (editor) => {
|
|
54089
|
+
const sections = getAllSections(editor);
|
|
54090
|
+
const processedSections = /* @__PURE__ */ new Set();
|
|
54091
|
+
const result = [];
|
|
54092
|
+
sections.forEach(({ node }) => {
|
|
54093
|
+
const { attrs } = node;
|
|
54094
|
+
const { id, title, description } = attrs;
|
|
54095
|
+
if (processedSections.has(id)) return;
|
|
54096
|
+
processedSections.add(id);
|
|
54097
|
+
result.push({
|
|
54098
|
+
id,
|
|
54099
|
+
title,
|
|
54100
|
+
description,
|
|
54101
|
+
content: node.toJSON()
|
|
54102
|
+
});
|
|
54103
|
+
});
|
|
53575
54104
|
return result;
|
|
53576
54105
|
};
|
|
53577
|
-
const
|
|
53578
|
-
const
|
|
53579
|
-
|
|
53580
|
-
if (
|
|
53581
|
-
|
|
53582
|
-
|
|
53583
|
-
|
|
53584
|
-
|
|
54106
|
+
const getLinkedSectionEditor = (id, options, editor) => {
|
|
54107
|
+
const sections = getAllSections(editor);
|
|
54108
|
+
const section = sections.find((s) => s.node.attrs.id === id);
|
|
54109
|
+
if (!section) return null;
|
|
54110
|
+
const child = editor.createChildEditor({
|
|
54111
|
+
...options,
|
|
54112
|
+
onUpdate: ({ editor: childEditor, transaction }) => {
|
|
54113
|
+
const isFromtLinkedParent = transaction.getMeta("fromLinkedParent");
|
|
54114
|
+
if (isFromtLinkedParent) return;
|
|
54115
|
+
const updatedContent = childEditor.state.doc.content;
|
|
54116
|
+
const sectionNode = getAllSections(editor)?.find((s) => s.node.attrs.id === id);
|
|
54117
|
+
if (!sectionNode) return;
|
|
54118
|
+
const { pos, node } = sectionNode;
|
|
54119
|
+
const newNode = node.type.create(node.attrs, updatedContent, node.marks);
|
|
54120
|
+
const tr = editor.state.tr.replaceWith(pos, pos + node.nodeSize, newNode);
|
|
54121
|
+
tr.setMeta("fromLinkedChild", true);
|
|
54122
|
+
editor.view.dispatch(tr);
|
|
54123
|
+
}
|
|
54124
|
+
});
|
|
54125
|
+
editor.on("update", ({ transaction }) => {
|
|
54126
|
+
const isFromLinkedChild = transaction.getMeta("fromLinkedChild");
|
|
54127
|
+
if (isFromLinkedChild) return;
|
|
54128
|
+
const sectionNode = getAllSections(editor)?.find((s) => s.node.attrs.id === id);
|
|
54129
|
+
if (!sectionNode) return;
|
|
54130
|
+
const sectionContent = sectionNode.node.content;
|
|
54131
|
+
const json = {
|
|
54132
|
+
type: "doc",
|
|
54133
|
+
content: sectionContent.content.map((node) => node.toJSON())
|
|
54134
|
+
};
|
|
54135
|
+
const childTr = child.state.tr;
|
|
54136
|
+
childTr.setMeta("fromLinkedParent", true);
|
|
54137
|
+
childTr.replaceWith(0, child.state.doc.content.size, child.schema.nodeFromJSON(json));
|
|
54138
|
+
child.view.dispatch(childTr);
|
|
54139
|
+
});
|
|
54140
|
+
return child;
|
|
54141
|
+
};
|
|
54142
|
+
const SectionHelpers = {
|
|
54143
|
+
getAllSections,
|
|
54144
|
+
exportSectionsToHTML,
|
|
54145
|
+
exportSectionsToJSON,
|
|
54146
|
+
getLinkedSectionEditor
|
|
54147
|
+
};
|
|
54148
|
+
const DocumentSection = Node$1.create({
|
|
54149
|
+
name: "documentSection",
|
|
54150
|
+
group: "block",
|
|
54151
|
+
content: "block*",
|
|
54152
|
+
atom: true,
|
|
54153
|
+
isolating: true,
|
|
54154
|
+
addOptions() {
|
|
54155
|
+
return {
|
|
54156
|
+
htmlAttributes: {
|
|
54157
|
+
class: "sd-document-section-block",
|
|
54158
|
+
"aria-label": "Structured content block"
|
|
54159
|
+
}
|
|
54160
|
+
};
|
|
54161
|
+
},
|
|
54162
|
+
parseDOM() {
|
|
54163
|
+
return [
|
|
54164
|
+
{
|
|
54165
|
+
tag: "div.sd-document-section-block",
|
|
54166
|
+
priority: 60
|
|
54167
|
+
}
|
|
54168
|
+
];
|
|
54169
|
+
},
|
|
54170
|
+
renderDOM({ htmlAttributes }) {
|
|
54171
|
+
return ["div", Attribute2.mergeAttributes(this.options.htmlAttributes, htmlAttributes), 0];
|
|
54172
|
+
},
|
|
54173
|
+
addAttributes() {
|
|
54174
|
+
return {
|
|
54175
|
+
id: {},
|
|
54176
|
+
sdBlockId: {
|
|
54177
|
+
default: null,
|
|
54178
|
+
keepOnSplit: false,
|
|
54179
|
+
parseDOM: (elem) => elem.getAttribute("data-sd-block-id"),
|
|
54180
|
+
renderDOM: (attrs) => {
|
|
54181
|
+
return attrs.sdBlockId ? { "data-sd-block-id": attrs.sdBlockId } : {};
|
|
54182
|
+
}
|
|
54183
|
+
},
|
|
54184
|
+
title: {},
|
|
54185
|
+
description: {},
|
|
54186
|
+
sectionType: {},
|
|
54187
|
+
isLocked: { default: false }
|
|
54188
|
+
};
|
|
54189
|
+
},
|
|
54190
|
+
addNodeView() {
|
|
54191
|
+
return ({ node, editor, getPos, decorations }) => {
|
|
54192
|
+
return new DocumentSectionView(node, getPos, decorations, editor);
|
|
54193
|
+
};
|
|
54194
|
+
},
|
|
54195
|
+
addCommands() {
|
|
54196
|
+
return {
|
|
54197
|
+
/**
|
|
54198
|
+
* Create a lockable content section
|
|
54199
|
+
* @category Command
|
|
54200
|
+
* @param {SectionCreate} [options={}] - Section configuration
|
|
54201
|
+
* @example
|
|
54202
|
+
* editor.commands.createDocumentSection({
|
|
54203
|
+
* id: 1,
|
|
54204
|
+
* title: 'Terms & Conditions',
|
|
54205
|
+
* isLocked: true,
|
|
54206
|
+
* html: '<p>Legal content...</p>'
|
|
54207
|
+
* })
|
|
54208
|
+
*/
|
|
54209
|
+
createDocumentSection: (options = {}) => ({ tr, state: state2, dispatch, editor }) => {
|
|
54210
|
+
const { selection } = state2;
|
|
54211
|
+
let { from: from2, to } = selection;
|
|
54212
|
+
let content = selection.content().content;
|
|
54213
|
+
const { html: optionsHTML, json: optionsJSON } = options;
|
|
54214
|
+
if (optionsHTML) {
|
|
54215
|
+
const html = htmlHandler(optionsHTML, this.editor);
|
|
54216
|
+
const doc2 = DOMParser$1.fromSchema(this.editor.schema).parse(html);
|
|
54217
|
+
content = doc2.content;
|
|
54218
|
+
}
|
|
54219
|
+
if (optionsJSON) {
|
|
54220
|
+
content = this.editor.schema.nodeFromJSON(optionsJSON);
|
|
54221
|
+
}
|
|
54222
|
+
if (!content?.content?.length) {
|
|
54223
|
+
content = this.editor.schema.nodeFromJSON({ type: "paragraph", content: [] });
|
|
54224
|
+
}
|
|
54225
|
+
if (!options.id) {
|
|
54226
|
+
const allSections = SectionHelpers.getAllSections(editor);
|
|
54227
|
+
options.id = allSections.length + 1;
|
|
54228
|
+
}
|
|
54229
|
+
if (!options.title) {
|
|
54230
|
+
options.title = "Document section";
|
|
54231
|
+
}
|
|
54232
|
+
const node = this.type.createAndFill(options, content);
|
|
54233
|
+
if (!node) return false;
|
|
54234
|
+
const isAlreadyInSdtBlock = findParentNode((node2) => node2.type.name === "documentSection")(selection);
|
|
54235
|
+
if (isAlreadyInSdtBlock && isAlreadyInSdtBlock.node) {
|
|
54236
|
+
const insertPos2 = isAlreadyInSdtBlock.pos + isAlreadyInSdtBlock.node.nodeSize;
|
|
54237
|
+
from2 = insertPos2;
|
|
54238
|
+
to = insertPos2;
|
|
54239
|
+
}
|
|
54240
|
+
tr.replaceRangeWith(from2, to, node);
|
|
54241
|
+
const nodeEnd = from2 + node.nodeSize;
|
|
54242
|
+
let shouldInsertParagraph = true;
|
|
54243
|
+
let insertPos = nodeEnd;
|
|
54244
|
+
if (nodeEnd >= tr.doc.content.size) {
|
|
54245
|
+
insertPos = tr.doc.content.size;
|
|
54246
|
+
if (insertPos > 0) {
|
|
54247
|
+
const $endPos = tr.doc.resolve(insertPos);
|
|
54248
|
+
if ($endPos.nodeBefore && $endPos.nodeBefore.type.name === "paragraph") {
|
|
54249
|
+
shouldInsertParagraph = false;
|
|
54250
|
+
}
|
|
54251
|
+
}
|
|
54252
|
+
}
|
|
54253
|
+
if (shouldInsertParagraph) {
|
|
54254
|
+
const emptyParagraph = tr.doc.type.schema.nodes.paragraph.create();
|
|
54255
|
+
tr.insert(insertPos, emptyParagraph);
|
|
54256
|
+
}
|
|
54257
|
+
if (dispatch) {
|
|
54258
|
+
tr.setMeta("documentSection", { action: "create" });
|
|
54259
|
+
dispatch(tr);
|
|
54260
|
+
setTimeout(() => {
|
|
54261
|
+
try {
|
|
54262
|
+
const currentState = editor.state;
|
|
54263
|
+
const docSize = currentState.doc.content.size;
|
|
54264
|
+
let targetPos = from2 + node.nodeSize;
|
|
54265
|
+
if (shouldInsertParagraph) {
|
|
54266
|
+
targetPos += 1;
|
|
54267
|
+
}
|
|
54268
|
+
targetPos = Math.min(targetPos, docSize);
|
|
54269
|
+
if (targetPos < docSize && targetPos > 0) {
|
|
54270
|
+
const newSelection = Selection.near(currentState.doc.resolve(targetPos));
|
|
54271
|
+
const newTr = currentState.tr.setSelection(newSelection);
|
|
54272
|
+
editor.view.dispatch(newTr);
|
|
54273
|
+
}
|
|
54274
|
+
} catch (e) {
|
|
54275
|
+
console.warn("Could not set delayed selection:", e);
|
|
54276
|
+
}
|
|
54277
|
+
}, 0);
|
|
54278
|
+
}
|
|
54279
|
+
return true;
|
|
54280
|
+
},
|
|
54281
|
+
/**
|
|
54282
|
+
* Remove section wrapper at cursor, preserving its content
|
|
54283
|
+
* @category Command
|
|
54284
|
+
* @example
|
|
54285
|
+
* editor.commands.removeSectionAtSelection()
|
|
54286
|
+
* @note Content stays in document, only section wrapper is removed
|
|
54287
|
+
*/
|
|
54288
|
+
removeSectionAtSelection: () => ({ tr, dispatch }) => {
|
|
54289
|
+
const sdtNode = findParentNode((node2) => node2.type.name === "documentSection")(tr.selection);
|
|
54290
|
+
if (!sdtNode) return false;
|
|
54291
|
+
const { node, pos } = sdtNode;
|
|
54292
|
+
const nodeStart = pos;
|
|
54293
|
+
const nodeEnd = nodeStart + node.nodeSize;
|
|
54294
|
+
const contentToPreserve = node.content;
|
|
54295
|
+
tr.delete(nodeStart, nodeEnd);
|
|
54296
|
+
if (contentToPreserve.size > 0) {
|
|
54297
|
+
tr.insert(nodeStart, contentToPreserve);
|
|
54298
|
+
}
|
|
54299
|
+
const newPos = Math.min(nodeStart, tr.doc.content.size);
|
|
54300
|
+
tr.setSelection(Selection.near(tr.doc.resolve(newPos)));
|
|
54301
|
+
if (dispatch) {
|
|
54302
|
+
tr.setMeta("documentSection", { action: "delete" });
|
|
54303
|
+
dispatch(tr);
|
|
54304
|
+
}
|
|
54305
|
+
return true;
|
|
54306
|
+
},
|
|
54307
|
+
/**
|
|
54308
|
+
* Delete section and all its content
|
|
54309
|
+
* @category Command
|
|
54310
|
+
* @param {number} id - Section to delete
|
|
54311
|
+
* @example
|
|
54312
|
+
* editor.commands.removeSectionById(123)
|
|
54313
|
+
*/
|
|
54314
|
+
removeSectionById: (id) => ({ tr, dispatch }) => {
|
|
54315
|
+
const sections = SectionHelpers.getAllSections(this.editor);
|
|
54316
|
+
const sectionToRemove = sections.find(({ node: node2 }) => node2.attrs.id === id);
|
|
54317
|
+
if (!sectionToRemove) return false;
|
|
54318
|
+
const { pos, node } = sectionToRemove;
|
|
54319
|
+
const nodeStart = pos;
|
|
54320
|
+
const nodeEnd = nodeStart + node.nodeSize;
|
|
54321
|
+
tr.delete(nodeStart, nodeEnd);
|
|
54322
|
+
if (dispatch) {
|
|
54323
|
+
tr.setMeta("documentSection", { action: "delete", id });
|
|
54324
|
+
dispatch(tr);
|
|
54325
|
+
}
|
|
54326
|
+
return true;
|
|
54327
|
+
},
|
|
54328
|
+
/**
|
|
54329
|
+
* Lock section against edits
|
|
54330
|
+
* @category Command
|
|
54331
|
+
* @param {number} id - Section to lock
|
|
54332
|
+
* @example
|
|
54333
|
+
* editor.commands.lockSectionById(123)
|
|
54334
|
+
*/
|
|
54335
|
+
lockSectionById: (id) => ({ tr, dispatch }) => {
|
|
54336
|
+
const sections = SectionHelpers.getAllSections(this.editor);
|
|
54337
|
+
const sectionToLock = sections.find(({ node }) => node.attrs.id === id);
|
|
54338
|
+
if (!sectionToLock) return false;
|
|
54339
|
+
tr.setNodeMarkup(sectionToLock.pos, null, { ...sectionToLock.node.attrs, isLocked: true });
|
|
54340
|
+
if (dispatch) {
|
|
54341
|
+
tr.setMeta("documentSection", { action: "lock", id });
|
|
54342
|
+
dispatch(tr);
|
|
54343
|
+
}
|
|
54344
|
+
return true;
|
|
54345
|
+
},
|
|
54346
|
+
/**
|
|
54347
|
+
* Modify section attributes or content
|
|
54348
|
+
* @category Command
|
|
54349
|
+
* @param {SectionUpdate} options - Changes to apply
|
|
54350
|
+
* @example
|
|
54351
|
+
* editor.commands.updateSectionById({ id: 123, attrs: { isLocked: false } })
|
|
54352
|
+
* editor.commands.updateSectionById({ id: 123, html: '<p>New content</p>' })
|
|
54353
|
+
* editor.commands.updateSectionById({
|
|
54354
|
+
* id: 123,
|
|
54355
|
+
* html: '<p>Updated</p>',
|
|
54356
|
+
* attrs: { title: 'New Title' }
|
|
54357
|
+
* })
|
|
54358
|
+
*/
|
|
54359
|
+
updateSectionById: ({ id, html, json, attrs }) => ({ tr, dispatch, editor }) => {
|
|
54360
|
+
const sections = SectionHelpers.getAllSections(editor || this.editor);
|
|
54361
|
+
const sectionToUpdate = sections.find(({ node: node2 }) => node2.attrs.id === id);
|
|
54362
|
+
if (!sectionToUpdate) return false;
|
|
54363
|
+
const { pos, node } = sectionToUpdate;
|
|
54364
|
+
let newContent = null;
|
|
54365
|
+
if (html) {
|
|
54366
|
+
const htmlDoc = htmlHandler(html, editor || this.editor);
|
|
54367
|
+
const doc2 = DOMParser$1.fromSchema((editor || this.editor).schema).parse(htmlDoc);
|
|
54368
|
+
newContent = doc2.content;
|
|
54369
|
+
}
|
|
54370
|
+
if (json) {
|
|
54371
|
+
newContent = (editor || this.editor).schema.nodeFromJSON(json);
|
|
54372
|
+
}
|
|
54373
|
+
if (!newContent) {
|
|
54374
|
+
newContent = node.content;
|
|
54375
|
+
}
|
|
54376
|
+
const updatedNode = node.type.create({ ...node.attrs, ...attrs }, newContent, node.marks);
|
|
54377
|
+
tr.replaceWith(pos, pos + node.nodeSize, updatedNode);
|
|
54378
|
+
if (dispatch) {
|
|
54379
|
+
tr.setMeta("documentSection", { action: "update", id, attrs });
|
|
54380
|
+
dispatch(tr);
|
|
54381
|
+
}
|
|
54382
|
+
return true;
|
|
54383
|
+
}
|
|
54384
|
+
};
|
|
54385
|
+
},
|
|
54386
|
+
addHelpers() {
|
|
54387
|
+
return {
|
|
54388
|
+
...SectionHelpers
|
|
54389
|
+
};
|
|
54390
|
+
}
|
|
54391
|
+
});
|
|
54392
|
+
const Document = Node$1.create({
|
|
54393
|
+
name: "doc",
|
|
54394
|
+
topNode: true,
|
|
54395
|
+
content: "block+",
|
|
54396
|
+
parseDOM() {
|
|
54397
|
+
return [{ tag: "doc" }];
|
|
54398
|
+
},
|
|
54399
|
+
renderDOM() {
|
|
54400
|
+
return ["doc", 0];
|
|
54401
|
+
},
|
|
54402
|
+
addAttributes() {
|
|
54403
|
+
return {
|
|
54404
|
+
attributes: {
|
|
54405
|
+
rendered: false,
|
|
54406
|
+
"aria-label": "Document node"
|
|
54407
|
+
}
|
|
54408
|
+
};
|
|
54409
|
+
},
|
|
54410
|
+
addCommands() {
|
|
54411
|
+
return {
|
|
54412
|
+
/**
|
|
54413
|
+
* Get document statistics
|
|
54414
|
+
* @category Command
|
|
54415
|
+
* @example
|
|
54416
|
+
* // Get word and character count
|
|
54417
|
+
* const stats = editor.commands.getDocumentStats()
|
|
54418
|
+
* console.log(`${stats.words} words, ${stats.characters} characters`)
|
|
54419
|
+
* @note Returns word count, character count, and paragraph count
|
|
54420
|
+
*/
|
|
54421
|
+
getDocumentStats: () => ({ editor }) => {
|
|
54422
|
+
const text = editor.getText();
|
|
54423
|
+
const words = text.split(/\s+/).filter((word) => word.length > 0).length;
|
|
54424
|
+
const characters = text.length;
|
|
54425
|
+
const paragraphs = editor.state.doc.content.childCount;
|
|
54426
|
+
return {
|
|
54427
|
+
words,
|
|
54428
|
+
characters,
|
|
54429
|
+
paragraphs
|
|
54430
|
+
};
|
|
54431
|
+
},
|
|
54432
|
+
/**
|
|
54433
|
+
* Clear entire document
|
|
54434
|
+
* @category Command
|
|
54435
|
+
* @example
|
|
54436
|
+
* editor.commands.clearDocument()
|
|
54437
|
+
* @note Replaces all content with an empty paragraph
|
|
54438
|
+
*/
|
|
54439
|
+
clearDocument: () => ({ commands: commands2 }) => {
|
|
54440
|
+
return commands2.setContent("<p></p>");
|
|
54441
|
+
}
|
|
54442
|
+
};
|
|
54443
|
+
}
|
|
54444
|
+
});
|
|
54445
|
+
const Text = Node$1.create({
|
|
54446
|
+
name: "text",
|
|
54447
|
+
group: "inline",
|
|
54448
|
+
inline: true,
|
|
54449
|
+
addOptions() {
|
|
54450
|
+
return {};
|
|
54451
|
+
}
|
|
54452
|
+
});
|
|
54453
|
+
const splitRun = () => (props) => {
|
|
54454
|
+
const { state: state2, view, tr } = props;
|
|
54455
|
+
const { $from, empty: empty2 } = state2.selection;
|
|
54456
|
+
if (!empty2) return false;
|
|
54457
|
+
if ($from.parent.type.name !== "run") return false;
|
|
54458
|
+
const handled = splitBlock(state2, (transaction) => {
|
|
54459
|
+
view.dispatch(transaction);
|
|
54460
|
+
});
|
|
54461
|
+
if (handled) {
|
|
54462
|
+
tr.setMeta("preventDispatch", true);
|
|
54463
|
+
}
|
|
54464
|
+
return handled;
|
|
54465
|
+
};
|
|
54466
|
+
const Run = OxmlNode.create({
|
|
54467
|
+
name: "run",
|
|
54468
|
+
oXmlName: "w:r",
|
|
54469
|
+
group: "inline",
|
|
54470
|
+
inline: true,
|
|
54471
|
+
content: "inline*",
|
|
54472
|
+
selectable: false,
|
|
54473
|
+
childToAttributes: ["runProperties"],
|
|
54474
|
+
addOptions() {
|
|
54475
|
+
return {
|
|
54476
|
+
htmlAttributes: {
|
|
54477
|
+
"data-run": "1"
|
|
54478
|
+
}
|
|
54479
|
+
};
|
|
54480
|
+
},
|
|
54481
|
+
addAttributes() {
|
|
54482
|
+
return {
|
|
54483
|
+
runProperties: {
|
|
54484
|
+
default: null,
|
|
54485
|
+
rendered: false,
|
|
54486
|
+
keepOnSplit: true
|
|
54487
|
+
},
|
|
54488
|
+
rsidR: {
|
|
54489
|
+
default: null,
|
|
54490
|
+
rendered: false,
|
|
54491
|
+
keepOnSplit: true
|
|
54492
|
+
},
|
|
54493
|
+
rsidRPr: {
|
|
54494
|
+
default: null,
|
|
54495
|
+
rendered: false,
|
|
54496
|
+
keepOnSplit: true
|
|
54497
|
+
},
|
|
54498
|
+
rsidDel: {
|
|
54499
|
+
default: null,
|
|
54500
|
+
rendered: false,
|
|
54501
|
+
keepOnSplit: true
|
|
54502
|
+
}
|
|
54503
|
+
};
|
|
54504
|
+
},
|
|
54505
|
+
addCommands() {
|
|
54506
|
+
return {
|
|
54507
|
+
splitRun
|
|
54508
|
+
};
|
|
54509
|
+
},
|
|
54510
|
+
parseDOM() {
|
|
54511
|
+
return [{ tag: "span[data-run]" }];
|
|
54512
|
+
},
|
|
54513
|
+
renderDOM({ htmlAttributes }) {
|
|
54514
|
+
const base2 = Attribute2.mergeAttributes(this.options.htmlAttributes, htmlAttributes);
|
|
54515
|
+
return ["span", base2, 0];
|
|
54516
|
+
}
|
|
54517
|
+
});
|
|
54518
|
+
const inputRegex$1 = /^\s*([-+*])\s$/;
|
|
54519
|
+
const BulletList = Node$1.create({
|
|
54520
|
+
name: "bulletList",
|
|
54521
|
+
group: "block list",
|
|
54522
|
+
selectable: false,
|
|
54523
|
+
content() {
|
|
54524
|
+
return `${this.options.itemTypeName}+`;
|
|
54525
|
+
},
|
|
54526
|
+
addOptions() {
|
|
54527
|
+
return {
|
|
54528
|
+
itemTypeName: "listItem",
|
|
54529
|
+
htmlAttributes: {
|
|
54530
|
+
"aria-label": "Bullet list node"
|
|
54531
|
+
},
|
|
54532
|
+
keepMarks: true,
|
|
54533
|
+
keepAttributes: false
|
|
54534
|
+
};
|
|
54535
|
+
},
|
|
54536
|
+
parseDOM() {
|
|
54537
|
+
return [{ tag: "ul" }];
|
|
54538
|
+
},
|
|
54539
|
+
renderDOM({ htmlAttributes }) {
|
|
54540
|
+
const attributes = Attribute2.mergeAttributes(this.options.htmlAttributes, htmlAttributes);
|
|
54541
|
+
return ["ul", attributes, 0];
|
|
54542
|
+
},
|
|
54543
|
+
addAttributes() {
|
|
54544
|
+
return {
|
|
54545
|
+
"list-style-type": {
|
|
54546
|
+
default: "bullet",
|
|
54547
|
+
rendered: false
|
|
54548
|
+
},
|
|
54549
|
+
listId: {
|
|
54550
|
+
rendered: false
|
|
54551
|
+
},
|
|
54552
|
+
sdBlockId: {
|
|
54553
|
+
default: null,
|
|
54554
|
+
keepOnSplit: false,
|
|
54555
|
+
parseDOM: (elem) => elem.getAttribute("data-sd-block-id"),
|
|
54556
|
+
renderDOM: (attrs) => {
|
|
54557
|
+
return attrs.sdBlockId ? { "data-sd-block-id": attrs.sdBlockId } : {};
|
|
54558
|
+
}
|
|
54559
|
+
},
|
|
54560
|
+
attributes: {
|
|
54561
|
+
rendered: false,
|
|
54562
|
+
keepOnSplit: true
|
|
54563
|
+
}
|
|
54564
|
+
};
|
|
54565
|
+
},
|
|
54566
|
+
addCommands() {
|
|
54567
|
+
return {
|
|
54568
|
+
/**
|
|
54569
|
+
* Toggle a bullet list at the current selection
|
|
54570
|
+
* @category Command
|
|
54571
|
+
* @example
|
|
54572
|
+
* // Toggle bullet list on selected text
|
|
54573
|
+
* editor.commands.toggleBulletList()
|
|
54574
|
+
* @note Converts selected paragraphs to list items or removes list formatting
|
|
54575
|
+
*/
|
|
54576
|
+
toggleBulletList: () => (params2) => {
|
|
54577
|
+
return toggleList(this.type)(params2);
|
|
54578
|
+
}
|
|
54579
|
+
};
|
|
54580
|
+
},
|
|
54581
|
+
addShortcuts() {
|
|
54582
|
+
return {
|
|
54583
|
+
"Mod-Shift-8": () => {
|
|
54584
|
+
return this.editor.commands.toggleBulletList();
|
|
54585
|
+
}
|
|
54586
|
+
};
|
|
54587
|
+
},
|
|
54588
|
+
addInputRules() {
|
|
54589
|
+
return [
|
|
54590
|
+
new InputRule({
|
|
54591
|
+
match: inputRegex$1,
|
|
54592
|
+
handler: ({ state: state2, range: range2 }) => {
|
|
54593
|
+
const $pos = state2.selection.$from;
|
|
54594
|
+
const listItemType = state2.schema.nodes.listItem;
|
|
54595
|
+
for (let depth = $pos.depth; depth >= 0; depth--) {
|
|
54596
|
+
if ($pos.node(depth).type === listItemType) {
|
|
54597
|
+
return null;
|
|
54598
|
+
}
|
|
54599
|
+
}
|
|
54600
|
+
const { tr } = state2;
|
|
54601
|
+
tr.delete(range2.from, range2.to);
|
|
54602
|
+
ListHelpers.createNewList({
|
|
54603
|
+
listType: this.type,
|
|
54604
|
+
tr,
|
|
54605
|
+
editor: this.editor
|
|
54606
|
+
});
|
|
54607
|
+
}
|
|
54608
|
+
})
|
|
54609
|
+
];
|
|
54610
|
+
}
|
|
54611
|
+
});
|
|
54612
|
+
const inputRegex = /^(\d+)\.\s$/;
|
|
54613
|
+
const OrderedList = Node$1.create({
|
|
54614
|
+
name: "orderedList",
|
|
54615
|
+
group: "block list",
|
|
54616
|
+
selectable: false,
|
|
54617
|
+
content() {
|
|
54618
|
+
return `${this.options.itemTypeName}+`;
|
|
54619
|
+
},
|
|
54620
|
+
addOptions() {
|
|
54621
|
+
return {
|
|
54622
|
+
itemTypeName: "listItem",
|
|
54623
|
+
htmlAttributes: {
|
|
54624
|
+
"aria-label": "Ordered list node"
|
|
54625
|
+
},
|
|
54626
|
+
keepMarks: true,
|
|
54627
|
+
keepAttributes: false,
|
|
54628
|
+
listStyleTypes: ["decimal", "lowerAlpha", "lowerRoman"]
|
|
54629
|
+
};
|
|
54630
|
+
},
|
|
54631
|
+
addAttributes() {
|
|
54632
|
+
return {
|
|
54633
|
+
order: {
|
|
54634
|
+
default: 1,
|
|
54635
|
+
parseDOM: (element) => {
|
|
54636
|
+
return element.hasAttribute("start") ? parseInt(element.getAttribute("start") || "", 10) : 1;
|
|
54637
|
+
},
|
|
54638
|
+
renderDOM: (attrs) => {
|
|
54639
|
+
return {
|
|
54640
|
+
start: attrs.order
|
|
54641
|
+
};
|
|
54642
|
+
}
|
|
54643
|
+
},
|
|
54644
|
+
sdBlockId: {
|
|
54645
|
+
default: null,
|
|
54646
|
+
keepOnSplit: false,
|
|
54647
|
+
parseDOM: (elem) => elem.getAttribute("data-sd-block-id"),
|
|
54648
|
+
renderDOM: (attrs) => {
|
|
54649
|
+
return attrs.sdBlockId ? { "data-sd-block-id": attrs.sdBlockId } : {};
|
|
54650
|
+
}
|
|
54651
|
+
},
|
|
54652
|
+
syncId: {
|
|
54653
|
+
default: null,
|
|
54654
|
+
parseDOM: (elem) => elem.getAttribute("data-sync-id"),
|
|
54655
|
+
renderDOM: (attrs) => {
|
|
54656
|
+
if (!attrs.syncId) return {};
|
|
54657
|
+
return {
|
|
54658
|
+
"data-sync-id": attrs.syncId
|
|
54659
|
+
};
|
|
54660
|
+
}
|
|
54661
|
+
// rendered: false,
|
|
54662
|
+
},
|
|
54663
|
+
listId: {
|
|
54664
|
+
keepOnSplit: true,
|
|
54665
|
+
parseDOM: (elem) => elem.getAttribute("data-list-id"),
|
|
54666
|
+
renderDOM: (attrs) => {
|
|
54667
|
+
if (!attrs.listId) return {};
|
|
54668
|
+
return {
|
|
54669
|
+
"data-list-id": attrs.listId
|
|
54670
|
+
};
|
|
54671
|
+
}
|
|
54672
|
+
},
|
|
54673
|
+
"list-style-type": {
|
|
54674
|
+
default: "decimal",
|
|
54675
|
+
rendered: false
|
|
54676
|
+
},
|
|
54677
|
+
attributes: {
|
|
54678
|
+
rendered: false,
|
|
54679
|
+
keepOnSplit: true
|
|
54680
|
+
}
|
|
54681
|
+
};
|
|
54682
|
+
},
|
|
54683
|
+
parseDOM() {
|
|
54684
|
+
return [{ tag: "ol" }];
|
|
54685
|
+
},
|
|
54686
|
+
renderDOM({ htmlAttributes }) {
|
|
54687
|
+
const { start: start2, ...restAttributes } = htmlAttributes;
|
|
54688
|
+
return start2 === 1 ? ["ol", Attribute2.mergeAttributes(this.options.htmlAttributes, restAttributes), 0] : ["ol", Attribute2.mergeAttributes(this.options.htmlAttributes, htmlAttributes), 0];
|
|
54689
|
+
},
|
|
54690
|
+
addCommands() {
|
|
54691
|
+
return {
|
|
54692
|
+
/**
|
|
54693
|
+
* Toggle ordered list formatting
|
|
54694
|
+
* @category Command
|
|
54695
|
+
* @example
|
|
54696
|
+
* editor.commands.toggleOrderedList()
|
|
54697
|
+
* @note Converts selection to ordered list or back to paragraphs
|
|
54698
|
+
*/
|
|
54699
|
+
toggleOrderedList: () => (params2) => {
|
|
54700
|
+
return toggleList(this.type)(params2);
|
|
54701
|
+
},
|
|
54702
|
+
/**
|
|
54703
|
+
* Restart list node numbering
|
|
54704
|
+
* @category Command
|
|
54705
|
+
* @param {Array} followingNodes - Nodes to restart
|
|
54706
|
+
* @param {number} pos - Starting position
|
|
54707
|
+
* @example
|
|
54708
|
+
* editor.commands.restartListNodes(nodes, position)
|
|
54709
|
+
* @note Resets list numbering for specified nodes
|
|
54710
|
+
*/
|
|
54711
|
+
restartListNodes: (followingNodes, pos) => ({ tr }) => {
|
|
54712
|
+
let currentNodePos = pos;
|
|
54713
|
+
const nodes = followingNodes.map((node) => {
|
|
54714
|
+
const resultNode = {
|
|
54715
|
+
node,
|
|
54716
|
+
pos: currentNodePos
|
|
54717
|
+
};
|
|
54718
|
+
currentNodePos += node.nodeSize;
|
|
54719
|
+
return resultNode;
|
|
54720
|
+
});
|
|
54721
|
+
nodes.forEach((item) => {
|
|
54722
|
+
const { pos: pos2 } = item;
|
|
54723
|
+
const newPos = tr.mapping.map(pos2);
|
|
54724
|
+
tr.setNodeMarkup(newPos, void 0, {});
|
|
54725
|
+
});
|
|
54726
|
+
return true;
|
|
54727
|
+
},
|
|
54728
|
+
/**
|
|
54729
|
+
* Update ordered list style type based on nesting level
|
|
54730
|
+
* @category Command
|
|
54731
|
+
* @example
|
|
54732
|
+
* editor.commands.updateOrderedListStyleType()
|
|
54733
|
+
* @note Cycles through decimal -> lowerAlpha -> lowerRoman based on depth
|
|
54734
|
+
*/
|
|
54735
|
+
updateOrderedListStyleType: () => ({ dispatch, tr }) => {
|
|
54736
|
+
let list = findParentNode((node) => node.type.name === this.name)(tr.selection);
|
|
54737
|
+
if (!list) {
|
|
54738
|
+
return true;
|
|
54739
|
+
}
|
|
54740
|
+
if (dispatch) {
|
|
54741
|
+
let listLevel = (list.depth - 1) / 2;
|
|
54742
|
+
let listStyleTypes = this.options.listStyleTypes;
|
|
54743
|
+
let listStyle = listStyleTypes[listLevel % listStyleTypes.length];
|
|
54744
|
+
let currentListStyle = list.node.attrs["list-style-type"];
|
|
54745
|
+
let nodeAtPos = tr.doc.nodeAt(list.pos);
|
|
54746
|
+
if (currentListStyle !== listStyle && nodeAtPos.eq(list.node)) {
|
|
54747
|
+
tr.setNodeMarkup(list.pos, void 0, {
|
|
54748
|
+
...list.node.attrs,
|
|
54749
|
+
...{
|
|
54750
|
+
"list-style-type": listStyle
|
|
54751
|
+
}
|
|
54752
|
+
});
|
|
54753
|
+
}
|
|
54754
|
+
}
|
|
54755
|
+
return true;
|
|
54756
|
+
}
|
|
54757
|
+
};
|
|
54758
|
+
},
|
|
54759
|
+
addShortcuts() {
|
|
54760
|
+
return {
|
|
54761
|
+
"Mod-Shift-7": () => {
|
|
54762
|
+
return this.editor.commands.toggleOrderedList();
|
|
54763
|
+
}
|
|
54764
|
+
};
|
|
54765
|
+
},
|
|
54766
|
+
addInputRules() {
|
|
54767
|
+
return [
|
|
54768
|
+
new InputRule({
|
|
54769
|
+
match: inputRegex,
|
|
54770
|
+
handler: ({ state: state2, range: range2 }) => {
|
|
54771
|
+
const $pos = state2.selection.$from;
|
|
54772
|
+
const listItemType = state2.schema.nodes.listItem;
|
|
54773
|
+
for (let depth = $pos.depth; depth >= 0; depth--) {
|
|
54774
|
+
if ($pos.node(depth).type === listItemType) {
|
|
54775
|
+
return null;
|
|
54776
|
+
}
|
|
54777
|
+
}
|
|
54778
|
+
const { tr } = state2;
|
|
54779
|
+
tr.delete(range2.from, range2.to);
|
|
54780
|
+
ListHelpers.createNewList({
|
|
54781
|
+
listType: this.type,
|
|
54782
|
+
tr,
|
|
54783
|
+
editor: this.editor
|
|
54784
|
+
});
|
|
54785
|
+
}
|
|
54786
|
+
})
|
|
54787
|
+
];
|
|
54788
|
+
}
|
|
54789
|
+
});
|
|
54790
|
+
const generateOrderedListIndex = ({ listLevel, lvlText, listNumberingType, customFormat }) => {
|
|
54791
|
+
const handler2 = listIndexMap[listNumberingType];
|
|
54792
|
+
return handler2 ? handler2(listLevel, lvlText, customFormat) : null;
|
|
54793
|
+
};
|
|
54794
|
+
const handleDecimal = (path, lvlText) => generateNumbering(path, lvlText, String);
|
|
54795
|
+
const handleRoman = (path, lvlText) => generateNumbering(path, lvlText, intToRoman);
|
|
54796
|
+
const handleLowerRoman = (path, lvlText) => handleRoman(path, lvlText).toLowerCase();
|
|
54797
|
+
const handleLowerAlpha = (path, lvlText) => handleAlpha(path, lvlText).toLowerCase();
|
|
54798
|
+
const handleAlpha = (path, lvlText) => generateNumbering(path, lvlText, (p) => intToAlpha(p));
|
|
54799
|
+
const handleOrdinal = (path, lvlText) => generateNumbering(path, lvlText, ordinalFormatter);
|
|
54800
|
+
const handleCustom = (path, lvlText, customFormat) => generateFromCustom(path, lvlText, customFormat);
|
|
54801
|
+
const handleJapaneseCounting = (path, lvlText) => generateNumbering(path, lvlText, intToJapaneseCounting);
|
|
54802
|
+
const listIndexMap = {
|
|
54803
|
+
decimal: handleDecimal,
|
|
54804
|
+
lowerRoman: handleLowerRoman,
|
|
54805
|
+
upperRoman: handleRoman,
|
|
54806
|
+
lowerLetter: handleLowerAlpha,
|
|
54807
|
+
upperLetter: handleAlpha,
|
|
54808
|
+
ordinal: handleOrdinal,
|
|
54809
|
+
custom: handleCustom,
|
|
54810
|
+
japaneseCounting: handleJapaneseCounting
|
|
54811
|
+
};
|
|
54812
|
+
const createNumbering = (values, lvlText) => {
|
|
54813
|
+
return values.reduce((acc, value, index2) => {
|
|
54814
|
+
return value > 9 ? acc.replace(/^0/, "").replace(`%${index2 + 1}`, value) : acc.replace(`%${index2 + 1}`, value);
|
|
54815
|
+
}, lvlText);
|
|
54816
|
+
};
|
|
54817
|
+
const generateNumbering = (path, lvlText, formatter) => {
|
|
54818
|
+
const formattedValues = path.map(formatter);
|
|
54819
|
+
return createNumbering(formattedValues, lvlText);
|
|
54820
|
+
};
|
|
54821
|
+
const ordinalFormatter = (level) => {
|
|
54822
|
+
const suffixes = ["th", "st", "nd", "rd"];
|
|
54823
|
+
const value = level % 100;
|
|
54824
|
+
const suffix2 = suffixes[(value - 20) % 10] || suffixes[value] || suffixes[0];
|
|
54825
|
+
const p = level + suffix2;
|
|
54826
|
+
return p;
|
|
54827
|
+
};
|
|
54828
|
+
const generateFromCustom = (path, lvlText, customFormat) => {
|
|
54829
|
+
if (customFormat !== "001, 002, 003, ...") return generateNumbering(path, lvlText, String);
|
|
54830
|
+
const match = customFormat.match(/(\d+)/);
|
|
54831
|
+
if (!match) throw new Error("Invalid format string: no numeric pattern found");
|
|
54832
|
+
const sample = match[1];
|
|
54833
|
+
const digitCount = sample.length;
|
|
54834
|
+
const index2 = path.pop();
|
|
54835
|
+
return String(index2).padStart(digitCount, "0");
|
|
53585
54836
|
};
|
|
54837
|
+
const intToRoman = (num) => {
|
|
54838
|
+
const romanNumeralMap = [
|
|
54839
|
+
{ value: 1e3, numeral: "M" },
|
|
54840
|
+
{ value: 900, numeral: "CM" },
|
|
54841
|
+
{ value: 500, numeral: "D" },
|
|
54842
|
+
{ value: 400, numeral: "CD" },
|
|
54843
|
+
{ value: 100, numeral: "C" },
|
|
54844
|
+
{ value: 90, numeral: "XC" },
|
|
54845
|
+
{ value: 50, numeral: "L" },
|
|
54846
|
+
{ value: 40, numeral: "XL" },
|
|
54847
|
+
{ value: 10, numeral: "X" },
|
|
54848
|
+
{ value: 9, numeral: "IX" },
|
|
54849
|
+
{ value: 5, numeral: "V" },
|
|
54850
|
+
{ value: 4, numeral: "IV" },
|
|
54851
|
+
{ value: 1, numeral: "I" }
|
|
54852
|
+
];
|
|
54853
|
+
let result = "";
|
|
54854
|
+
for (const { value, numeral } of romanNumeralMap) {
|
|
54855
|
+
while (num >= value) {
|
|
54856
|
+
result += numeral;
|
|
54857
|
+
num -= value;
|
|
54858
|
+
}
|
|
54859
|
+
}
|
|
54860
|
+
return result;
|
|
54861
|
+
};
|
|
54862
|
+
const intToAlpha = (num) => {
|
|
54863
|
+
let result = "";
|
|
54864
|
+
const alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
|
|
54865
|
+
while (num > 0) {
|
|
54866
|
+
let index2 = (num - 1) % 26;
|
|
54867
|
+
result = alphabet[index2] + result;
|
|
54868
|
+
num = Math.floor((num - 1) / 26);
|
|
54869
|
+
}
|
|
54870
|
+
return result;
|
|
54871
|
+
};
|
|
54872
|
+
const intToJapaneseCounting = (num) => {
|
|
54873
|
+
const digits = ["", "一", "二", "三", "四", "五", "六", "七", "八", "九"];
|
|
54874
|
+
const units = ["", "十", "百", "千"];
|
|
54875
|
+
if (num === 0) return "零";
|
|
54876
|
+
if (num < 10) return digits[num];
|
|
54877
|
+
let result = "";
|
|
54878
|
+
let tempNum = num;
|
|
54879
|
+
let unitIndex = 0;
|
|
54880
|
+
while (tempNum > 0) {
|
|
54881
|
+
const digit = tempNum % 10;
|
|
54882
|
+
if (digit !== 0) {
|
|
54883
|
+
const digitStr = digit === 1 && unitIndex > 0 ? "" : digits[digit];
|
|
54884
|
+
result = digitStr + (unitIndex > 0 ? units[unitIndex] : "") + result;
|
|
54885
|
+
} else if (result && tempNum > 0) {
|
|
54886
|
+
if (!result.startsWith("零") && tempNum % 100 !== 0) {
|
|
54887
|
+
result = "零" + result;
|
|
54888
|
+
}
|
|
54889
|
+
}
|
|
54890
|
+
tempNum = Math.floor(tempNum / 10);
|
|
54891
|
+
unitIndex++;
|
|
54892
|
+
if (unitIndex > 3) break;
|
|
54893
|
+
}
|
|
54894
|
+
if (num >= 10 && num < 20) {
|
|
54895
|
+
result = result.replace(/^一十/, "十");
|
|
54896
|
+
}
|
|
54897
|
+
return result;
|
|
54898
|
+
};
|
|
54899
|
+
const isKeyboardInvocation = (event) => {
|
|
54900
|
+
return event.type === "contextmenu" && typeof event.detail === "number" && event.detail === 0 && (event.button === 0 || event.button === void 0) && event.clientX === 0 && event.clientY === 0;
|
|
54901
|
+
};
|
|
54902
|
+
const prefersNativeMenu = (event) => {
|
|
54903
|
+
if (!event) return false;
|
|
54904
|
+
if (event.ctrlKey || event.metaKey) {
|
|
54905
|
+
return true;
|
|
54906
|
+
}
|
|
54907
|
+
return isKeyboardInvocation(event);
|
|
54908
|
+
};
|
|
54909
|
+
const shouldAllowNativeContextMenu = (event) => {
|
|
54910
|
+
return prefersNativeMenu(event);
|
|
54911
|
+
};
|
|
54912
|
+
const shouldBypassContextMenu = shouldAllowNativeContextMenu;
|
|
54913
|
+
const DEFAULT_SELECTION_STATE = Object.freeze({
|
|
54914
|
+
focused: false,
|
|
54915
|
+
preservedSelection: null,
|
|
54916
|
+
showVisualSelection: false,
|
|
54917
|
+
skipFocusReset: false
|
|
54918
|
+
});
|
|
54919
|
+
const normalizeSelectionState = (state2 = {}) => ({
|
|
54920
|
+
...DEFAULT_SELECTION_STATE,
|
|
54921
|
+
...state2
|
|
54922
|
+
});
|
|
54923
|
+
const CustomSelectionPluginKey = new PluginKey("CustomSelection");
|
|
53586
54924
|
const handleClickOutside = (event, editor) => {
|
|
53587
54925
|
const editorElem = editor?.options?.element;
|
|
53588
54926
|
if (!editorElem) return;
|
|
@@ -53619,11 +54957,7 @@ const CustomSelection = Extension.create({
|
|
|
53619
54957
|
const customSelectionPlugin = new Plugin({
|
|
53620
54958
|
key: CustomSelectionPluginKey,
|
|
53621
54959
|
state: {
|
|
53622
|
-
init: () => ({
|
|
53623
|
-
focused: false,
|
|
53624
|
-
preservedSelection: null,
|
|
53625
|
-
showVisualSelection: false
|
|
53626
|
-
}),
|
|
54960
|
+
init: () => ({ ...DEFAULT_SELECTION_STATE }),
|
|
53627
54961
|
apply: (tr, value) => {
|
|
53628
54962
|
const meta = getFocusMeta(tr);
|
|
53629
54963
|
if (meta !== void 0) {
|
|
@@ -53654,7 +54988,8 @@ const CustomSelection = Extension.create({
|
|
|
53654
54988
|
setFocusMeta(view.state.tr, {
|
|
53655
54989
|
focused: true,
|
|
53656
54990
|
preservedSelection: selection,
|
|
53657
|
-
showVisualSelection: true
|
|
54991
|
+
showVisualSelection: true,
|
|
54992
|
+
skipFocusReset: true
|
|
53658
54993
|
})
|
|
53659
54994
|
);
|
|
53660
54995
|
}
|
|
@@ -53675,7 +55010,8 @@ const CustomSelection = Extension.create({
|
|
|
53675
55010
|
setFocusMeta(view.state.tr, {
|
|
53676
55011
|
focused: true,
|
|
53677
55012
|
preservedSelection: selection2,
|
|
53678
|
-
showVisualSelection: true
|
|
55013
|
+
showVisualSelection: true,
|
|
55014
|
+
skipFocusReset: true
|
|
53679
55015
|
})
|
|
53680
55016
|
);
|
|
53681
55017
|
this.editor.setOptions({
|
|
@@ -53698,7 +55034,8 @@ const CustomSelection = Extension.create({
|
|
|
53698
55034
|
setFocusMeta(view.state.tr, {
|
|
53699
55035
|
focused: true,
|
|
53700
55036
|
preservedSelection: selection,
|
|
53701
|
-
showVisualSelection: true
|
|
55037
|
+
showVisualSelection: true,
|
|
55038
|
+
skipFocusReset: false
|
|
53702
55039
|
})
|
|
53703
55040
|
);
|
|
53704
55041
|
this.editor.setOptions({
|
|
@@ -53716,7 +55053,8 @@ const CustomSelection = Extension.create({
|
|
|
53716
55053
|
setFocusMeta(view.state.tr, {
|
|
53717
55054
|
focused: true,
|
|
53718
55055
|
preservedSelection: selection,
|
|
53719
|
-
showVisualSelection: true
|
|
55056
|
+
showVisualSelection: true,
|
|
55057
|
+
skipFocusReset: false
|
|
53720
55058
|
})
|
|
53721
55059
|
);
|
|
53722
55060
|
}
|
|
@@ -53727,7 +55065,8 @@ const CustomSelection = Extension.create({
|
|
|
53727
55065
|
setFocusMeta(view.state.tr, {
|
|
53728
55066
|
focused: false,
|
|
53729
55067
|
preservedSelection: null,
|
|
53730
|
-
showVisualSelection: false
|
|
55068
|
+
showVisualSelection: false,
|
|
55069
|
+
skipFocusReset: false
|
|
53731
55070
|
})
|
|
53732
55071
|
);
|
|
53733
55072
|
if (!selection.empty && !this.editor.options.element?.contains(target)) {
|
|
@@ -53744,12 +55083,20 @@ const CustomSelection = Extension.create({
|
|
|
53744
55083
|
const isElement2 = target instanceof Element;
|
|
53745
55084
|
const isToolbarBtn = isElement2 && isToolbarButton(target);
|
|
53746
55085
|
const isToolbarInp = isElement2 && isToolbarInput(target);
|
|
55086
|
+
const focusState = getFocusState(view.state);
|
|
55087
|
+
if (focusState?.skipFocusReset) {
|
|
55088
|
+
view.dispatch(
|
|
55089
|
+
setFocusMeta(view.state.tr, normalizeSelectionState({ ...focusState, skipFocusReset: false }))
|
|
55090
|
+
);
|
|
55091
|
+
return false;
|
|
55092
|
+
}
|
|
53747
55093
|
if (!isToolbarBtn && !isToolbarInp) {
|
|
53748
55094
|
view.dispatch(
|
|
53749
55095
|
setFocusMeta(view.state.tr, {
|
|
53750
55096
|
focused: false,
|
|
53751
55097
|
preservedSelection: null,
|
|
53752
|
-
showVisualSelection: false
|
|
55098
|
+
showVisualSelection: false,
|
|
55099
|
+
skipFocusReset: false
|
|
53753
55100
|
})
|
|
53754
55101
|
);
|
|
53755
55102
|
}
|
|
@@ -53760,12 +55107,16 @@ const CustomSelection = Extension.create({
|
|
|
53760
55107
|
const isToolbarBtn = isElement2 && isToolbarButton(target);
|
|
53761
55108
|
const isToolbarInp = isElement2 && isToolbarInput(target);
|
|
53762
55109
|
const state2 = getFocusState(view.state);
|
|
55110
|
+
if (state2?.skipFocusReset) {
|
|
55111
|
+
return false;
|
|
55112
|
+
}
|
|
53763
55113
|
if (isToolbarBtn || isToolbarInp) {
|
|
53764
55114
|
view.dispatch(
|
|
53765
55115
|
setFocusMeta(view.state.tr, {
|
|
53766
55116
|
focused: true,
|
|
53767
55117
|
preservedSelection: state2.preservedSelection || view.state.selection,
|
|
53768
|
-
showVisualSelection: true
|
|
55118
|
+
showVisualSelection: true,
|
|
55119
|
+
skipFocusReset: false
|
|
53769
55120
|
})
|
|
53770
55121
|
);
|
|
53771
55122
|
} else {
|
|
@@ -53773,7 +55124,8 @@ const CustomSelection = Extension.create({
|
|
|
53773
55124
|
setFocusMeta(view.state.tr, {
|
|
53774
55125
|
focused: false,
|
|
53775
55126
|
preservedSelection: null,
|
|
53776
|
-
showVisualSelection: false
|
|
55127
|
+
showVisualSelection: false,
|
|
55128
|
+
skipFocusReset: false
|
|
53777
55129
|
})
|
|
53778
55130
|
);
|
|
53779
55131
|
}
|
|
@@ -54619,7 +55971,7 @@ class ListItemNodeView {
|
|
|
54619
55971
|
this.decorations = decorations;
|
|
54620
55972
|
this.view = editor.view;
|
|
54621
55973
|
this.getPos = getPos;
|
|
54622
|
-
__privateMethod$1(this, _ListItemNodeView_instances,
|
|
55974
|
+
__privateMethod$1(this, _ListItemNodeView_instances, init_fn3).call(this);
|
|
54623
55975
|
activeListItemNodeViews.add(this);
|
|
54624
55976
|
}
|
|
54625
55977
|
refreshIndentStyling() {
|
|
@@ -54680,7 +56032,7 @@ class ListItemNodeView {
|
|
|
54680
56032
|
}
|
|
54681
56033
|
}
|
|
54682
56034
|
_ListItemNodeView_instances = /* @__PURE__ */ new WeakSet();
|
|
54683
|
-
|
|
56035
|
+
init_fn3 = function() {
|
|
54684
56036
|
const { attrs } = this.node;
|
|
54685
56037
|
const { listLevel, listNumberingType, lvlText, numId, level, customFormat } = attrs;
|
|
54686
56038
|
let orderMarker = "";
|
|
@@ -61796,977 +63148,328 @@ const PageNumber = Node$1.create({
|
|
|
61796
63148
|
rendered: false
|
|
61797
63149
|
}
|
|
61798
63150
|
};
|
|
61799
|
-
},
|
|
61800
|
-
addNodeView() {
|
|
61801
|
-
return ({ node, editor, getPos, decorations }) => {
|
|
61802
|
-
const htmlAttributes = this.options.htmlAttributes;
|
|
61803
|
-
return new AutoPageNumberNodeView(node, getPos, decorations, editor, htmlAttributes);
|
|
61804
|
-
};
|
|
61805
|
-
},
|
|
61806
|
-
parseDOM() {
|
|
61807
|
-
return [{ tag: 'span[data-id="auto-page-number"' }];
|
|
61808
|
-
},
|
|
61809
|
-
renderDOM({ htmlAttributes }) {
|
|
61810
|
-
return ["span", Attribute2.mergeAttributes(this.options.htmlAttributes, htmlAttributes)];
|
|
61811
|
-
},
|
|
61812
|
-
addCommands() {
|
|
61813
|
-
return {
|
|
61814
|
-
/**
|
|
61815
|
-
* Insert an automatic page number
|
|
61816
|
-
* @category Command
|
|
61817
|
-
* @returns {Function} Command function
|
|
61818
|
-
* @example
|
|
61819
|
-
* editor.commands.addAutoPageNumber()
|
|
61820
|
-
* @note Only works in header/footer contexts
|
|
61821
|
-
*/
|
|
61822
|
-
addAutoPageNumber: () => ({ tr, dispatch, state: state2, editor }) => {
|
|
61823
|
-
const { options } = editor;
|
|
61824
|
-
if (!options.isHeaderOrFooter) return false;
|
|
61825
|
-
const { schema } = state2;
|
|
61826
|
-
const pageNumberType = schema?.nodes?.["page-number"];
|
|
61827
|
-
if (!pageNumberType) return false;
|
|
61828
|
-
const pageNumberNodeJSON = { type: "page-number" };
|
|
61829
|
-
const pageNumberNode = schema.nodeFromJSON(pageNumberNodeJSON);
|
|
61830
|
-
if (dispatch) {
|
|
61831
|
-
tr.replaceSelectionWith(pageNumberNode, false);
|
|
61832
|
-
tr.setMeta("forceUpdatePagination", true);
|
|
61833
|
-
}
|
|
61834
|
-
return true;
|
|
61835
|
-
}
|
|
61836
|
-
};
|
|
61837
|
-
},
|
|
61838
|
-
addShortcuts() {
|
|
61839
|
-
return {
|
|
61840
|
-
"Mod-Shift-alt-p": () => this.editor.commands.addAutoPageNumber()
|
|
61841
|
-
};
|
|
61842
|
-
}
|
|
61843
|
-
});
|
|
61844
|
-
const TotalPageCount = Node$1.create({
|
|
61845
|
-
name: "total-page-number",
|
|
61846
|
-
group: "inline",
|
|
61847
|
-
inline: true,
|
|
61848
|
-
atom: true,
|
|
61849
|
-
draggable: false,
|
|
61850
|
-
selectable: false,
|
|
61851
|
-
content: "text*",
|
|
61852
|
-
addOptions() {
|
|
61853
|
-
return {
|
|
61854
|
-
htmlAttributes: {
|
|
61855
|
-
contenteditable: false,
|
|
61856
|
-
"data-id": "auto-total-pages",
|
|
61857
|
-
"aria-label": "Total page count node",
|
|
61858
|
-
class: "sd-editor-auto-total-pages"
|
|
61859
|
-
}
|
|
61860
|
-
};
|
|
61861
|
-
},
|
|
61862
|
-
addAttributes() {
|
|
61863
|
-
return {
|
|
61864
|
-
marksAsAttrs: {
|
|
61865
|
-
default: null,
|
|
61866
|
-
rendered: false
|
|
61867
|
-
}
|
|
61868
|
-
};
|
|
61869
|
-
},
|
|
61870
|
-
addNodeView() {
|
|
61871
|
-
return ({ node, editor, getPos, decorations }) => {
|
|
61872
|
-
const htmlAttributes = this.options.htmlAttributes;
|
|
61873
|
-
return new AutoPageNumberNodeView(node, getPos, decorations, editor, htmlAttributes);
|
|
61874
|
-
};
|
|
61875
|
-
},
|
|
61876
|
-
parseDOM() {
|
|
61877
|
-
return [{ tag: 'span[data-id="auto-total-pages"' }];
|
|
61878
|
-
},
|
|
61879
|
-
renderDOM({ htmlAttributes }) {
|
|
61880
|
-
return ["span", Attribute2.mergeAttributes(this.options.htmlAttributes, htmlAttributes), 0];
|
|
61881
|
-
},
|
|
61882
|
-
addCommands() {
|
|
61883
|
-
return {
|
|
61884
|
-
/**
|
|
61885
|
-
* Insert total page count
|
|
61886
|
-
* @category Command
|
|
61887
|
-
* @returns {Function} Command function
|
|
61888
|
-
* @example
|
|
61889
|
-
* editor.commands.addTotalPageCount()
|
|
61890
|
-
* @note Only works in header/footer contexts
|
|
61891
|
-
*/
|
|
61892
|
-
addTotalPageCount: () => ({ tr, dispatch, state: state2, editor }) => {
|
|
61893
|
-
const { options } = editor;
|
|
61894
|
-
if (!options.isHeaderOrFooter) return false;
|
|
61895
|
-
const { schema } = state2;
|
|
61896
|
-
const pageNumberType = schema.nodes?.["total-page-number"];
|
|
61897
|
-
if (!pageNumberType) return false;
|
|
61898
|
-
const currentPages = editor?.options?.parentEditor?.currentTotalPages || 1;
|
|
61899
|
-
const pageNumberNode = {
|
|
61900
|
-
type: "total-page-number",
|
|
61901
|
-
content: [{ type: "text", text: String(currentPages) }]
|
|
61902
|
-
};
|
|
61903
|
-
const pageNode = schema.nodeFromJSON(pageNumberNode);
|
|
61904
|
-
if (dispatch) {
|
|
61905
|
-
tr.replaceSelectionWith(pageNode, false);
|
|
61906
|
-
}
|
|
61907
|
-
return true;
|
|
61908
|
-
}
|
|
61909
|
-
};
|
|
61910
|
-
},
|
|
61911
|
-
addShortcuts() {
|
|
61912
|
-
return {
|
|
61913
|
-
"Mod-Shift-alt-c": () => this.editor.commands.addTotalPageCount()
|
|
61914
|
-
};
|
|
61915
|
-
}
|
|
61916
|
-
});
|
|
61917
|
-
const getNodeAttributes = (nodeName, editor) => {
|
|
61918
|
-
switch (nodeName) {
|
|
61919
|
-
case "page-number":
|
|
61920
|
-
return {
|
|
61921
|
-
text: editor.options.currentPageNumber || "1",
|
|
61922
|
-
className: "sd-editor-auto-page-number",
|
|
61923
|
-
dataId: "auto-page-number",
|
|
61924
|
-
ariaLabel: "Page number node"
|
|
61925
|
-
};
|
|
61926
|
-
case "total-page-number":
|
|
61927
|
-
return {
|
|
61928
|
-
text: editor.options.parentEditor?.currentTotalPages || "1",
|
|
61929
|
-
className: "sd-editor-auto-total-pages",
|
|
61930
|
-
dataId: "auto-total-pages",
|
|
61931
|
-
ariaLabel: "Total page count node"
|
|
61932
|
-
};
|
|
61933
|
-
default:
|
|
61934
|
-
return {};
|
|
61935
|
-
}
|
|
61936
|
-
};
|
|
61937
|
-
class AutoPageNumberNodeView {
|
|
61938
|
-
constructor(node, getPos, decorations, editor, htmlAttributes = {}) {
|
|
61939
|
-
__privateAdd$1(this, _AutoPageNumberNodeView_instances);
|
|
61940
|
-
this.node = node;
|
|
61941
|
-
this.editor = editor;
|
|
61942
|
-
this.view = editor.view;
|
|
61943
|
-
this.getPos = getPos;
|
|
61944
|
-
this.editor = editor;
|
|
61945
|
-
this.dom = __privateMethod$1(this, _AutoPageNumberNodeView_instances, renderDom_fn).call(this, node, htmlAttributes);
|
|
61946
|
-
}
|
|
61947
|
-
update(node) {
|
|
61948
|
-
const incomingType = node?.type?.name;
|
|
61949
|
-
const currentType = this.node?.type?.name;
|
|
61950
|
-
if (!incomingType || incomingType !== currentType) return false;
|
|
61951
|
-
this.node = node;
|
|
61952
|
-
return true;
|
|
61953
|
-
}
|
|
61954
|
-
}
|
|
61955
|
-
_AutoPageNumberNodeView_instances = /* @__PURE__ */ new WeakSet();
|
|
61956
|
-
renderDom_fn = function(node, htmlAttributes) {
|
|
61957
|
-
const attrs = getNodeAttributes(this.node.type.name, this.editor);
|
|
61958
|
-
const content = document.createTextNode(String(attrs.text));
|
|
61959
|
-
const nodeContent = document.createElement("span");
|
|
61960
|
-
nodeContent.className = attrs.className;
|
|
61961
|
-
nodeContent.setAttribute("data-id", attrs.dataId);
|
|
61962
|
-
nodeContent.setAttribute("aria-label", attrs.ariaLabel);
|
|
61963
|
-
const currentPos = this.getPos();
|
|
61964
|
-
const { styles, marks } = getMarksFromNeighbors(currentPos, this.view);
|
|
61965
|
-
__privateMethod$1(this, _AutoPageNumberNodeView_instances, scheduleUpdateNodeStyle_fn).call(this, currentPos, marks);
|
|
61966
|
-
Object.assign(nodeContent.style, styles);
|
|
61967
|
-
nodeContent.appendChild(content);
|
|
61968
|
-
Object.entries(htmlAttributes).forEach(([key2, value]) => {
|
|
61969
|
-
if (value) nodeContent.setAttribute(key2, value);
|
|
61970
|
-
});
|
|
61971
|
-
return nodeContent;
|
|
61972
|
-
};
|
|
61973
|
-
scheduleUpdateNodeStyle_fn = function(pos, marks) {
|
|
61974
|
-
setTimeout(() => {
|
|
61975
|
-
const { state: state2 } = this.editor;
|
|
61976
|
-
const { dispatch } = this.view;
|
|
61977
|
-
const node = state2.doc.nodeAt(pos);
|
|
61978
|
-
if (!node || node.isText) return;
|
|
61979
|
-
const currentMarks = node.attrs.marksAsAttrs || [];
|
|
61980
|
-
const newMarks = marks.map((m2) => ({ type: m2.type.name, attrs: m2.attrs }));
|
|
61981
|
-
const isEqual = JSON.stringify(currentMarks) === JSON.stringify(newMarks);
|
|
61982
|
-
if (isEqual) return;
|
|
61983
|
-
const newAttrs = {
|
|
61984
|
-
...node.attrs,
|
|
61985
|
-
marksAsAttrs: newMarks
|
|
61986
|
-
};
|
|
61987
|
-
const tr = state2.tr.setNodeMarkup(pos, void 0, newAttrs);
|
|
61988
|
-
dispatch(tr);
|
|
61989
|
-
}, 0);
|
|
61990
|
-
};
|
|
61991
|
-
const getMarksFromNeighbors = (currentPos, view) => {
|
|
61992
|
-
const $pos = view.state.doc.resolve(currentPos);
|
|
61993
|
-
const styles = {};
|
|
61994
|
-
const marks = [];
|
|
61995
|
-
const before = $pos.nodeBefore;
|
|
61996
|
-
if (before) {
|
|
61997
|
-
Object.assign(styles, processMarks(before.marks));
|
|
61998
|
-
marks.push(...before.marks);
|
|
61999
|
-
}
|
|
62000
|
-
const after = $pos.nodeAfter;
|
|
62001
|
-
if (after) {
|
|
62002
|
-
Object.assign(styles, { ...styles, ...processMarks(after.marks) });
|
|
62003
|
-
marks.push(...after.marks);
|
|
62004
|
-
}
|
|
62005
|
-
return {
|
|
62006
|
-
styles,
|
|
62007
|
-
marks
|
|
62008
|
-
};
|
|
62009
|
-
};
|
|
62010
|
-
const processMarks = (marks) => {
|
|
62011
|
-
const styles = {};
|
|
62012
|
-
marks.forEach((mark) => {
|
|
62013
|
-
const { type: type2, attrs } = mark;
|
|
62014
|
-
switch (type2.name) {
|
|
62015
|
-
case "textStyle":
|
|
62016
|
-
if (attrs.fontFamily) styles["font-family"] = attrs.fontFamily;
|
|
62017
|
-
if (attrs.fontSize) styles["font-size"] = attrs.fontSize;
|
|
62018
|
-
if (attrs.color) styles["color"] = attrs.color;
|
|
62019
|
-
if (attrs.backgroundColor) styles["background-color"] = attrs.backgroundColor;
|
|
62020
|
-
break;
|
|
62021
|
-
case "bold":
|
|
62022
|
-
styles["font-weight"] = "bold";
|
|
62023
|
-
break;
|
|
62024
|
-
case "italic":
|
|
62025
|
-
styles["font-style"] = "italic";
|
|
62026
|
-
break;
|
|
62027
|
-
case "underline":
|
|
62028
|
-
styles["text-decoration"] = (styles["text-decoration"] || "") + " underline";
|
|
62029
|
-
break;
|
|
62030
|
-
case "strike":
|
|
62031
|
-
styles["text-decoration"] = (styles["text-decoration"] || "") + " line-through";
|
|
62032
|
-
break;
|
|
62033
|
-
default:
|
|
62034
|
-
if (attrs?.style) {
|
|
62035
|
-
Object.entries(attrs.style).forEach(([key2, value]) => {
|
|
62036
|
-
styles[key2] = value;
|
|
62037
|
-
});
|
|
62038
|
-
}
|
|
62039
|
-
break;
|
|
62040
|
-
}
|
|
62041
|
-
});
|
|
62042
|
-
return styles;
|
|
62043
|
-
};
|
|
62044
|
-
const ShapeContainer = Node$1.create({
|
|
62045
|
-
name: "shapeContainer",
|
|
62046
|
-
group: "block",
|
|
62047
|
-
content: "block+",
|
|
62048
|
-
isolating: true,
|
|
62049
|
-
addOptions() {
|
|
62050
|
-
return {
|
|
62051
|
-
htmlAttributes: {
|
|
62052
|
-
class: "sd-editor-shape-container",
|
|
62053
|
-
"aria-label": "Shape container node"
|
|
62054
|
-
}
|
|
62055
|
-
};
|
|
62056
|
-
},
|
|
62057
|
-
addAttributes() {
|
|
62058
|
-
return {
|
|
62059
|
-
fillcolor: {
|
|
62060
|
-
renderDOM: (attrs) => {
|
|
62061
|
-
if (!attrs.fillcolor) return {};
|
|
62062
|
-
return {
|
|
62063
|
-
style: `background-color: ${attrs.fillcolor}`
|
|
62064
|
-
};
|
|
62065
|
-
}
|
|
62066
|
-
},
|
|
62067
|
-
sdBlockId: {
|
|
62068
|
-
default: null,
|
|
62069
|
-
keepOnSplit: false,
|
|
62070
|
-
parseDOM: (elem) => elem.getAttribute("data-sd-block-id"),
|
|
62071
|
-
renderDOM: (attrs) => {
|
|
62072
|
-
return attrs.sdBlockId ? { "data-sd-block-id": attrs.sdBlockId } : {};
|
|
62073
|
-
}
|
|
62074
|
-
},
|
|
62075
|
-
style: {
|
|
62076
|
-
renderDOM: (attrs) => {
|
|
62077
|
-
if (!attrs.style) return {};
|
|
62078
|
-
return {
|
|
62079
|
-
style: attrs.style
|
|
62080
|
-
};
|
|
62081
|
-
}
|
|
62082
|
-
},
|
|
62083
|
-
wrapAttributes: {
|
|
62084
|
-
rendered: false
|
|
62085
|
-
},
|
|
62086
|
-
attributes: {
|
|
62087
|
-
rendered: false
|
|
62088
|
-
}
|
|
62089
|
-
};
|
|
62090
|
-
},
|
|
62091
|
-
parseDOM() {
|
|
62092
|
-
return [
|
|
62093
|
-
{
|
|
62094
|
-
tag: `div[data-type="${this.name}"]`
|
|
62095
|
-
}
|
|
62096
|
-
];
|
|
62097
|
-
},
|
|
62098
|
-
renderDOM({ htmlAttributes }) {
|
|
62099
|
-
return [
|
|
62100
|
-
"div",
|
|
62101
|
-
Attribute2.mergeAttributes(this.options.htmlAttributes, htmlAttributes, { "data-type": this.name }),
|
|
62102
|
-
0
|
|
62103
|
-
];
|
|
62104
|
-
}
|
|
62105
|
-
});
|
|
62106
|
-
const ShapeTextbox = Node$1.create({
|
|
62107
|
-
name: "shapeTextbox",
|
|
62108
|
-
group: "block",
|
|
62109
|
-
content: "paragraph* block*",
|
|
62110
|
-
isolating: true,
|
|
62111
|
-
addOptions() {
|
|
62112
|
-
return {
|
|
62113
|
-
htmlAttributes: {
|
|
62114
|
-
class: "sd-editor-shape-textbox",
|
|
62115
|
-
"aria-label": "Shape textbox node"
|
|
62116
|
-
}
|
|
62117
|
-
};
|
|
62118
|
-
},
|
|
62119
|
-
addAttributes() {
|
|
62120
|
-
return {
|
|
62121
|
-
sdBlockId: {
|
|
62122
|
-
default: null,
|
|
62123
|
-
keepOnSplit: false,
|
|
62124
|
-
parseDOM: (elem) => elem.getAttribute("data-sd-block-id"),
|
|
62125
|
-
renderDOM: (attrs) => {
|
|
62126
|
-
return attrs.sdBlockId ? { "data-sd-block-id": attrs.sdBlockId } : {};
|
|
62127
|
-
}
|
|
62128
|
-
},
|
|
62129
|
-
attributes: {
|
|
62130
|
-
rendered: false
|
|
62131
|
-
}
|
|
62132
|
-
};
|
|
62133
|
-
},
|
|
62134
|
-
parseDOM() {
|
|
62135
|
-
return [
|
|
62136
|
-
{
|
|
62137
|
-
tag: `div[data-type="${this.name}"]`
|
|
62138
|
-
}
|
|
62139
|
-
];
|
|
62140
|
-
},
|
|
62141
|
-
renderDOM({ htmlAttributes }) {
|
|
62142
|
-
return [
|
|
62143
|
-
"div",
|
|
62144
|
-
Attribute2.mergeAttributes(this.options.htmlAttributes, htmlAttributes, { "data-type": this.name }),
|
|
62145
|
-
0
|
|
62146
|
-
];
|
|
62147
|
-
}
|
|
62148
|
-
});
|
|
62149
|
-
const ContentBlock = Node$1.create({
|
|
62150
|
-
name: "contentBlock",
|
|
62151
|
-
group: "inline",
|
|
62152
|
-
content: "",
|
|
62153
|
-
isolating: true,
|
|
62154
|
-
atom: true,
|
|
62155
|
-
inline: true,
|
|
62156
|
-
addOptions() {
|
|
62157
|
-
return {
|
|
62158
|
-
htmlAttributes: {
|
|
62159
|
-
contenteditable: false
|
|
62160
|
-
}
|
|
62161
|
-
};
|
|
62162
|
-
},
|
|
62163
|
-
addAttributes() {
|
|
62164
|
-
return {
|
|
62165
|
-
horizontalRule: {
|
|
62166
|
-
default: false,
|
|
62167
|
-
renderDOM: ({ horizontalRule }) => {
|
|
62168
|
-
if (!horizontalRule) return {};
|
|
62169
|
-
return { "data-horizontal-rule": "true" };
|
|
62170
|
-
}
|
|
62171
|
-
},
|
|
62172
|
-
size: {
|
|
62173
|
-
default: null,
|
|
62174
|
-
renderDOM: ({ size: size2 }) => {
|
|
62175
|
-
if (!size2) return {};
|
|
62176
|
-
let style2 = "";
|
|
62177
|
-
if (size2.top) style2 += `top: ${size2.top}px; `;
|
|
62178
|
-
if (size2.left) style2 += `left: ${size2.left}px; `;
|
|
62179
|
-
if (size2.width) style2 += `width: ${size2.width.toString().endsWith("%") ? size2.width : `${size2.width}px`}; `;
|
|
62180
|
-
if (size2.height)
|
|
62181
|
-
style2 += `height: ${size2.height.toString().endsWith("%") ? size2.height : `${size2.height}px`}; `;
|
|
62182
|
-
return { style: style2 };
|
|
62183
|
-
}
|
|
62184
|
-
},
|
|
62185
|
-
background: {
|
|
62186
|
-
default: null,
|
|
62187
|
-
renderDOM: (attrs) => {
|
|
62188
|
-
if (!attrs.background) return {};
|
|
62189
|
-
return {
|
|
62190
|
-
style: `background-color: ${attrs.background}`
|
|
62191
|
-
};
|
|
62192
|
-
}
|
|
62193
|
-
},
|
|
62194
|
-
drawingContent: {
|
|
62195
|
-
rendered: false
|
|
62196
|
-
},
|
|
62197
|
-
attributes: {
|
|
62198
|
-
rendered: false
|
|
62199
|
-
}
|
|
63151
|
+
},
|
|
63152
|
+
addNodeView() {
|
|
63153
|
+
return ({ node, editor, getPos, decorations }) => {
|
|
63154
|
+
const htmlAttributes = this.options.htmlAttributes;
|
|
63155
|
+
return new AutoPageNumberNodeView(node, getPos, decorations, editor, htmlAttributes);
|
|
62200
63156
|
};
|
|
62201
63157
|
},
|
|
62202
63158
|
parseDOM() {
|
|
62203
|
-
return [
|
|
62204
|
-
{
|
|
62205
|
-
tag: `div[data-type="${this.name}"]`
|
|
62206
|
-
}
|
|
62207
|
-
];
|
|
63159
|
+
return [{ tag: 'span[data-id="auto-page-number"' }];
|
|
62208
63160
|
},
|
|
62209
63161
|
renderDOM({ htmlAttributes }) {
|
|
62210
|
-
return ["
|
|
63162
|
+
return ["span", Attribute2.mergeAttributes(this.options.htmlAttributes, htmlAttributes)];
|
|
62211
63163
|
},
|
|
62212
63164
|
addCommands() {
|
|
62213
63165
|
return {
|
|
62214
63166
|
/**
|
|
62215
|
-
* Insert
|
|
62216
|
-
* @category Command
|
|
62217
|
-
* @example
|
|
62218
|
-
* editor.commands.insertHorizontalRule()
|
|
62219
|
-
* @note Creates a visual separator between content sections
|
|
62220
|
-
*/
|
|
62221
|
-
insertHorizontalRule: () => ({ commands: commands2 }) => {
|
|
62222
|
-
return commands2.insertContent({
|
|
62223
|
-
type: this.name,
|
|
62224
|
-
attrs: {
|
|
62225
|
-
horizontalRule: true,
|
|
62226
|
-
size: { width: "100%", height: 2 },
|
|
62227
|
-
background: "#e5e7eb"
|
|
62228
|
-
}
|
|
62229
|
-
});
|
|
62230
|
-
},
|
|
62231
|
-
/**
|
|
62232
|
-
* Insert a content block
|
|
63167
|
+
* Insert an automatic page number
|
|
62233
63168
|
* @category Command
|
|
62234
|
-
* @
|
|
62235
|
-
* @example
|
|
62236
|
-
* // Insert a spacer block
|
|
62237
|
-
* editor.commands.insertContentBlock({ size: { height: 20 } })
|
|
62238
|
-
*
|
|
63169
|
+
* @returns {Function} Command function
|
|
62239
63170
|
* @example
|
|
62240
|
-
*
|
|
62241
|
-
*
|
|
62242
|
-
* size: { width: '50%', height: 3 },
|
|
62243
|
-
* background: '#3b82f6'
|
|
62244
|
-
* })
|
|
62245
|
-
* @note Used for spacing, dividers, and special inline content
|
|
63171
|
+
* editor.commands.addAutoPageNumber()
|
|
63172
|
+
* @note Only works in header/footer contexts
|
|
62246
63173
|
*/
|
|
62247
|
-
|
|
62248
|
-
|
|
62249
|
-
|
|
62250
|
-
|
|
62251
|
-
|
|
63174
|
+
addAutoPageNumber: () => ({ tr, dispatch, state: state2, editor }) => {
|
|
63175
|
+
const { options } = editor;
|
|
63176
|
+
if (!options.isHeaderOrFooter) return false;
|
|
63177
|
+
const { schema } = state2;
|
|
63178
|
+
const pageNumberType = schema?.nodes?.["page-number"];
|
|
63179
|
+
if (!pageNumberType) return false;
|
|
63180
|
+
const pageNumberNodeJSON = { type: "page-number" };
|
|
63181
|
+
const pageNumberNode = schema.nodeFromJSON(pageNumberNodeJSON);
|
|
63182
|
+
if (dispatch) {
|
|
63183
|
+
tr.replaceSelectionWith(pageNumberNode, false);
|
|
63184
|
+
tr.setMeta("forceUpdatePagination", true);
|
|
63185
|
+
}
|
|
63186
|
+
return true;
|
|
62252
63187
|
}
|
|
62253
63188
|
};
|
|
63189
|
+
},
|
|
63190
|
+
addShortcuts() {
|
|
63191
|
+
return {
|
|
63192
|
+
"Mod-Shift-alt-p": () => this.editor.commands.addAutoPageNumber()
|
|
63193
|
+
};
|
|
62254
63194
|
}
|
|
62255
63195
|
});
|
|
62256
|
-
|
|
62257
|
-
|
|
62258
|
-
|
|
62259
|
-
__publicField$1(this, "view");
|
|
62260
|
-
__publicField$1(this, "getPos");
|
|
62261
|
-
__publicField$1(this, "decorations");
|
|
62262
|
-
__publicField$1(this, "innerDecorations");
|
|
62263
|
-
__publicField$1(this, "editor");
|
|
62264
|
-
__publicField$1(this, "extension");
|
|
62265
|
-
__publicField$1(this, "htmlAttributes");
|
|
62266
|
-
__publicField$1(this, "root");
|
|
62267
|
-
__publicField$1(this, "isDragging", false);
|
|
62268
|
-
this.node = props.node;
|
|
62269
|
-
this.view = props.editor.view;
|
|
62270
|
-
this.getPos = props.getPos;
|
|
62271
|
-
this.decorations = props.decorations;
|
|
62272
|
-
this.innerDecorations = props.innerDecorations;
|
|
62273
|
-
this.editor = props.editor;
|
|
62274
|
-
this.extension = props.extension;
|
|
62275
|
-
this.htmlAttributes = props.htmlAttributes;
|
|
62276
|
-
this.mount(props);
|
|
62277
|
-
}
|
|
62278
|
-
mount() {
|
|
62279
|
-
return;
|
|
62280
|
-
}
|
|
62281
|
-
get dom() {
|
|
62282
|
-
return this.root;
|
|
62283
|
-
}
|
|
62284
|
-
get contentDOM() {
|
|
62285
|
-
return null;
|
|
62286
|
-
}
|
|
62287
|
-
update(node, decorations, innerDecorations) {
|
|
62288
|
-
if (node.type !== this.node.type) {
|
|
62289
|
-
return false;
|
|
62290
|
-
}
|
|
62291
|
-
this.node = node;
|
|
62292
|
-
this.decorations = decorations;
|
|
62293
|
-
this.innerDecorations = innerDecorations;
|
|
62294
|
-
this.updateHTMLAttributes();
|
|
62295
|
-
return true;
|
|
62296
|
-
}
|
|
62297
|
-
stopEvent(event) {
|
|
62298
|
-
if (!this.dom) return false;
|
|
62299
|
-
const target = event.target;
|
|
62300
|
-
const isInElement = this.dom.contains(target) && !this.contentDOM?.contains(target);
|
|
62301
|
-
if (!isInElement) return false;
|
|
62302
|
-
const isDragEvent = event.type.startsWith("drag");
|
|
62303
|
-
const isDropEvent = event.type === "drop";
|
|
62304
|
-
const isInput = ["INPUT", "BUTTON", "SELECT", "TEXTAREA"].includes(target.tagName) || target.isContentEditable;
|
|
62305
|
-
if (isInput && !isDropEvent && !isDragEvent) return true;
|
|
62306
|
-
const { isEditable } = this.editor;
|
|
62307
|
-
const { isDragging } = this;
|
|
62308
|
-
const isDraggable = !!this.node.type.spec.draggable;
|
|
62309
|
-
const isSelectable = NodeSelection.isSelectable(this.node);
|
|
62310
|
-
const isCopyEvent = event.type === "copy";
|
|
62311
|
-
const isPasteEvent = event.type === "paste";
|
|
62312
|
-
const isCutEvent = event.type === "cut";
|
|
62313
|
-
const isClickEvent = event.type === "mousedown";
|
|
62314
|
-
if (!isDraggable && isSelectable && isDragEvent && event.target === this.dom) {
|
|
62315
|
-
event.preventDefault();
|
|
62316
|
-
}
|
|
62317
|
-
if (isDraggable && isDragEvent && !isDragging && event.target === this.dom) {
|
|
62318
|
-
event.preventDefault();
|
|
62319
|
-
return false;
|
|
62320
|
-
}
|
|
62321
|
-
if (isDraggable && isEditable && !isDragging && isClickEvent) {
|
|
62322
|
-
const dragHandle = target.closest("[data-drag-handle]");
|
|
62323
|
-
const isValidDragHandle = dragHandle && (this.dom === dragHandle || this.dom.contains(dragHandle));
|
|
62324
|
-
if (isValidDragHandle) {
|
|
62325
|
-
this.isDragging = true;
|
|
62326
|
-
document.addEventListener(
|
|
62327
|
-
"dragend",
|
|
62328
|
-
() => {
|
|
62329
|
-
this.isDragging = false;
|
|
62330
|
-
},
|
|
62331
|
-
{ once: true }
|
|
62332
|
-
);
|
|
62333
|
-
document.addEventListener(
|
|
62334
|
-
"drop",
|
|
62335
|
-
() => {
|
|
62336
|
-
this.isDragging = false;
|
|
62337
|
-
},
|
|
62338
|
-
{ once: true }
|
|
62339
|
-
);
|
|
62340
|
-
document.addEventListener(
|
|
62341
|
-
"mouseup",
|
|
62342
|
-
() => {
|
|
62343
|
-
this.isDragging = false;
|
|
62344
|
-
},
|
|
62345
|
-
{ once: true }
|
|
62346
|
-
);
|
|
62347
|
-
}
|
|
62348
|
-
}
|
|
62349
|
-
if (isDragging || isDropEvent || isCopyEvent || isPasteEvent || isCutEvent || isClickEvent && isSelectable) {
|
|
62350
|
-
return false;
|
|
62351
|
-
}
|
|
62352
|
-
return true;
|
|
62353
|
-
}
|
|
62354
|
-
ignoreMutation(mutation) {
|
|
62355
|
-
if (!this.dom || !this.contentDOM) return true;
|
|
62356
|
-
if (this.node.isLeaf || this.node.isAtom) return true;
|
|
62357
|
-
if (mutation.type === "selection") return false;
|
|
62358
|
-
if (this.contentDOM === mutation.target && mutation.type === "attributes") return true;
|
|
62359
|
-
if (this.contentDOM.contains(mutation.target)) return false;
|
|
62360
|
-
return true;
|
|
62361
|
-
}
|
|
62362
|
-
destroy() {
|
|
62363
|
-
this.dom.remove();
|
|
62364
|
-
this.contentDOM?.remove();
|
|
62365
|
-
}
|
|
62366
|
-
updateAttributes(attrs) {
|
|
62367
|
-
const pos = this.getPos();
|
|
62368
|
-
if (typeof pos !== "number") {
|
|
62369
|
-
return;
|
|
62370
|
-
}
|
|
62371
|
-
return this.view.dispatch(
|
|
62372
|
-
this.view.state.tr.setNodeMarkup(pos, void 0, {
|
|
62373
|
-
...this.node.attrs,
|
|
62374
|
-
...attrs
|
|
62375
|
-
})
|
|
62376
|
-
);
|
|
62377
|
-
}
|
|
62378
|
-
updateHTMLAttributes() {
|
|
62379
|
-
const { extensionService } = this.editor;
|
|
62380
|
-
const { attributes } = extensionService;
|
|
62381
|
-
const extensionAttrs = attributes.filter((i) => i.type === this.node.type.name);
|
|
62382
|
-
this.htmlAttributes = Attribute2.getAttributesToRender(this.node, extensionAttrs);
|
|
62383
|
-
}
|
|
62384
|
-
createDragHandle() {
|
|
62385
|
-
const dragHandle = document.createElement("span");
|
|
62386
|
-
dragHandle.classList.add("sd-structured-content-draggable");
|
|
62387
|
-
dragHandle.draggable = true;
|
|
62388
|
-
dragHandle.contentEditable = "false";
|
|
62389
|
-
dragHandle.dataset.dragHandle = "";
|
|
62390
|
-
const textElement = document.createElement("span");
|
|
62391
|
-
textElement.textContent = "Structured content";
|
|
62392
|
-
dragHandle.append(textElement);
|
|
62393
|
-
return dragHandle;
|
|
62394
|
-
}
|
|
62395
|
-
onDragStart(event) {
|
|
62396
|
-
const { view } = this.editor;
|
|
62397
|
-
const target = event.target;
|
|
62398
|
-
const dragHandle = target.nodeType === 3 ? target.parentElement?.closest("[data-drag-handle]") : target.closest("[data-drag-handle]");
|
|
62399
|
-
if (!this.dom || this.contentDOM?.contains(target) || !dragHandle) {
|
|
62400
|
-
return;
|
|
62401
|
-
}
|
|
62402
|
-
let x = 0;
|
|
62403
|
-
let y2 = 0;
|
|
62404
|
-
if (this.dom !== dragHandle) {
|
|
62405
|
-
const domBox = this.dom.getBoundingClientRect();
|
|
62406
|
-
const handleBox = dragHandle.getBoundingClientRect();
|
|
62407
|
-
const offsetX = event.offsetX ?? event.nativeEvent?.offsetX;
|
|
62408
|
-
const offsetY = event.offsetY ?? event.nativeEvent?.offsetY;
|
|
62409
|
-
x = handleBox.x - domBox.x + offsetX;
|
|
62410
|
-
y2 = handleBox.y - domBox.y + offsetY;
|
|
62411
|
-
}
|
|
62412
|
-
event.dataTransfer?.setDragImage(this.dom, x, y2);
|
|
62413
|
-
const pos = this.getPos();
|
|
62414
|
-
if (typeof pos !== "number") {
|
|
62415
|
-
return;
|
|
62416
|
-
}
|
|
62417
|
-
const selection = NodeSelection.create(view.state.doc, pos);
|
|
62418
|
-
const transaction = view.state.tr.setSelection(selection);
|
|
62419
|
-
view.dispatch(transaction);
|
|
62420
|
-
}
|
|
62421
|
-
}
|
|
62422
|
-
class StructuredContentInlineView extends StructuredContentViewBase {
|
|
62423
|
-
constructor(props) {
|
|
62424
|
-
super(props);
|
|
62425
|
-
}
|
|
62426
|
-
mount() {
|
|
62427
|
-
this.buildView();
|
|
62428
|
-
}
|
|
62429
|
-
get contentDOM() {
|
|
62430
|
-
const contentElement = this.dom?.querySelector(`.${structuredContentInnerClass$1}`);
|
|
62431
|
-
return contentElement || null;
|
|
62432
|
-
}
|
|
62433
|
-
createElement() {
|
|
62434
|
-
const element = document.createElement("span");
|
|
62435
|
-
element.classList.add(structuredContentClass$1);
|
|
62436
|
-
element.setAttribute("data-structured-content", "");
|
|
62437
|
-
const contentElement = document.createElement("span");
|
|
62438
|
-
contentElement.classList.add(structuredContentInnerClass$1);
|
|
62439
|
-
element.append(contentElement);
|
|
62440
|
-
const domAttrs = Attribute2.mergeAttributes(this.htmlAttributes);
|
|
62441
|
-
updateDOMAttributes(element, { ...domAttrs });
|
|
62442
|
-
return { element, contentElement };
|
|
62443
|
-
}
|
|
62444
|
-
buildView() {
|
|
62445
|
-
const { element } = this.createElement();
|
|
62446
|
-
const dragHandle = this.createDragHandle();
|
|
62447
|
-
element.prepend(dragHandle);
|
|
62448
|
-
element.addEventListener("dragstart", (e) => this.onDragStart(e));
|
|
62449
|
-
this.root = element;
|
|
62450
|
-
}
|
|
62451
|
-
updateView() {
|
|
62452
|
-
const domAttrs = Attribute2.mergeAttributes(this.htmlAttributes);
|
|
62453
|
-
updateDOMAttributes(this.dom, { ...domAttrs });
|
|
62454
|
-
}
|
|
62455
|
-
update(node, decorations, innerDecorations) {
|
|
62456
|
-
const result = super.update(node, decorations, innerDecorations);
|
|
62457
|
-
if (!result) return false;
|
|
62458
|
-
this.updateView();
|
|
62459
|
-
return true;
|
|
62460
|
-
}
|
|
62461
|
-
}
|
|
62462
|
-
const structuredContentClass$1 = "sd-structured-content";
|
|
62463
|
-
const structuredContentInnerClass$1 = "sd-structured-content__content";
|
|
62464
|
-
const StructuredContent = Node$1.create({
|
|
62465
|
-
name: "structuredContent",
|
|
62466
|
-
group: "inline structuredContent",
|
|
63196
|
+
const TotalPageCount = Node$1.create({
|
|
63197
|
+
name: "total-page-number",
|
|
63198
|
+
group: "inline",
|
|
62467
63199
|
inline: true,
|
|
62468
|
-
|
|
62469
|
-
|
|
62470
|
-
|
|
62471
|
-
|
|
62472
|
-
draggable: true,
|
|
63200
|
+
atom: true,
|
|
63201
|
+
draggable: false,
|
|
63202
|
+
selectable: false,
|
|
63203
|
+
content: "text*",
|
|
62473
63204
|
addOptions() {
|
|
62474
63205
|
return {
|
|
62475
63206
|
htmlAttributes: {
|
|
62476
|
-
|
|
62477
|
-
"
|
|
63207
|
+
contenteditable: false,
|
|
63208
|
+
"data-id": "auto-total-pages",
|
|
63209
|
+
"aria-label": "Total page count node",
|
|
63210
|
+
class: "sd-editor-auto-total-pages"
|
|
62478
63211
|
}
|
|
62479
63212
|
};
|
|
62480
63213
|
},
|
|
62481
63214
|
addAttributes() {
|
|
62482
63215
|
return {
|
|
62483
|
-
|
|
63216
|
+
marksAsAttrs: {
|
|
62484
63217
|
default: null,
|
|
62485
|
-
parseDOM: (elem) => elem.getAttribute("data-id"),
|
|
62486
|
-
renderDOM: (attrs) => {
|
|
62487
|
-
if (!attrs.id) return {};
|
|
62488
|
-
return { "data-id": attrs.id };
|
|
62489
|
-
}
|
|
62490
|
-
},
|
|
62491
|
-
sdtPr: {
|
|
62492
63218
|
rendered: false
|
|
62493
63219
|
}
|
|
62494
63220
|
};
|
|
62495
63221
|
},
|
|
63222
|
+
addNodeView() {
|
|
63223
|
+
return ({ node, editor, getPos, decorations }) => {
|
|
63224
|
+
const htmlAttributes = this.options.htmlAttributes;
|
|
63225
|
+
return new AutoPageNumberNodeView(node, getPos, decorations, editor, htmlAttributes);
|
|
63226
|
+
};
|
|
63227
|
+
},
|
|
62496
63228
|
parseDOM() {
|
|
62497
|
-
return [{ tag:
|
|
63229
|
+
return [{ tag: 'span[data-id="auto-total-pages"' }];
|
|
62498
63230
|
},
|
|
62499
63231
|
renderDOM({ htmlAttributes }) {
|
|
62500
|
-
return [
|
|
62501
|
-
"span",
|
|
62502
|
-
Attribute2.mergeAttributes(this.options.htmlAttributes, htmlAttributes, {
|
|
62503
|
-
"data-structured-content": ""
|
|
62504
|
-
}),
|
|
62505
|
-
0
|
|
62506
|
-
];
|
|
63232
|
+
return ["span", Attribute2.mergeAttributes(this.options.htmlAttributes, htmlAttributes), 0];
|
|
62507
63233
|
},
|
|
62508
|
-
|
|
62509
|
-
return
|
|
62510
|
-
|
|
63234
|
+
addCommands() {
|
|
63235
|
+
return {
|
|
63236
|
+
/**
|
|
63237
|
+
* Insert total page count
|
|
63238
|
+
* @category Command
|
|
63239
|
+
* @returns {Function} Command function
|
|
63240
|
+
* @example
|
|
63241
|
+
* editor.commands.addTotalPageCount()
|
|
63242
|
+
* @note Only works in header/footer contexts
|
|
63243
|
+
*/
|
|
63244
|
+
addTotalPageCount: () => ({ tr, dispatch, state: state2, editor }) => {
|
|
63245
|
+
const { options } = editor;
|
|
63246
|
+
if (!options.isHeaderOrFooter) return false;
|
|
63247
|
+
const { schema } = state2;
|
|
63248
|
+
const pageNumberType = schema.nodes?.["total-page-number"];
|
|
63249
|
+
if (!pageNumberType) return false;
|
|
63250
|
+
const currentPages = editor?.options?.parentEditor?.currentTotalPages || 1;
|
|
63251
|
+
const pageNumberNode = {
|
|
63252
|
+
type: "total-page-number",
|
|
63253
|
+
content: [{ type: "text", text: String(currentPages) }]
|
|
63254
|
+
};
|
|
63255
|
+
const pageNode = schema.nodeFromJSON(pageNumberNode);
|
|
63256
|
+
if (dispatch) {
|
|
63257
|
+
tr.replaceSelectionWith(pageNode, false);
|
|
63258
|
+
}
|
|
63259
|
+
return true;
|
|
63260
|
+
}
|
|
63261
|
+
};
|
|
63262
|
+
},
|
|
63263
|
+
addShortcuts() {
|
|
63264
|
+
return {
|
|
63265
|
+
"Mod-Shift-alt-c": () => this.editor.commands.addTotalPageCount()
|
|
62511
63266
|
};
|
|
62512
63267
|
}
|
|
62513
63268
|
});
|
|
62514
|
-
|
|
62515
|
-
|
|
62516
|
-
|
|
62517
|
-
|
|
62518
|
-
|
|
62519
|
-
|
|
62520
|
-
|
|
62521
|
-
|
|
62522
|
-
|
|
62523
|
-
|
|
62524
|
-
|
|
62525
|
-
|
|
62526
|
-
|
|
62527
|
-
|
|
62528
|
-
|
|
62529
|
-
|
|
62530
|
-
|
|
62531
|
-
|
|
62532
|
-
const domAttrs = Attribute2.mergeAttributes(this.htmlAttributes);
|
|
62533
|
-
updateDOMAttributes(element, { ...domAttrs });
|
|
62534
|
-
return { element, contentElement };
|
|
62535
|
-
}
|
|
62536
|
-
buildView() {
|
|
62537
|
-
const { element } = this.createElement();
|
|
62538
|
-
const dragHandle = this.createDragHandle();
|
|
62539
|
-
element.prepend(dragHandle);
|
|
62540
|
-
element.addEventListener("dragstart", (e) => this.onDragStart(e));
|
|
62541
|
-
this.root = element;
|
|
63269
|
+
const getNodeAttributes = (nodeName, editor) => {
|
|
63270
|
+
switch (nodeName) {
|
|
63271
|
+
case "page-number":
|
|
63272
|
+
return {
|
|
63273
|
+
text: editor.options.currentPageNumber || "1",
|
|
63274
|
+
className: "sd-editor-auto-page-number",
|
|
63275
|
+
dataId: "auto-page-number",
|
|
63276
|
+
ariaLabel: "Page number node"
|
|
63277
|
+
};
|
|
63278
|
+
case "total-page-number":
|
|
63279
|
+
return {
|
|
63280
|
+
text: editor.options.parentEditor?.currentTotalPages || "1",
|
|
63281
|
+
className: "sd-editor-auto-total-pages",
|
|
63282
|
+
dataId: "auto-total-pages",
|
|
63283
|
+
ariaLabel: "Total page count node"
|
|
63284
|
+
};
|
|
63285
|
+
default:
|
|
63286
|
+
return {};
|
|
62542
63287
|
}
|
|
62543
|
-
|
|
62544
|
-
|
|
62545
|
-
|
|
63288
|
+
};
|
|
63289
|
+
class AutoPageNumberNodeView {
|
|
63290
|
+
constructor(node, getPos, decorations, editor, htmlAttributes = {}) {
|
|
63291
|
+
__privateAdd$1(this, _AutoPageNumberNodeView_instances);
|
|
63292
|
+
this.node = node;
|
|
63293
|
+
this.editor = editor;
|
|
63294
|
+
this.view = editor.view;
|
|
63295
|
+
this.getPos = getPos;
|
|
63296
|
+
this.editor = editor;
|
|
63297
|
+
this.dom = __privateMethod$1(this, _AutoPageNumberNodeView_instances, renderDom_fn).call(this, node, htmlAttributes);
|
|
62546
63298
|
}
|
|
62547
|
-
update(node
|
|
62548
|
-
const
|
|
62549
|
-
|
|
62550
|
-
|
|
63299
|
+
update(node) {
|
|
63300
|
+
const incomingType = node?.type?.name;
|
|
63301
|
+
const currentType = this.node?.type?.name;
|
|
63302
|
+
if (!incomingType || incomingType !== currentType) return false;
|
|
63303
|
+
this.node = node;
|
|
62551
63304
|
return true;
|
|
62552
63305
|
}
|
|
62553
63306
|
}
|
|
62554
|
-
|
|
62555
|
-
|
|
62556
|
-
const
|
|
62557
|
-
|
|
62558
|
-
|
|
62559
|
-
|
|
63307
|
+
_AutoPageNumberNodeView_instances = /* @__PURE__ */ new WeakSet();
|
|
63308
|
+
renderDom_fn = function(node, htmlAttributes) {
|
|
63309
|
+
const attrs = getNodeAttributes(this.node.type.name, this.editor);
|
|
63310
|
+
const content = document.createTextNode(String(attrs.text));
|
|
63311
|
+
const nodeContent = document.createElement("span");
|
|
63312
|
+
nodeContent.className = attrs.className;
|
|
63313
|
+
nodeContent.setAttribute("data-id", attrs.dataId);
|
|
63314
|
+
nodeContent.setAttribute("aria-label", attrs.ariaLabel);
|
|
63315
|
+
const currentPos = this.getPos();
|
|
63316
|
+
const { styles, marks } = getMarksFromNeighbors(currentPos, this.view);
|
|
63317
|
+
__privateMethod$1(this, _AutoPageNumberNodeView_instances, scheduleUpdateNodeStyle_fn).call(this, currentPos, marks);
|
|
63318
|
+
Object.assign(nodeContent.style, styles);
|
|
63319
|
+
nodeContent.appendChild(content);
|
|
63320
|
+
Object.entries(htmlAttributes).forEach(([key2, value]) => {
|
|
63321
|
+
if (value) nodeContent.setAttribute(key2, value);
|
|
63322
|
+
});
|
|
63323
|
+
return nodeContent;
|
|
63324
|
+
};
|
|
63325
|
+
scheduleUpdateNodeStyle_fn = function(pos, marks) {
|
|
63326
|
+
setTimeout(() => {
|
|
63327
|
+
const { state: state2 } = this.editor;
|
|
63328
|
+
const { dispatch } = this.view;
|
|
63329
|
+
const node = state2.doc.nodeAt(pos);
|
|
63330
|
+
if (!node || node.isText) return;
|
|
63331
|
+
const currentMarks = node.attrs.marksAsAttrs || [];
|
|
63332
|
+
const newMarks = marks.map((m2) => ({ type: m2.type.name, attrs: m2.attrs }));
|
|
63333
|
+
const isEqual = JSON.stringify(currentMarks) === JSON.stringify(newMarks);
|
|
63334
|
+
if (isEqual) return;
|
|
63335
|
+
const newAttrs = {
|
|
63336
|
+
...node.attrs,
|
|
63337
|
+
marksAsAttrs: newMarks
|
|
63338
|
+
};
|
|
63339
|
+
const tr = state2.tr.setNodeMarkup(pos, void 0, newAttrs);
|
|
63340
|
+
dispatch(tr);
|
|
63341
|
+
}, 0);
|
|
63342
|
+
};
|
|
63343
|
+
const getMarksFromNeighbors = (currentPos, view) => {
|
|
63344
|
+
const $pos = view.state.doc.resolve(currentPos);
|
|
63345
|
+
const styles = {};
|
|
63346
|
+
const marks = [];
|
|
63347
|
+
const before = $pos.nodeBefore;
|
|
63348
|
+
if (before) {
|
|
63349
|
+
Object.assign(styles, processMarks(before.marks));
|
|
63350
|
+
marks.push(...before.marks);
|
|
63351
|
+
}
|
|
63352
|
+
const after = $pos.nodeAfter;
|
|
63353
|
+
if (after) {
|
|
63354
|
+
Object.assign(styles, { ...styles, ...processMarks(after.marks) });
|
|
63355
|
+
marks.push(...after.marks);
|
|
63356
|
+
}
|
|
63357
|
+
return {
|
|
63358
|
+
styles,
|
|
63359
|
+
marks
|
|
63360
|
+
};
|
|
63361
|
+
};
|
|
63362
|
+
const processMarks = (marks) => {
|
|
63363
|
+
const styles = {};
|
|
63364
|
+
marks.forEach((mark) => {
|
|
63365
|
+
const { type: type2, attrs } = mark;
|
|
63366
|
+
switch (type2.name) {
|
|
63367
|
+
case "textStyle":
|
|
63368
|
+
if (attrs.fontFamily) styles["font-family"] = attrs.fontFamily;
|
|
63369
|
+
if (attrs.fontSize) styles["font-size"] = attrs.fontSize;
|
|
63370
|
+
if (attrs.color) styles["color"] = attrs.color;
|
|
63371
|
+
if (attrs.backgroundColor) styles["background-color"] = attrs.backgroundColor;
|
|
63372
|
+
break;
|
|
63373
|
+
case "bold":
|
|
63374
|
+
styles["font-weight"] = "bold";
|
|
63375
|
+
break;
|
|
63376
|
+
case "italic":
|
|
63377
|
+
styles["font-style"] = "italic";
|
|
63378
|
+
break;
|
|
63379
|
+
case "underline":
|
|
63380
|
+
styles["text-decoration"] = (styles["text-decoration"] || "") + " underline";
|
|
63381
|
+
break;
|
|
63382
|
+
case "strike":
|
|
63383
|
+
styles["text-decoration"] = (styles["text-decoration"] || "") + " line-through";
|
|
63384
|
+
break;
|
|
63385
|
+
default:
|
|
63386
|
+
if (attrs?.style) {
|
|
63387
|
+
Object.entries(attrs.style).forEach(([key2, value]) => {
|
|
63388
|
+
styles[key2] = value;
|
|
63389
|
+
});
|
|
63390
|
+
}
|
|
63391
|
+
break;
|
|
63392
|
+
}
|
|
63393
|
+
});
|
|
63394
|
+
return styles;
|
|
63395
|
+
};
|
|
63396
|
+
const ShapeContainer = Node$1.create({
|
|
63397
|
+
name: "shapeContainer",
|
|
63398
|
+
group: "block",
|
|
63399
|
+
content: "block+",
|
|
62560
63400
|
isolating: true,
|
|
62561
|
-
atom: false,
|
|
62562
|
-
// false - has editable content.
|
|
62563
|
-
draggable: true,
|
|
62564
63401
|
addOptions() {
|
|
62565
63402
|
return {
|
|
62566
63403
|
htmlAttributes: {
|
|
62567
|
-
class:
|
|
62568
|
-
"aria-label": "
|
|
63404
|
+
class: "sd-editor-shape-container",
|
|
63405
|
+
"aria-label": "Shape container node"
|
|
62569
63406
|
}
|
|
62570
63407
|
};
|
|
62571
63408
|
},
|
|
62572
63409
|
addAttributes() {
|
|
62573
63410
|
return {
|
|
62574
|
-
|
|
63411
|
+
fillcolor: {
|
|
63412
|
+
renderDOM: (attrs) => {
|
|
63413
|
+
if (!attrs.fillcolor) return {};
|
|
63414
|
+
return {
|
|
63415
|
+
style: `background-color: ${attrs.fillcolor}`
|
|
63416
|
+
};
|
|
63417
|
+
}
|
|
63418
|
+
},
|
|
63419
|
+
sdBlockId: {
|
|
62575
63420
|
default: null,
|
|
62576
|
-
|
|
63421
|
+
keepOnSplit: false,
|
|
63422
|
+
parseDOM: (elem) => elem.getAttribute("data-sd-block-id"),
|
|
62577
63423
|
renderDOM: (attrs) => {
|
|
62578
|
-
|
|
62579
|
-
return { "data-id": attrs.id };
|
|
63424
|
+
return attrs.sdBlockId ? { "data-sd-block-id": attrs.sdBlockId } : {};
|
|
62580
63425
|
}
|
|
62581
63426
|
},
|
|
62582
|
-
|
|
63427
|
+
style: {
|
|
63428
|
+
renderDOM: (attrs) => {
|
|
63429
|
+
if (!attrs.style) return {};
|
|
63430
|
+
return {
|
|
63431
|
+
style: attrs.style
|
|
63432
|
+
};
|
|
63433
|
+
}
|
|
63434
|
+
},
|
|
63435
|
+
wrapAttributes: {
|
|
63436
|
+
rendered: false
|
|
63437
|
+
},
|
|
63438
|
+
attributes: {
|
|
62583
63439
|
rendered: false
|
|
62584
63440
|
}
|
|
62585
63441
|
};
|
|
62586
63442
|
},
|
|
62587
63443
|
parseDOM() {
|
|
62588
|
-
return [
|
|
63444
|
+
return [
|
|
63445
|
+
{
|
|
63446
|
+
tag: `div[data-type="${this.name}"]`
|
|
63447
|
+
}
|
|
63448
|
+
];
|
|
62589
63449
|
},
|
|
62590
63450
|
renderDOM({ htmlAttributes }) {
|
|
62591
63451
|
return [
|
|
62592
63452
|
"div",
|
|
62593
|
-
Attribute2.mergeAttributes(this.options.htmlAttributes, htmlAttributes, {
|
|
62594
|
-
"data-structured-content-block": ""
|
|
62595
|
-
}),
|
|
63453
|
+
Attribute2.mergeAttributes(this.options.htmlAttributes, htmlAttributes, { "data-type": this.name }),
|
|
62596
63454
|
0
|
|
62597
63455
|
];
|
|
62598
|
-
},
|
|
62599
|
-
addNodeView() {
|
|
62600
|
-
return (props) => {
|
|
62601
|
-
return new StructuredContentBlockView({ ...props });
|
|
62602
|
-
};
|
|
62603
63456
|
}
|
|
62604
63457
|
});
|
|
62605
|
-
|
|
62606
|
-
|
|
62607
|
-
__privateAdd$1(this, _DocumentSectionView_instances);
|
|
62608
|
-
this.node = node;
|
|
62609
|
-
this.editor = editor;
|
|
62610
|
-
this.decorations = decorations;
|
|
62611
|
-
this.view = editor.view;
|
|
62612
|
-
this.getPos = getPos;
|
|
62613
|
-
__privateMethod$1(this, _DocumentSectionView_instances, init_fn3).call(this);
|
|
62614
|
-
}
|
|
62615
|
-
}
|
|
62616
|
-
_DocumentSectionView_instances = /* @__PURE__ */ new WeakSet();
|
|
62617
|
-
init_fn3 = function() {
|
|
62618
|
-
const { attrs } = this.node;
|
|
62619
|
-
const { id, title, description } = attrs;
|
|
62620
|
-
this.dom = document.createElement("div");
|
|
62621
|
-
this.dom.className = "sd-document-section-block";
|
|
62622
|
-
this.dom.setAttribute("data-id", id);
|
|
62623
|
-
this.dom.setAttribute("data-title", title);
|
|
62624
|
-
this.dom.setAttribute("data-description", description);
|
|
62625
|
-
this.dom.setAttribute("aria-label", "Document section");
|
|
62626
|
-
__privateMethod$1(this, _DocumentSectionView_instances, addToolTip_fn).call(this);
|
|
62627
|
-
this.contentDOM = document.createElement("div");
|
|
62628
|
-
this.contentDOM.className = "sd-document-section-block-content";
|
|
62629
|
-
this.contentDOM.setAttribute("contenteditable", "true");
|
|
62630
|
-
this.dom.appendChild(this.contentDOM);
|
|
62631
|
-
};
|
|
62632
|
-
addToolTip_fn = function() {
|
|
62633
|
-
const { title } = this.node.attrs;
|
|
62634
|
-
this.infoDiv = document.createElement("div");
|
|
62635
|
-
this.infoDiv.className = "sd-document-section-block-info";
|
|
62636
|
-
const textSpan = document.createElement("span");
|
|
62637
|
-
textSpan.textContent = title || "Document section";
|
|
62638
|
-
this.infoDiv.appendChild(textSpan);
|
|
62639
|
-
this.infoDiv.setAttribute("contenteditable", "false");
|
|
62640
|
-
this.dom.appendChild(this.infoDiv);
|
|
62641
|
-
};
|
|
62642
|
-
const getAllSections = (editor) => {
|
|
62643
|
-
if (!editor) return [];
|
|
62644
|
-
const type2 = editor.schema.nodes.documentSection;
|
|
62645
|
-
if (!type2) return [];
|
|
62646
|
-
const sections = [];
|
|
62647
|
-
const { state: state2 } = editor;
|
|
62648
|
-
state2.doc.descendants((node, pos) => {
|
|
62649
|
-
if (node.type.name === type2.name) {
|
|
62650
|
-
sections.push({ node, pos });
|
|
62651
|
-
}
|
|
62652
|
-
});
|
|
62653
|
-
return sections;
|
|
62654
|
-
};
|
|
62655
|
-
const exportSectionsToHTML = (editor) => {
|
|
62656
|
-
const sections = getAllSections(editor);
|
|
62657
|
-
const processedSections = /* @__PURE__ */ new Set();
|
|
62658
|
-
const result = [];
|
|
62659
|
-
sections.forEach(({ node }) => {
|
|
62660
|
-
const { attrs } = node;
|
|
62661
|
-
const { id, title, description } = attrs;
|
|
62662
|
-
if (processedSections.has(id)) return;
|
|
62663
|
-
processedSections.add(id);
|
|
62664
|
-
const html = getHTMLFromNode(node, editor);
|
|
62665
|
-
result.push({
|
|
62666
|
-
id,
|
|
62667
|
-
title,
|
|
62668
|
-
description,
|
|
62669
|
-
html
|
|
62670
|
-
});
|
|
62671
|
-
});
|
|
62672
|
-
return result;
|
|
62673
|
-
};
|
|
62674
|
-
const getHTMLFromNode = (node, editor) => {
|
|
62675
|
-
const tempDocument = document.implementation.createHTMLDocument();
|
|
62676
|
-
const container = tempDocument.createElement("div");
|
|
62677
|
-
const fragment = DOMSerializer.fromSchema(editor.schema).serializeFragment(node.content);
|
|
62678
|
-
container.appendChild(fragment);
|
|
62679
|
-
let html = container.innerHTML;
|
|
62680
|
-
return html;
|
|
62681
|
-
};
|
|
62682
|
-
const exportSectionsToJSON = (editor) => {
|
|
62683
|
-
const sections = getAllSections(editor);
|
|
62684
|
-
const processedSections = /* @__PURE__ */ new Set();
|
|
62685
|
-
const result = [];
|
|
62686
|
-
sections.forEach(({ node }) => {
|
|
62687
|
-
const { attrs } = node;
|
|
62688
|
-
const { id, title, description } = attrs;
|
|
62689
|
-
if (processedSections.has(id)) return;
|
|
62690
|
-
processedSections.add(id);
|
|
62691
|
-
result.push({
|
|
62692
|
-
id,
|
|
62693
|
-
title,
|
|
62694
|
-
description,
|
|
62695
|
-
content: node.toJSON()
|
|
62696
|
-
});
|
|
62697
|
-
});
|
|
62698
|
-
return result;
|
|
62699
|
-
};
|
|
62700
|
-
const getLinkedSectionEditor = (id, options, editor) => {
|
|
62701
|
-
const sections = getAllSections(editor);
|
|
62702
|
-
const section = sections.find((s) => s.node.attrs.id === id);
|
|
62703
|
-
if (!section) return null;
|
|
62704
|
-
const child = editor.createChildEditor({
|
|
62705
|
-
...options,
|
|
62706
|
-
onUpdate: ({ editor: childEditor, transaction }) => {
|
|
62707
|
-
const isFromtLinkedParent = transaction.getMeta("fromLinkedParent");
|
|
62708
|
-
if (isFromtLinkedParent) return;
|
|
62709
|
-
const updatedContent = childEditor.state.doc.content;
|
|
62710
|
-
const sectionNode = getAllSections(editor)?.find((s) => s.node.attrs.id === id);
|
|
62711
|
-
if (!sectionNode) return;
|
|
62712
|
-
const { pos, node } = sectionNode;
|
|
62713
|
-
const newNode = node.type.create(node.attrs, updatedContent, node.marks);
|
|
62714
|
-
const tr = editor.state.tr.replaceWith(pos, pos + node.nodeSize, newNode);
|
|
62715
|
-
tr.setMeta("fromLinkedChild", true);
|
|
62716
|
-
editor.view.dispatch(tr);
|
|
62717
|
-
}
|
|
62718
|
-
});
|
|
62719
|
-
editor.on("update", ({ transaction }) => {
|
|
62720
|
-
const isFromLinkedChild = transaction.getMeta("fromLinkedChild");
|
|
62721
|
-
if (isFromLinkedChild) return;
|
|
62722
|
-
const sectionNode = getAllSections(editor)?.find((s) => s.node.attrs.id === id);
|
|
62723
|
-
if (!sectionNode) return;
|
|
62724
|
-
const sectionContent = sectionNode.node.content;
|
|
62725
|
-
const json = {
|
|
62726
|
-
type: "doc",
|
|
62727
|
-
content: sectionContent.content.map((node) => node.toJSON())
|
|
62728
|
-
};
|
|
62729
|
-
const childTr = child.state.tr;
|
|
62730
|
-
childTr.setMeta("fromLinkedParent", true);
|
|
62731
|
-
childTr.replaceWith(0, child.state.doc.content.size, child.schema.nodeFromJSON(json));
|
|
62732
|
-
child.view.dispatch(childTr);
|
|
62733
|
-
});
|
|
62734
|
-
return child;
|
|
62735
|
-
};
|
|
62736
|
-
const SectionHelpers = {
|
|
62737
|
-
getAllSections,
|
|
62738
|
-
exportSectionsToHTML,
|
|
62739
|
-
exportSectionsToJSON,
|
|
62740
|
-
getLinkedSectionEditor
|
|
62741
|
-
};
|
|
62742
|
-
const DocumentSection = Node$1.create({
|
|
62743
|
-
name: "documentSection",
|
|
63458
|
+
const ShapeTextbox = Node$1.create({
|
|
63459
|
+
name: "shapeTextbox",
|
|
62744
63460
|
group: "block",
|
|
62745
|
-
content: "block*",
|
|
62746
|
-
atom: true,
|
|
63461
|
+
content: "paragraph* block*",
|
|
62747
63462
|
isolating: true,
|
|
62748
63463
|
addOptions() {
|
|
62749
63464
|
return {
|
|
62750
63465
|
htmlAttributes: {
|
|
62751
|
-
class: "sd-
|
|
62752
|
-
"aria-label": "
|
|
63466
|
+
class: "sd-editor-shape-textbox",
|
|
63467
|
+
"aria-label": "Shape textbox node"
|
|
62753
63468
|
}
|
|
62754
63469
|
};
|
|
62755
63470
|
},
|
|
62756
|
-
parseDOM() {
|
|
62757
|
-
return [
|
|
62758
|
-
{
|
|
62759
|
-
tag: "div.sd-document-section-block",
|
|
62760
|
-
priority: 60
|
|
62761
|
-
}
|
|
62762
|
-
];
|
|
62763
|
-
},
|
|
62764
|
-
renderDOM({ htmlAttributes }) {
|
|
62765
|
-
return ["div", Attribute2.mergeAttributes(this.options.htmlAttributes, htmlAttributes), 0];
|
|
62766
|
-
},
|
|
62767
63471
|
addAttributes() {
|
|
62768
63472
|
return {
|
|
62769
|
-
id: {},
|
|
62770
63473
|
sdBlockId: {
|
|
62771
63474
|
default: null,
|
|
62772
63475
|
keepOnSplit: false,
|
|
@@ -62775,212 +63478,131 @@ const DocumentSection = Node$1.create({
|
|
|
62775
63478
|
return attrs.sdBlockId ? { "data-sd-block-id": attrs.sdBlockId } : {};
|
|
62776
63479
|
}
|
|
62777
63480
|
},
|
|
62778
|
-
|
|
62779
|
-
|
|
62780
|
-
|
|
62781
|
-
isLocked: { default: false }
|
|
63481
|
+
attributes: {
|
|
63482
|
+
rendered: false
|
|
63483
|
+
}
|
|
62782
63484
|
};
|
|
62783
63485
|
},
|
|
62784
|
-
|
|
62785
|
-
return
|
|
62786
|
-
|
|
63486
|
+
parseDOM() {
|
|
63487
|
+
return [
|
|
63488
|
+
{
|
|
63489
|
+
tag: `div[data-type="${this.name}"]`
|
|
63490
|
+
}
|
|
63491
|
+
];
|
|
63492
|
+
},
|
|
63493
|
+
renderDOM({ htmlAttributes }) {
|
|
63494
|
+
return [
|
|
63495
|
+
"div",
|
|
63496
|
+
Attribute2.mergeAttributes(this.options.htmlAttributes, htmlAttributes, { "data-type": this.name }),
|
|
63497
|
+
0
|
|
63498
|
+
];
|
|
63499
|
+
}
|
|
63500
|
+
});
|
|
63501
|
+
const ContentBlock = Node$1.create({
|
|
63502
|
+
name: "contentBlock",
|
|
63503
|
+
group: "inline",
|
|
63504
|
+
content: "",
|
|
63505
|
+
isolating: true,
|
|
63506
|
+
atom: true,
|
|
63507
|
+
inline: true,
|
|
63508
|
+
addOptions() {
|
|
63509
|
+
return {
|
|
63510
|
+
htmlAttributes: {
|
|
63511
|
+
contenteditable: false
|
|
63512
|
+
}
|
|
62787
63513
|
};
|
|
62788
63514
|
},
|
|
62789
|
-
|
|
63515
|
+
addAttributes() {
|
|
62790
63516
|
return {
|
|
62791
|
-
|
|
62792
|
-
|
|
62793
|
-
|
|
62794
|
-
|
|
62795
|
-
|
|
62796
|
-
* editor.commands.createDocumentSection({
|
|
62797
|
-
* id: 1,
|
|
62798
|
-
* title: 'Terms & Conditions',
|
|
62799
|
-
* isLocked: true,
|
|
62800
|
-
* html: '<p>Legal content...</p>'
|
|
62801
|
-
* })
|
|
62802
|
-
*/
|
|
62803
|
-
createDocumentSection: (options = {}) => ({ tr, state: state2, dispatch, editor }) => {
|
|
62804
|
-
const { selection } = state2;
|
|
62805
|
-
let { from: from2, to } = selection;
|
|
62806
|
-
let content = selection.content().content;
|
|
62807
|
-
const { html: optionsHTML, json: optionsJSON } = options;
|
|
62808
|
-
if (optionsHTML) {
|
|
62809
|
-
const html = htmlHandler(optionsHTML, this.editor);
|
|
62810
|
-
const doc2 = DOMParser$1.fromSchema(this.editor.schema).parse(html);
|
|
62811
|
-
content = doc2.content;
|
|
62812
|
-
}
|
|
62813
|
-
if (optionsJSON) {
|
|
62814
|
-
content = this.editor.schema.nodeFromJSON(optionsJSON);
|
|
62815
|
-
}
|
|
62816
|
-
if (!content?.content?.length) {
|
|
62817
|
-
content = this.editor.schema.nodeFromJSON({ type: "paragraph", content: [] });
|
|
62818
|
-
}
|
|
62819
|
-
if (!options.id) {
|
|
62820
|
-
const allSections = SectionHelpers.getAllSections(editor);
|
|
62821
|
-
options.id = allSections.length + 1;
|
|
62822
|
-
}
|
|
62823
|
-
if (!options.title) {
|
|
62824
|
-
options.title = "Document section";
|
|
62825
|
-
}
|
|
62826
|
-
const node = this.type.createAndFill(options, content);
|
|
62827
|
-
if (!node) return false;
|
|
62828
|
-
const isAlreadyInSdtBlock = findParentNode((node2) => node2.type.name === "documentSection")(selection);
|
|
62829
|
-
if (isAlreadyInSdtBlock && isAlreadyInSdtBlock.node) {
|
|
62830
|
-
const insertPos2 = isAlreadyInSdtBlock.pos + isAlreadyInSdtBlock.node.nodeSize;
|
|
62831
|
-
from2 = insertPos2;
|
|
62832
|
-
to = insertPos2;
|
|
62833
|
-
}
|
|
62834
|
-
tr.replaceRangeWith(from2, to, node);
|
|
62835
|
-
const nodeEnd = from2 + node.nodeSize;
|
|
62836
|
-
let shouldInsertParagraph = true;
|
|
62837
|
-
let insertPos = nodeEnd;
|
|
62838
|
-
if (nodeEnd >= tr.doc.content.size) {
|
|
62839
|
-
insertPos = tr.doc.content.size;
|
|
62840
|
-
if (insertPos > 0) {
|
|
62841
|
-
const $endPos = tr.doc.resolve(insertPos);
|
|
62842
|
-
if ($endPos.nodeBefore && $endPos.nodeBefore.type.name === "paragraph") {
|
|
62843
|
-
shouldInsertParagraph = false;
|
|
62844
|
-
}
|
|
62845
|
-
}
|
|
62846
|
-
}
|
|
62847
|
-
if (shouldInsertParagraph) {
|
|
62848
|
-
const emptyParagraph = tr.doc.type.schema.nodes.paragraph.create();
|
|
62849
|
-
tr.insert(insertPos, emptyParagraph);
|
|
62850
|
-
}
|
|
62851
|
-
if (dispatch) {
|
|
62852
|
-
tr.setMeta("documentSection", { action: "create" });
|
|
62853
|
-
dispatch(tr);
|
|
62854
|
-
setTimeout(() => {
|
|
62855
|
-
try {
|
|
62856
|
-
const currentState = editor.state;
|
|
62857
|
-
const docSize = currentState.doc.content.size;
|
|
62858
|
-
let targetPos = from2 + node.nodeSize;
|
|
62859
|
-
if (shouldInsertParagraph) {
|
|
62860
|
-
targetPos += 1;
|
|
62861
|
-
}
|
|
62862
|
-
targetPos = Math.min(targetPos, docSize);
|
|
62863
|
-
if (targetPos < docSize && targetPos > 0) {
|
|
62864
|
-
const newSelection = Selection.near(currentState.doc.resolve(targetPos));
|
|
62865
|
-
const newTr = currentState.tr.setSelection(newSelection);
|
|
62866
|
-
editor.view.dispatch(newTr);
|
|
62867
|
-
}
|
|
62868
|
-
} catch (e) {
|
|
62869
|
-
console.warn("Could not set delayed selection:", e);
|
|
62870
|
-
}
|
|
62871
|
-
}, 0);
|
|
63517
|
+
horizontalRule: {
|
|
63518
|
+
default: false,
|
|
63519
|
+
renderDOM: ({ horizontalRule }) => {
|
|
63520
|
+
if (!horizontalRule) return {};
|
|
63521
|
+
return { "data-horizontal-rule": "true" };
|
|
62872
63522
|
}
|
|
62873
|
-
return true;
|
|
62874
63523
|
},
|
|
62875
|
-
|
|
62876
|
-
|
|
62877
|
-
|
|
62878
|
-
|
|
62879
|
-
|
|
62880
|
-
|
|
62881
|
-
|
|
62882
|
-
|
|
62883
|
-
|
|
62884
|
-
|
|
62885
|
-
|
|
62886
|
-
const nodeStart = pos;
|
|
62887
|
-
const nodeEnd = nodeStart + node.nodeSize;
|
|
62888
|
-
const contentToPreserve = node.content;
|
|
62889
|
-
tr.delete(nodeStart, nodeEnd);
|
|
62890
|
-
if (contentToPreserve.size > 0) {
|
|
62891
|
-
tr.insert(nodeStart, contentToPreserve);
|
|
62892
|
-
}
|
|
62893
|
-
const newPos = Math.min(nodeStart, tr.doc.content.size);
|
|
62894
|
-
tr.setSelection(Selection.near(tr.doc.resolve(newPos)));
|
|
62895
|
-
if (dispatch) {
|
|
62896
|
-
tr.setMeta("documentSection", { action: "delete" });
|
|
62897
|
-
dispatch(tr);
|
|
63524
|
+
size: {
|
|
63525
|
+
default: null,
|
|
63526
|
+
renderDOM: ({ size: size2 }) => {
|
|
63527
|
+
if (!size2) return {};
|
|
63528
|
+
let style2 = "";
|
|
63529
|
+
if (size2.top) style2 += `top: ${size2.top}px; `;
|
|
63530
|
+
if (size2.left) style2 += `left: ${size2.left}px; `;
|
|
63531
|
+
if (size2.width) style2 += `width: ${size2.width.toString().endsWith("%") ? size2.width : `${size2.width}px`}; `;
|
|
63532
|
+
if (size2.height)
|
|
63533
|
+
style2 += `height: ${size2.height.toString().endsWith("%") ? size2.height : `${size2.height}px`}; `;
|
|
63534
|
+
return { style: style2 };
|
|
62898
63535
|
}
|
|
62899
|
-
return true;
|
|
62900
63536
|
},
|
|
62901
|
-
|
|
62902
|
-
|
|
62903
|
-
|
|
62904
|
-
|
|
62905
|
-
|
|
62906
|
-
|
|
62907
|
-
|
|
62908
|
-
removeSectionById: (id) => ({ tr, dispatch }) => {
|
|
62909
|
-
const sections = SectionHelpers.getAllSections(this.editor);
|
|
62910
|
-
const sectionToRemove = sections.find(({ node: node2 }) => node2.attrs.id === id);
|
|
62911
|
-
if (!sectionToRemove) return false;
|
|
62912
|
-
const { pos, node } = sectionToRemove;
|
|
62913
|
-
const nodeStart = pos;
|
|
62914
|
-
const nodeEnd = nodeStart + node.nodeSize;
|
|
62915
|
-
tr.delete(nodeStart, nodeEnd);
|
|
62916
|
-
if (dispatch) {
|
|
62917
|
-
tr.setMeta("documentSection", { action: "delete", id });
|
|
62918
|
-
dispatch(tr);
|
|
63537
|
+
background: {
|
|
63538
|
+
default: null,
|
|
63539
|
+
renderDOM: (attrs) => {
|
|
63540
|
+
if (!attrs.background) return {};
|
|
63541
|
+
return {
|
|
63542
|
+
style: `background-color: ${attrs.background}`
|
|
63543
|
+
};
|
|
62919
63544
|
}
|
|
62920
|
-
return true;
|
|
62921
63545
|
},
|
|
63546
|
+
drawingContent: {
|
|
63547
|
+
rendered: false
|
|
63548
|
+
},
|
|
63549
|
+
attributes: {
|
|
63550
|
+
rendered: false
|
|
63551
|
+
}
|
|
63552
|
+
};
|
|
63553
|
+
},
|
|
63554
|
+
parseDOM() {
|
|
63555
|
+
return [
|
|
63556
|
+
{
|
|
63557
|
+
tag: `div[data-type="${this.name}"]`
|
|
63558
|
+
}
|
|
63559
|
+
];
|
|
63560
|
+
},
|
|
63561
|
+
renderDOM({ htmlAttributes }) {
|
|
63562
|
+
return ["div", Attribute2.mergeAttributes(this.options.htmlAttributes, htmlAttributes, { "data-type": this.name })];
|
|
63563
|
+
},
|
|
63564
|
+
addCommands() {
|
|
63565
|
+
return {
|
|
62922
63566
|
/**
|
|
62923
|
-
*
|
|
63567
|
+
* Insert a horizontal rule
|
|
62924
63568
|
* @category Command
|
|
62925
|
-
* @param {number} id - Section to lock
|
|
62926
63569
|
* @example
|
|
62927
|
-
* editor.commands.
|
|
63570
|
+
* editor.commands.insertHorizontalRule()
|
|
63571
|
+
* @note Creates a visual separator between content sections
|
|
62928
63572
|
*/
|
|
62929
|
-
|
|
62930
|
-
|
|
62931
|
-
|
|
62932
|
-
|
|
62933
|
-
|
|
62934
|
-
|
|
62935
|
-
|
|
62936
|
-
|
|
62937
|
-
}
|
|
62938
|
-
return true;
|
|
63573
|
+
insertHorizontalRule: () => ({ commands: commands2 }) => {
|
|
63574
|
+
return commands2.insertContent({
|
|
63575
|
+
type: this.name,
|
|
63576
|
+
attrs: {
|
|
63577
|
+
horizontalRule: true,
|
|
63578
|
+
size: { width: "100%", height: 2 },
|
|
63579
|
+
background: "#e5e7eb"
|
|
63580
|
+
}
|
|
63581
|
+
});
|
|
62939
63582
|
},
|
|
62940
63583
|
/**
|
|
62941
|
-
*
|
|
63584
|
+
* Insert a content block
|
|
62942
63585
|
* @category Command
|
|
62943
|
-
* @param {
|
|
63586
|
+
* @param {ContentBlockConfig} config - Block configuration
|
|
62944
63587
|
* @example
|
|
62945
|
-
*
|
|
62946
|
-
* editor.commands.
|
|
62947
|
-
*
|
|
62948
|
-
*
|
|
62949
|
-
*
|
|
62950
|
-
*
|
|
63588
|
+
* // Insert a spacer block
|
|
63589
|
+
* editor.commands.insertContentBlock({ size: { height: 20 } })
|
|
63590
|
+
*
|
|
63591
|
+
* @example
|
|
63592
|
+
* // Insert a colored divider
|
|
63593
|
+
* editor.commands.insertContentBlock({
|
|
63594
|
+
* size: { width: '50%', height: 3 },
|
|
63595
|
+
* background: '#3b82f6'
|
|
62951
63596
|
* })
|
|
63597
|
+
* @note Used for spacing, dividers, and special inline content
|
|
62952
63598
|
*/
|
|
62953
|
-
|
|
62954
|
-
|
|
62955
|
-
|
|
62956
|
-
|
|
62957
|
-
|
|
62958
|
-
let newContent = null;
|
|
62959
|
-
if (html) {
|
|
62960
|
-
const htmlDoc = htmlHandler(html, editor || this.editor);
|
|
62961
|
-
const doc2 = DOMParser$1.fromSchema((editor || this.editor).schema).parse(htmlDoc);
|
|
62962
|
-
newContent = doc2.content;
|
|
62963
|
-
}
|
|
62964
|
-
if (json) {
|
|
62965
|
-
newContent = (editor || this.editor).schema.nodeFromJSON(json);
|
|
62966
|
-
}
|
|
62967
|
-
if (!newContent) {
|
|
62968
|
-
newContent = node.content;
|
|
62969
|
-
}
|
|
62970
|
-
const updatedNode = node.type.create({ ...node.attrs, ...attrs }, newContent, node.marks);
|
|
62971
|
-
tr.replaceWith(pos, pos + node.nodeSize, updatedNode);
|
|
62972
|
-
if (dispatch) {
|
|
62973
|
-
tr.setMeta("documentSection", { action: "update", id, attrs });
|
|
62974
|
-
dispatch(tr);
|
|
62975
|
-
}
|
|
62976
|
-
return true;
|
|
63599
|
+
insertContentBlock: (config2) => ({ commands: commands2 }) => {
|
|
63600
|
+
return commands2.insertContent({
|
|
63601
|
+
type: this.name,
|
|
63602
|
+
attrs: config2
|
|
63603
|
+
});
|
|
62977
63604
|
}
|
|
62978
63605
|
};
|
|
62979
|
-
},
|
|
62980
|
-
addHelpers() {
|
|
62981
|
-
return {
|
|
62982
|
-
...SectionHelpers
|
|
62983
|
-
};
|
|
62984
63606
|
}
|
|
62985
63607
|
});
|
|
62986
63608
|
const { findChildren } = helpers;
|
|
@@ -69548,7 +70170,8 @@ const nodeResizer = (nodeNames = ["image"], editor) => {
|
|
|
69548
70170
|
const prevSelection = prevState.selection;
|
|
69549
70171
|
if (selection.from !== prevSelection.from || selection.to !== prevSelection.to) {
|
|
69550
70172
|
setTimeout(() => {
|
|
69551
|
-
const
|
|
70173
|
+
const searchRoot = editorView?.dom;
|
|
70174
|
+
const selectedResizableWrapper = searchRoot?.querySelector(".sd-editor-resizable-wrapper");
|
|
69552
70175
|
if (selectedResizableWrapper) {
|
|
69553
70176
|
showResizeHandles(view2, selectedResizableWrapper);
|
|
69554
70177
|
} else {
|
|
@@ -69829,6 +70452,7 @@ const getStarterExtensions = () => {
|
|
|
69829
70452
|
Search,
|
|
69830
70453
|
StructuredContent,
|
|
69831
70454
|
StructuredContentBlock,
|
|
70455
|
+
StructuredContentCommands,
|
|
69832
70456
|
DocumentSection,
|
|
69833
70457
|
NodeResizer,
|
|
69834
70458
|
CustomSelection,
|
|
@@ -83084,7 +83708,7 @@ class SuperToolbar extends EventEmitter2 {
|
|
|
83084
83708
|
if (!argument) return;
|
|
83085
83709
|
item.onActivate({ zoom: argument });
|
|
83086
83710
|
this.emit("superdoc-command", { item, argument });
|
|
83087
|
-
const layers =
|
|
83711
|
+
const layers = this.superdoc.element?.querySelector(".layers");
|
|
83088
83712
|
if (!layers) return;
|
|
83089
83713
|
const isMobileDevice = typeof screen.orientation !== "undefined";
|
|
83090
83714
|
const isSmallScreen = window.matchMedia("(max-width: 834px)").matches;
|
|
@@ -84146,14 +84770,6 @@ function getStructureFromResolvedPos(state2, pos) {
|
|
|
84146
84770
|
return null;
|
|
84147
84771
|
}
|
|
84148
84772
|
}
|
|
84149
|
-
const shouldBypassContextMenu = (event) => {
|
|
84150
|
-
if (!event) return false;
|
|
84151
|
-
if (event.ctrlKey || event.metaKey) {
|
|
84152
|
-
return true;
|
|
84153
|
-
}
|
|
84154
|
-
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;
|
|
84155
|
-
return Boolean(isKeyboardInvocation);
|
|
84156
|
-
};
|
|
84157
84773
|
const isModuleEnabled = (editorOptions, moduleName) => {
|
|
84158
84774
|
switch (moduleName) {
|
|
84159
84775
|
case "ai":
|