@portone/docx-editor 0.1.0
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/CHANGELOG.md +7 -0
- package/CONTRIBUTING.md +63 -0
- package/LICENSE +203 -0
- package/README.md +48 -0
- package/assets/editor.png +0 -0
- package/dist/DocxEditor.d.ts +123 -0
- package/dist/DocxEditor.js +348 -0
- package/dist/core.d.ts +36 -0
- package/dist/core.js +38 -0
- package/dist/docx/comments/constants.d.ts +8 -0
- package/dist/docx/comments/constants.js +20 -0
- package/dist/docx/comments/model.d.ts +37 -0
- package/dist/docx/comments/model.js +104 -0
- package/dist/docx/comments/reading.d.ts +36 -0
- package/dist/docx/comments/reading.js +149 -0
- package/dist/docx/comments/writing.d.ts +11 -0
- package/dist/docx/comments/writing.js +327 -0
- package/dist/docx/comments.d.ts +3 -0
- package/dist/docx/comments.js +4 -0
- package/dist/docx/container.d.ts +12 -0
- package/dist/docx/container.js +130 -0
- package/dist/docx/documentSettings.d.ts +4 -0
- package/dist/docx/documentSettings.js +14 -0
- package/dist/docx/exportDocx.d.ts +15 -0
- package/dist/docx/exportDocx.js +163 -0
- package/dist/docx/exportRefs.d.ts +16 -0
- package/dist/docx/exportRefs.js +10 -0
- package/dist/docx/formatting/direct.d.ts +30 -0
- package/dist/docx/formatting/direct.js +201 -0
- package/dist/docx/formatting/effectiveParagraph.d.ts +15 -0
- package/dist/docx/formatting/effectiveParagraph.js +81 -0
- package/dist/docx/formatting/styles.d.ts +67 -0
- package/dist/docx/formatting/styles.js +165 -0
- package/dist/docx/formatting/tabStops.d.ts +8 -0
- package/dist/docx/formatting/tabStops.js +65 -0
- package/dist/docx/formatting.d.ts +4 -0
- package/dist/docx/formatting.js +4 -0
- package/dist/docx/headersFooters.d.ts +36 -0
- package/dist/docx/headersFooters.js +218 -0
- package/dist/docx/hyperlink.d.ts +75 -0
- package/dist/docx/hyperlink.js +71 -0
- package/dist/docx/importDocx.d.ts +21 -0
- package/dist/docx/importDocx.js +263 -0
- package/dist/docx/importParagraph.d.ts +32 -0
- package/dist/docx/importParagraph.js +308 -0
- package/dist/docx/importTable.d.ts +9 -0
- package/dist/docx/importTable.js +275 -0
- package/dist/docx/media.d.ts +60 -0
- package/dist/docx/media.js +213 -0
- package/dist/docx/notes.d.ts +22 -0
- package/dist/docx/notes.js +71 -0
- package/dist/docx/pageGeometry.d.ts +75 -0
- package/dist/docx/pageGeometry.js +88 -0
- package/dist/docx/paraProps.d.ts +74 -0
- package/dist/docx/paraProps.js +167 -0
- package/dist/docx/propsXml.d.ts +49 -0
- package/dist/docx/propsXml.js +302 -0
- package/dist/docx/relationships.d.ts +42 -0
- package/dist/docx/relationships.js +94 -0
- package/dist/docx/runProps.d.ts +51 -0
- package/dist/docx/runProps.js +207 -0
- package/dist/docx/scan.d.ts +20 -0
- package/dist/docx/scan.js +110 -0
- package/dist/docx/sdt.d.ts +56 -0
- package/dist/docx/sdt.js +104 -0
- package/dist/docx/sdtProps.d.ts +18 -0
- package/dist/docx/sdtProps.js +11 -0
- package/dist/docx/serializeBlock.d.ts +4 -0
- package/dist/docx/serializeBlock.js +30 -0
- package/dist/docx/serializeParagraph.d.ts +15 -0
- package/dist/docx/serializeParagraph.js +208 -0
- package/dist/docx/serializeTable.d.ts +12 -0
- package/dist/docx/serializeTable.js +134 -0
- package/dist/docx/session.d.ts +81 -0
- package/dist/docx/session.js +79 -0
- package/dist/docx/tableFormatting/editing.d.ts +64 -0
- package/dist/docx/tableFormatting/editing.js +318 -0
- package/dist/docx/tableFormatting/reading.d.ts +96 -0
- package/dist/docx/tableFormatting/reading.js +221 -0
- package/dist/docx/tableFormatting.d.ts +2 -0
- package/dist/docx/tableFormatting.js +3 -0
- package/dist/docx/tableTemplate.d.ts +22 -0
- package/dist/docx/tableTemplate.js +111 -0
- package/dist/docx/theme.d.ts +40 -0
- package/dist/docx/theme.js +61 -0
- package/dist/docx/uniqueControls.d.ts +14 -0
- package/dist/docx/uniqueControls.js +62 -0
- package/dist/download.d.ts +57 -0
- package/dist/download.js +44 -0
- package/dist/editor/clipboard/images.d.ts +14 -0
- package/dist/editor/clipboard/images.js +158 -0
- package/dist/editor/clipboard/inlineFormatting.d.ts +21 -0
- package/dist/editor/clipboard/inlineFormatting.js +232 -0
- package/dist/editor/commands/breakCommands.d.ts +8 -0
- package/dist/editor/commands/breakCommands.js +19 -0
- package/dist/editor/commands/canRunCommand.d.ts +6 -0
- package/dist/editor/commands/canRunCommand.js +10 -0
- package/dist/editor/commands/commentCommands.d.ts +3 -0
- package/dist/editor/commands/commentCommands.js +4 -0
- package/dist/editor/commands/comments/editing.d.ts +21 -0
- package/dist/editor/commands/comments/editing.js +305 -0
- package/dist/editor/commands/comments/model.d.ts +31 -0
- package/dist/editor/commands/comments/model.js +0 -0
- package/dist/editor/commands/comments/reading.d.ts +8 -0
- package/dist/editor/commands/comments/reading.js +58 -0
- package/dist/editor/commands/formatting/editing.d.ts +32 -0
- package/dist/editor/commands/formatting/editing.js +138 -0
- package/dist/editor/commands/formatting/reading.d.ts +57 -0
- package/dist/editor/commands/formatting/reading.js +82 -0
- package/dist/editor/commands/formatting/shared.d.ts +32 -0
- package/dist/editor/commands/formatting/shared.js +53 -0
- package/dist/editor/commands/formattingCommands.d.ts +2 -0
- package/dist/editor/commands/formattingCommands.js +3 -0
- package/dist/editor/commands/historyCommands.d.ts +11 -0
- package/dist/editor/commands/historyCommands.js +16 -0
- package/dist/editor/commands/indentCommands.d.ts +15 -0
- package/dist/editor/commands/indentCommands.js +44 -0
- package/dist/editor/commands/index.d.ts +82 -0
- package/dist/editor/commands/index.js +171 -0
- package/dist/editor/commands/linkCommands.d.ts +56 -0
- package/dist/editor/commands/linkCommands.js +146 -0
- package/dist/editor/commands/listCommands.d.ts +58 -0
- package/dist/editor/commands/listCommands.js +140 -0
- package/dist/editor/commands/lockCommands.d.ts +47 -0
- package/dist/editor/commands/lockCommands.js +198 -0
- package/dist/editor/commands/noteQueries.d.ts +12 -0
- package/dist/editor/commands/noteQueries.js +29 -0
- package/dist/editor/commands/paragraphCommands.d.ts +59 -0
- package/dist/editor/commands/paragraphCommands.js +113 -0
- package/dist/editor/commands/spacingCommands.d.ts +23 -0
- package/dist/editor/commands/spacingCommands.js +48 -0
- package/dist/editor/commands/tabCommands.d.ts +5 -0
- package/dist/editor/commands/tabCommands.js +65 -0
- package/dist/editor/createEditor.d.ts +59 -0
- package/dist/editor/createEditor.js +160 -0
- package/dist/editor/documentStyles.d.ts +60 -0
- package/dist/editor/documentStyles.js +80 -0
- package/dist/editor/externalClipboard.d.ts +11 -0
- package/dist/editor/externalClipboard.js +323 -0
- package/dist/editor/imageFiles.d.ts +74 -0
- package/dist/editor/imageFiles.js +173 -0
- package/dist/editor/insertImage.d.ts +31 -0
- package/dist/editor/insertImage.js +35 -0
- package/dist/editor/insertTable.d.ts +18 -0
- package/dist/editor/insertTable.js +44 -0
- package/dist/editor/paragraphEdits.d.ts +42 -0
- package/dist/editor/paragraphEdits.js +59 -0
- package/dist/editor/plainText.d.ts +3 -0
- package/dist/editor/plainText.js +50 -0
- package/dist/editor/plugins/bookmarkProtection.d.ts +3 -0
- package/dist/editor/plugins/bookmarkProtection.js +28 -0
- package/dist/editor/plugins/columnResize.d.ts +27 -0
- package/dist/editor/plugins/columnResize.js +192 -0
- package/dist/editor/plugins/commentDecorations.d.ts +3 -0
- package/dist/editor/plugins/commentDecorations.js +23 -0
- package/dist/editor/plugins/commentReservations.d.ts +5 -0
- package/dist/editor/plugins/commentReservations.js +26 -0
- package/dist/editor/plugins/dropCaret.d.ts +10 -0
- package/dist/editor/plugins/dropCaret.js +11 -0
- package/dist/editor/plugins/imagePaste.d.ts +8 -0
- package/dist/editor/plugins/imagePaste.js +265 -0
- package/dist/editor/plugins/keymap.d.ts +5 -0
- package/dist/editor/plugins/keymap.js +94 -0
- package/dist/editor/plugins/linkPanel.d.ts +23 -0
- package/dist/editor/plugins/linkPanel.js +39 -0
- package/dist/editor/plugins/listInputRules.d.ts +14 -0
- package/dist/editor/plugins/listInputRules.js +36 -0
- package/dist/editor/plugins/lockedContent.d.ts +6 -0
- package/dist/editor/plugins/lockedContent.js +41 -0
- package/dist/editor/plugins/noteProtection.d.ts +3 -0
- package/dist/editor/plugins/noteProtection.js +25 -0
- package/dist/editor/plugins/numberingDecorations.d.ts +42 -0
- package/dist/editor/plugins/numberingDecorations.js +110 -0
- package/dist/editor/plugins/rowResize.d.ts +15 -0
- package/dist/editor/plugins/rowResize.js +196 -0
- package/dist/editor/plugins/styledParagraphs.d.ts +15 -0
- package/dist/editor/plugins/styledParagraphs.js +65 -0
- package/dist/editor/plugins/tabCaret.d.ts +3 -0
- package/dist/editor/plugins/tabCaret.js +126 -0
- package/dist/editor/plugins/tabDecorations.d.ts +11 -0
- package/dist/editor/plugins/tabDecorations.js +87 -0
- package/dist/editor/plugins/tabLayout.d.ts +16 -0
- package/dist/editor/plugins/tabLayout.js +328 -0
- package/dist/editor/plugins/tabPointer.d.ts +7 -0
- package/dist/editor/plugins/tabPointer.js +95 -0
- package/dist/editor/plugins/tableContextMenu.d.ts +21 -0
- package/dist/editor/plugins/tableContextMenu.js +88 -0
- package/dist/editor/plugins/textContextMenu.d.ts +15 -0
- package/dist/editor/plugins/textContextMenu.js +90 -0
- package/dist/editor/views/imageResize.d.ts +53 -0
- package/dist/editor/views/imageResize.js +167 -0
- package/dist/editor/views/runMarkView.d.ts +15 -0
- package/dist/editor/views/runMarkView.js +9 -0
- package/dist/editor/views/tableView.d.ts +24 -0
- package/dist/editor/views/tableView.js +32 -0
- package/dist/index.d.ts +44 -0
- package/dist/index.js +38 -0
- package/dist/model/format.d.ts +240 -0
- package/dist/model/format.js +305 -0
- package/dist/model/tabStops.d.ts +17 -0
- package/dist/model/tabStops.js +22 -0
- package/dist/numbering/listTemplate.d.ts +29 -0
- package/dist/numbering/listTemplate.js +83 -0
- package/dist/numbering/markers.d.ts +24 -0
- package/dist/numbering/markers.js +93 -0
- package/dist/numbering/parseNumbering.d.ts +65 -0
- package/dist/numbering/parseNumbering.js +116 -0
- package/dist/numbering/writeNumbering.d.ts +13 -0
- package/dist/numbering/writeNumbering.js +49 -0
- package/dist/ooxml/errors.d.ts +39 -0
- package/dist/ooxml/errors.js +21 -0
- package/dist/ooxml/image.d.ts +88 -0
- package/dist/ooxml/image.js +106 -0
- package/dist/ooxml/tabStops.d.ts +3 -0
- package/dist/ooxml/tabStops.js +51 -0
- package/dist/ooxml/units.d.ts +37 -0
- package/dist/ooxml/units.js +116 -0
- package/dist/ooxml/xml.d.ts +36 -0
- package/dist/ooxml/xml.js +89 -0
- package/dist/page/PageGuides.d.ts +16 -0
- package/dist/page/PageGuides.js +114 -0
- package/dist/page/measureBlocks.d.ts +25 -0
- package/dist/page/measureBlocks.js +80 -0
- package/dist/page/pageDecorations.d.ts +36 -0
- package/dist/page/pageDecorations.js +211 -0
- package/dist/page/pageLayout.d.ts +176 -0
- package/dist/page/pageLayout.js +157 -0
- package/dist/page/tableMeasurements.d.ts +10 -0
- package/dist/page/tableMeasurements.js +115 -0
- package/dist/page/usePageLayout.d.ts +57 -0
- package/dist/page/usePageLayout.js +141 -0
- package/dist/schema/docxSchema.d.ts +9 -0
- package/dist/schema/docxSchema.js +863 -0
- package/dist/schema/index.d.ts +2 -0
- package/dist/schema/index.js +9 -0
- package/dist/schema/locks.d.ts +112 -0
- package/dist/schema/locks.js +211 -0
- package/dist/schema/rendering.d.ts +6 -0
- package/dist/schema/rendering.js +46 -0
- package/dist/styles/classNames.d.ts +214 -0
- package/dist/styles/classNames.js +208 -0
- package/dist/styles/colors.d.ts +11 -0
- package/dist/styles/colors.js +14 -0
- package/dist/styles/fontSizes.d.ts +6 -0
- package/dist/styles/fontSizes.js +20 -0
- package/dist/styles/fontStack.d.ts +55 -0
- package/dist/styles/fontStack.js +262 -0
- package/dist/styles/fonts.d.ts +6 -0
- package/dist/styles/fonts.js +11 -0
- package/dist/styles/inlineStyle.d.ts +67 -0
- package/dist/styles/inlineStyle.js +212 -0
- package/dist/styles/lineSpacings.d.ts +11 -0
- package/dist/styles/lineSpacings.js +10 -0
- package/dist/styles.css +1650 -0
- package/dist/table/cellBorders.d.ts +12 -0
- package/dist/table/cellBorders.js +9 -0
- package/dist/table/cellFormatting.d.ts +57 -0
- package/dist/table/cellFormatting.js +173 -0
- package/dist/table/columns.d.ts +25 -0
- package/dist/table/columns.js +155 -0
- package/dist/table/commands.d.ts +19 -0
- package/dist/table/commands.js +63 -0
- package/dist/table/format.d.ts +35 -0
- package/dist/table/format.js +26 -0
- package/dist/table/gridBorders.d.ts +42 -0
- package/dist/table/gridBorders.js +192 -0
- package/dist/table/index.d.ts +16 -0
- package/dist/table/index.js +52 -0
- package/dist/table/merge.d.ts +36 -0
- package/dist/table/merge.js +125 -0
- package/dist/table/resize.d.ts +55 -0
- package/dist/table/resize.js +66 -0
- package/dist/table/rowResize.d.ts +14 -0
- package/dist/table/rowResize.js +44 -0
- package/dist/table/rows.d.ts +32 -0
- package/dist/table/rows.js +89 -0
- package/dist/table/widths.d.ts +69 -0
- package/dist/table/widths.js +97 -0
- package/dist/ui/AlignMenu.d.ts +15 -0
- package/dist/ui/AlignMenu.js +64 -0
- package/dist/ui/CellStyleGroup.d.ts +15 -0
- package/dist/ui/CellStyleGroup.js +232 -0
- package/dist/ui/ColorPicker.d.ts +13 -0
- package/dist/ui/ColorPicker.js +165 -0
- package/dist/ui/CommentsPanel.d.ts +15 -0
- package/dist/ui/CommentsPanel.js +348 -0
- package/dist/ui/FontFamilySelect.d.ts +14 -0
- package/dist/ui/FontFamilySelect.js +59 -0
- package/dist/ui/FontSizeSelect.d.ts +11 -0
- package/dist/ui/FontSizeSelect.js +49 -0
- package/dist/ui/InsertImageButton.d.ts +9 -0
- package/dist/ui/InsertImageButton.js +47 -0
- package/dist/ui/LinkCard.d.ts +12 -0
- package/dist/ui/LinkCard.js +127 -0
- package/dist/ui/LinkPanel.d.ts +9 -0
- package/dist/ui/LinkPanel.js +121 -0
- package/dist/ui/MenuChoice.d.ts +11 -0
- package/dist/ui/MenuChoice.js +32 -0
- package/dist/ui/NotesPanel.d.ts +6 -0
- package/dist/ui/NotesPanel.js +33 -0
- package/dist/ui/ParagraphStyleSelect.d.ts +11 -0
- package/dist/ui/ParagraphStyleSelect.js +62 -0
- package/dist/ui/Popover.d.ts +22 -0
- package/dist/ui/Popover.js +74 -0
- package/dist/ui/SpacingMenu.d.ts +12 -0
- package/dist/ui/SpacingMenu.js +54 -0
- package/dist/ui/TableMenu.d.ts +12 -0
- package/dist/ui/TableMenu.js +112 -0
- package/dist/ui/TableSizePicker.d.ts +9 -0
- package/dist/ui/TableSizePicker.js +53 -0
- package/dist/ui/TextMenu.d.ts +15 -0
- package/dist/ui/TextMenu.js +194 -0
- package/dist/ui/Toolbar.d.ts +19 -0
- package/dist/ui/Toolbar.js +448 -0
- package/dist/ui/ToolbarButton.d.ts +23 -0
- package/dist/ui/ToolbarButton.js +56 -0
- package/dist/ui/Tooltip.d.ts +19 -0
- package/dist/ui/Tooltip.js +47 -0
- package/dist/ui/ZoomSelect.d.ts +7 -0
- package/dist/ui/ZoomSelect.js +44 -0
- package/dist/ui/comments/CommentComposer.d.ts +17 -0
- package/dist/ui/comments/CommentComposer.js +59 -0
- package/dist/ui/comments/useCommentRailLayout.d.ts +18 -0
- package/dist/ui/comments/useCommentRailLayout.js +183 -0
- package/dist/ui/keyboardWalk.d.ts +22 -0
- package/dist/ui/keyboardWalk.js +70 -0
- package/dist/ui/openAddress.d.ts +11 -0
- package/dist/ui/openAddress.js +16 -0
- package/dist/ui/panelPlacement.d.ts +51 -0
- package/dist/ui/panelPlacement.js +71 -0
- package/dist/ui/presets.d.ts +11 -0
- package/dist/ui/presets.js +0 -0
- package/dist/ui/rovingFocus.d.ts +20 -0
- package/dist/ui/rovingFocus.js +61 -0
- package/dist/ui/runCommand.d.ts +5 -0
- package/dist/ui/runCommand.js +13 -0
- package/dist/ui/useDismiss.d.ts +6 -0
- package/dist/ui/useDismiss.js +31 -0
- package/dist/ui/useFitWidthZoom.d.ts +2 -0
- package/dist/ui/useFitWidthZoom.js +26 -0
- package/dist/ui/useGridKeyboard.d.ts +12 -0
- package/dist/ui/useGridKeyboard.js +90 -0
- package/dist/ui/useMenuKeyboard.d.ts +12 -0
- package/dist/ui/useMenuKeyboard.js +56 -0
- package/dist/ui/zoom.d.ts +4 -0
- package/dist/ui/zoom.js +21 -0
- package/package.json +120 -0
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
// src/editor/commands/paragraphCommands.ts
|
|
2
|
+
import { layerRunFormat, styleIdOf } from "../../docx/formatting.js";
|
|
3
|
+
import {
|
|
4
|
+
withParagraphAlign,
|
|
5
|
+
withParagraphStyle
|
|
6
|
+
} from "../../docx/paraProps.js";
|
|
7
|
+
import { readRunProps } from "../../docx/runProps.js";
|
|
8
|
+
import {
|
|
9
|
+
toParagraphFormat
|
|
10
|
+
} from "../../model/format.js";
|
|
11
|
+
import { docxSchema } from "../../schema/index.js";
|
|
12
|
+
import { lockedMarkOf } from "../../schema/locks.js";
|
|
13
|
+
import { defaultParagraphStyleId, documentStyles } from "../documentStyles.js";
|
|
14
|
+
import {
|
|
15
|
+
editableParagraphs,
|
|
16
|
+
editParagraphs,
|
|
17
|
+
paragraphPPr,
|
|
18
|
+
selectedParagraphs
|
|
19
|
+
} from "../paragraphEdits.js";
|
|
20
|
+
function alignOf(node) {
|
|
21
|
+
return toParagraphFormat(node.attrs.format)?.align ?? "left";
|
|
22
|
+
}
|
|
23
|
+
function setParagraphAlign(align) {
|
|
24
|
+
return (state, dispatch) => editParagraphs(
|
|
25
|
+
state,
|
|
26
|
+
dispatch,
|
|
27
|
+
(node, styles, defaultStyleId) => (
|
|
28
|
+
// A paragraph already rendered with that alignment is left untouched, so its original XML survives
|
|
29
|
+
alignOf(node) === align ? null : withParagraphAlign(paragraphPPr(node), align, styles, defaultStyleId)
|
|
30
|
+
)
|
|
31
|
+
);
|
|
32
|
+
}
|
|
33
|
+
function canSetParagraphAlign(state) {
|
|
34
|
+
return editableParagraphs(state).length > 0;
|
|
35
|
+
}
|
|
36
|
+
function activeParagraphAlign(state) {
|
|
37
|
+
const aligns = selectedParagraphs(state).map(({ node }) => alignOf(node));
|
|
38
|
+
const first = aligns[0];
|
|
39
|
+
return first !== void 0 && aligns.every((align) => align === first) ? { kind: "shared", align: first } : { kind: "mixed" };
|
|
40
|
+
}
|
|
41
|
+
function text(value) {
|
|
42
|
+
return typeof value === "string" ? value : null;
|
|
43
|
+
}
|
|
44
|
+
function restyledMark(child, style) {
|
|
45
|
+
const mark = child.marks.find((entry) => entry.type === docxSchema.marks.run);
|
|
46
|
+
if (mark) {
|
|
47
|
+
const format2 = layerRunFormat(style, readRunProps(text(mark.attrs.rPr)));
|
|
48
|
+
return mark.type.create({ ...mark.attrs, format: format2 });
|
|
49
|
+
}
|
|
50
|
+
if (!child.isText) return null;
|
|
51
|
+
const format = layerRunFormat(style, null);
|
|
52
|
+
if (format === null) return null;
|
|
53
|
+
return docxSchema.marks.run.create({ rPr: null, rAttrs: null, format });
|
|
54
|
+
}
|
|
55
|
+
function restyledMarks(spot, style) {
|
|
56
|
+
const changes = [];
|
|
57
|
+
spot.node.forEach((child, offset) => {
|
|
58
|
+
if (lockedMarkOf(child)) return;
|
|
59
|
+
const mark = restyledMark(child, style);
|
|
60
|
+
if (!mark) return;
|
|
61
|
+
const from = spot.pos + 1 + offset;
|
|
62
|
+
changes.push({ from, to: from + child.nodeSize, mark });
|
|
63
|
+
});
|
|
64
|
+
return changes;
|
|
65
|
+
}
|
|
66
|
+
function writeStyleChanges(state, changed) {
|
|
67
|
+
const tr = state.tr;
|
|
68
|
+
for (const { spot, props, marks } of changed) {
|
|
69
|
+
tr.setNodeMarkup(tr.mapping.map(spot.pos), void 0, {
|
|
70
|
+
...spot.node.attrs,
|
|
71
|
+
pPr: props.pPr,
|
|
72
|
+
format: props.format,
|
|
73
|
+
styleRun: props.styleRun
|
|
74
|
+
});
|
|
75
|
+
for (const change of marks) {
|
|
76
|
+
tr.addMark(change.from, change.to, change.mark);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
return tr;
|
|
80
|
+
}
|
|
81
|
+
function setParagraphStyle(styleId) {
|
|
82
|
+
return (state, dispatch) => {
|
|
83
|
+
const styles = documentStyles(state);
|
|
84
|
+
const defaultStyleId = defaultParagraphStyleId(state);
|
|
85
|
+
const changed = editableParagraphs(state).flatMap((spot) => {
|
|
86
|
+
const pPr = paragraphPPr(spot.node);
|
|
87
|
+
if (styleIdOf(pPr) === styleId) return [];
|
|
88
|
+
const props = withParagraphStyle(pPr, styleId, styles, defaultStyleId);
|
|
89
|
+
if (!props) return [];
|
|
90
|
+
return [
|
|
91
|
+
{ spot, props, marks: restyledMarks(spot, props.styleRun ?? {}) }
|
|
92
|
+
];
|
|
93
|
+
});
|
|
94
|
+
if (changed.length === 0) return false;
|
|
95
|
+
if (dispatch) dispatch(writeStyleChanges(state, changed).scrollIntoView());
|
|
96
|
+
return true;
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
function activeParagraphStyle(state) {
|
|
100
|
+
const ids = selectedParagraphs(state).map(
|
|
101
|
+
({ node }) => styleIdOf(paragraphPPr(node))
|
|
102
|
+
);
|
|
103
|
+
if (ids.length === 0) return { kind: "none" };
|
|
104
|
+
const first = ids[0] ?? null;
|
|
105
|
+
return ids.every((id) => id === first) ? { kind: "shared", styleId: first } : { kind: "mixed" };
|
|
106
|
+
}
|
|
107
|
+
export {
|
|
108
|
+
activeParagraphAlign,
|
|
109
|
+
activeParagraphStyle,
|
|
110
|
+
canSetParagraphAlign,
|
|
111
|
+
setParagraphAlign,
|
|
112
|
+
setParagraphStyle
|
|
113
|
+
};
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The line spacing of a paragraph.
|
|
3
|
+
*
|
|
4
|
+
* It is set to one of the presets the toolbar offers.
|
|
5
|
+
* All XML handling belongs to `docx/paraProps`; this file only decides which paragraphs to
|
|
6
|
+
* change and to what.
|
|
7
|
+
*/
|
|
8
|
+
import type { Command, EditorState } from "prosemirror-state";
|
|
9
|
+
import { type LineSpacing } from "../../model/format";
|
|
10
|
+
/** One line of text, which is what a paragraph nobody gave a line spacing is drawn with */
|
|
11
|
+
export declare const SINGLE_LINE_SPACING: LineSpacing;
|
|
12
|
+
/**
|
|
13
|
+
* Sets the line spacing of the selected paragraphs.
|
|
14
|
+
* A paragraph already drawn with that spacing is left untouched, so its original XML survives.
|
|
15
|
+
*/
|
|
16
|
+
export declare function setLineSpacing(spacing: LineSpacing): Command;
|
|
17
|
+
/** The line spacing the selected paragraphs share. Null when several spacings are mixed or nothing is selected */
|
|
18
|
+
export declare function activeLineSpacing(state: EditorState): LineSpacing | null;
|
|
19
|
+
/**
|
|
20
|
+
* Whether the selection holds a paragraph to space out at all. The toolbar disables the menu when it
|
|
21
|
+
* holds none, a selection the lock leaves nothing of included (`editor/paragraphEdits`)
|
|
22
|
+
*/
|
|
23
|
+
export declare function canSetLineSpacing(state: EditorState): boolean;
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
// src/editor/commands/spacingCommands.ts
|
|
2
|
+
import { withLineSpacing } from "../../docx/paraProps.js";
|
|
3
|
+
import {
|
|
4
|
+
toParagraphFormat
|
|
5
|
+
} from "../../model/format.js";
|
|
6
|
+
import { documentDefaults } from "../documentStyles.js";
|
|
7
|
+
import {
|
|
8
|
+
editableParagraphs,
|
|
9
|
+
editParagraphs,
|
|
10
|
+
paragraphPPr,
|
|
11
|
+
selectedParagraphs
|
|
12
|
+
} from "../paragraphEdits.js";
|
|
13
|
+
var SINGLE_LINE_SPACING = { rule: "auto", lines: 1 };
|
|
14
|
+
function lineSpacingOf(node, defaults) {
|
|
15
|
+
return toParagraphFormat(node.attrs.format)?.lineSpacing ?? defaults.lineSpacing ?? SINGLE_LINE_SPACING;
|
|
16
|
+
}
|
|
17
|
+
function sameLineSpacing(a, b) {
|
|
18
|
+
if (a.rule === "auto") return b.rule === "auto" && a.lines === b.lines;
|
|
19
|
+
return b.rule === a.rule && a.pt === b.pt;
|
|
20
|
+
}
|
|
21
|
+
function setLineSpacing(spacing) {
|
|
22
|
+
return (state, dispatch) => {
|
|
23
|
+
const defaults = documentDefaults(state);
|
|
24
|
+
return editParagraphs(
|
|
25
|
+
state,
|
|
26
|
+
dispatch,
|
|
27
|
+
(node, styles, defaultStyleId) => sameLineSpacing(lineSpacingOf(node, defaults), spacing) ? null : withLineSpacing(paragraphPPr(node), spacing, styles, defaultStyleId)
|
|
28
|
+
);
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
function activeLineSpacing(state) {
|
|
32
|
+
const defaults = documentDefaults(state);
|
|
33
|
+
const spacings = selectedParagraphs(state).map(
|
|
34
|
+
({ node }) => lineSpacingOf(node, defaults)
|
|
35
|
+
);
|
|
36
|
+
const first = spacings[0];
|
|
37
|
+
if (!first) return null;
|
|
38
|
+
return spacings.every((spacing) => sameLineSpacing(spacing, first)) ? first : null;
|
|
39
|
+
}
|
|
40
|
+
function canSetLineSpacing(state) {
|
|
41
|
+
return editableParagraphs(state).length > 0;
|
|
42
|
+
}
|
|
43
|
+
export {
|
|
44
|
+
SINGLE_LINE_SPACING,
|
|
45
|
+
activeLineSpacing,
|
|
46
|
+
canSetLineSpacing,
|
|
47
|
+
setLineSpacing
|
|
48
|
+
};
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { type Command } from "prosemirror-state";
|
|
2
|
+
/** Inserts an editable OOXML tab in an ordinary paragraph. */
|
|
3
|
+
export declare const insertTab: Command;
|
|
4
|
+
/** Moves one logical text position only when that position contains a tab. */
|
|
5
|
+
export declare function moveAcrossTab(visualDirection: "left" | "right", extend: boolean): Command;
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
// src/editor/commands/tabCommands.ts
|
|
2
|
+
import {
|
|
3
|
+
TextSelection
|
|
4
|
+
} from "prosemirror-state";
|
|
5
|
+
import { toParagraphFormat } from "../../model/format.js";
|
|
6
|
+
import { docxSchema } from "../../schema/index.js";
|
|
7
|
+
import { replacementShut } from "../../schema/locks.js";
|
|
8
|
+
function isOrdinaryParagraph(state) {
|
|
9
|
+
const { $from } = state.selection;
|
|
10
|
+
if ($from.parent.type !== docxSchema.nodes.paragraph || toParagraphFormat($from.parent.attrs.format)?.numbering) {
|
|
11
|
+
return false;
|
|
12
|
+
}
|
|
13
|
+
for (let depth = $from.depth - 1; depth > 0; depth -= 1) {
|
|
14
|
+
if ($from.node(depth).type.spec.tableRole === "cell") return false;
|
|
15
|
+
}
|
|
16
|
+
return true;
|
|
17
|
+
}
|
|
18
|
+
var insertTab = (state, dispatch) => {
|
|
19
|
+
const { selection } = state;
|
|
20
|
+
if (!(selection instanceof TextSelection) || !selection.$from.sameParent(selection.$to) || !isOrdinaryParagraph(state) || replacementShut(selection, state.doc)) {
|
|
21
|
+
return false;
|
|
22
|
+
}
|
|
23
|
+
if (dispatch) {
|
|
24
|
+
const inherited = state.storedMarks ?? (selection.empty ? selection.$from.marks() : selection.$from.marksAcross(selection.$to) ?? []);
|
|
25
|
+
const marks = inherited.filter(
|
|
26
|
+
(mark) => mark.type !== docxSchema.marks.tab
|
|
27
|
+
);
|
|
28
|
+
const tab = docxSchema.text(
|
|
29
|
+
" ",
|
|
30
|
+
docxSchema.marks.tab.create().addToSet(marks)
|
|
31
|
+
);
|
|
32
|
+
dispatch(state.tr.replaceSelectionWith(tab, false).scrollIntoView());
|
|
33
|
+
}
|
|
34
|
+
return true;
|
|
35
|
+
};
|
|
36
|
+
function moveAcrossTab(visualDirection, extend) {
|
|
37
|
+
return (state, dispatch) => {
|
|
38
|
+
const { selection } = state;
|
|
39
|
+
if (!(selection instanceof TextSelection) || !extend && !selection.empty) {
|
|
40
|
+
return false;
|
|
41
|
+
}
|
|
42
|
+
const { $head } = selection;
|
|
43
|
+
if ($head.parent.type !== docxSchema.nodes.paragraph) return false;
|
|
44
|
+
const rtl = toParagraphFormat($head.parent.attrs.format)?.direction === "rtl";
|
|
45
|
+
const forward = visualDirection === "right" ? !rtl : rtl;
|
|
46
|
+
const delta = forward ? 1 : -1;
|
|
47
|
+
const nextOffset = $head.parentOffset + delta;
|
|
48
|
+
if (nextOffset < 0 || nextOffset > $head.parent.content.size) return false;
|
|
49
|
+
const from = delta > 0 ? $head.pos : $head.pos - 1;
|
|
50
|
+
if (state.doc.textBetween(from, from + 1, "", "") !== " ") return false;
|
|
51
|
+
if (dispatch) {
|
|
52
|
+
const anchor = extend ? selection.anchor : $head.pos + delta;
|
|
53
|
+
dispatch(
|
|
54
|
+
state.tr.setSelection(
|
|
55
|
+
TextSelection.create(state.doc, anchor, $head.pos + delta)
|
|
56
|
+
).scrollIntoView()
|
|
57
|
+
);
|
|
58
|
+
}
|
|
59
|
+
return true;
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
export {
|
|
63
|
+
insertTab,
|
|
64
|
+
moveAcrossTab
|
|
65
|
+
};
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* This file knows nothing about zip or XML. All it knows is the document model and the screen.
|
|
3
|
+
*/
|
|
4
|
+
import type { Node as PMNode } from "prosemirror-model";
|
|
5
|
+
import { EditorState, type Plugin } from "prosemirror-state";
|
|
6
|
+
import { EditorView } from "prosemirror-view";
|
|
7
|
+
import { type ParagraphFormatLayer, type ParagraphStyleOption, type StyleTable } from "../docx/formatting";
|
|
8
|
+
import { type PageGeometry } from "../docx/pageGeometry";
|
|
9
|
+
import type { DocumentDefaults } from "../model/format";
|
|
10
|
+
import { type Numbering } from "../numbering/parseNumbering";
|
|
11
|
+
import { type FontFallbacks } from "../styles/fontStack";
|
|
12
|
+
export interface EditorStateOptions {
|
|
13
|
+
numbering?: Numbering;
|
|
14
|
+
styles?: StyleTable;
|
|
15
|
+
defaults?: DocumentDefaults;
|
|
16
|
+
/** Paragraph properties from styles.xml docDefaults. */
|
|
17
|
+
paragraphDefaults?: ParagraphFormatLayer;
|
|
18
|
+
/**
|
|
19
|
+
* Whether the document has a place (numbering.xml) to write the definition of a new list.
|
|
20
|
+
* Callers that build a state without opening a document assume that place exists and behave
|
|
21
|
+
* as they do today.
|
|
22
|
+
*/
|
|
23
|
+
canStartNewList?: boolean;
|
|
24
|
+
/** The plugins handed in from outside the package */
|
|
25
|
+
consumerPlugins?: readonly Plugin[];
|
|
26
|
+
/** The styles the document defines for the style picker to offer */
|
|
27
|
+
paragraphStyles?: ParagraphStyleOption[];
|
|
28
|
+
/**
|
|
29
|
+
* Whether the right click is the editor's own. Turned off, the browser's own menu is never
|
|
30
|
+
* taken away, which is what a consumer drawing menus of its own needs.
|
|
31
|
+
*/
|
|
32
|
+
contextMenus?: boolean;
|
|
33
|
+
/** The paper the document names. A4 where a document names none */
|
|
34
|
+
geometry?: PageGeometry;
|
|
35
|
+
/** The interval between automatic tab stops, in points. */
|
|
36
|
+
defaultTabStopPt?: number;
|
|
37
|
+
/** Every id already present in the opened Comments part, including unreferenced entries. */
|
|
38
|
+
reservedCommentIds?: Iterable<string>;
|
|
39
|
+
/** Every paragraph id present in the opened comment parts, including orphan extension entries. */
|
|
40
|
+
reservedCommentParaIds?: Iterable<string>;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Creates a single editing state.
|
|
44
|
+
* The list definitions, the style table, and the document defaults are what the document
|
|
45
|
+
* wrote down, and commands and the toolbar read them through plugins.
|
|
46
|
+
*/
|
|
47
|
+
export declare function createEditorState(doc: PMNode, { numbering, styles, defaults, paragraphDefaults, canStartNewList, consumerPlugins, paragraphStyles, contextMenus, geometry, defaultTabStopPt, reservedCommentIds, reservedCommentParaIds, }?: EditorStateOptions): EditorState;
|
|
48
|
+
export interface EditorOptions {
|
|
49
|
+
mount: HTMLElement;
|
|
50
|
+
state: EditorState;
|
|
51
|
+
defaults: DocumentDefaults;
|
|
52
|
+
/** The paper the document names. The sheet is drawn from it, A4 where a document names none */
|
|
53
|
+
geometry?: PageGeometry;
|
|
54
|
+
readOnly: boolean;
|
|
55
|
+
/** The fonts stood in for the ones the document declares. The built-in set when none is given */
|
|
56
|
+
fontFallbacks?: FontFallbacks;
|
|
57
|
+
onStateChange: (state: EditorState) => void;
|
|
58
|
+
}
|
|
59
|
+
export declare function createEditorView({ mount, state, defaults, geometry, readOnly, fontFallbacks, onStateChange, }: EditorOptions): EditorView;
|
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
// src/editor/createEditor.ts
|
|
2
|
+
import { baseKeymap } from "prosemirror-commands";
|
|
3
|
+
import { dropCursor } from "prosemirror-dropcursor";
|
|
4
|
+
import { history } from "prosemirror-history";
|
|
5
|
+
import { keymap } from "prosemirror-keymap";
|
|
6
|
+
import { EditorState } from "prosemirror-state";
|
|
7
|
+
import { tableEditing } from "prosemirror-tables";
|
|
8
|
+
import { EditorView } from "prosemirror-view";
|
|
9
|
+
import { DEFAULT_TAB_STOP_PT } from "../docx/documentSettings.js";
|
|
10
|
+
import {
|
|
11
|
+
NO_DOCUMENT_DEFAULTS,
|
|
12
|
+
NO_STYLES
|
|
13
|
+
} from "../docx/formatting.js";
|
|
14
|
+
import { A4_PORTRAIT } from "../docx/pageGeometry.js";
|
|
15
|
+
import { EMPTY_NUMBERING } from "../numbering/parseNumbering.js";
|
|
16
|
+
import { pageDecorations } from "../page/pageDecorations.js";
|
|
17
|
+
import { pageGeometryStyle, pagePixels } from "../page/pageLayout.js";
|
|
18
|
+
import { editorClassNames } from "../styles/classNames.js";
|
|
19
|
+
import {
|
|
20
|
+
DEFAULT_FONT_FALLBACKS
|
|
21
|
+
} from "../styles/fontStack.js";
|
|
22
|
+
import { documentDefaultsStyle } from "../styles/inlineStyle.js";
|
|
23
|
+
import { gridBorders, withDerivedGridBorders } from "../table/gridBorders.js";
|
|
24
|
+
import { documentDefaultTabStopPt, documentStyleTable } from "./documentStyles.js";
|
|
25
|
+
import { externalClipboard } from "./externalClipboard.js";
|
|
26
|
+
import { imageFiles } from "./imageFiles.js";
|
|
27
|
+
import { bookmarkProtection } from "./plugins/bookmarkProtection.js";
|
|
28
|
+
import { columnResize } from "./plugins/columnResize.js";
|
|
29
|
+
import { commentDecorations } from "./plugins/commentDecorations.js";
|
|
30
|
+
import { commentReservations } from "./plugins/commentReservations.js";
|
|
31
|
+
import { imagePaste } from "./plugins/imagePaste.js";
|
|
32
|
+
import { docxKeymap } from "./plugins/keymap.js";
|
|
33
|
+
import { linkPanel } from "./plugins/linkPanel.js";
|
|
34
|
+
import { listInputRules } from "./plugins/listInputRules.js";
|
|
35
|
+
import { lockedContent } from "./plugins/lockedContent.js";
|
|
36
|
+
import { noteProtection } from "./plugins/noteProtection.js";
|
|
37
|
+
import { numberingMarkers } from "./plugins/numberingDecorations.js";
|
|
38
|
+
import { rowResize } from "./plugins/rowResize.js";
|
|
39
|
+
import { styledParagraphs } from "./plugins/styledParagraphs.js";
|
|
40
|
+
import { tabCaret } from "./plugins/tabCaret.js";
|
|
41
|
+
import { tabDecorations } from "./plugins/tabDecorations.js";
|
|
42
|
+
import { tabLayout } from "./plugins/tabLayout.js";
|
|
43
|
+
import { tableContextMenu } from "./plugins/tableContextMenu.js";
|
|
44
|
+
import { tabPointer } from "./plugins/tabPointer.js";
|
|
45
|
+
import { textContextMenu } from "./plugins/textContextMenu.js";
|
|
46
|
+
import { ImageNodeView } from "./views/imageResize.js";
|
|
47
|
+
import { runMarkView } from "./views/runMarkView.js";
|
|
48
|
+
function createEditorState(doc, {
|
|
49
|
+
numbering = EMPTY_NUMBERING,
|
|
50
|
+
styles = NO_STYLES,
|
|
51
|
+
defaults = NO_DOCUMENT_DEFAULTS,
|
|
52
|
+
paragraphDefaults = {},
|
|
53
|
+
canStartNewList = true,
|
|
54
|
+
consumerPlugins = [],
|
|
55
|
+
paragraphStyles = [],
|
|
56
|
+
contextMenus = true,
|
|
57
|
+
geometry = A4_PORTRAIT,
|
|
58
|
+
defaultTabStopPt = DEFAULT_TAB_STOP_PT,
|
|
59
|
+
reservedCommentIds = [],
|
|
60
|
+
reservedCommentParaIds = []
|
|
61
|
+
} = {}) {
|
|
62
|
+
return EditorState.create({
|
|
63
|
+
doc: withDerivedGridBorders(doc),
|
|
64
|
+
plugins: [
|
|
65
|
+
// Consumer plugins lead the array. ProseMirror walks the plugins in order and takes the
|
|
66
|
+
// first answer for a keypress, a paste, a drop or any other DOM event, so this is the
|
|
67
|
+
// only place from which a consumer handler can win over the built-in one.
|
|
68
|
+
...consumerPlugins,
|
|
69
|
+
// Refuses every edit inside a locked content control, whoever asked for it. It is not
|
|
70
|
+
// optional: a document that locked a part of itself stays locked in every consumer.
|
|
71
|
+
lockedContent(),
|
|
72
|
+
// Bookmark ranges are preserved rather than edited, so neither half may disappear.
|
|
73
|
+
bookmarkProtection(),
|
|
74
|
+
// Note bodies are display-only, so their imported main-story references stay paired.
|
|
75
|
+
noteProtection(),
|
|
76
|
+
// An orphan Comments-part entry still owns its id and must not be replaced by a new comment.
|
|
77
|
+
commentReservations(reservedCommentIds, reservedCommentParaIds),
|
|
78
|
+
history(),
|
|
79
|
+
keymap(docxKeymap),
|
|
80
|
+
keymap(baseKeymap),
|
|
81
|
+
// Holds whether the link panel is open, which Cmd+K above and the toolbar button both set
|
|
82
|
+
linkPanel(),
|
|
83
|
+
// Turns a typed list prefix ("1. ", "- ") into a list. Backspace, bound in `docxKeymap`
|
|
84
|
+
// above, is what takes such a conversion back
|
|
85
|
+
listInputRules(),
|
|
86
|
+
dropCursor(),
|
|
87
|
+
// Clipboard priority is files, resolvable HTML images, then regular HTML or plain text.
|
|
88
|
+
imageFiles(),
|
|
89
|
+
imagePaste(),
|
|
90
|
+
externalClipboard(),
|
|
91
|
+
// A press that grabs a table edge must be intercepted before a cell-selection drag starts.
|
|
92
|
+
// For DOM events the plugin registered first wins, so both resizers precede `tableEditing`.
|
|
93
|
+
columnResize(),
|
|
94
|
+
rowResize(),
|
|
95
|
+
tableEditing(),
|
|
96
|
+
// Comment anchors live in the model; this paints their ranges without changing document XML.
|
|
97
|
+
commentDecorations(),
|
|
98
|
+
// Adjacent text tabs still need separate DOM ranges for layout and pointer selection.
|
|
99
|
+
tabDecorations(),
|
|
100
|
+
tabPointer(),
|
|
101
|
+
tabLayout(),
|
|
102
|
+
tabCaret(),
|
|
103
|
+
// Keeps table-cell lines aligned with OOXML precedence after an edit
|
|
104
|
+
gridBorders(),
|
|
105
|
+
// Reads the document's styles into the paragraphs an edit built from nothing
|
|
106
|
+
styledParagraphs(),
|
|
107
|
+
// Receiving a right-click means taking the browser's own menu away, so both of these stand
|
|
108
|
+
// or fall together with the menus the editor draws. The text menu stands ahead of the table
|
|
109
|
+
// menu, and hands a click with nothing selected inside a cell back to it
|
|
110
|
+
...contextMenus ? [textContextMenu(), tableContextMenu()] : [],
|
|
111
|
+
numberingMarkers(numbering, canStartNewList),
|
|
112
|
+
// Values only go in when page display is turned on
|
|
113
|
+
pageDecorations(),
|
|
114
|
+
documentStyleTable(
|
|
115
|
+
styles,
|
|
116
|
+
defaults,
|
|
117
|
+
paragraphStyles,
|
|
118
|
+
geometry,
|
|
119
|
+
paragraphDefaults,
|
|
120
|
+
numbering,
|
|
121
|
+
defaultTabStopPt
|
|
122
|
+
)
|
|
123
|
+
]
|
|
124
|
+
});
|
|
125
|
+
}
|
|
126
|
+
function createEditorView({
|
|
127
|
+
mount,
|
|
128
|
+
state,
|
|
129
|
+
defaults,
|
|
130
|
+
geometry = A4_PORTRAIT,
|
|
131
|
+
readOnly,
|
|
132
|
+
fontFallbacks = DEFAULT_FONT_FALLBACKS,
|
|
133
|
+
onStateChange
|
|
134
|
+
}) {
|
|
135
|
+
const view = new EditorView(mount, {
|
|
136
|
+
state,
|
|
137
|
+
editable: () => !readOnly,
|
|
138
|
+
attributes: {
|
|
139
|
+
class: editorClassNames.sheet,
|
|
140
|
+
// The paper first, so a document that names one is drawn on it from the first frame
|
|
141
|
+
style: `${pageGeometryStyle(pagePixels(geometry))};${documentDefaultsStyle(defaults, fontFallbacks)};tab-size:${documentDefaultTabStopPt(state)}pt`
|
|
142
|
+
},
|
|
143
|
+
// The schema can only draw a run with the default fallback fonts, so this editor draws its own
|
|
144
|
+
markViews: { run: runMarkView(fontFallbacks) },
|
|
145
|
+
// An image is drawn by a view of its own, which is what carries the resize handles
|
|
146
|
+
nodeViews: {
|
|
147
|
+
image: (node, imageView, getPos) => new ImageNodeView(node, imageView, getPos)
|
|
148
|
+
},
|
|
149
|
+
dispatchTransaction(transaction) {
|
|
150
|
+
const next = view.state.apply(transaction);
|
|
151
|
+
view.updateState(next);
|
|
152
|
+
onStateChange(next);
|
|
153
|
+
}
|
|
154
|
+
});
|
|
155
|
+
return view;
|
|
156
|
+
}
|
|
157
|
+
export {
|
|
158
|
+
createEditorState,
|
|
159
|
+
createEditorView
|
|
160
|
+
};
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Brings what the document laid down into the editor: what styles.xml told us, and the paper it
|
|
3
|
+
* is written on.
|
|
4
|
+
*
|
|
5
|
+
* Commands and the toolbar know nothing about the session, so this plugin holds all of it on
|
|
6
|
+
* their behalf: deriving the display values again after a formatting edit needs the values the
|
|
7
|
+
* style laid down, the toolbar needs the size a run is rendered at where nobody wrote a size
|
|
8
|
+
* down, and a new table is fitted to the width of the body the paper leaves.
|
|
9
|
+
* The values are fixed the moment the document is opened and do not change while editing.
|
|
10
|
+
*/
|
|
11
|
+
import { type EditorState, Plugin } from "prosemirror-state";
|
|
12
|
+
import { type ParagraphFormatLayer, type ParagraphFormattingContext, type ParagraphStyleOption, type StyleTable } from "../docx/formatting";
|
|
13
|
+
import { type PageGeometry } from "../docx/pageGeometry";
|
|
14
|
+
import type { DocumentDefaults } from "../model/format";
|
|
15
|
+
import { type Numbering } from "../numbering/parseNumbering";
|
|
16
|
+
/** Values that apply to the whole document */
|
|
17
|
+
interface DocumentInfo {
|
|
18
|
+
styles: StyleTable;
|
|
19
|
+
defaults: DocumentDefaults;
|
|
20
|
+
paragraphDefaults: ParagraphFormatLayer;
|
|
21
|
+
numbering: Numbering;
|
|
22
|
+
paragraphStyles: ParagraphStyleOption[];
|
|
23
|
+
/** The paper the document is written on, which decides the width a new table is fitted to */
|
|
24
|
+
geometry: PageGeometry;
|
|
25
|
+
/** The distance between automatic tab stops when no custom stop applies. */
|
|
26
|
+
defaultTabStopPt: number;
|
|
27
|
+
}
|
|
28
|
+
/** This document's style table. Empty when the editor does not know the table */
|
|
29
|
+
export declare function documentStyles(state: EditorState): StyleTable;
|
|
30
|
+
/** The default formatting this document wrote down. When the editor does not know it, it is the same as nothing being specified */
|
|
31
|
+
export declare function documentDefaults(state: EditorState): DocumentDefaults;
|
|
32
|
+
/** The values required to resolve the OOXML paragraph-property hierarchy. */
|
|
33
|
+
export declare function documentParagraphFormatting(state: EditorState): ParagraphFormattingContext;
|
|
34
|
+
/** The paragraph styles this document defines. Empty when the editor does not know them */
|
|
35
|
+
export declare function documentParagraphStyles(state: EditorState): ParagraphStyleOption[];
|
|
36
|
+
/**
|
|
37
|
+
* The style a paragraph pointing at none of its own wears (`w:default="1"`). Null when the
|
|
38
|
+
* document marks none.
|
|
39
|
+
*
|
|
40
|
+
* It is the style the list of them marks, of which `readParagraphStyles` leaves exactly one.
|
|
41
|
+
*/
|
|
42
|
+
export declare function defaultParagraphStyleId(state: EditorState): string | null;
|
|
43
|
+
/**
|
|
44
|
+
* The paper the document is written on. A document the editor knows no paper for is drawn on
|
|
45
|
+
* the same A4 every document was drawn on before the geometry was read
|
|
46
|
+
*/
|
|
47
|
+
export declare function documentGeometry(state: EditorState): PageGeometry;
|
|
48
|
+
/** The document-wide interval between automatic tab stops, in points. */
|
|
49
|
+
export declare function documentDefaultTabStopPt(state: EditorState): number;
|
|
50
|
+
/**
|
|
51
|
+
* The width one line of body text occupies on this document's paper, in pixels.
|
|
52
|
+
*
|
|
53
|
+
* It is the width an image wider than the page is shrunk to, so a caller inserting an image
|
|
54
|
+
* itself asks for it rather than taking the A4 width `fittedExtent` falls back to.
|
|
55
|
+
*/
|
|
56
|
+
export declare function documentBodyWidthPx(state: EditorState): number;
|
|
57
|
+
/** The height one page of body content occupies, in pixels. */
|
|
58
|
+
export declare function documentBodyHeightPx(state: EditorState): number;
|
|
59
|
+
export declare function documentStyleTable(styles: StyleTable, defaults?: DocumentDefaults, paragraphStyles?: ParagraphStyleOption[], geometry?: PageGeometry, paragraphDefaults?: ParagraphFormatLayer, numbering?: Numbering, defaultTabStopPt?: number): Plugin<DocumentInfo>;
|
|
60
|
+
export {};
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
// src/editor/documentStyles.ts
|
|
2
|
+
import { Plugin, PluginKey } from "prosemirror-state";
|
|
3
|
+
import { DEFAULT_TAB_STOP_PT } from "../docx/documentSettings.js";
|
|
4
|
+
import {
|
|
5
|
+
NO_DOCUMENT_DEFAULTS,
|
|
6
|
+
NO_PARAGRAPH_FORMATTING,
|
|
7
|
+
NO_STYLES
|
|
8
|
+
} from "../docx/formatting.js";
|
|
9
|
+
import {
|
|
10
|
+
A4_PORTRAIT,
|
|
11
|
+
bodyHeightTwips,
|
|
12
|
+
bodyWidth,
|
|
13
|
+
twipsToPx
|
|
14
|
+
} from "../docx/pageGeometry.js";
|
|
15
|
+
import { EMPTY_NUMBERING } from "../numbering/parseNumbering.js";
|
|
16
|
+
var NO_PARAGRAPH_STYLES = [];
|
|
17
|
+
var documentKey = new PluginKey("docxEditorDocument");
|
|
18
|
+
function documentStyles(state) {
|
|
19
|
+
return documentKey.getState(state)?.styles ?? NO_STYLES;
|
|
20
|
+
}
|
|
21
|
+
function documentDefaults(state) {
|
|
22
|
+
return documentKey.getState(state)?.defaults ?? NO_DOCUMENT_DEFAULTS;
|
|
23
|
+
}
|
|
24
|
+
function documentParagraphFormatting(state) {
|
|
25
|
+
const info = documentKey.getState(state);
|
|
26
|
+
if (!info) return NO_PARAGRAPH_FORMATTING;
|
|
27
|
+
return {
|
|
28
|
+
styles: info.styles,
|
|
29
|
+
defaultStyleId: info.paragraphStyles.find((style) => style.isDefault)?.id ?? null,
|
|
30
|
+
defaults: info.paragraphDefaults,
|
|
31
|
+
numbering: info.numbering
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
function documentParagraphStyles(state) {
|
|
35
|
+
return documentKey.getState(state)?.paragraphStyles ?? NO_PARAGRAPH_STYLES;
|
|
36
|
+
}
|
|
37
|
+
function defaultParagraphStyleId(state) {
|
|
38
|
+
return documentParagraphStyles(state).find((style) => style.isDefault)?.id ?? null;
|
|
39
|
+
}
|
|
40
|
+
function documentGeometry(state) {
|
|
41
|
+
return documentKey.getState(state)?.geometry ?? A4_PORTRAIT;
|
|
42
|
+
}
|
|
43
|
+
function documentDefaultTabStopPt(state) {
|
|
44
|
+
return documentKey.getState(state)?.defaultTabStopPt ?? DEFAULT_TAB_STOP_PT;
|
|
45
|
+
}
|
|
46
|
+
function documentBodyWidthPx(state) {
|
|
47
|
+
return bodyWidth(documentGeometry(state)).px;
|
|
48
|
+
}
|
|
49
|
+
function documentBodyHeightPx(state) {
|
|
50
|
+
return twipsToPx(bodyHeightTwips(documentGeometry(state)));
|
|
51
|
+
}
|
|
52
|
+
function documentStyleTable(styles, defaults = NO_DOCUMENT_DEFAULTS, paragraphStyles = NO_PARAGRAPH_STYLES, geometry = A4_PORTRAIT, paragraphDefaults = {}, numbering = EMPTY_NUMBERING, defaultTabStopPt = DEFAULT_TAB_STOP_PT) {
|
|
53
|
+
return new Plugin({
|
|
54
|
+
key: documentKey,
|
|
55
|
+
state: {
|
|
56
|
+
init: () => ({
|
|
57
|
+
styles,
|
|
58
|
+
defaults,
|
|
59
|
+
paragraphDefaults,
|
|
60
|
+
numbering,
|
|
61
|
+
paragraphStyles,
|
|
62
|
+
geometry,
|
|
63
|
+
defaultTabStopPt
|
|
64
|
+
}),
|
|
65
|
+
apply: (_tr, current) => current
|
|
66
|
+
}
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
export {
|
|
70
|
+
defaultParagraphStyleId,
|
|
71
|
+
documentBodyHeightPx,
|
|
72
|
+
documentBodyWidthPx,
|
|
73
|
+
documentDefaultTabStopPt,
|
|
74
|
+
documentDefaults,
|
|
75
|
+
documentGeometry,
|
|
76
|
+
documentParagraphFormatting,
|
|
77
|
+
documentParagraphStyles,
|
|
78
|
+
documentStyleTable,
|
|
79
|
+
documentStyles
|
|
80
|
+
};
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { Slice } from "prosemirror-model";
|
|
2
|
+
import { type EditorState, Plugin } from "prosemirror-state";
|
|
3
|
+
import type { EditorView } from "prosemirror-view";
|
|
4
|
+
import type { ImageToInsert } from "./insertImage";
|
|
5
|
+
export declare function richHtmlSlice(state: EditorState, document: Document, source: string, images?: ReadonlyMap<string, ImageToInsert>): Slice | null;
|
|
6
|
+
export declare function insertRichHtml(view: EditorView, source: string): boolean;
|
|
7
|
+
export declare function insertClipboardData(view: EditorView, data: {
|
|
8
|
+
html?: string;
|
|
9
|
+
text?: string;
|
|
10
|
+
}): void;
|
|
11
|
+
export declare function externalClipboard(): Plugin;
|