@docen/docx 0.3.2 → 0.3.4
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/blockquote-DY80QC06.d.mts +21 -0
- package/dist/bullet-list-DF60pnSL.d.mts +12 -0
- package/dist/converters/docx.d.mts +25 -4
- package/dist/converters/docx.mjs +217 -41
- package/dist/converters/html.d.mts +1 -1
- package/dist/converters/html.mjs +1 -1
- package/dist/converters/markdown.d.mts +1 -1
- package/dist/converters/markdown.mjs +1 -1
- package/dist/converters/patch.d.mts +1 -1
- package/dist/converters/prepare.d.mts +1 -1
- package/dist/converters/prepare.mjs +6 -9
- package/dist/converters/styles.d.mts +7 -1
- package/dist/converters/styles.mjs +31 -8
- package/dist/{core-DT9IrTzN.mjs → core-BnF8XhVE.mjs} +229 -33
- package/dist/core-DC0_-WcE.d.mts +387 -0
- package/dist/core.d.mts +1 -1
- package/dist/core.mjs +1 -1
- package/dist/details-Dd5MqqmR.d.mts +17 -0
- package/dist/document-Cws7XTYL.d.mts +28 -0
- package/dist/editor.d.mts +1 -1
- package/dist/editor.mjs +1 -1
- package/dist/extensions/blockquote.d.mts +2 -22
- package/dist/extensions/bullet-list.d.mts +2 -0
- package/dist/extensions/bullet-list.mjs +21 -0
- package/dist/extensions/code-block.d.mts +1 -18
- package/dist/extensions/column-break.d.mts +1 -30
- package/dist/extensions/column-break.mjs +1 -1
- package/dist/extensions/details.d.mts +2 -18
- package/dist/extensions/document.d.mts +1 -1
- package/dist/extensions/document.mjs +3 -6
- package/dist/extensions/extensions.d.mts +10 -6
- package/dist/extensions/extensions.mjs +9 -4
- package/dist/extensions/formatting-marks.d.mts +1 -37
- package/dist/extensions/formatting-marks.mjs +1 -1
- package/dist/extensions/heading.mjs +31 -9
- package/dist/extensions/image.d.mts +1 -1
- package/dist/extensions/image.mjs +20 -4
- package/dist/extensions/index.d.mts +17 -4
- package/dist/extensions/index.mjs +18 -3
- package/dist/extensions/link.d.mts +2 -0
- package/dist/extensions/link.mjs +56 -0
- package/dist/extensions/mention.d.mts +2 -24
- package/dist/extensions/ordered-list.d.mts +1 -24
- package/dist/extensions/ordered-list.mjs +10 -1
- package/dist/extensions/page-break.d.mts +1 -1
- package/dist/extensions/page-break.mjs +1 -1
- package/dist/extensions/paragraph.mjs +14 -6
- package/dist/extensions/passthrough.d.mts +2 -2
- package/dist/extensions/passthrough.mjs +2 -2
- package/dist/extensions/scroll.d.mts +2 -0
- package/dist/extensions/scroll.mjs +33 -0
- package/dist/extensions/section-break.d.mts +1 -43
- package/dist/extensions/section-break.mjs +1 -1
- package/dist/extensions/strike.mjs +1 -5
- package/dist/extensions/tab.d.mts +2 -0
- package/dist/extensions/tab.mjs +2 -0
- package/dist/extensions/table-cell.mjs +3 -8
- package/dist/extensions/table-header.mjs +1 -6
- package/dist/extensions/table-row.mjs +1 -6
- package/dist/extensions/table.mjs +1 -6
- package/dist/extensions/task-item.d.mts +2 -26
- package/dist/extensions/text-style.mjs +1 -6
- package/dist/extensions/tiptap.d.mts +1 -1
- package/dist/extensions/toc-field.d.mts +2 -0
- package/dist/extensions/toc-field.mjs +2 -0
- package/dist/extensions/utils.d.mts +2 -2
- package/dist/extensions/utils.mjs +10 -1
- package/dist/extensions/wpg-group.d.mts +2 -2
- package/dist/extensions/wpg-group.mjs +2 -2
- package/dist/extensions/wps-shape.d.mts +1 -1
- package/dist/extensions/wps-shape.mjs +1 -1
- package/dist/index.d.mts +48 -11
- package/dist/index.mjs +19 -4
- package/dist/link-BawPjQZR.d.mts +6 -0
- package/dist/mention-BGLzLVYw.d.mts +23 -0
- package/dist/ordered-list-DFAe-YEV.d.mts +25 -0
- package/dist/scroll-ZNeThJsJ.d.mts +18 -0
- package/dist/task-item-B0ntvQ1Y.d.mts +25 -0
- package/dist/{tiptap-pZsNPsvV.d.mts → tiptap-BKqn41uT.d.mts} +2 -2
- package/dist/{utils-D87vukzp.d.mts → utils-BJwDQts7.d.mts} +10 -1
- package/package.json +3 -3
- package/dist/core-C9VunJ8o.d.mts +0 -174
- package/dist/document-BH1y4qHM.d.mts +0 -6
|
@@ -1,13 +1,15 @@
|
|
|
1
|
-
import { Blockquote, Bold,
|
|
1
|
+
import { Blockquote, Bold, Code, CodeBlockLowlight, Details, DetailsContent, DetailsSummary, Emoji, HardBreak, Highlight, HorizontalRule, Italic, ListItem, Mathematics, Mention, Subscript, Superscript, TaskItem, TaskList, Text, TextAlign, Underline } from "./extensions/tiptap.mjs";
|
|
2
2
|
import "./extensions/blockquote.mjs";
|
|
3
|
+
import { BulletList } from "./extensions/bullet-list.mjs";
|
|
3
4
|
import { CodeBlock } from "./extensions/code-block.mjs";
|
|
4
5
|
import "./extensions/details.mjs";
|
|
6
|
+
import { attrNative, floatAnchorScope, floatingToStyles, normalizeColorToHex, renderRunStyles } from "./extensions/utils.mjs";
|
|
5
7
|
import { Document } from "./extensions/document.mjs";
|
|
6
|
-
import { floatAnchorScope, floatingToStyles, normalizeColorToHex, renderRunStyles } from "./extensions/utils.mjs";
|
|
7
8
|
import { Heading } from "./extensions/heading.mjs";
|
|
8
9
|
import { Image } from "./extensions/image.mjs";
|
|
10
|
+
import { Link } from "./extensions/link.mjs";
|
|
9
11
|
import "./extensions/mention.mjs";
|
|
10
|
-
import "./extensions/ordered-list.mjs";
|
|
12
|
+
import { OrderedList } from "./extensions/ordered-list.mjs";
|
|
11
13
|
import { Paragraph } from "./extensions/paragraph.mjs";
|
|
12
14
|
import { Strike } from "./extensions/strike.mjs";
|
|
13
15
|
import { Table } from "./extensions/table.mjs";
|
|
@@ -18,7 +20,6 @@ import "./extensions/task-item.mjs";
|
|
|
18
20
|
import { TextStyle } from "./extensions/text-style.mjs";
|
|
19
21
|
import { Editor, Extension, Mark, Node } from "@tiptap/core";
|
|
20
22
|
import { all, createLowlight } from "lowlight";
|
|
21
|
-
import { TextAlign } from "@tiptap/extension-text-align";
|
|
22
23
|
import { Plugin, PluginKey, TextSelection } from "@tiptap/pm/state";
|
|
23
24
|
import { Decoration, DecorationSet } from "@tiptap/pm/view";
|
|
24
25
|
import { convertEmuToPixels, encodeBase64 } from "@office-open/core";
|
|
@@ -224,7 +225,7 @@ const PageBreak = Node.create({
|
|
|
224
225
|
//#region src/extensions/passthrough.ts
|
|
225
226
|
/**
|
|
226
227
|
* Passthrough — block atom carrying an opaque {@link SectionChild} that has
|
|
227
|
-
* no native Tiptap representation (rawXml, bookmarkStart/End,
|
|
228
|
+
* no native Tiptap representation (rawXml, bookmarkStart/End, textbox,
|
|
228
229
|
* altChunk, subDoc, customXml).
|
|
229
230
|
*
|
|
230
231
|
* The full SectionChild is stored as JSON in `attrs.data` so the DOCX→JSON→DOCX
|
|
@@ -277,6 +278,46 @@ const Passthrough = Node.create({
|
|
|
277
278
|
];
|
|
278
279
|
}
|
|
279
280
|
});
|
|
281
|
+
/**
|
|
282
|
+
* InlinePassthrough — inline atom carrying an opaque inline ParagraphChild that
|
|
283
|
+
* has no native Tiptap representation (bookmarkStart/End, comment range markers,
|
|
284
|
+
* proofErr, track-change markers, …). The full ParagraphChild rides in
|
|
285
|
+
* `attrs.data` as JSON so DOCX→JSON→DOCX round-trips byte-faithful; the atom is
|
|
286
|
+
* zero-width (bookmark/range markers carry no layout box), matching Word's
|
|
287
|
+
* non-printing metadata. Mirrors the block-level Passthrough for inline children.
|
|
288
|
+
*/
|
|
289
|
+
const InlinePassthrough = Node.create({
|
|
290
|
+
name: "inlinePassthrough",
|
|
291
|
+
group: "inline",
|
|
292
|
+
inline: true,
|
|
293
|
+
atom: true,
|
|
294
|
+
addAttributes() {
|
|
295
|
+
return { data: {
|
|
296
|
+
default: "{}",
|
|
297
|
+
rendered: false,
|
|
298
|
+
parseHTML: (element) => element.getAttribute("data-inline-passthrough") ?? "{}"
|
|
299
|
+
} };
|
|
300
|
+
},
|
|
301
|
+
parseHTML() {
|
|
302
|
+
return [{ tag: "span[data-inline-passthrough]" }];
|
|
303
|
+
},
|
|
304
|
+
renderHTML({ node }) {
|
|
305
|
+
const data = node.attrs.data || "{}";
|
|
306
|
+
let bookmarkName;
|
|
307
|
+
try {
|
|
308
|
+
bookmarkName = JSON.parse(data).bookmarkStart?.name;
|
|
309
|
+
} catch {}
|
|
310
|
+
const attrs = {
|
|
311
|
+
"data-inline-passthrough": data,
|
|
312
|
+
contenteditable: "false"
|
|
313
|
+
};
|
|
314
|
+
if (bookmarkName) {
|
|
315
|
+
attrs.id = bookmarkName;
|
|
316
|
+
attrs.style = "display:inline-block;width:0;height:0;overflow:hidden;vertical-align:baseline";
|
|
317
|
+
} else attrs.style = "display:none";
|
|
318
|
+
return ["span", attrs];
|
|
319
|
+
}
|
|
320
|
+
});
|
|
280
321
|
//#endregion
|
|
281
322
|
//#region src/extensions/section-break.ts
|
|
282
323
|
/**
|
|
@@ -342,6 +383,81 @@ const SectionBreak = Extension.create({
|
|
|
342
383
|
}
|
|
343
384
|
});
|
|
344
385
|
//#endregion
|
|
386
|
+
//#region src/extensions/tab.ts
|
|
387
|
+
/**
|
|
388
|
+
* Tab — an inline atom representing a DOCX `<w:r><w:tab/></w:r>` tab character.
|
|
389
|
+
*
|
|
390
|
+
* office-open parses `<w:tab/>` as `{ tab: true }` inside a run's children. The
|
|
391
|
+
* resolve path turns that into this node so the tab is not lost: previously
|
|
392
|
+
* `<w:tab/>` was dropped, which let `mergeTextNodes` collapse a TOC entry's title
|
|
393
|
+
* and page number into adjacent text (no leader, no right alignment). The node is
|
|
394
|
+
* zero-width, non-editable, and carries no text height — measure skips it the
|
|
395
|
+
* same way it skips other inline atoms, so pagination is unaffected. It only
|
|
396
|
+
* marks where a tab leader (e.g. a TOC's dotted leader) renders. compile turns it
|
|
397
|
+
* back into `{ tab: true }`.
|
|
398
|
+
*/
|
|
399
|
+
const Tab = Node.create({
|
|
400
|
+
name: "tab",
|
|
401
|
+
group: "inline",
|
|
402
|
+
inline: true,
|
|
403
|
+
atom: true,
|
|
404
|
+
parseHTML() {
|
|
405
|
+
return [{ tag: "span.docx-tab" }];
|
|
406
|
+
},
|
|
407
|
+
renderHTML() {
|
|
408
|
+
return ["span", {
|
|
409
|
+
class: "docx-tab",
|
|
410
|
+
contenteditable: "false"
|
|
411
|
+
}];
|
|
412
|
+
}
|
|
413
|
+
});
|
|
414
|
+
//#endregion
|
|
415
|
+
//#region src/extensions/toc-field.ts
|
|
416
|
+
/**
|
|
417
|
+
* TOC field (`tocField`) — a block container representing a DOCX table of
|
|
418
|
+
* contents, with the rendered entries as editable `content` and the TOC field
|
|
419
|
+
* switches on `attrs.options`.
|
|
420
|
+
*
|
|
421
|
+
* Named `tocField` (not `tableOfContents`) to avoid colliding with the official
|
|
422
|
+
* `@tiptap/extension-table-of-contents`, which is an `Extension` (a live outline
|
|
423
|
+
* generator injected into the editor) that already owns the `tableOfContents`
|
|
424
|
+
* name. Same-name extensions dedupe in Tiptap, and since the official one is not
|
|
425
|
+
* a node it would erase this node type from the schema. The two coexist for
|
|
426
|
+
* different purposes: this node persists a DOCX's rendered TOC; the official
|
|
427
|
+
* extension drives the heading-outline pane.
|
|
428
|
+
*
|
|
429
|
+
* Structuring the TOC as a node (instead of opaque passthrough) is what fixes
|
|
430
|
+
* the export crash. Each entry paragraph's `w:hyperlink` wraps a HYPERLINK field
|
|
431
|
+
* whose content-less runs (fldChar begin/separate/end) office-open parses as
|
|
432
|
+
* `null`. As opaque passthrough those nulls survived verbatim to
|
|
433
|
+
* `generateDocument`, where office-open's `stringifyRunInline(null).break`
|
|
434
|
+
* crashed. Resolving the entries through `resolveParagraphChildren` drops the
|
|
435
|
+
* nulls (the existing `child !== null` guard), so compile rebuilds clean entries
|
|
436
|
+
* and the generate path never sees a null — no office-open change required.
|
|
437
|
+
*
|
|
438
|
+
* DOCX serialization is inlined in DocxManager (resolve/compile read/write
|
|
439
|
+
* `attrs.options` + the entry content directly), so no renderDocx/parseDocx is
|
|
440
|
+
* needed here — the same pattern as the details extension.
|
|
441
|
+
*/
|
|
442
|
+
const TocField = Node.create({
|
|
443
|
+
name: "tocField",
|
|
444
|
+
group: "block",
|
|
445
|
+
content: "block+",
|
|
446
|
+
addAttributes() {
|
|
447
|
+
return { options: attrNative() };
|
|
448
|
+
},
|
|
449
|
+
parseHTML() {
|
|
450
|
+
return [{ tag: "div.docx-toc" }];
|
|
451
|
+
},
|
|
452
|
+
renderHTML() {
|
|
453
|
+
return [
|
|
454
|
+
"div",
|
|
455
|
+
{ class: "docx-toc" },
|
|
456
|
+
0
|
|
457
|
+
];
|
|
458
|
+
}
|
|
459
|
+
});
|
|
460
|
+
//#endregion
|
|
345
461
|
//#region src/extensions/wpg-group.ts
|
|
346
462
|
/**
|
|
347
463
|
* wpgGroup — inline atom carrying a DOCX drawing group (wpg: wordprocessingGroup)
|
|
@@ -453,6 +569,35 @@ function renderWpsText(children) {
|
|
|
453
569
|
];
|
|
454
570
|
});
|
|
455
571
|
}
|
|
572
|
+
/** Inner style of a wps text-box: fill + outline + textbox insets (padding).
|
|
573
|
+
* Lives on the contentDOM (the editable interior). Never carries rotation or
|
|
574
|
+
* writing-mode — those go on the outer positioning wrapper (see
|
|
575
|
+
* wpsRotationVert), because transform/writing-mode on an editable region
|
|
576
|
+
* distort the caret rect and break CJK IME composition. */
|
|
577
|
+
function wpsInnerStyle(data) {
|
|
578
|
+
const parts = [];
|
|
579
|
+
const fill = fillToCss(data.fill);
|
|
580
|
+
if (fill) parts.push(`background-color:${fill}`);
|
|
581
|
+
const outline = outlineToCss(data.outline);
|
|
582
|
+
if (outline) parts.push(outline);
|
|
583
|
+
const bp = data.bodyProperties;
|
|
584
|
+
if (bp) {
|
|
585
|
+
const ins = (v) => v != null ? `${(v / EMU_PER_PX).toFixed(1)}px` : "0px";
|
|
586
|
+
parts.push(`padding:${ins(bp.tIns)} ${ins(bp.rIns)} ${ins(bp.bIns)} ${ins(bp.lIns)}`);
|
|
587
|
+
}
|
|
588
|
+
return parts.join(";");
|
|
589
|
+
}
|
|
590
|
+
/** Rotation + writing-mode (text direction) for a wps shape. Lives on the
|
|
591
|
+
* positioning wrapper OUTSIDE the contentDOM. `rotationOverride` covers a
|
|
592
|
+
* group child whose rotation comes from the group transform, not bodyPr. */
|
|
593
|
+
function wpsRotationVert(data, rotationOverride) {
|
|
594
|
+
const parts = [];
|
|
595
|
+
const rotation = rotationOverride ?? data.bodyProperties?.rotation;
|
|
596
|
+
if (rotation) parts.push(`transform:rotate(${rotation}deg)`);
|
|
597
|
+
const vert = data.bodyProperties?.vert;
|
|
598
|
+
if (vert && vert !== "horz") parts.push(`writing-mode:${vert === "vert270" ? "vertical-lr" : "vertical-rl"}`);
|
|
599
|
+
return parts.join(";");
|
|
600
|
+
}
|
|
456
601
|
/**
|
|
457
602
|
* Render a wps shape's interior (fill/outline/insets/rotation/writing-mode + text
|
|
458
603
|
* body) as a positioned div. Shared by the wpg group's inline wps children and
|
|
@@ -461,23 +606,18 @@ function renderWpsText(children) {
|
|
|
461
606
|
* carries the placement — absolute group coords for a group child, the floating
|
|
462
607
|
* anchor CSS for a standalone shape. `opts.rotation` overrides bodyPr rotation
|
|
463
608
|
* (a group child's rotation may come from the group transform, not bodyPr).
|
|
609
|
+
*
|
|
610
|
+
* The wpg path merges placement + interior into ONE div (an atom has no
|
|
611
|
+
* contentDOM, so rotation/writing-mode on the element is safe — no caret inside).
|
|
612
|
+
* The editable wpsShape node instead splits these across two elements via
|
|
613
|
+
* wpsShapeStyles (outer = position+rotation+vert, inner = contentDOM).
|
|
464
614
|
*/
|
|
465
615
|
function renderWpsInterior(data, positionStyle, opts) {
|
|
466
|
-
const
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
const bp = data.bodyProperties;
|
|
472
|
-
if (bp) {
|
|
473
|
-
const ins = (v) => v != null ? `${(v / EMU_PER_PX).toFixed(1)}px` : "0px";
|
|
474
|
-
styles.push(`padding:${ins(bp.tIns)} ${ins(bp.rIns)} ${ins(bp.bIns)} ${ins(bp.lIns)}`);
|
|
475
|
-
}
|
|
476
|
-
const rotation = opts?.rotation ?? bp?.rotation;
|
|
477
|
-
if (rotation) styles.push(`transform:rotate(${rotation}deg)`);
|
|
478
|
-
const vert = bp?.vert;
|
|
479
|
-
if (vert && vert !== "horz") styles.push(`writing-mode:${vert === "vert270" ? "vertical-lr" : "vertical-rl"}`);
|
|
480
|
-
const attrs = { style: styles.join(";") };
|
|
616
|
+
const attrs = { style: [
|
|
617
|
+
positionStyle,
|
|
618
|
+
wpsInnerStyle(data),
|
|
619
|
+
wpsRotationVert(data, opts?.rotation)
|
|
620
|
+
].filter(Boolean).join(";") };
|
|
481
621
|
if (opts?.attrs) Object.assign(attrs, opts.attrs);
|
|
482
622
|
return [
|
|
483
623
|
"div",
|
|
@@ -485,6 +625,37 @@ function renderWpsInterior(data, positionStyle, opts) {
|
|
|
485
625
|
...renderWpsText(data.children)
|
|
486
626
|
];
|
|
487
627
|
}
|
|
628
|
+
/** Two-element style split for an editable standalone wpsShape: `outer` for the
|
|
629
|
+
* positioning wrapper (dom), `inner` for the contentDOM. rotation/writing-mode
|
|
630
|
+
* stay on `outer` so the editable interior has a clean caret/IME rect. The
|
|
631
|
+
* geometry (EMU extent → px, floating anchor CSS) is computed here so the
|
|
632
|
+
* editor's NodeView and generateHTML render identically without re-deriving
|
|
633
|
+
* the engine's EMU/floating math. */
|
|
634
|
+
function wpsShapeStyles(ws) {
|
|
635
|
+
const sizeStyle = `width:${ws.transformation?.width != null ? convertEmuToPixels(ws.transformation.width) : 0}px;height:${ws.transformation?.height != null ? convertEmuToPixels(ws.transformation.height) : 0}px;box-sizing:border-box;overflow:hidden`;
|
|
636
|
+
const rotVert = wpsRotationVert(ws);
|
|
637
|
+
let outer;
|
|
638
|
+
let paragraphAnchor = false;
|
|
639
|
+
if (ws.floating) {
|
|
640
|
+
outer = [
|
|
641
|
+
...floatingToStyles(ws.floating, void 0, ws.transformation?.width),
|
|
642
|
+
sizeStyle,
|
|
643
|
+
rotVert
|
|
644
|
+
].filter(Boolean).join(";");
|
|
645
|
+
paragraphAnchor = floatAnchorScope(ws.floating) === "paragraph";
|
|
646
|
+
} else outer = [
|
|
647
|
+
`display:inline-block;vertical-align:middle`,
|
|
648
|
+
sizeStyle,
|
|
649
|
+
rotVert
|
|
650
|
+
].filter(Boolean).join(";");
|
|
651
|
+
const anchor = ws.bodyProperties?.anchor;
|
|
652
|
+
const inner = `box-sizing:border-box;display:flex;flex-direction:column;justify-content:${anchor === "ctr" ? "center" : anchor === "b" ? "flex-end" : "flex-start"};height:100%;${wpsInnerStyle(ws)}`;
|
|
653
|
+
return {
|
|
654
|
+
outer,
|
|
655
|
+
inner,
|
|
656
|
+
paragraphAnchor
|
|
657
|
+
};
|
|
658
|
+
}
|
|
488
659
|
/** Render a wpg group (top-level or nested) as a positioned container.
|
|
489
660
|
* actualW/H are the group's real pixel size — top-level groups read them from
|
|
490
661
|
* transformation.width/height; nested groups receive the box their parent
|
|
@@ -504,7 +675,7 @@ function renderGroup(group, actualW, actualH, containerStyle, extraAttrs) {
|
|
|
504
675
|
const style = containerStyle ?? `position:relative;display:inline-block;vertical-align:middle;width:${actualW}px;height:${actualH}px`;
|
|
505
676
|
const children = (group.children ?? []).map((c) => renderChild(c, chOff, scaleX, scaleY)).filter((c) => Array.isArray(c) && c.length > 0);
|
|
506
677
|
const attrs = {
|
|
507
|
-
"data-wpg-group":
|
|
678
|
+
"data-wpg-group": JSON.stringify(group),
|
|
508
679
|
style
|
|
509
680
|
};
|
|
510
681
|
if (extraAttrs) Object.assign(attrs, extraAttrs);
|
|
@@ -551,6 +722,16 @@ const WpgGroup = Node.create({
|
|
|
551
722
|
});
|
|
552
723
|
//#endregion
|
|
553
724
|
//#region src/extensions/wps-shape.ts
|
|
725
|
+
/**
|
|
726
|
+
* wpsShape — inline node carrying a standalone DOCX text-box shape
|
|
727
|
+
* (wp:anchor > wps:wsp > wps:txbx; NOT inside a wpg group). The shape geometry
|
|
728
|
+
* + styling (transformation/floating/fill/outline/bodyProperties) ride on
|
|
729
|
+
* attrs.wpsShape; the editable text body is PM content (block+), one paragraph
|
|
730
|
+
* per office-open ParagraphOptions. Unlike a group's interior wps children
|
|
731
|
+
* (laid out in the group's coordinate space), this shape floats on its own
|
|
732
|
+
* anchor. The engine node has no NodeView (UI-free); the editor layer extends
|
|
733
|
+
* it with a two-element NodeView (outer placement/rotation, inner contentDOM).
|
|
734
|
+
*/
|
|
554
735
|
const attrWpsShape = () => ({
|
|
555
736
|
default: null,
|
|
556
737
|
rendered: false,
|
|
@@ -568,23 +749,35 @@ const WpsShape = Node.create({
|
|
|
568
749
|
name: "wpsShape",
|
|
569
750
|
group: "inline",
|
|
570
751
|
inline: true,
|
|
571
|
-
|
|
752
|
+
content: "block+",
|
|
753
|
+
isolating: true,
|
|
754
|
+
defining: true,
|
|
572
755
|
addAttributes() {
|
|
573
756
|
return { wpsShape: attrWpsShape() };
|
|
574
757
|
},
|
|
575
758
|
parseHTML() {
|
|
576
|
-
return [{
|
|
759
|
+
return [{
|
|
760
|
+
tag: "div[data-wps-shape]",
|
|
761
|
+
contentElement: "div"
|
|
762
|
+
}];
|
|
577
763
|
},
|
|
578
764
|
renderHTML({ node }) {
|
|
579
765
|
const ws = node.attrs.wpsShape ?? {};
|
|
580
|
-
const
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
766
|
+
const { outer, inner, paragraphAnchor } = wpsShapeStyles(ws);
|
|
767
|
+
const attrs = {
|
|
768
|
+
"data-wps-shape": JSON.stringify(ws),
|
|
769
|
+
style: outer
|
|
770
|
+
};
|
|
771
|
+
if (paragraphAnchor) attrs["data-float-anchor"] = "paragraph";
|
|
772
|
+
return [
|
|
773
|
+
"div",
|
|
774
|
+
attrs,
|
|
775
|
+
[
|
|
776
|
+
"div",
|
|
777
|
+
{ style: inner },
|
|
778
|
+
0
|
|
779
|
+
]
|
|
780
|
+
];
|
|
588
781
|
}
|
|
589
782
|
});
|
|
590
783
|
//#endregion
|
|
@@ -596,8 +789,11 @@ const tiptapNodeExtensions = [
|
|
|
596
789
|
HardBreak,
|
|
597
790
|
PageBreak,
|
|
598
791
|
ColumnBreak,
|
|
792
|
+
Tab,
|
|
599
793
|
SectionBreak,
|
|
600
794
|
Passthrough,
|
|
795
|
+
InlinePassthrough,
|
|
796
|
+
TocField,
|
|
601
797
|
Blockquote,
|
|
602
798
|
OrderedList,
|
|
603
799
|
BulletList,
|
|
@@ -620,7 +816,7 @@ const tiptapNodeExtensions = [
|
|
|
620
816
|
TaskList,
|
|
621
817
|
TaskItem,
|
|
622
818
|
Heading,
|
|
623
|
-
TextAlign
|
|
819
|
+
TextAlign.configure({ types: ["heading", "paragraph"] })
|
|
624
820
|
];
|
|
625
821
|
const tiptapMarkExtensions = [
|
|
626
822
|
Bold,
|
|
@@ -667,4 +863,4 @@ const DocxKit = Extension.create({
|
|
|
667
863
|
}
|
|
668
864
|
});
|
|
669
865
|
//#endregion
|
|
670
|
-
export { FormattingMarks as _, DocxKit as a,
|
|
866
|
+
export { ColumnBreak as C, FormattingMarks as S, Tab as _, DocxKit as a, Passthrough as b, tiptapNodeExtensions as c, renderWpsInterior as d, renderWpsText as f, TocField as g, wpsShapeStyles as h, Node as i, WpsShape as l, wpsRotationVert as m, Extension as n, docxExtensions as o, wpsInnerStyle as p, Mark as r, tiptapMarkExtensions as s, Editor as t, WpgGroup as u, SectionBreak as v, PageBreak as x, InlinePassthrough as y };
|