@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
|
@@ -1,29 +1,14 @@
|
|
|
1
1
|
// src/editor/plugins/tableContextMenu.ts
|
|
2
2
|
import {
|
|
3
|
-
Plugin,
|
|
4
|
-
PluginKey,
|
|
5
3
|
TextSelection
|
|
6
4
|
} from "prosemirror-state";
|
|
7
5
|
import { editsShut } from "../../schema/protectionState.js";
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
return typeof value === "object" && value !== null;
|
|
12
|
-
}
|
|
13
|
-
function toAnchor(value) {
|
|
14
|
-
if (!isRecord(value)) return null;
|
|
6
|
+
import { panelPlugin } from "./panelState.js";
|
|
7
|
+
function isTableMenuAnchor(value) {
|
|
8
|
+
if (typeof value !== "object" || value === null) return false;
|
|
15
9
|
const { clientX, clientY } = value;
|
|
16
|
-
|
|
17
|
-
return { clientX, clientY };
|
|
18
|
-
}
|
|
19
|
-
function tableMenuAnchor(state) {
|
|
20
|
-
return menuKey.getState(state) ?? null;
|
|
10
|
+
return typeof clientX === "number" && typeof clientY === "number";
|
|
21
11
|
}
|
|
22
|
-
var closeTableMenu = (state, dispatch) => {
|
|
23
|
-
if (tableMenuAnchor(state) === null) return false;
|
|
24
|
-
if (dispatch) dispatch(state.tr.setMeta(menuKey, CLOSE));
|
|
25
|
-
return true;
|
|
26
|
-
};
|
|
27
12
|
function cellStart($pos) {
|
|
28
13
|
for (let depth = $pos.depth; depth > 0; depth -= 1) {
|
|
29
14
|
if ($pos.node(depth).type.spec.tableRole === "cell") {
|
|
@@ -46,41 +31,39 @@ function selectionCovers(state, cellPos) {
|
|
|
46
31
|
}
|
|
47
32
|
function openMenu(view, cellPos, anchor) {
|
|
48
33
|
const state = view.state;
|
|
49
|
-
const tr = state.tr
|
|
34
|
+
const tr = menu.opening(state.tr, anchor);
|
|
50
35
|
if (!selectionCovers(state, cellPos)) {
|
|
51
36
|
tr.setSelection(TextSelection.near(tr.doc.resolve(cellPos + 1)));
|
|
52
37
|
}
|
|
53
38
|
view.dispatch(tr);
|
|
54
39
|
}
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
const cellPos = cellAtEvent(view, event.target);
|
|
73
|
-
if (cellPos === null) return false;
|
|
74
|
-
event.preventDefault();
|
|
75
|
-
openMenu(view, cellPos, {
|
|
76
|
-
clientX: event.clientX,
|
|
77
|
-
clientY: event.clientY
|
|
78
|
-
});
|
|
79
|
-
return true;
|
|
80
|
-
}
|
|
40
|
+
var menu = panelPlugin({
|
|
41
|
+
name: "docxEditorTableMenu",
|
|
42
|
+
isAnchor: isTableMenuAnchor,
|
|
43
|
+
// Once the document changes, the cell the menu pointed at may no longer be there
|
|
44
|
+
onDocChange: "close",
|
|
45
|
+
props: {
|
|
46
|
+
handleDOMEvents: {
|
|
47
|
+
contextmenu(view, event) {
|
|
48
|
+
if (editsShut(view.state)) return false;
|
|
49
|
+
const cellPos = cellAtEvent(view, event.target);
|
|
50
|
+
if (cellPos === null) return false;
|
|
51
|
+
event.preventDefault();
|
|
52
|
+
openMenu(view, cellPos, {
|
|
53
|
+
clientX: event.clientX,
|
|
54
|
+
clientY: event.clientY
|
|
55
|
+
});
|
|
56
|
+
return true;
|
|
81
57
|
}
|
|
82
58
|
}
|
|
83
|
-
}
|
|
59
|
+
}
|
|
60
|
+
});
|
|
61
|
+
function tableMenuAnchor(state) {
|
|
62
|
+
return menu.anchor(state);
|
|
63
|
+
}
|
|
64
|
+
var closeTableMenu = menu.close;
|
|
65
|
+
function tableContextMenu() {
|
|
66
|
+
return menu.plugin;
|
|
84
67
|
}
|
|
85
68
|
export {
|
|
86
69
|
closeTableMenu,
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* Replaces the native text context menu and moves the selection to the clicked position. Unselected
|
|
3
3
|
* table cells are left to the table context-menu plugin.
|
|
4
4
|
*/
|
|
5
|
-
import { type Command, type EditorState, Plugin } from "prosemirror-state";
|
|
5
|
+
import { type Command, type EditorState, type Plugin } from "prosemirror-state";
|
|
6
6
|
/** Where the menu should stand (viewport coordinates) */
|
|
7
7
|
export interface TextMenuAnchor {
|
|
8
8
|
clientX: number;
|
|
@@ -1,30 +1,15 @@
|
|
|
1
1
|
// src/editor/plugins/textContextMenu.ts
|
|
2
2
|
import {
|
|
3
|
-
Plugin,
|
|
4
|
-
PluginKey,
|
|
5
3
|
TextSelection
|
|
6
4
|
} from "prosemirror-state";
|
|
7
5
|
import { CellSelection } from "prosemirror-tables";
|
|
8
6
|
import { editingProtection, editsShut } from "../../schema/protectionState.js";
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
return typeof value === "object" && value !== null;
|
|
13
|
-
}
|
|
14
|
-
function toAnchor(value) {
|
|
15
|
-
if (!isRecord(value)) return null;
|
|
7
|
+
import { panelPlugin } from "./panelState.js";
|
|
8
|
+
function isTextMenuAnchor(value) {
|
|
9
|
+
if (typeof value !== "object" || value === null) return false;
|
|
16
10
|
const { clientX, clientY } = value;
|
|
17
|
-
|
|
18
|
-
return { clientX, clientY };
|
|
19
|
-
}
|
|
20
|
-
function textMenuAnchor(state) {
|
|
21
|
-
return menuKey.getState(state) ?? null;
|
|
11
|
+
return typeof clientX === "number" && typeof clientY === "number";
|
|
22
12
|
}
|
|
23
|
-
var closeTextMenu = (state, dispatch) => {
|
|
24
|
-
if (textMenuAnchor(state) === null) return false;
|
|
25
|
-
if (dispatch) dispatch(state.tr.setMeta(menuKey, CLOSE));
|
|
26
|
-
return true;
|
|
27
|
-
};
|
|
28
13
|
function isInEditor(view, target) {
|
|
29
14
|
return target instanceof Node && view.dom.contains(target);
|
|
30
15
|
}
|
|
@@ -50,43 +35,41 @@ function forTableMenu(view, target, spot) {
|
|
|
50
35
|
return aboutCells && isInTableCell(view, target);
|
|
51
36
|
}
|
|
52
37
|
function openMenu(state, event, spot) {
|
|
53
|
-
const tr = state.tr
|
|
38
|
+
const tr = menu.opening(state.tr, {
|
|
54
39
|
clientX: event.clientX,
|
|
55
40
|
clientY: event.clientY
|
|
56
41
|
});
|
|
57
42
|
if (isInSelection(state, spot)) return tr;
|
|
58
43
|
return tr.setSelection(TextSelection.near(tr.doc.resolve(spot)));
|
|
59
44
|
}
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
if (
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
props: {
|
|
74
|
-
handleDOMEvents: {
|
|
75
|
-
contextmenu(view, event) {
|
|
76
|
-
if (editingProtection(view.state) === "readOnly") return false;
|
|
77
|
-
if (!isInEditor(view, event.target)) return false;
|
|
78
|
-
const spot = clickedSpot(view, event);
|
|
79
|
-
if (editsShut(view.state) && !isInSelection(view.state, spot)) {
|
|
80
|
-
return false;
|
|
81
|
-
}
|
|
82
|
-
if (forTableMenu(view, event.target, spot)) return false;
|
|
83
|
-
event.preventDefault();
|
|
84
|
-
view.dispatch(openMenu(view.state, event, spot));
|
|
85
|
-
return true;
|
|
45
|
+
var menu = panelPlugin({
|
|
46
|
+
name: "docxEditorTextMenu",
|
|
47
|
+
isAnchor: isTextMenuAnchor,
|
|
48
|
+
// Once the document changes, what the menu was aimed at may no longer be there
|
|
49
|
+
onDocChange: "close",
|
|
50
|
+
props: {
|
|
51
|
+
handleDOMEvents: {
|
|
52
|
+
contextmenu(view, event) {
|
|
53
|
+
if (editingProtection(view.state) === "readOnly") return false;
|
|
54
|
+
if (!isInEditor(view, event.target)) return false;
|
|
55
|
+
const spot = clickedSpot(view, event);
|
|
56
|
+
if (editsShut(view.state) && !isInSelection(view.state, spot)) {
|
|
57
|
+
return false;
|
|
86
58
|
}
|
|
59
|
+
if (forTableMenu(view, event.target, spot)) return false;
|
|
60
|
+
event.preventDefault();
|
|
61
|
+
view.dispatch(openMenu(view.state, event, spot));
|
|
62
|
+
return true;
|
|
87
63
|
}
|
|
88
64
|
}
|
|
89
|
-
}
|
|
65
|
+
}
|
|
66
|
+
});
|
|
67
|
+
function textMenuAnchor(state) {
|
|
68
|
+
return menu.anchor(state);
|
|
69
|
+
}
|
|
70
|
+
var closeTextMenu = menu.close;
|
|
71
|
+
function textContextMenu() {
|
|
72
|
+
return menu.plugin;
|
|
90
73
|
}
|
|
91
74
|
export {
|
|
92
75
|
closeTextMenu,
|
package/dist/ooxml/fragment.d.ts
CHANGED
|
@@ -16,6 +16,7 @@
|
|
|
16
16
|
* What a raw XML string has to look like to be let into the attr that carries it.
|
|
17
17
|
*
|
|
18
18
|
* `element` is a whole element: a properties fragment, a drawing, an annotation reference.
|
|
19
|
+
* `elements` is a run of them standing side by side, as a table carries between its rows.
|
|
19
20
|
* `attributes` is what stood inside an opening tag, as `attrString` writes it.
|
|
20
21
|
* `openTag` is an opening tag with everything it wrapped cut away, which the writer puts back by
|
|
21
22
|
* appending the closing text `closedBy` names. `head` is what may still stand between the two:
|
|
@@ -24,6 +25,8 @@
|
|
|
24
25
|
export type RawXmlShape = {
|
|
25
26
|
kind: "element";
|
|
26
27
|
names: readonly string[] | "any";
|
|
28
|
+
} | {
|
|
29
|
+
kind: "elements";
|
|
27
30
|
} | {
|
|
28
31
|
kind: "attributes";
|
|
29
32
|
} | {
|
|
@@ -42,6 +45,14 @@ export declare function ELEMENT(...names: string[]): RawXmlShape;
|
|
|
42
45
|
* turn a document the editor reads today into a demoted one.
|
|
43
46
|
*/
|
|
44
47
|
export declare const ANY_ELEMENT: RawXmlShape;
|
|
48
|
+
/**
|
|
49
|
+
* A run of one or more elements standing side by side, of any name, in any namespace.
|
|
50
|
+
*
|
|
51
|
+
* A table carries the markers that stood between its rows, and a row those between its cells
|
|
52
|
+
* (`docx/importTable`), and there may be several of them in a row: the end of one bookmark and the
|
|
53
|
+
* start of the next stand together with nothing between them.
|
|
54
|
+
*/
|
|
55
|
+
export declare const ANY_ELEMENTS: RawXmlShape;
|
|
45
56
|
/** The attributes of an opening tag, with neither the tag nor anything it held */
|
|
46
57
|
export declare const ATTRIBUTES: RawXmlShape;
|
|
47
58
|
/**
|
package/dist/ooxml/fragment.js
CHANGED
|
@@ -10,17 +10,22 @@ function ELEMENT(...names) {
|
|
|
10
10
|
return { kind: "element", names };
|
|
11
11
|
}
|
|
12
12
|
var ANY_ELEMENT = { kind: "element", names: "any" };
|
|
13
|
+
var ANY_ELEMENTS = { kind: "elements" };
|
|
13
14
|
var ATTRIBUTES = { kind: "attributes" };
|
|
14
|
-
function
|
|
15
|
+
function wrappedElements(xml) {
|
|
15
16
|
let root;
|
|
16
17
|
try {
|
|
17
18
|
root = parseXml(`<x ${namespaceDecls(xml)}>${xml}</x>`).documentElement;
|
|
18
19
|
} catch {
|
|
19
20
|
return null;
|
|
20
21
|
}
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
return
|
|
22
|
+
const elements = elementChildren(root);
|
|
23
|
+
if (root.childNodes.length !== elements.length) return null;
|
|
24
|
+
return elements.some(rebindsReservedPrefix) ? null : elements;
|
|
25
|
+
}
|
|
26
|
+
function loneElement(xml) {
|
|
27
|
+
const elements = wrappedElements(xml);
|
|
28
|
+
return elements?.length === 1 ? elements[0] : null;
|
|
24
29
|
}
|
|
25
30
|
function isNamed(el, names) {
|
|
26
31
|
if (!names.includes(el.localName)) return false;
|
|
@@ -54,6 +59,10 @@ function holdsShape(shape, value) {
|
|
|
54
59
|
if (el === null) return false;
|
|
55
60
|
return shape.names === "any" || isNamed(el, shape.names);
|
|
56
61
|
}
|
|
62
|
+
case "elements": {
|
|
63
|
+
const elements = wrappedElements(value);
|
|
64
|
+
return elements !== null && elements.length > 0;
|
|
65
|
+
}
|
|
57
66
|
case "attributes": {
|
|
58
67
|
const el = loneElement(`<y ${value}></y>`);
|
|
59
68
|
return el !== null && el.childNodes.length === 0;
|
|
@@ -70,6 +79,7 @@ function acceptRawXml(shape, value) {
|
|
|
70
79
|
}
|
|
71
80
|
export {
|
|
72
81
|
ANY_ELEMENT,
|
|
82
|
+
ANY_ELEMENTS,
|
|
73
83
|
ATTRIBUTES,
|
|
74
84
|
ELEMENT,
|
|
75
85
|
acceptRawXml
|
package/dist/ooxml/image.d.ts
CHANGED
|
@@ -67,11 +67,10 @@ export interface DrawingPicture {
|
|
|
67
67
|
*/
|
|
68
68
|
export declare function readDrawingPicture(drawing: Element): DrawingPicture | null;
|
|
69
69
|
/**
|
|
70
|
-
* The same drawing XML with
|
|
70
|
+
* The same drawing XML with its inline extent and its picture transform's extent set to this size.
|
|
71
71
|
*
|
|
72
|
-
* Only those two elements are touched; every other byte
|
|
73
|
-
*
|
|
74
|
-
* unchanged, so nothing has to keep track of whether a resize happened.
|
|
72
|
+
* Only those two elements' size attributes are touched; every other byte stays where it was.
|
|
73
|
+
* Values already equal to the requested size keep their original spelling as well.
|
|
75
74
|
*/
|
|
76
75
|
export declare function withExtent(xml: string, extent: ImageExtent): string;
|
|
77
76
|
/** A picture that was inserted during editing and has no original XML to go back to */
|
package/dist/ooxml/image.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
// src/ooxml/image.ts
|
|
2
2
|
import { NAMESPACES } from "./names.js";
|
|
3
|
-
import {
|
|
3
|
+
import { parseAttrs, readTag } from "./tagScan.js";
|
|
4
|
+
import { childByLocalName, escapeXml, localPart, R_NS } from "./xml.js";
|
|
4
5
|
var EMU_PER_PX = 9525;
|
|
5
6
|
function emuToPx(emu) {
|
|
6
7
|
return emu / EMU_PER_PX;
|
|
@@ -76,11 +77,55 @@ function readDrawingPicture(drawing) {
|
|
|
76
77
|
const descr = childOf(inline, "docPr")?.getAttribute("descr") ?? null;
|
|
77
78
|
return { relId, extent, alt: descr === "" ? null : descr };
|
|
78
79
|
}
|
|
79
|
-
|
|
80
|
-
|
|
80
|
+
function isPictureSize(path) {
|
|
81
|
+
const names = path.join("/");
|
|
82
|
+
return names === "drawing/inline/extent" || names === "drawing/inline/graphic/graphicData/pic/spPr/xfrm/ext";
|
|
83
|
+
}
|
|
84
|
+
function resizeTag(open, extent) {
|
|
85
|
+
const tag = readTag(open, 0);
|
|
86
|
+
if (!tag) return open;
|
|
87
|
+
const attrs = new Map(
|
|
88
|
+
parseAttrs(
|
|
89
|
+
open.slice(tag.nameEnd, tag.end - (tag.kind === "empty" ? 2 : 1))
|
|
90
|
+
) ?? []
|
|
91
|
+
);
|
|
92
|
+
return open.replace(
|
|
93
|
+
/(\s+)([^\s=/>]+)(\s*=\s*)(["'])([\s\S]*?)\4/g,
|
|
94
|
+
(whole, gap, name, equals, quote) => {
|
|
95
|
+
if (name !== "cx" && name !== "cy") return whole;
|
|
96
|
+
const size = extent[name];
|
|
97
|
+
if (Number(attrs.get(name)) === size) return whole;
|
|
98
|
+
return `${gap}${name}${equals}${quote}${size}${quote}`;
|
|
99
|
+
}
|
|
100
|
+
);
|
|
101
|
+
}
|
|
81
102
|
function withExtent(xml, extent) {
|
|
82
|
-
const
|
|
83
|
-
|
|
103
|
+
const path = [];
|
|
104
|
+
const parts = [];
|
|
105
|
+
let at = 0;
|
|
106
|
+
let kept = 0;
|
|
107
|
+
for (; ; ) {
|
|
108
|
+
const lt = xml.indexOf("<", at);
|
|
109
|
+
if (lt === -1) break;
|
|
110
|
+
const tag = readTag(xml, lt);
|
|
111
|
+
if (!tag) return xml;
|
|
112
|
+
if (tag.kind === "close") {
|
|
113
|
+
path.pop();
|
|
114
|
+
} else if (tag.kind !== "other") {
|
|
115
|
+
path.push(localPart(tag.name));
|
|
116
|
+
if (isPictureSize(path)) {
|
|
117
|
+
parts.push(
|
|
118
|
+
xml.slice(kept, lt),
|
|
119
|
+
resizeTag(xml.slice(lt, tag.end), extent)
|
|
120
|
+
);
|
|
121
|
+
kept = tag.end;
|
|
122
|
+
}
|
|
123
|
+
if (tag.kind === "empty") path.pop();
|
|
124
|
+
}
|
|
125
|
+
at = tag.end;
|
|
126
|
+
}
|
|
127
|
+
parts.push(xml.slice(kept));
|
|
128
|
+
return parts.join("");
|
|
84
129
|
}
|
|
85
130
|
function imageDrawingXml(image) {
|
|
86
131
|
const size = `cx="${image.extent.cx}" cy="${image.extent.cy}"`;
|
package/dist/ooxml/names.d.ts
CHANGED
|
@@ -13,6 +13,12 @@ export declare const W_NS = "http://schemas.openxmlformats.org/wordprocessingml/
|
|
|
13
13
|
* every relationship type name is built on
|
|
14
14
|
*/
|
|
15
15
|
export declare const R_NS = "http://schemas.openxmlformats.org/officeDocument/2006/relationships";
|
|
16
|
+
/**
|
|
17
|
+
* The math namespace. Nothing here is written under a prefix of ours - a `m:oMath` travels as the
|
|
18
|
+
* XML it arrived as - so it names the namespace alone and stays out of `NAMESPACES`, which is the
|
|
19
|
+
* list of prefixes the writer spells out.
|
|
20
|
+
*/
|
|
21
|
+
export declare const M_NS = "http://schemas.openxmlformats.org/officeDocument/2006/math";
|
|
16
22
|
/** The prefix every WordprocessingML element and attribute this package writes carries */
|
|
17
23
|
export declare const W_PREFIX = "w";
|
|
18
24
|
export declare const NAMESPACES: {
|
package/dist/ooxml/names.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
// src/ooxml/names.ts
|
|
2
2
|
var W_NS = "http://schemas.openxmlformats.org/wordprocessingml/2006/main";
|
|
3
3
|
var R_NS = "http://schemas.openxmlformats.org/officeDocument/2006/relationships";
|
|
4
|
+
var M_NS = "http://schemas.openxmlformats.org/officeDocument/2006/math";
|
|
4
5
|
var W_PREFIX = "w";
|
|
5
6
|
var NAMESPACES = {
|
|
6
7
|
w: W_NS,
|
|
@@ -25,6 +26,7 @@ function xmlnsDecl(prefix) {
|
|
|
25
26
|
return `xmlns:${prefix}="${NAMESPACES[prefix]}"`;
|
|
26
27
|
}
|
|
27
28
|
export {
|
|
29
|
+
M_NS,
|
|
28
30
|
NAMESPACES,
|
|
29
31
|
R_NS,
|
|
30
32
|
W_NS,
|
package/dist/ooxml/props.d.ts
CHANGED
|
@@ -52,6 +52,14 @@ export declare function renderProps(props: Props): string;
|
|
|
52
52
|
* carries children in a different order under a different parent (`pPr/rPr`).
|
|
53
53
|
*/
|
|
54
54
|
export declare function setChild(props: Props, name: string, xml: string | null, parent?: string): Props;
|
|
55
|
+
/**
|
|
56
|
+
* Replaces every child of one name with this list of them, in the order given.
|
|
57
|
+
*
|
|
58
|
+
* `CT_SectPr` lets a section name a header and a footer once per variant, so a name standing more
|
|
59
|
+
* than once is a list rather than a single child, and writing one of them is writing the list. An
|
|
60
|
+
* empty list takes them all away.
|
|
61
|
+
*/
|
|
62
|
+
export declare function setChildren(props: Props, name: string, xmls: readonly string[], parent?: string): Props;
|
|
55
63
|
export declare function propsChild(children: readonly PropsChild[], name: string): PropsChild | undefined;
|
|
56
64
|
/**
|
|
57
65
|
* The opening tag's attributes as pairs, and null when their shape cannot be made out.
|
|
@@ -110,3 +118,5 @@ export declare function editChild(props: Props, path: readonly [string, ...strin
|
|
|
110
118
|
* null if its shape cannot be made out, in which case the caller leaves the display values alone.
|
|
111
119
|
*/
|
|
112
120
|
export declare function parsePropsXml(xml: string): Element | null;
|
|
121
|
+
/** The style name the paragraph formatting XML points at. null if it points at none */
|
|
122
|
+
export declare function styleIdOf(pPr: unknown): string | null;
|
package/dist/ooxml/props.js
CHANGED
|
@@ -3,6 +3,7 @@ import { childOrderOf } from "./childOrder.js";
|
|
|
3
3
|
import { attrsText, emptyTagXml } from "./element.js";
|
|
4
4
|
import { wName } from "./names.js";
|
|
5
5
|
import { parseAttrs, readTag } from "./tagScan.js";
|
|
6
|
+
import { childValue } from "./units.js";
|
|
6
7
|
import { elementChildren, localPart, namespaceDecls, parseXml } from "./xml.js";
|
|
7
8
|
function rawAttrs(source, tag) {
|
|
8
9
|
const closeLength = tag.kind === "empty" ? 2 : 1;
|
|
@@ -115,28 +116,37 @@ function tailWith(props, carried) {
|
|
|
115
116
|
return tail === "" ? {} : { tail };
|
|
116
117
|
}
|
|
117
118
|
function setChild(props, name, xml, parent) {
|
|
119
|
+
return setChildren(props, name, xml === null ? [] : [xml], parent);
|
|
120
|
+
}
|
|
121
|
+
function setChildren(props, name, xmls, parent) {
|
|
118
122
|
const order = childOrderOf(localPart(props.tag), parent);
|
|
119
123
|
const at = props.children.findIndex((entry) => entry.name === name);
|
|
120
|
-
if (at !== -1 &&
|
|
124
|
+
if (at !== -1 && xmls.length > 0) {
|
|
121
125
|
const rest = dropChildren(props.children.slice(at + 1), name);
|
|
122
126
|
return {
|
|
123
127
|
...props,
|
|
124
128
|
children: [
|
|
125
129
|
...props.children.slice(0, at),
|
|
126
|
-
|
|
130
|
+
...xmls.map(
|
|
131
|
+
(xml, index2) => index2 === 0 ? { ...props.children[at], xml } : { name, xml }
|
|
132
|
+
),
|
|
127
133
|
...rest.kept
|
|
128
134
|
],
|
|
129
135
|
...tailWith(props, rest.carried)
|
|
130
136
|
};
|
|
131
137
|
}
|
|
132
138
|
const { kept, carried } = dropChildren(props.children, name);
|
|
133
|
-
if (
|
|
139
|
+
if (xmls.length === 0) {
|
|
134
140
|
return { ...props, children: kept, ...tailWith(props, carried) };
|
|
135
141
|
}
|
|
136
142
|
const index = insertIndex(kept, name, order, props.tag);
|
|
137
143
|
return {
|
|
138
144
|
...props,
|
|
139
|
-
children: [
|
|
145
|
+
children: [
|
|
146
|
+
...kept.slice(0, index),
|
|
147
|
+
...xmls.map((xml) => ({ name, xml })),
|
|
148
|
+
...kept.slice(index)
|
|
149
|
+
],
|
|
140
150
|
...tailWith(props, carried)
|
|
141
151
|
};
|
|
142
152
|
}
|
|
@@ -198,6 +208,18 @@ function parsePropsXml(xml) {
|
|
|
198
208
|
return null;
|
|
199
209
|
}
|
|
200
210
|
}
|
|
211
|
+
var styleIdsByPPr = /* @__PURE__ */ new Map();
|
|
212
|
+
var STYLE_ID_CACHE_LIMIT = 2e3;
|
|
213
|
+
function styleIdOf(pPr) {
|
|
214
|
+
if (typeof pPr !== "string" || !pPr.includes("pStyle")) return null;
|
|
215
|
+
const known = styleIdsByPPr.get(pPr);
|
|
216
|
+
if (known !== void 0) return known;
|
|
217
|
+
const el = parsePropsXml(pPr);
|
|
218
|
+
const id = el ? childValue(el, "pStyle") : null;
|
|
219
|
+
if (styleIdsByPPr.size >= STYLE_ID_CACHE_LIMIT) styleIdsByPPr.clear();
|
|
220
|
+
styleIdsByPPr.set(pPr, id);
|
|
221
|
+
return id;
|
|
222
|
+
}
|
|
201
223
|
export {
|
|
202
224
|
attrsOf,
|
|
203
225
|
childElement,
|
|
@@ -210,5 +232,7 @@ export {
|
|
|
210
232
|
renderElement,
|
|
211
233
|
renderProps,
|
|
212
234
|
setChild,
|
|
235
|
+
setChildren,
|
|
236
|
+
styleIdOf,
|
|
213
237
|
withAttrs
|
|
214
238
|
};
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
/** `EG_RangeMarkupElements` less the comment markers modelled inside paragraphs and wrappers */
|
|
2
|
+
export declare const RANGE_MARKERS: string[];
|
|
3
|
+
/** The markers of `EG_RunLevelElts` that stand outside `EG_RangeMarkupElements` */
|
|
4
|
+
export declare const PERMISSION_MARKERS: string[];
|
|
5
|
+
export declare const COMMENT_RANGE_MARKERS: string[];
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
// src/ooxml/rangeMarkers.ts
|
|
2
|
+
var RANGE_MARKERS = [
|
|
3
|
+
"bookmarkStart",
|
|
4
|
+
"bookmarkEnd",
|
|
5
|
+
"moveFromRangeStart",
|
|
6
|
+
"moveFromRangeEnd",
|
|
7
|
+
"moveToRangeStart",
|
|
8
|
+
"moveToRangeEnd",
|
|
9
|
+
"customXmlInsRangeStart",
|
|
10
|
+
"customXmlInsRangeEnd",
|
|
11
|
+
"customXmlDelRangeStart",
|
|
12
|
+
"customXmlDelRangeEnd",
|
|
13
|
+
"customXmlMoveFromRangeStart",
|
|
14
|
+
"customXmlMoveFromRangeEnd",
|
|
15
|
+
"customXmlMoveToRangeStart",
|
|
16
|
+
"customXmlMoveToRangeEnd"
|
|
17
|
+
];
|
|
18
|
+
var PERMISSION_MARKERS = ["permStart", "permEnd"];
|
|
19
|
+
var COMMENT_RANGE_MARKERS = ["commentRangeStart", "commentRangeEnd"];
|
|
20
|
+
export {
|
|
21
|
+
COMMENT_RANGE_MARKERS,
|
|
22
|
+
PERMISSION_MARKERS,
|
|
23
|
+
RANGE_MARKERS
|
|
24
|
+
};
|
|
@@ -6,11 +6,15 @@
|
|
|
6
6
|
* Only the places crossed by a block taller than one page are marked over the text, with
|
|
7
7
|
* a faint dotted line.
|
|
8
8
|
* The box only paints, so the mouse still reaches the text beneath it.
|
|
9
|
+
*
|
|
10
|
+
* Each page draws the header and footer of the section it opens with, since a document names its
|
|
11
|
+
* headers section by section (`docx/headersFooters`).
|
|
9
12
|
*/
|
|
10
13
|
import type { ReactElement } from "react";
|
|
11
14
|
import { type HeadersFooters } from "../docx/headersFooters";
|
|
12
|
-
import type { PageOverlay } from "./usePageLayout";
|
|
13
|
-
export declare function PageGuides({ overlay,
|
|
15
|
+
import type { PageFace, PageOverlay } from "./usePageLayout";
|
|
16
|
+
export declare function PageGuides({ overlay, headersFootersFor, }: {
|
|
14
17
|
overlay: PageOverlay;
|
|
15
|
-
|
|
18
|
+
/** The stories the section this page belongs to shows. Left out while no document is open */
|
|
19
|
+
headersFootersFor?: (page: PageFace) => HeadersFooters | null;
|
|
16
20
|
}): ReactElement;
|
package/dist/page/PageGuides.js
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
// src/page/PageGuides.tsx
|
|
2
2
|
import {
|
|
3
3
|
displayPageNumber,
|
|
4
|
-
|
|
4
|
+
headerFooterOn,
|
|
5
5
|
headerFooterText
|
|
6
6
|
} from "../docx/headersFooters.js";
|
|
7
7
|
import { editorClassNames } from "../styles/classNames.js";
|
|
8
8
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
9
9
|
function PageGuides({
|
|
10
10
|
overlay,
|
|
11
|
-
|
|
11
|
+
headersFootersFor
|
|
12
12
|
}) {
|
|
13
13
|
const totalPages = overlay.pages.length;
|
|
14
14
|
return /* @__PURE__ */ jsxs(
|
|
@@ -34,30 +34,19 @@ function PageGuides({
|
|
|
34
34
|
},
|
|
35
35
|
mark.page
|
|
36
36
|
)),
|
|
37
|
-
|
|
38
|
-
|
|
37
|
+
headersFootersFor && overlay.pages.flatMap((page) => {
|
|
38
|
+
const headersFooters = page.crossed ? null : headersFootersFor(page);
|
|
39
|
+
if (headersFooters === null) return [];
|
|
39
40
|
const number = displayPageNumber(headersFooters, page.page);
|
|
40
|
-
const header =
|
|
41
|
+
const header = headerFooterOn(
|
|
41
42
|
headersFooters.headers,
|
|
42
43
|
headersFooters,
|
|
43
|
-
page.
|
|
44
|
-
totalPages
|
|
44
|
+
page.pageInSection
|
|
45
45
|
);
|
|
46
|
-
const footer =
|
|
46
|
+
const footer = headerFooterOn(
|
|
47
47
|
headersFooters.footers,
|
|
48
48
|
headersFooters,
|
|
49
|
-
page.
|
|
50
|
-
totalPages
|
|
51
|
-
);
|
|
52
|
-
const headerAlign = headerFooterAlign(
|
|
53
|
-
headersFooters.headers,
|
|
54
|
-
headersFooters,
|
|
55
|
-
page.page
|
|
56
|
-
);
|
|
57
|
-
const footerAlign = headerFooterAlign(
|
|
58
|
-
headersFooters.footers,
|
|
59
|
-
headersFooters,
|
|
60
|
-
page.page
|
|
49
|
+
page.pageInSection
|
|
61
50
|
);
|
|
62
51
|
return [
|
|
63
52
|
header === null ? null : /* @__PURE__ */ jsx(
|
|
@@ -68,10 +57,10 @@ function PageGuides({
|
|
|
68
57
|
top: `${page.headerTop}px`,
|
|
69
58
|
left: `${page.left}px`,
|
|
70
59
|
width: `${page.width}px`,
|
|
71
|
-
textAlign:
|
|
60
|
+
textAlign: header.align ?? void 0
|
|
72
61
|
},
|
|
73
62
|
title: `Page ${number} header`,
|
|
74
|
-
children: header
|
|
63
|
+
children: headerFooterText(header.story, number, totalPages)
|
|
75
64
|
},
|
|
76
65
|
`header-${page.page}`
|
|
77
66
|
),
|
|
@@ -83,10 +72,10 @@ function PageGuides({
|
|
|
83
72
|
top: `${page.footerTop}px`,
|
|
84
73
|
left: `${page.left}px`,
|
|
85
74
|
width: `${page.width}px`,
|
|
86
|
-
textAlign:
|
|
75
|
+
textAlign: footer.align ?? void 0
|
|
87
76
|
},
|
|
88
77
|
title: `Page ${number} footer`,
|
|
89
|
-
children: footer
|
|
78
|
+
children: headerFooterText(footer.story, number, totalPages)
|
|
90
79
|
},
|
|
91
80
|
`footer-${page.page}`
|
|
92
81
|
)
|