@portone/docx-editor 0.4.0 → 0.5.1
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 +201 -0
- package/CONTRIBUTING.md +2 -0
- package/assets/editor.png +0 -0
- package/dist/DocxEditor.d.ts +1 -1
- package/dist/DocxEditor.js +44 -25
- package/dist/docx/cloning.js +4 -9
- package/dist/docx/commentOnlyChange.d.ts +5 -3
- package/dist/docx/comments/grammar.d.ts +27 -10
- package/dist/docx/comments/grammar.js +18 -67
- package/dist/docx/comments/model.d.ts +5 -6
- package/dist/docx/comments/model.js +0 -9
- package/dist/docx/comments/parts.d.ts +16 -10
- package/dist/docx/comments/parts.js +65 -13
- package/dist/docx/comments/people.d.ts +11 -3
- package/dist/docx/comments/people.js +20 -6
- package/dist/docx/comments/policy.js +7 -1
- package/dist/docx/comments/reading.d.ts +4 -2
- package/dist/docx/comments/reading.js +1 -14
- package/dist/docx/comments/writing.js +65 -28
- package/dist/docx/exportDocx.js +10 -14
- package/dist/docx/exportRefs.d.ts +8 -3
- package/dist/docx/exportRefs.js +2 -1
- package/dist/docx/fidelity.js +24 -10
- package/dist/docx/fields.d.ts +42 -0
- package/dist/docx/fields.js +76 -0
- package/dist/docx/formatting/styles.d.ts +0 -2
- package/dist/docx/formatting/styles.js +2 -15
- package/dist/docx/headersFooters.d.ts +89 -20
- package/dist/docx/headersFooters.js +163 -172
- package/dist/docx/identities.js +17 -26
- package/dist/docx/importDocx.d.ts +1 -1
- package/dist/docx/importDocx.js +100 -48
- package/dist/docx/importParagraph.d.ts +18 -5
- package/dist/docx/importParagraph.js +75 -128
- package/dist/docx/importPolicy.d.ts +70 -0
- package/dist/docx/importPolicy.js +195 -0
- package/dist/docx/importPreserved.d.ts +30 -0
- package/dist/docx/importPreserved.js +54 -0
- package/dist/docx/importTable.js +56 -12
- package/dist/docx/invariants.js +16 -18
- package/dist/docx/notes.d.ts +6 -1
- package/dist/docx/notes.js +6 -16
- package/dist/docx/pageGeometry.d.ts +5 -14
- package/dist/docx/pageGeometry.js +0 -12
- package/dist/docx/protectionPolicy.d.ts +13 -5
- package/dist/docx/protectionPolicy.js +32 -22
- package/dist/docx/scan.d.ts +18 -8
- package/dist/docx/scan.js +17 -11
- package/dist/docx/sections.d.ts +126 -0
- package/dist/docx/sections.js +207 -0
- package/dist/docx/serializeBlock.d.ts +13 -4
- package/dist/docx/serializeBlock.js +16 -18
- package/dist/docx/serializeParagraph.d.ts +9 -4
- package/dist/docx/serializeParagraph.js +23 -58
- package/dist/docx/serializePreserved.d.ts +14 -0
- package/dist/docx/serializePreserved.js +24 -0
- package/dist/docx/serializeStory.d.ts +17 -0
- package/dist/docx/serializeStory.js +17 -0
- package/dist/docx/serializeTable.js +10 -13
- package/dist/docx/session.d.ts +23 -6
- package/dist/docx/session.js +26 -5
- package/dist/docx/story.d.ts +140 -0
- package/dist/docx/story.js +237 -0
- package/dist/docx/storyProjection.js +6 -1
- package/dist/docx/tableTemplate.d.ts +25 -0
- package/dist/docx/tableTemplate.js +30 -16
- package/dist/docx/wrappers.d.ts +67 -0
- package/dist/docx/wrappers.js +117 -0
- package/dist/editor/clipboard/blockReaders.d.ts +74 -0
- package/dist/editor/clipboard/blockReaders.js +193 -0
- package/dist/editor/clipboard/htmlReader.d.ts +26 -0
- package/dist/editor/clipboard/htmlReader.js +376 -0
- package/dist/editor/clipboard/inlineFormatting.d.ts +0 -7
- package/dist/editor/clipboard/inlineFormatting.js +1 -7
- package/dist/editor/clipboard/internalChannel.d.ts +57 -0
- package/dist/editor/clipboard/internalChannel.js +58 -0
- package/dist/editor/clipboard/normalizers.d.ts +99 -0
- package/dist/editor/clipboard/normalizers.js +199 -0
- package/dist/editor/clipboard/parser.d.ts +34 -0
- package/dist/editor/clipboard/parser.js +58 -0
- package/dist/editor/clipboard/plugin.d.ts +21 -0
- package/dist/editor/clipboard/plugin.js +188 -0
- package/dist/editor/clipboard/readContext.d.ts +34 -0
- package/dist/editor/clipboard/readContext.js +25 -0
- package/dist/editor/clipboard/readers.d.ts +33 -0
- package/dist/editor/clipboard/readers.js +37 -0
- package/dist/editor/clipboard/source.d.ts +12 -0
- package/dist/editor/clipboard/source.js +21 -0
- package/dist/editor/commands/comments/editing.d.ts +26 -6
- package/dist/editor/commands/comments/editing.js +177 -106
- package/dist/editor/commands/comments/model.d.ts +34 -17
- package/dist/editor/commands/comments/model.js +11 -0
- package/dist/editor/commands/comments/reading.d.ts +5 -3
- package/dist/editor/commands/comments/reading.js +8 -58
- package/dist/editor/commands/index.d.ts +2 -2
- package/dist/editor/commands/index.js +2 -0
- package/dist/editor/commands/linkCommands.js +20 -5
- package/dist/editor/commands/listCommands.d.ts +6 -0
- package/dist/editor/commands/listCommands.js +3 -2
- package/dist/editor/commands/lockCommands.js +59 -16
- package/dist/editor/commands/noteQueries.d.ts +22 -5
- package/dist/editor/commands/noteQueries.js +34 -6
- package/dist/editor/commands/paragraphCommands.js +2 -2
- package/dist/editor/createEditor.js +13 -3
- package/dist/editor/documentStyles.d.ts +26 -4
- package/dist/editor/documentStyles.js +9 -4
- package/dist/editor/imageFiles.d.ts +2 -2
- package/dist/editor/imageFiles.js +2 -0
- package/dist/editor/insertTable.d.ts +1 -1
- package/dist/editor/insertTable.js +2 -2
- package/dist/editor/plainText.d.ts +12 -0
- package/dist/editor/plainText.js +2 -1
- package/dist/editor/plugins/columnResize.js +6 -3
- package/dist/editor/plugins/commentComposer.d.ts +28 -0
- package/dist/editor/plugins/commentComposer.js +46 -0
- package/dist/editor/plugins/commentDecorations.d.ts +29 -2
- package/dist/editor/plugins/commentDecorations.js +89 -15
- package/dist/editor/plugins/documentProjection.d.ts +31 -0
- package/dist/editor/plugins/documentProjection.js +22 -0
- package/dist/editor/plugins/imagePaste.js +15 -8
- package/dist/editor/plugins/linkPanel.d.ts +7 -3
- package/dist/editor/plugins/linkPanel.js +13 -27
- package/dist/editor/plugins/panelState.d.ts +67 -0
- package/dist/editor/plugins/panelState.js +54 -0
- package/dist/editor/plugins/tableContextMenu.d.ts +1 -1
- package/dist/editor/plugins/tableContextMenu.js +30 -47
- package/dist/editor/plugins/textContextMenu.d.ts +1 -1
- package/dist/editor/plugins/textContextMenu.js +30 -47
- package/dist/ooxml/fragment.d.ts +11 -0
- package/dist/ooxml/fragment.js +14 -4
- package/dist/ooxml/image.d.ts +3 -4
- package/dist/ooxml/image.js +50 -5
- package/dist/ooxml/names.d.ts +6 -0
- package/dist/ooxml/names.js +2 -0
- package/dist/ooxml/props.d.ts +10 -0
- package/dist/ooxml/props.js +28 -4
- package/dist/ooxml/rangeMarkers.d.ts +5 -0
- package/dist/ooxml/rangeMarkers.js +24 -0
- package/dist/page/PageGuides.d.ts +7 -3
- package/dist/page/PageGuides.js +13 -24
- package/dist/page/pageLayout.d.ts +64 -5
- package/dist/page/pageLayout.js +90 -29
- package/dist/page/usePageLayout.d.ts +14 -4
- package/dist/page/usePageLayout.js +19 -20
- package/dist/schema/attrRoles.js +46 -23
- package/dist/schema/clipboard.d.ts +72 -0
- package/dist/schema/clipboard.js +288 -0
- package/dist/schema/docxSchema.d.ts +9 -1
- package/dist/schema/docxSchema.js +217 -165
- package/dist/schema/editGuard.d.ts +1 -1
- package/dist/schema/guards.js +2 -2
- package/dist/schema/index.d.ts +1 -0
- package/dist/schema/locks.d.ts +3 -0
- package/dist/schema/locks.js +29 -12
- package/dist/schema/preservedFragments.d.ts +12 -0
- package/dist/schema/preservedFragments.js +38 -0
- package/dist/schema/preservedGuards.d.ts +9 -7
- package/dist/schema/preservedGuards.js +112 -11
- package/dist/schema/protection.d.ts +34 -5
- package/dist/schema/protection.js +42 -14
- package/dist/schema/rendering.d.ts +14 -0
- package/dist/schema/rendering.js +27 -12
- package/dist/schema/stories.d.ts +49 -0
- package/dist/schema/stories.js +78 -0
- package/dist/schema/wrappers.d.ts +58 -0
- package/dist/schema/wrappers.js +77 -0
- package/dist/styles/classNames.d.ts +3 -5
- package/dist/styles/classNames.js +3 -5
- package/dist/styles.css +74 -12
- package/dist/table/resize.d.ts +5 -3
- package/dist/ui/CommentsPanel.d.ts +1 -3
- package/dist/ui/CommentsPanel.js +24 -15
- package/dist/ui/NotesPanel.js +2 -2
- package/dist/ui/TextMenu.d.ts +1 -3
- package/dist/ui/TextMenu.js +10 -6
- package/dist/ui/comments/CommentComposer.d.ts +6 -1
- package/dist/ui/comments/CommentComposer.js +26 -3
- package/package.json +5 -4
- package/dist/editor/externalClipboard.d.ts +0 -22
- package/dist/editor/externalClipboard.js +0 -486
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@portone/docx-editor",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.5.1",
|
|
4
4
|
"description": "A simple DOCX editor for React, built directly on OOXML.",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"type": "module",
|
|
@@ -107,7 +107,7 @@
|
|
|
107
107
|
"build:demo": "vite build --config demo/vite.config.ts",
|
|
108
108
|
"dev:site": "pnpm --filter @portone/docx-editor-site dev",
|
|
109
109
|
"build:site": "pnpm --filter @portone/docx-editor-site build",
|
|
110
|
-
"check": "pnpm lint && pnpm typecheck && pnpm test && pnpm test:fixtures && pnpm test:site-release && pnpm check:demo-library",
|
|
110
|
+
"check": "pnpm lint && pnpm typecheck && pnpm test && pnpm test:fixtures && pnpm test:site-release && pnpm test:release && pnpm check:demo-library",
|
|
111
111
|
"typecheck": "tsc --noEmit && tsc --noEmit -p e2e && tsc --noEmit -p demo && pnpm --filter @portone/docx-editor-site typecheck",
|
|
112
112
|
"lint": "pnpm biome check . --diagnostic-level=error",
|
|
113
113
|
"test": "vitest run",
|
|
@@ -119,9 +119,10 @@
|
|
|
119
119
|
"api:update": "pnpm build && node scripts/api-report.mjs --local",
|
|
120
120
|
"spec": "node scripts/index-ooxml-spec.mjs",
|
|
121
121
|
"changeset": "changeset",
|
|
122
|
-
"
|
|
122
|
+
"release:pr": "node scripts/release.mjs pr",
|
|
123
123
|
"test:e2e": "playwright test",
|
|
124
|
-
"test:site-release": "node --test scripts/site-release.test.mjs"
|
|
124
|
+
"test:site-release": "node --test scripts/site-release.test.mjs",
|
|
125
|
+
"test:release": "node --test scripts/release.test.mjs"
|
|
125
126
|
},
|
|
126
127
|
"types": "./dist/index.d.ts"
|
|
127
128
|
}
|
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
import { Slice } from "prosemirror-model";
|
|
2
|
-
import { type EditorState, Plugin, type Transaction } from "prosemirror-state";
|
|
3
|
-
import type { EditorView } from "prosemirror-view";
|
|
4
|
-
import { type NewLists } from "../numbering/listRegistry";
|
|
5
|
-
import type { ImageToInsert } from "./insertImage";
|
|
6
|
-
/** What a paste puts in: the content, and the definitions of the lists it started */
|
|
7
|
-
export interface PastedContent {
|
|
8
|
-
slice: Slice;
|
|
9
|
-
newLists: NewLists;
|
|
10
|
-
}
|
|
11
|
-
export declare function richHtmlSlice(state: EditorState, document: Document, source: string, images?: ReadonlyMap<string, ImageToInsert>): PastedContent | null;
|
|
12
|
-
/**
|
|
13
|
-
* The transaction a paste is put in with: the content, and the definitions of the lists it started
|
|
14
|
-
* recorded on the document node so that the export writes them out and undo takes them back.
|
|
15
|
-
*/
|
|
16
|
-
export declare function withPastedContent(tr: Transaction, content: PastedContent): Transaction;
|
|
17
|
-
export declare function insertRichHtml(view: EditorView, source: string): boolean;
|
|
18
|
-
export declare function insertClipboardData(view: EditorView, data: {
|
|
19
|
-
html?: string;
|
|
20
|
-
text?: string;
|
|
21
|
-
}): void;
|
|
22
|
-
export declare function externalClipboard(): Plugin;
|
|
@@ -1,486 +0,0 @@
|
|
|
1
|
-
// src/editor/externalClipboard.ts
|
|
2
|
-
import {
|
|
3
|
-
DOMSerializer,
|
|
4
|
-
Fragment,
|
|
5
|
-
Slice
|
|
6
|
-
} from "prosemirror-model";
|
|
7
|
-
import { Plugin } from "prosemirror-state";
|
|
8
|
-
import {
|
|
9
|
-
paragraphAttrsFor,
|
|
10
|
-
styleIdOf
|
|
11
|
-
} from "../docx/formatting.js";
|
|
12
|
-
import {
|
|
13
|
-
withListNumbering,
|
|
14
|
-
withParagraphStyle
|
|
15
|
-
} from "../docx/paraProps.js";
|
|
16
|
-
import {
|
|
17
|
-
listsWorn,
|
|
18
|
-
NEW_LISTS_ATTR,
|
|
19
|
-
newListsValue
|
|
20
|
-
} from "../numbering/listRegistry.js";
|
|
21
|
-
import {
|
|
22
|
-
allocateList,
|
|
23
|
-
MAX_ILVL,
|
|
24
|
-
templateList
|
|
25
|
-
} from "../numbering/listTemplate.js";
|
|
26
|
-
import { docxSchema, isPageBreak } from "../schema/index.js";
|
|
27
|
-
import { editorClassNames } from "../styles/classNames.js";
|
|
28
|
-
import { PASTED_IMAGE_ATTRIBUTE } from "./clipboard/images.js";
|
|
29
|
-
import {
|
|
30
|
-
appendInline,
|
|
31
|
-
contextFor,
|
|
32
|
-
marksFor,
|
|
33
|
-
safeHref,
|
|
34
|
-
withInlineStyle
|
|
35
|
-
} from "./clipboard/inlineFormatting.js";
|
|
36
|
-
import { numIdsIn } from "./commands/listCommands.js";
|
|
37
|
-
import { documentFormatting, documentParagraphStyles } from "./documentStyles.js";
|
|
38
|
-
import { insertPlainText } from "./plainText.js";
|
|
39
|
-
import { moveCaretToDrop } from "./plugins/dropCaret.js";
|
|
40
|
-
import { canStartNewList } from "./plugins/numberingDecorations.js";
|
|
41
|
-
var BLOCK_TAGS = /* @__PURE__ */ new Set([
|
|
42
|
-
"ADDRESS",
|
|
43
|
-
"ARTICLE",
|
|
44
|
-
"ASIDE",
|
|
45
|
-
"BLOCKQUOTE",
|
|
46
|
-
"DIV",
|
|
47
|
-
"H1",
|
|
48
|
-
"H2",
|
|
49
|
-
"H3",
|
|
50
|
-
"H4",
|
|
51
|
-
"H5",
|
|
52
|
-
"H6",
|
|
53
|
-
"LI",
|
|
54
|
-
"P",
|
|
55
|
-
"PRE",
|
|
56
|
-
"SECTION"
|
|
57
|
-
]);
|
|
58
|
-
var HEADING_LEVELS = {
|
|
59
|
-
H1: 1,
|
|
60
|
-
H2: 2,
|
|
61
|
-
H3: 3,
|
|
62
|
-
H4: 4,
|
|
63
|
-
H5: 5,
|
|
64
|
-
H6: 6
|
|
65
|
-
};
|
|
66
|
-
var HEADING_FALLBACKS = {
|
|
67
|
-
1: { bold: true, fontSizePt: 24 },
|
|
68
|
-
2: { bold: true, fontSizePt: 18 },
|
|
69
|
-
3: { bold: true, fontSizePt: 14 },
|
|
70
|
-
4: { bold: true, fontSizePt: 12 },
|
|
71
|
-
5: { bold: true, fontSizePt: 10 },
|
|
72
|
-
6: { bold: true, fontSizePt: 8 }
|
|
73
|
-
};
|
|
74
|
-
var PUBLIC_ATTRIBUTES = /* @__PURE__ */ new Set([
|
|
75
|
-
"alt",
|
|
76
|
-
"aria-label",
|
|
77
|
-
"class",
|
|
78
|
-
"colspan",
|
|
79
|
-
"height",
|
|
80
|
-
"href",
|
|
81
|
-
"lang",
|
|
82
|
-
"rowspan",
|
|
83
|
-
"src",
|
|
84
|
-
"style",
|
|
85
|
-
"width"
|
|
86
|
-
]);
|
|
87
|
-
var COPIED_STYLE_ATTRIBUTE = "data-style";
|
|
88
|
-
function isAttributes(value) {
|
|
89
|
-
return typeof value === "object" && value !== null && !Array.isArray(value) && !(value instanceof Node);
|
|
90
|
-
}
|
|
91
|
-
function publicAttributes(attrs) {
|
|
92
|
-
return Object.fromEntries(
|
|
93
|
-
Object.entries(attrs).filter(([name]) => PUBLIC_ATTRIBUTES.has(name))
|
|
94
|
-
);
|
|
95
|
-
}
|
|
96
|
-
function isSpecArray(value) {
|
|
97
|
-
return Array.isArray(value) && typeof value[0] === "string";
|
|
98
|
-
}
|
|
99
|
-
function stripPrivateAttributes(spec) {
|
|
100
|
-
if (!isSpecArray(spec)) return spec;
|
|
101
|
-
const [tag, ...rest] = spec;
|
|
102
|
-
const attrs = isAttributes(rest[0]) ? publicAttributes(rest[0]) : null;
|
|
103
|
-
const children = (attrs === null ? rest : rest.slice(1)).map(
|
|
104
|
-
(child) => isSpecArray(child) ? stripPrivateAttributes(child) : child
|
|
105
|
-
);
|
|
106
|
-
return attrs === null ? [tag, ...children] : [tag, attrs, ...children];
|
|
107
|
-
}
|
|
108
|
-
function withDomAttribute(spec, name, value) {
|
|
109
|
-
if (!isSpecArray(spec)) return spec;
|
|
110
|
-
const [tag, ...rest] = spec;
|
|
111
|
-
return isAttributes(rest[0]) ? [tag, { ...rest[0], [name]: value }, ...rest.slice(1)] : [tag, { [name]: value }, ...rest];
|
|
112
|
-
}
|
|
113
|
-
function asTag(spec, tag) {
|
|
114
|
-
return isSpecArray(spec) ? [tag, ...spec.slice(1)] : spec;
|
|
115
|
-
}
|
|
116
|
-
function copiedMarkSpec(mark, spec) {
|
|
117
|
-
const stripped = stripPrivateAttributes(spec);
|
|
118
|
-
if (mark.type !== docxSchema.marks.link) return stripped;
|
|
119
|
-
const href = safeHref(
|
|
120
|
-
typeof mark.attrs.href === "string" ? mark.attrs.href : null
|
|
121
|
-
);
|
|
122
|
-
return href === null ? stripped : asTag(withDomAttribute(stripped, "href", href), "a");
|
|
123
|
-
}
|
|
124
|
-
function copiedNodeSpec(node, spec) {
|
|
125
|
-
const stripped = stripPrivateAttributes(spec);
|
|
126
|
-
if (node.type !== docxSchema.nodes.paragraph) return stripped;
|
|
127
|
-
const styleId = styleIdOf(node.attrs.pPr);
|
|
128
|
-
return styleId === null ? stripped : withDomAttribute(stripped, COPIED_STYLE_ATTRIBUTE, styleId);
|
|
129
|
-
}
|
|
130
|
-
function clipboardSerializer() {
|
|
131
|
-
const drawn = DOMSerializer.fromSchema(docxSchema);
|
|
132
|
-
const nodes = Object.fromEntries(
|
|
133
|
-
Object.entries(drawn.nodes).map(([name, toDOM]) => [
|
|
134
|
-
name,
|
|
135
|
-
(node) => copiedNodeSpec(node, toDOM(node))
|
|
136
|
-
])
|
|
137
|
-
);
|
|
138
|
-
const marks = Object.fromEntries(
|
|
139
|
-
Object.entries(drawn.marks).map(([name, toDOM]) => [
|
|
140
|
-
name,
|
|
141
|
-
(mark, inline) => copiedMarkSpec(mark, toDOM(mark, inline))
|
|
142
|
-
])
|
|
143
|
-
);
|
|
144
|
-
return new DOMSerializer(nodes, marks);
|
|
145
|
-
}
|
|
146
|
-
var UNREADABLE_BLOCKS = /* @__PURE__ */ new Set([
|
|
147
|
-
"bookmarkBlock",
|
|
148
|
-
"docxRaw",
|
|
149
|
-
"rawBlock"
|
|
150
|
-
]);
|
|
151
|
-
function stringAttr(value) {
|
|
152
|
-
return typeof value === "string" ? value : "";
|
|
153
|
-
}
|
|
154
|
-
function inlineText(node) {
|
|
155
|
-
if (node.isText) return node.text ?? "";
|
|
156
|
-
if (node.type === docxSchema.nodes.hardBreak) {
|
|
157
|
-
return isPageBreak(node.attrs.brAttrs) ? "\f" : "\n";
|
|
158
|
-
}
|
|
159
|
-
if (node.type === docxSchema.nodes.image) return stringAttr(node.attrs.alt);
|
|
160
|
-
if (node.type === docxSchema.nodes.noteReference) {
|
|
161
|
-
return node.attrs.customMarkFollows === true ? "" : stringAttr(node.attrs.label);
|
|
162
|
-
}
|
|
163
|
-
return "";
|
|
164
|
-
}
|
|
165
|
-
function rowsText(table) {
|
|
166
|
-
const rows = [];
|
|
167
|
-
table.forEach((row) => {
|
|
168
|
-
const cells = [];
|
|
169
|
-
row.forEach((cell) => {
|
|
170
|
-
cells.push(fragmentText(cell.content));
|
|
171
|
-
});
|
|
172
|
-
rows.push(cells.join(" "));
|
|
173
|
-
});
|
|
174
|
-
return rows.join("\n");
|
|
175
|
-
}
|
|
176
|
-
function blockText(node) {
|
|
177
|
-
if (node.type === docxSchema.nodes.table) return rowsText(node);
|
|
178
|
-
if (UNREADABLE_BLOCKS.has(node.type.name)) return "";
|
|
179
|
-
return fragmentText(node.content);
|
|
180
|
-
}
|
|
181
|
-
function fragmentText(fragment) {
|
|
182
|
-
const pieces = [];
|
|
183
|
-
fragment.forEach((child) => {
|
|
184
|
-
pieces.push(child.isInline ? inlineText(child) : blockText(child));
|
|
185
|
-
});
|
|
186
|
-
return pieces.join(fragment.firstChild?.isInline === true ? "" : "\n");
|
|
187
|
-
}
|
|
188
|
-
function bareWrappers(content, openStart, openEnd) {
|
|
189
|
-
const wrapper = content.firstChild;
|
|
190
|
-
if (openStart <= 1 || openEnd <= 1 || content.childCount !== 1)
|
|
191
|
-
return content;
|
|
192
|
-
if (wrapper === null || wrapper.childCount !== 1) return content;
|
|
193
|
-
return Fragment.from(
|
|
194
|
-
wrapper.type.create(
|
|
195
|
-
null,
|
|
196
|
-
bareWrappers(wrapper.content, openStart - 1, openEnd - 1),
|
|
197
|
-
wrapper.marks
|
|
198
|
-
)
|
|
199
|
-
);
|
|
200
|
-
}
|
|
201
|
-
function copiedSlice(slice) {
|
|
202
|
-
return new Slice(
|
|
203
|
-
bareWrappers(slice.content, slice.openStart, slice.openEnd),
|
|
204
|
-
slice.openStart,
|
|
205
|
-
slice.openEnd
|
|
206
|
-
);
|
|
207
|
-
}
|
|
208
|
-
function clipboardText(slice) {
|
|
209
|
-
return fragmentText(slice.content);
|
|
210
|
-
}
|
|
211
|
-
function normalizedStyleName(value) {
|
|
212
|
-
return value.toLowerCase().replace(/[\s_-]+/g, "");
|
|
213
|
-
}
|
|
214
|
-
function copiedStyleId(element) {
|
|
215
|
-
if (!element.classList.contains(editorClassNames.paragraph)) return null;
|
|
216
|
-
return element.getAttribute(COPIED_STYLE_ATTRIBUTE) ?? styleIdOf(element.getAttribute("data-ppr"));
|
|
217
|
-
}
|
|
218
|
-
function headingLevel(element, sourceStyleId) {
|
|
219
|
-
const direct = HEADING_LEVELS[element.tagName];
|
|
220
|
-
if (direct !== void 0) return direct;
|
|
221
|
-
const match = /^heading([1-6])$/.exec(
|
|
222
|
-
normalizedStyleName(sourceStyleId ?? "")
|
|
223
|
-
);
|
|
224
|
-
return match ? Number.parseInt(match[1] ?? "", 10) : null;
|
|
225
|
-
}
|
|
226
|
-
function destinationStyleId(state, sourceStyleId, level) {
|
|
227
|
-
const styles = documentParagraphStyles(state);
|
|
228
|
-
if (sourceStyleId && styles.some((style) => style.id === sourceStyleId)) {
|
|
229
|
-
return sourceStyleId;
|
|
230
|
-
}
|
|
231
|
-
if (level === null) return null;
|
|
232
|
-
const wanted = `heading${level}`;
|
|
233
|
-
return styles.find(
|
|
234
|
-
(style) => normalizedStyleName(style.id) === wanted || normalizedStyleName(style.name) === wanted
|
|
235
|
-
)?.id ?? null;
|
|
236
|
-
}
|
|
237
|
-
function blockContext(state, parent, element, preserveParagraphStyle) {
|
|
238
|
-
const editorParagraph = element.classList.contains(
|
|
239
|
-
editorClassNames.paragraph
|
|
240
|
-
);
|
|
241
|
-
const sourceStyleId = copiedStyleId(element);
|
|
242
|
-
const level = headingLevel(element, sourceStyleId);
|
|
243
|
-
if (!preserveParagraphStyle && editorParagraph) {
|
|
244
|
-
return {
|
|
245
|
-
inline: contextFor(parent, element),
|
|
246
|
-
paragraph: null
|
|
247
|
-
};
|
|
248
|
-
}
|
|
249
|
-
const styleId = destinationStyleId(state, sourceStyleId, level);
|
|
250
|
-
const paragraph = styleId === null ? null : withParagraphStyle(null, styleId);
|
|
251
|
-
const usesDestinationStyle = editorParagraph && (sourceStyleId === null || paragraph !== null);
|
|
252
|
-
let inline = parent;
|
|
253
|
-
if (paragraph === null && level !== null) {
|
|
254
|
-
inline = withInlineStyle(inline, HEADING_FALLBACKS[level] ?? {});
|
|
255
|
-
}
|
|
256
|
-
return {
|
|
257
|
-
inline: contextFor(inline, element, !usesDestinationStyle),
|
|
258
|
-
paragraph
|
|
259
|
-
};
|
|
260
|
-
}
|
|
261
|
-
function listParagraphProps(list) {
|
|
262
|
-
if (!list || list.numId === null) return null;
|
|
263
|
-
return withListNumbering(null, {
|
|
264
|
-
numbering: { numId: list.numId, ilvl: Math.min(MAX_ILVL, list.level) },
|
|
265
|
-
indent: { kind: "keep" }
|
|
266
|
-
});
|
|
267
|
-
}
|
|
268
|
-
function paragraphAttrs(formatting, list, paragraph) {
|
|
269
|
-
const props = listParagraphProps(list) ?? paragraph;
|
|
270
|
-
return props ? { pPr: props.pPr, ...paragraphAttrsFor(props.pPr, formatting) } : null;
|
|
271
|
-
}
|
|
272
|
-
var HtmlReader = class {
|
|
273
|
-
constructor(state, preserveParagraphStyles, images) {
|
|
274
|
-
this.state = state;
|
|
275
|
-
this.preserveParagraphStyles = preserveParagraphStyles;
|
|
276
|
-
this.images = images;
|
|
277
|
-
this.formatting = documentFormatting(state);
|
|
278
|
-
this.used = numIdsIn(state.doc);
|
|
279
|
-
this.canCreateLists = canStartNewList(state);
|
|
280
|
-
}
|
|
281
|
-
state;
|
|
282
|
-
preserveParagraphStyles;
|
|
283
|
-
images;
|
|
284
|
-
blocks = [];
|
|
285
|
-
used;
|
|
286
|
-
canCreateLists;
|
|
287
|
-
/**
|
|
288
|
-
* What the pasted paragraphs are resolved against: the document's context, holding the
|
|
289
|
-
* definition of each pasted list as it is read, so that an item is drawn against the list it
|
|
290
|
-
* is joining rather than against a list nothing yet defines.
|
|
291
|
-
*/
|
|
292
|
-
formatting;
|
|
293
|
-
/** The definitions of every list started while editing, the pasted ones among them */
|
|
294
|
-
get newLists() {
|
|
295
|
-
return this.formatting.numbering.added;
|
|
296
|
-
}
|
|
297
|
-
read(root) {
|
|
298
|
-
this.readFlow(root, { style: {}, href: null, preserveWhitespace: false });
|
|
299
|
-
return this.blocks;
|
|
300
|
-
}
|
|
301
|
-
appendInline(target, node, context) {
|
|
302
|
-
appendInline(target, node, context, (content, element, inline) => {
|
|
303
|
-
if (element.tagName !== "IMG") return false;
|
|
304
|
-
const token = element.getAttribute(PASTED_IMAGE_ATTRIBUTE);
|
|
305
|
-
const image = token === null ? void 0 : this.images.get(token);
|
|
306
|
-
if (!image) return true;
|
|
307
|
-
content.push(
|
|
308
|
-
docxSchema.nodes.image.create(
|
|
309
|
-
{
|
|
310
|
-
...image,
|
|
311
|
-
// The source drawing may point at a relationship in another package.
|
|
312
|
-
xml: null
|
|
313
|
-
},
|
|
314
|
-
null,
|
|
315
|
-
marksFor(inline)
|
|
316
|
-
)
|
|
317
|
-
);
|
|
318
|
-
return true;
|
|
319
|
-
});
|
|
320
|
-
}
|
|
321
|
-
addParagraph(content, list = null, paragraph = null) {
|
|
322
|
-
if (list && list.numId === null) {
|
|
323
|
-
const marker = list.kind === "bullet" ? "\u2022 " : "1. ";
|
|
324
|
-
content.unshift(docxSchema.text(marker));
|
|
325
|
-
}
|
|
326
|
-
this.blocks.push(
|
|
327
|
-
docxSchema.nodes.paragraph.create(
|
|
328
|
-
paragraphAttrs(this.formatting, list, paragraph),
|
|
329
|
-
content
|
|
330
|
-
)
|
|
331
|
-
);
|
|
332
|
-
}
|
|
333
|
-
readFlow(parent, context, paragraph = null) {
|
|
334
|
-
let inline = [];
|
|
335
|
-
const flush = () => {
|
|
336
|
-
if (inline.length === 0) return;
|
|
337
|
-
this.addParagraph(inline, null, paragraph);
|
|
338
|
-
inline = [];
|
|
339
|
-
};
|
|
340
|
-
for (const child of parent.childNodes) {
|
|
341
|
-
const element = child.nodeType === child.ELEMENT_NODE ? child : null;
|
|
342
|
-
if (element?.tagName === "UL" || element?.tagName === "OL") {
|
|
343
|
-
flush();
|
|
344
|
-
this.readList(element, context, 0, null);
|
|
345
|
-
} else if (element && BLOCK_TAGS.has(element.tagName)) {
|
|
346
|
-
flush();
|
|
347
|
-
const before = this.blocks.length;
|
|
348
|
-
const block = blockContext(
|
|
349
|
-
this.state,
|
|
350
|
-
context,
|
|
351
|
-
element,
|
|
352
|
-
this.preserveParagraphStyles
|
|
353
|
-
);
|
|
354
|
-
this.readFlow(element, block.inline, block.paragraph);
|
|
355
|
-
if (this.blocks.length === before) {
|
|
356
|
-
this.addParagraph([], null, block.paragraph);
|
|
357
|
-
}
|
|
358
|
-
} else {
|
|
359
|
-
this.appendInline(inline, child, context);
|
|
360
|
-
}
|
|
361
|
-
}
|
|
362
|
-
flush();
|
|
363
|
-
}
|
|
364
|
-
/**
|
|
365
|
-
* The number a pasted list takes, registered with the definition that list is drawn and written
|
|
366
|
-
* with. A pasted list is started here just as the list button starts one.
|
|
367
|
-
*/
|
|
368
|
-
takeNumId(kind) {
|
|
369
|
-
if (!this.canCreateLists) return null;
|
|
370
|
-
const started = allocateList(
|
|
371
|
-
this.formatting.numbering,
|
|
372
|
-
this.used,
|
|
373
|
-
templateList(kind)
|
|
374
|
-
);
|
|
375
|
-
this.formatting = { ...this.formatting, numbering: started.numbering };
|
|
376
|
-
this.used.add(started.numId);
|
|
377
|
-
return started.numId;
|
|
378
|
-
}
|
|
379
|
-
readList(list, context, level, inherited) {
|
|
380
|
-
const kind = list.tagName === "UL" ? "bullet" : "numbered";
|
|
381
|
-
const listContext = {
|
|
382
|
-
kind,
|
|
383
|
-
numId: inherited?.kind === kind ? inherited.numId : this.takeNumId(kind),
|
|
384
|
-
level
|
|
385
|
-
};
|
|
386
|
-
const items = Array.from(list.children).filter(
|
|
387
|
-
(child) => child.tagName === "LI"
|
|
388
|
-
);
|
|
389
|
-
for (const item of items) {
|
|
390
|
-
const itemContext = contextFor(context, item);
|
|
391
|
-
const content = [];
|
|
392
|
-
for (const child of item.childNodes) {
|
|
393
|
-
const nested = child.nodeType === child.ELEMENT_NODE ? child : null;
|
|
394
|
-
if (nested?.tagName === "UL" || nested?.tagName === "OL") continue;
|
|
395
|
-
this.appendInline(content, child, itemContext);
|
|
396
|
-
}
|
|
397
|
-
this.addParagraph(content, listContext);
|
|
398
|
-
for (const nested of Array.from(item.children)) {
|
|
399
|
-
if (nested.tagName === "UL" || nested.tagName === "OL") {
|
|
400
|
-
this.readList(
|
|
401
|
-
nested,
|
|
402
|
-
itemContext,
|
|
403
|
-
level + 1,
|
|
404
|
-
listContext
|
|
405
|
-
);
|
|
406
|
-
}
|
|
407
|
-
}
|
|
408
|
-
}
|
|
409
|
-
}
|
|
410
|
-
};
|
|
411
|
-
function sliceDepth(root) {
|
|
412
|
-
const marker = root.querySelector("[data-pm-slice]");
|
|
413
|
-
const openStart = Number.parseInt(
|
|
414
|
-
marker?.getAttribute("data-pm-slice")?.split(/\s+/, 1)[0] ?? "",
|
|
415
|
-
10
|
|
416
|
-
);
|
|
417
|
-
if (Number.isFinite(openStart)) return openStart === 0 ? 0 : 1;
|
|
418
|
-
const blocks = [...BLOCK_TAGS, "OL", "UL"].map((tag) => tag.toLowerCase());
|
|
419
|
-
return root.querySelector(blocks.join(",")) ? 0 : 1;
|
|
420
|
-
}
|
|
421
|
-
function richHtmlSlice(state, document, source, images = /* @__PURE__ */ new Map()) {
|
|
422
|
-
if (source.trim() === "") return null;
|
|
423
|
-
const template = document.createElement("template");
|
|
424
|
-
template.innerHTML = source;
|
|
425
|
-
const open = sliceDepth(template.content);
|
|
426
|
-
const reader = new HtmlReader(state, open === 0, images);
|
|
427
|
-
const blocks = reader.read(template.content);
|
|
428
|
-
return blocks.length === 0 ? null : {
|
|
429
|
-
slice: new Slice(Fragment.fromArray([...blocks]), open, open),
|
|
430
|
-
newLists: reader.newLists
|
|
431
|
-
};
|
|
432
|
-
}
|
|
433
|
-
function withPastedContent(tr, content) {
|
|
434
|
-
return tr.setDocAttribute(
|
|
435
|
-
NEW_LISTS_ATTR,
|
|
436
|
-
newListsValue(listsWorn(content.newLists, numIdsIn(tr.doc)))
|
|
437
|
-
);
|
|
438
|
-
}
|
|
439
|
-
function insertRichHtml(view, source) {
|
|
440
|
-
const content = richHtmlSlice(view.state, view.dom.ownerDocument, source);
|
|
441
|
-
if (content === null) return false;
|
|
442
|
-
view.dispatch(
|
|
443
|
-
withPastedContent(
|
|
444
|
-
view.state.tr.replaceSelection(content.slice),
|
|
445
|
-
content
|
|
446
|
-
).scrollIntoView()
|
|
447
|
-
);
|
|
448
|
-
return true;
|
|
449
|
-
}
|
|
450
|
-
function insertClipboardData(view, data) {
|
|
451
|
-
if (insertRichHtml(view, data.html ?? "")) return;
|
|
452
|
-
insertPlainText(view, data.text ?? "");
|
|
453
|
-
}
|
|
454
|
-
function externalClipboard() {
|
|
455
|
-
const serializer = clipboardSerializer();
|
|
456
|
-
return new Plugin({
|
|
457
|
-
props: {
|
|
458
|
-
clipboardSerializer: serializer,
|
|
459
|
-
clipboardTextSerializer: clipboardText,
|
|
460
|
-
transformCopied: copiedSlice,
|
|
461
|
-
handlePaste(view, event) {
|
|
462
|
-
insertClipboardData(view, {
|
|
463
|
-
html: event.clipboardData?.getData("text/html"),
|
|
464
|
-
text: event.clipboardData?.getData("text/plain")
|
|
465
|
-
});
|
|
466
|
-
return true;
|
|
467
|
-
},
|
|
468
|
-
handleDrop(view, event) {
|
|
469
|
-
if (view.dragging) return false;
|
|
470
|
-
const text = event.dataTransfer?.getData("text/plain") ?? "";
|
|
471
|
-
if (text) {
|
|
472
|
-
moveCaretToDrop(view, event);
|
|
473
|
-
insertPlainText(view, text);
|
|
474
|
-
}
|
|
475
|
-
return true;
|
|
476
|
-
}
|
|
477
|
-
}
|
|
478
|
-
});
|
|
479
|
-
}
|
|
480
|
-
export {
|
|
481
|
-
externalClipboard,
|
|
482
|
-
insertClipboardData,
|
|
483
|
-
insertRichHtml,
|
|
484
|
-
richHtmlSlice,
|
|
485
|
-
withPastedContent
|
|
486
|
-
};
|