@twip/web 0.1.0-alpha.1 → 0.1.0-pre.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/README.md +35 -0
- package/dist/THIRD-PARTY-NOTICES.md +1009 -221
- package/dist/commands.d.ts +637 -0
- package/dist/commands.js +188 -0
- package/dist/editor.d.ts +218 -0
- package/dist/editor.js +460 -0
- package/dist/errors.d.ts +21 -0
- package/dist/errors.js +26 -0
- package/dist/events.d.ts +126 -0
- package/dist/events.js +1 -0
- package/dist/fonts/google.d.ts +3 -0
- package/dist/fonts/google.js +39 -0
- package/dist/fonts/library.d.ts +65 -0
- package/dist/fonts/library.js +130 -0
- package/dist/host/a11y.d.ts +3 -0
- package/dist/host/a11y.js +62 -0
- package/dist/host/chrome.d.ts +28 -0
- package/dist/host/chrome.js +144 -0
- package/dist/host/clipboard.d.ts +16 -0
- package/dist/host/clipboard.js +128 -0
- package/dist/host/dom.d.ts +45 -0
- package/dist/host/dom.js +122 -0
- package/dist/host/frames.d.ts +14 -0
- package/dist/host/frames.js +87 -0
- package/dist/host/gpu.d.ts +58 -0
- package/dist/host/gpu.js +79 -0
- package/dist/host/ime.d.ts +3 -0
- package/dist/host/ime.js +11 -0
- package/dist/host/input.d.ts +12 -0
- package/dist/host/input.js +86 -0
- package/dist/host/keys.d.ts +16 -0
- package/dist/host/keys.js +27 -0
- package/dist/host/mount.d.ts +11 -0
- package/dist/host/mount.js +72 -0
- package/dist/host/pointer.d.ts +4 -0
- package/dist/host/pointer.js +171 -0
- package/dist/host/scroll.d.ts +14 -0
- package/dist/host/scroll.js +95 -0
- package/dist/index.d.ts +27 -98
- package/dist/index.js +10 -0
- package/dist/review.d.ts +156 -0
- package/dist/review.js +38 -0
- package/dist/services/accessibility.d.ts +52 -0
- package/dist/services/accessibility.js +71 -0
- package/dist/services/dialogs.d.ts +181 -0
- package/dist/services/dialogs.js +18 -0
- package/dist/services/elements.d.ts +146 -0
- package/dist/services/elements.js +18 -0
- package/dist/services/find.d.ts +50 -0
- package/dist/services/find.js +12 -0
- package/dist/services/menus.d.ts +82 -0
- package/dist/services/menus.js +8 -0
- package/dist/services/navigation.d.ts +58 -0
- package/dist/services/navigation.js +12 -0
- package/dist/services/ruler.d.ts +95 -0
- package/dist/services/ruler.js +16 -0
- package/dist/services/spelling.d.ts +34 -0
- package/dist/services/spelling.js +14 -0
- package/dist/services/view.d.ts +70 -0
- package/dist/services/view.js +19 -0
- package/dist/state.d.ts +483 -0
- package/dist/state.js +1 -0
- package/dist/transport/direct.d.ts +31 -0
- package/dist/transport/direct.js +405 -0
- package/dist/transport/module.d.ts +51 -0
- package/dist/transport/module.js +17 -0
- package/dist/transport/protocol.d.ts +265 -0
- package/dist/transport/protocol.js +132 -0
- package/dist/transport/worker.d.ts +54 -0
- package/dist/transport/worker.js +203 -0
- package/dist/twip-wasm.js +1 -1
- package/dist/twip_wasm.wasm +0 -0
- package/dist/types.d.ts +134 -0
- package/dist/types.js +16 -0
- package/dist/worker/entry.d.ts +1 -0
- package/dist/worker/entry.js +53 -0
- package/dist/worker.d.ts +1 -0
- package/dist/worker.js +2 -0
- package/package.json +12 -7
- package/dist/AccessibleNode.d.ts +0 -51
- package/dist/AccessibleNode.mjs +0 -177
- package/dist/Alignment.d.ts +0 -38
- package/dist/Alignment.mjs +0 -90
- package/dist/BorderEdges.d.ts +0 -50
- package/dist/BorderEdges.mjs +0 -114
- package/dist/BorderStyle.d.ts +0 -27
- package/dist/BorderStyle.mjs +0 -81
- package/dist/Bytes.d.ts +0 -19
- package/dist/Bytes.mjs +0 -76
- package/dist/CaretPosition.d.ts +0 -34
- package/dist/CaretPosition.mjs +0 -148
- package/dist/CellAlignment.d.ts +0 -25
- package/dist/CellAlignment.mjs +0 -75
- package/dist/CellShift.d.ts +0 -30
- package/dist/CellShift.mjs +0 -78
- package/dist/Clipboard.d.ts +0 -22
- package/dist/Clipboard.mjs +0 -90
- package/dist/ColumnSide.d.ts +0 -24
- package/dist/ColumnSide.mjs +0 -72
- package/dist/ControlKind.d.ts +0 -28
- package/dist/ControlKind.mjs +0 -84
- package/dist/ControlLock.d.ts +0 -42
- package/dist/ControlLock.mjs +0 -96
- package/dist/DocumentStatus.d.ts +0 -34
- package/dist/DocumentStatus.mjs +0 -148
- package/dist/Editor.d.ts +0 -773
- package/dist/Editor.mjs +0 -2269
- package/dist/EditorMode.d.ts +0 -34
- package/dist/EditorMode.mjs +0 -84
- package/dist/Element.d.ts +0 -57
- package/dist/Element.mjs +0 -201
- package/dist/ElementKind.d.ts +0 -28
- package/dist/ElementKind.mjs +0 -78
- package/dist/ElementList.d.ts +0 -20
- package/dist/ElementList.mjs +0 -71
- package/dist/ElementText.d.ts +0 -34
- package/dist/ElementText.mjs +0 -84
- package/dist/Event.d.ts +0 -45
- package/dist/Event.mjs +0 -159
- package/dist/EventKind.d.ts +0 -39
- package/dist/EventKind.mjs +0 -93
- package/dist/EventList.d.ts +0 -20
- package/dist/EventList.mjs +0 -71
- package/dist/Fonts.d.ts +0 -29
- package/dist/Fonts.mjs +0 -107
- package/dist/Highlight.d.ts +0 -41
- package/dist/Highlight.mjs +0 -117
- package/dist/MarginPreset.d.ts +0 -38
- package/dist/MarginPreset.mjs +0 -90
- package/dist/MarkSeverity.d.ts +0 -25
- package/dist/MarkSeverity.mjs +0 -75
- package/dist/Modifiers.d.ts +0 -34
- package/dist/Modifiers.mjs +0 -148
- package/dist/OpenError.d.ts +0 -30
- package/dist/OpenError.mjs +0 -78
- package/dist/Orientation.d.ts +0 -30
- package/dist/Orientation.mjs +0 -78
- package/dist/PageNumber.d.ts +0 -34
- package/dist/PageNumber.mjs +0 -84
- package/dist/PaperSize.d.ts +0 -50
- package/dist/PaperSize.mjs +0 -108
- package/dist/ParagraphBorders.d.ts +0 -34
- package/dist/ParagraphBorders.mjs +0 -84
- package/dist/PictureWrap.d.ts +0 -34
- package/dist/PictureWrap.mjs +0 -90
- package/dist/PointerKind.d.ts +0 -23
- package/dist/PointerKind.mjs +0 -75
- package/dist/Rect.d.ts +0 -34
- package/dist/Rect.mjs +0 -148
- package/dist/Request.d.ts +0 -55
- package/dist/Request.mjs +0 -207
- package/dist/RequestKind.d.ts +0 -45
- package/dist/RequestKind.mjs +0 -105
- package/dist/RequestList.d.ts +0 -20
- package/dist/RequestList.mjs +0 -71
- package/dist/RowHeightRule.d.ts +0 -34
- package/dist/RowHeightRule.mjs +0 -84
- package/dist/RowSide.d.ts +0 -24
- package/dist/RowSide.mjs +0 -72
- package/dist/SaveError.d.ts +0 -24
- package/dist/SaveError.mjs +0 -72
- package/dist/SelectionInfo.d.ts +0 -39
- package/dist/SelectionInfo.mjs +0 -166
- package/dist/SelectionKind.d.ts +0 -37
- package/dist/SelectionKind.mjs +0 -93
- package/dist/TableAlignment.d.ts +0 -25
- package/dist/TableAlignment.mjs +0 -75
- package/dist/TableSelection.d.ts +0 -38
- package/dist/TableSelection.mjs +0 -90
- package/dist/TableWidthUnit.d.ts +0 -31
- package/dist/TableWidthUnit.mjs +0 -81
- package/dist/TextUnit.d.ts +0 -25
- package/dist/TextUnit.mjs +0 -75
- package/dist/diplomat-runtime.d.ts +0 -15
- package/dist/diplomat-runtime.mjs +0 -786
- package/dist/diplomat-wasm.mjs +0 -18
- package/dist/gpu.d.ts +0 -15
- package/dist/gpu.mjs +0 -42
- package/dist/index.mjs +0 -101
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import { EditorError } from '../errors.js';
|
|
2
|
+
import { Method } from '../transport/protocol.js';
|
|
3
|
+
/** The accessibility tree over a session. */
|
|
4
|
+
export function createAccessibility(s) {
|
|
5
|
+
return { tree: () => s.call(Method.AccessibleTree) };
|
|
6
|
+
}
|
|
7
|
+
/** The keys the application owns (the engine's host keys), by their Windows shortcut. */
|
|
8
|
+
const hostKeys = {
|
|
9
|
+
'Ctrl+S': 'save',
|
|
10
|
+
F12: 'saveAs',
|
|
11
|
+
'Ctrl+P': 'print',
|
|
12
|
+
'Ctrl+O': 'open',
|
|
13
|
+
'Ctrl+N': 'new',
|
|
14
|
+
'Ctrl+F': 'find',
|
|
15
|
+
'Ctrl+H': 'replace',
|
|
16
|
+
'Ctrl+G': 'goTo',
|
|
17
|
+
'Ctrl+K': 'insertHyperlink',
|
|
18
|
+
F7: 'nextMisspelling',
|
|
19
|
+
'Ctrl+Shift+F': 'focusFont',
|
|
20
|
+
'Ctrl+Shift+P': 'focusFontSize',
|
|
21
|
+
F1: 'help',
|
|
22
|
+
};
|
|
23
|
+
/** A shortcut in one spelling: modifiers sorted, case ignored. `'Ctrl+Alt+S'`, `'⌥⌘S'`. */
|
|
24
|
+
function normalize(keys) {
|
|
25
|
+
const glyphs = /^[⌘⌥⇧⌃]*/u.exec(keys)[0];
|
|
26
|
+
const parts = glyphs ? [...glyphs, keys.slice(glyphs.length)] : keys.split(/\+(?=.)/);
|
|
27
|
+
const key = parts.pop().toLowerCase();
|
|
28
|
+
return [...parts.map((p) => p.toLowerCase()).sort(), key].join('+');
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Shortcuts over a session. Lookups are answered here, from the catalog, the host keys and the registrations, so
|
|
32
|
+
* they can be synchronous; registrations also go to the engine, which presses them.
|
|
33
|
+
*/
|
|
34
|
+
export function createShortcuts(s) {
|
|
35
|
+
const registered = new Map();
|
|
36
|
+
const lookup = (keys) => {
|
|
37
|
+
const key = normalize(keys);
|
|
38
|
+
const matches = (k) => normalize(k) === key;
|
|
39
|
+
for (const [id, k] of registered)
|
|
40
|
+
if (matches(k.windows) || matches(k.mac))
|
|
41
|
+
return { kind: 'shortcut', id };
|
|
42
|
+
for (const c of s.catalog)
|
|
43
|
+
if ([...c.shortcuts.windows, ...c.shortcuts.mac].some(matches))
|
|
44
|
+
return { kind: 'command', id: c.id };
|
|
45
|
+
const host = Object.entries(hostKeys).find(([k]) => matches(k));
|
|
46
|
+
return host ? { kind: 'host', command: host[1] } : null;
|
|
47
|
+
};
|
|
48
|
+
const report = (call) => call.catch((e) => s.emit('error', e instanceof EditorError ? e : new EditorError('internal', String(e), { cause: e })));
|
|
49
|
+
return {
|
|
50
|
+
register: ({ id, keys }) => {
|
|
51
|
+
const both = typeof keys === 'string' ? { windows: keys, mac: keys } : keys;
|
|
52
|
+
if (s.destroyed)
|
|
53
|
+
throw new EditorError('destroyed', 'the editor was destroyed');
|
|
54
|
+
for (const k of new Set([both.windows, both.mac])) {
|
|
55
|
+
const taken = lookup(k);
|
|
56
|
+
if (taken)
|
|
57
|
+
throw new EditorError('unavailable', `${k} is already ${taken.kind === 'host' ? `the ${taken.command} key` : `bound to ${taken.id}`}`);
|
|
58
|
+
}
|
|
59
|
+
registered.set(id, both);
|
|
60
|
+
report(s.call(Method.ShortcutsRegister, { id, keys }));
|
|
61
|
+
return () => {
|
|
62
|
+
if (registered.get(id) !== both)
|
|
63
|
+
return;
|
|
64
|
+
registered.delete(id);
|
|
65
|
+
if (!s.destroyed)
|
|
66
|
+
report(s.call(Method.ShortcutsUnregister, id));
|
|
67
|
+
};
|
|
68
|
+
},
|
|
69
|
+
lookup,
|
|
70
|
+
};
|
|
71
|
+
}
|
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
import type { Session } from '../editor.js';
|
|
2
|
+
import type { LineSpacing, Mixed, RowHeight, TableWidth, Tri, UnderlineStyle } from '../state.js';
|
|
3
|
+
import type { Color, Points } from '../types.js';
|
|
4
|
+
import type { TabAlignment, TabLeader } from './ruler.js';
|
|
5
|
+
/** The editor's dialogs as typed models: the application draws them. */
|
|
6
|
+
export interface Dialogs {
|
|
7
|
+
/** Opens a dialog over the selection's current values. */
|
|
8
|
+
open<K extends DialogKind>(kind: K): Promise<DialogSessionOf<K>>;
|
|
9
|
+
}
|
|
10
|
+
/** A dialog. */
|
|
11
|
+
export type DialogKind = 'font' | 'paragraph' | 'pageSetup' | 'insertTable' | 'tableProperties' | 'pictureSize' | 'altText' | 'hyperlink' | 'tabs' | 'accessibility';
|
|
12
|
+
/** An open dialog. */
|
|
13
|
+
export interface DialogSession<K extends DialogKind> {
|
|
14
|
+
/** Which dialog. */
|
|
15
|
+
readonly kind: K;
|
|
16
|
+
/** The selection's current values, `'mixed'` where they differ. */
|
|
17
|
+
readonly values: DialogValues[K];
|
|
18
|
+
/** Each field's label, kind, range and state, by field name; a field may have no entry. */
|
|
19
|
+
readonly fields: {
|
|
20
|
+
readonly [F in keyof DialogValues[K]]?: FieldInfo;
|
|
21
|
+
};
|
|
22
|
+
/** Changes some values; dependent values and field states are recomputed. Resolves with the new model. */
|
|
23
|
+
update(patch: Partial<DialogValues[K]>): Promise<DialogSessionOf<K>>;
|
|
24
|
+
/** Validates, then applies: one transaction and one undo step. */
|
|
25
|
+
apply(): Promise<void>;
|
|
26
|
+
/** Closes the dialog and changes nothing. */
|
|
27
|
+
cancel(): void;
|
|
28
|
+
}
|
|
29
|
+
/** The accessibility dialog's session: adds selecting an issue's object. */
|
|
30
|
+
export interface AccessibilityDialogSession extends DialogSession<'accessibility'> {
|
|
31
|
+
/** Selects the issue's object. */
|
|
32
|
+
select(issueId: string): Promise<void>;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* A dialog kind's session: {@link AccessibilityDialogSession} for `'accessibility'`, else {@link DialogSession}. Over a
|
|
36
|
+
* kind known only at run time it is a union by `kind`: code that draws any dialog from its fields can update it by
|
|
37
|
+
* field name, and narrow on `kind` for the accessibility dialog's `select`.
|
|
38
|
+
*/
|
|
39
|
+
export type DialogSessionOf<K extends DialogKind = DialogKind> = K extends 'accessibility' ? AccessibilityDialogSession : DialogSession<K>;
|
|
40
|
+
/** A dialog field's metadata. */
|
|
41
|
+
export interface FieldInfo {
|
|
42
|
+
/** The English label. */
|
|
43
|
+
label: string;
|
|
44
|
+
/** Whether it can be changed now. */
|
|
45
|
+
enabled: boolean;
|
|
46
|
+
/** The control it wants. */
|
|
47
|
+
kind: 'number' | 'length' | 'text' | 'choice' | 'toggle' | 'color' | 'list';
|
|
48
|
+
/** The minimum. */
|
|
49
|
+
min?: number;
|
|
50
|
+
/** The maximum. */
|
|
51
|
+
max?: number;
|
|
52
|
+
/** The step. */
|
|
53
|
+
step?: number;
|
|
54
|
+
/** A choice's options. */
|
|
55
|
+
options?: {
|
|
56
|
+
value: string;
|
|
57
|
+
label: string;
|
|
58
|
+
}[];
|
|
59
|
+
}
|
|
60
|
+
/** Each dialog's values. */
|
|
61
|
+
export interface DialogValues {
|
|
62
|
+
/** The Font dialog. */
|
|
63
|
+
font: {
|
|
64
|
+
font: Mixed<string>;
|
|
65
|
+
style: Mixed<'regular' | 'italic' | 'bold' | 'boldItalic'>;
|
|
66
|
+
size: Mixed<Points>;
|
|
67
|
+
color: Mixed<Color | 'auto'>;
|
|
68
|
+
underline: Mixed<UnderlineStyle>;
|
|
69
|
+
underlineColor: Mixed<Color | 'auto'>;
|
|
70
|
+
strikethrough: Tri;
|
|
71
|
+
doubleStrikethrough: Tri;
|
|
72
|
+
superscript: Tri;
|
|
73
|
+
subscript: Tri;
|
|
74
|
+
smallCaps: Tri;
|
|
75
|
+
allCaps: Tri;
|
|
76
|
+
hidden: Tri;
|
|
77
|
+
characterSpacing: Mixed<Points>;
|
|
78
|
+
position: Mixed<Points>;
|
|
79
|
+
};
|
|
80
|
+
/** The Paragraph dialog. */
|
|
81
|
+
paragraph: {
|
|
82
|
+
alignment: Mixed<'left' | 'center' | 'right' | 'justify'>;
|
|
83
|
+
outlineLevel: Mixed<number | 'body'>;
|
|
84
|
+
left: Mixed<Points>;
|
|
85
|
+
right: Mixed<Points>;
|
|
86
|
+
special: Mixed<'none' | 'firstLine' | 'hanging'>;
|
|
87
|
+
by: Mixed<Points>;
|
|
88
|
+
before: Mixed<Points | 'auto'>;
|
|
89
|
+
after: Mixed<Points | 'auto'>;
|
|
90
|
+
lineSpacing: Mixed<LineSpacing>;
|
|
91
|
+
keepWithNext: Tri;
|
|
92
|
+
keepLinesTogether: Tri;
|
|
93
|
+
pageBreakBefore: Tri;
|
|
94
|
+
widowControl: Tri;
|
|
95
|
+
};
|
|
96
|
+
/** The Page setup dialog. */
|
|
97
|
+
pageSetup: {
|
|
98
|
+
top: Points;
|
|
99
|
+
bottom: Points;
|
|
100
|
+
left: Points;
|
|
101
|
+
right: Points;
|
|
102
|
+
gutter: Points;
|
|
103
|
+
orientation: 'portrait' | 'landscape';
|
|
104
|
+
width: Points;
|
|
105
|
+
height: Points;
|
|
106
|
+
headerDistance: Points;
|
|
107
|
+
footerDistance: Points;
|
|
108
|
+
differentFirstPage: boolean;
|
|
109
|
+
differentOddEven: boolean;
|
|
110
|
+
applyTo: 'section' | 'wholeDocument';
|
|
111
|
+
};
|
|
112
|
+
/** The Insert table dialog. */
|
|
113
|
+
insertTable: {
|
|
114
|
+
rows: number;
|
|
115
|
+
columns: number;
|
|
116
|
+
};
|
|
117
|
+
/** The Table properties dialog. */
|
|
118
|
+
tableProperties: {
|
|
119
|
+
width: TableWidth;
|
|
120
|
+
alignment: 'left' | 'center' | 'right';
|
|
121
|
+
indent: Points;
|
|
122
|
+
rowHeight: Mixed<RowHeight>;
|
|
123
|
+
rowCanBreak: Tri;
|
|
124
|
+
headerRow: Tri;
|
|
125
|
+
columnWidth: Mixed<Points>;
|
|
126
|
+
cellAlignment: Mixed<'top' | 'center' | 'bottom'>;
|
|
127
|
+
cellMargins: {
|
|
128
|
+
top: Points;
|
|
129
|
+
bottom: Points;
|
|
130
|
+
left: Points;
|
|
131
|
+
right: Points;
|
|
132
|
+
};
|
|
133
|
+
};
|
|
134
|
+
/** The Picture size dialog. */
|
|
135
|
+
pictureSize: {
|
|
136
|
+
width: Points;
|
|
137
|
+
height: Points;
|
|
138
|
+
scaleWidth: number;
|
|
139
|
+
scaleHeight: number;
|
|
140
|
+
lockAspect: boolean;
|
|
141
|
+
reset: boolean;
|
|
142
|
+
};
|
|
143
|
+
/** The Alt text dialog. */
|
|
144
|
+
altText: {
|
|
145
|
+
text: string;
|
|
146
|
+
decorative: boolean;
|
|
147
|
+
};
|
|
148
|
+
/** The Hyperlink dialog. */
|
|
149
|
+
hyperlink: {
|
|
150
|
+
text: string;
|
|
151
|
+
address: string;
|
|
152
|
+
};
|
|
153
|
+
/** The Tabs dialog. */
|
|
154
|
+
tabs: {
|
|
155
|
+
stops: {
|
|
156
|
+
position: Points;
|
|
157
|
+
alignment: TabAlignment;
|
|
158
|
+
leader: TabLeader;
|
|
159
|
+
inherited: boolean;
|
|
160
|
+
}[];
|
|
161
|
+
defaultStop: Points;
|
|
162
|
+
/** The stop being edited. */
|
|
163
|
+
position: Points | null;
|
|
164
|
+
alignment: TabAlignment;
|
|
165
|
+
leader: TabLeader;
|
|
166
|
+
/** Stops to clear on apply. */
|
|
167
|
+
cleared: Points[];
|
|
168
|
+
/** The Set, Clear and Clear All buttons, applied by `update`. */
|
|
169
|
+
action: 'none' | 'set' | 'clear' | 'clearAll';
|
|
170
|
+
};
|
|
171
|
+
/** The Accessibility checker (read only). */
|
|
172
|
+
accessibility: {
|
|
173
|
+
issues: {
|
|
174
|
+
id: string;
|
|
175
|
+
text: string;
|
|
176
|
+
tip: boolean;
|
|
177
|
+
}[];
|
|
178
|
+
};
|
|
179
|
+
}
|
|
180
|
+
/** The dialogs over a session. */
|
|
181
|
+
export declare function createDialogs(s: Session): Dialogs;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { Method } from '../transport/protocol.js';
|
|
2
|
+
/** The dialogs over a session. */
|
|
3
|
+
export function createDialogs(s) {
|
|
4
|
+
const open = (model) => {
|
|
5
|
+
const { kind, values, fields } = model;
|
|
6
|
+
const dialog = {
|
|
7
|
+
kind,
|
|
8
|
+
values,
|
|
9
|
+
fields,
|
|
10
|
+
update: async (patch) => open(await s.call(Method.DialogUpdate, { model, patch: { ...patch, kind } })),
|
|
11
|
+
apply: () => s.commit(Method.DialogApply, model),
|
|
12
|
+
cancel: () => { },
|
|
13
|
+
};
|
|
14
|
+
const select = (issueId) => s.call(Method.DialogSelectIssue, issueId);
|
|
15
|
+
return (kind === 'accessibility' ? Object.assign(dialog, { select }) : dialog);
|
|
16
|
+
};
|
|
17
|
+
return { open: async (kind) => open(await s.call(Method.DialogOpen, kind)) };
|
|
18
|
+
}
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
import type { Op } from '../commands.js';
|
|
2
|
+
import type { Session } from '../editor.js';
|
|
3
|
+
import type { SelectionSummary } from '../state.js';
|
|
4
|
+
import type { ClientPoint, ElementId } from '../types.js';
|
|
5
|
+
/** A content control's kind. */
|
|
6
|
+
export type ControlKind = 'richText' | 'plainText' | 'picture' | 'checkbox' | 'date' | 'dropDown' | 'comboBox' | 'group' | 'repeatingSection';
|
|
7
|
+
/** The merge designer's elements: fields and content controls. Changing them is done with the commands. */
|
|
8
|
+
export interface Elements {
|
|
9
|
+
/** The elements, in document order. */
|
|
10
|
+
list(filter?: {
|
|
11
|
+
kind?: 'field' | ControlKind;
|
|
12
|
+
match?: {
|
|
13
|
+
in: 'code' | 'tag' | 'title';
|
|
14
|
+
text: string;
|
|
15
|
+
};
|
|
16
|
+
story?: SelectionSummary['story'];
|
|
17
|
+
}): Promise<ElementInfo[]>;
|
|
18
|
+
/** One element in detail. */
|
|
19
|
+
get(id: ElementId): Promise<ElementDetail>;
|
|
20
|
+
/** The body (or an element) as blocks. */
|
|
21
|
+
structure(options?: {
|
|
22
|
+
root?: ElementId;
|
|
23
|
+
depth?: number;
|
|
24
|
+
}): Promise<Block[]>;
|
|
25
|
+
/** Selects an element; enters a header or footer when needed. */
|
|
26
|
+
select(id: ElementId, options?: {
|
|
27
|
+
reveal?: boolean;
|
|
28
|
+
}): Promise<void>;
|
|
29
|
+
/** The unfilled picture placeholders, in document order (the headers and footers after the body). */
|
|
30
|
+
placeholders(): Promise<PlaceholderInfo[]>;
|
|
31
|
+
}
|
|
32
|
+
/** An unfilled picture placeholder. */
|
|
33
|
+
export interface PlaceholderInfo {
|
|
34
|
+
/** Its key: what `fillPlaceholder` takes. */
|
|
35
|
+
key: string;
|
|
36
|
+
/** The control it is in. */
|
|
37
|
+
element: ElementId | null;
|
|
38
|
+
}
|
|
39
|
+
/** {@link Elements} on a mounted editor: adds drop targets and hit testing. */
|
|
40
|
+
export interface MountedElements extends Elements {
|
|
41
|
+
/** What is under a point, without moving the selection. */
|
|
42
|
+
hitTest(at: ClientPoint): Promise<{
|
|
43
|
+
element: ElementId | null;
|
|
44
|
+
editable: boolean;
|
|
45
|
+
}>;
|
|
46
|
+
/** An external drag (a field list beside the editor): shows the drop caret. */
|
|
47
|
+
dragOver(at: ClientPoint): void;
|
|
48
|
+
/** The external drag left the editor. */
|
|
49
|
+
dragLeave(): void;
|
|
50
|
+
/** Drops at the point: runs `op` there, as one transaction. */
|
|
51
|
+
drop(at: ClientPoint, op: Op): Promise<void>;
|
|
52
|
+
}
|
|
53
|
+
/** An element. */
|
|
54
|
+
export interface ElementInfo {
|
|
55
|
+
/** The element. */
|
|
56
|
+
id: ElementId;
|
|
57
|
+
/** Its kind. */
|
|
58
|
+
kind: 'field' | ControlKind;
|
|
59
|
+
/** A field's code. */
|
|
60
|
+
code?: string;
|
|
61
|
+
/** A control's tag. */
|
|
62
|
+
tag?: string;
|
|
63
|
+
/** A control's title. */
|
|
64
|
+
title?: string;
|
|
65
|
+
/** The result or content text, up to 200 characters. */
|
|
66
|
+
display: string;
|
|
67
|
+
/** The story it is in. */
|
|
68
|
+
story: SelectionSummary['story'];
|
|
69
|
+
/** The element it is in. */
|
|
70
|
+
parent: ElementId | null;
|
|
71
|
+
/** Locked against editing. */
|
|
72
|
+
locked: boolean;
|
|
73
|
+
}
|
|
74
|
+
/** An element in detail. */
|
|
75
|
+
export interface ElementDetail extends ElementInfo {
|
|
76
|
+
/** A control's lock. */
|
|
77
|
+
lock: 'none' | 'control' | 'content' | 'both';
|
|
78
|
+
/** A control's placeholder text. */
|
|
79
|
+
placeholder?: string;
|
|
80
|
+
/** A control's data binding. */
|
|
81
|
+
binding?: DataBinding;
|
|
82
|
+
/** A control's options. */
|
|
83
|
+
options?: ControlOptions;
|
|
84
|
+
/** The elements inside it. */
|
|
85
|
+
children: ElementId[];
|
|
86
|
+
}
|
|
87
|
+
/** A content control's binding to a custom XML part. */
|
|
88
|
+
export interface DataBinding {
|
|
89
|
+
/** The XPath of the bound node. */
|
|
90
|
+
xpath: string;
|
|
91
|
+
/** The data part's item id. */
|
|
92
|
+
storeItemId?: string;
|
|
93
|
+
/** The XPath's namespace prefixes. */
|
|
94
|
+
prefixMappings?: string;
|
|
95
|
+
}
|
|
96
|
+
/** A content control's options, by kind: checkbox, date, list, or plain text. */
|
|
97
|
+
export type ControlOptions = {
|
|
98
|
+
checked?: boolean;
|
|
99
|
+
} | {
|
|
100
|
+
format?: string;
|
|
101
|
+
locale?: string;
|
|
102
|
+
} | {
|
|
103
|
+
items: {
|
|
104
|
+
text: string;
|
|
105
|
+
value: string;
|
|
106
|
+
}[];
|
|
107
|
+
} | {
|
|
108
|
+
multiline?: boolean;
|
|
109
|
+
};
|
|
110
|
+
/** A block of the document structure. */
|
|
111
|
+
export type Block = {
|
|
112
|
+
kind: 'paragraph';
|
|
113
|
+
textLength: number;
|
|
114
|
+
elements: ElementId[];
|
|
115
|
+
} | {
|
|
116
|
+
kind: 'table';
|
|
117
|
+
rows: {
|
|
118
|
+
cells: {
|
|
119
|
+
span: number;
|
|
120
|
+
verticalMerge: 'none' | 'start' | 'continue';
|
|
121
|
+
empty: boolean;
|
|
122
|
+
blocks: Block[];
|
|
123
|
+
}[];
|
|
124
|
+
}[];
|
|
125
|
+
};
|
|
126
|
+
/** The document's custom XML data parts. Writing and removing them is done with commands. */
|
|
127
|
+
export interface DataParts {
|
|
128
|
+
/** Every data part. */
|
|
129
|
+
list(): Promise<{
|
|
130
|
+
namespace: string | null;
|
|
131
|
+
itemId: string;
|
|
132
|
+
}[]>;
|
|
133
|
+
/** The data parts with a namespace or an item id. */
|
|
134
|
+
get(options: {
|
|
135
|
+
namespace?: string;
|
|
136
|
+
itemId?: string;
|
|
137
|
+
}): Promise<{
|
|
138
|
+
namespace: string | null;
|
|
139
|
+
itemId: string;
|
|
140
|
+
xml: string;
|
|
141
|
+
}[]>;
|
|
142
|
+
}
|
|
143
|
+
/** The elements over a session. */
|
|
144
|
+
export declare function createElements(s: Session): Elements;
|
|
145
|
+
/** The data parts over a session. */
|
|
146
|
+
export declare function createDataParts(s: Session): DataParts;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { Method } from '../transport/protocol.js';
|
|
2
|
+
/** The elements over a session. */
|
|
3
|
+
export function createElements(s) {
|
|
4
|
+
return {
|
|
5
|
+
list: (filter) => s.call(Method.Elements, filter ?? null),
|
|
6
|
+
get: (id) => s.call(Method.Element, id),
|
|
7
|
+
structure: (options) => s.call(Method.Structure, options ?? null),
|
|
8
|
+
select: (id, options) => s.call(Method.SelectElement, { id, reveal: options?.reveal ?? false }),
|
|
9
|
+
placeholders: () => s.call(Method.Placeholders),
|
|
10
|
+
};
|
|
11
|
+
}
|
|
12
|
+
/** The data parts over a session. */
|
|
13
|
+
export function createDataParts(s) {
|
|
14
|
+
return {
|
|
15
|
+
list: async () => (await s.call(Method.DataParts)).map(({ namespace, itemId }) => ({ namespace, itemId })),
|
|
16
|
+
get: (options) => s.call(Method.DataParts, options),
|
|
17
|
+
};
|
|
18
|
+
}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import type { Session } from '../editor.js';
|
|
2
|
+
import type { MatchId } from '../types.js';
|
|
3
|
+
/** Find and replace, over the text of the current markup view. */
|
|
4
|
+
export interface Find {
|
|
5
|
+
/** Selects and reveals the next match. */
|
|
6
|
+
next(query: FindQuery): Promise<FindResult>;
|
|
7
|
+
/** Selects and reveals the previous match. */
|
|
8
|
+
previous(query: FindQuery): Promise<FindResult>;
|
|
9
|
+
/** Every match, for a navigation pane's results list. */
|
|
10
|
+
all(query: FindQuery): Promise<FindMatch[]>;
|
|
11
|
+
/** Selects and reveals a match from {@link Find.all}. */
|
|
12
|
+
select(match: MatchId): Promise<void>;
|
|
13
|
+
/** Replaces the current match, then finds the next. */
|
|
14
|
+
replace(query: FindQuery, replacement: string): Promise<FindResult>;
|
|
15
|
+
/** Replaces every match: one transaction. */
|
|
16
|
+
replaceAll(query: FindQuery, replacement: string): Promise<{
|
|
17
|
+
count: number;
|
|
18
|
+
}>;
|
|
19
|
+
}
|
|
20
|
+
/** What to find. */
|
|
21
|
+
export interface FindQuery {
|
|
22
|
+
/** The text. */
|
|
23
|
+
text: string;
|
|
24
|
+
/** Case-sensitive. Default false. */
|
|
25
|
+
matchCase?: boolean;
|
|
26
|
+
/** Whole words only. Default false. */
|
|
27
|
+
wholeWords?: boolean;
|
|
28
|
+
}
|
|
29
|
+
/** The result of a find step. */
|
|
30
|
+
export interface FindResult {
|
|
31
|
+
/** A match was found and selected. */
|
|
32
|
+
found: boolean;
|
|
33
|
+
/** The search wrapped around the document's end. */
|
|
34
|
+
wrapped: boolean;
|
|
35
|
+
}
|
|
36
|
+
/** A match in a results list. */
|
|
37
|
+
export interface FindMatch {
|
|
38
|
+
/** The match, for {@link Find.select}. */
|
|
39
|
+
id: MatchId;
|
|
40
|
+
/** Some text before it. */
|
|
41
|
+
before: string;
|
|
42
|
+
/** The matched text. */
|
|
43
|
+
text: string;
|
|
44
|
+
/** Some text after it. */
|
|
45
|
+
after: string;
|
|
46
|
+
/** Its page. */
|
|
47
|
+
page: number;
|
|
48
|
+
}
|
|
49
|
+
/** Find and replace over a session. */
|
|
50
|
+
export declare function createFind(s: Session): Find;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { Method } from '../transport/protocol.js';
|
|
2
|
+
/** Find and replace over a session. */
|
|
3
|
+
export function createFind(s) {
|
|
4
|
+
return {
|
|
5
|
+
next: (query) => s.call(Method.Find, { query, direction: 'next' }),
|
|
6
|
+
previous: (query) => s.call(Method.Find, { query, direction: 'previous' }),
|
|
7
|
+
all: (query) => s.call(Method.FindAll, query),
|
|
8
|
+
select: (match) => s.call(Method.SelectMatch, match),
|
|
9
|
+
replace: (query, replacement) => s.call(Method.Replace, { query, with: replacement }),
|
|
10
|
+
replaceAll: (query, replacement) => s.call(Method.ReplaceAll, { query, with: replacement }),
|
|
11
|
+
};
|
|
12
|
+
}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import type { CommandId } from '../commands.js';
|
|
2
|
+
import type { Session } from '../editor.js';
|
|
3
|
+
import type { ClientPoint, CommentId, ElementId, RevisionId } from '../types.js';
|
|
4
|
+
/** The context menu as a typed model: the application draws it. */
|
|
5
|
+
export interface Menus {
|
|
6
|
+
/** The menu for the selection, as the context-menu key would open it. */
|
|
7
|
+
contextMenu(): Promise<ContextMenu>;
|
|
8
|
+
/** Runs an item: one transaction. */
|
|
9
|
+
invoke(action: MenuAction): Promise<void>;
|
|
10
|
+
}
|
|
11
|
+
/** The `contextMenu` event: the user asked for a menu. */
|
|
12
|
+
export interface ContextMenuEvent {
|
|
13
|
+
/** The menu to show. */
|
|
14
|
+
menu: ContextMenu;
|
|
15
|
+
/** Where to show it. */
|
|
16
|
+
at: ClientPoint;
|
|
17
|
+
/** A right-click, or the keyboard. */
|
|
18
|
+
via: 'pointer' | 'keyboard';
|
|
19
|
+
}
|
|
20
|
+
/** A context menu. */
|
|
21
|
+
export interface ContextMenu {
|
|
22
|
+
/** What the menu is for. */
|
|
23
|
+
target: MenuTarget;
|
|
24
|
+
/** The items, in order. */
|
|
25
|
+
items: MenuItem[];
|
|
26
|
+
}
|
|
27
|
+
/** What a context menu is for. */
|
|
28
|
+
export type MenuTarget = {
|
|
29
|
+
kind: 'text';
|
|
30
|
+
} | {
|
|
31
|
+
kind: 'misspelling';
|
|
32
|
+
word: string;
|
|
33
|
+
language: string;
|
|
34
|
+
} | {
|
|
35
|
+
kind: 'link';
|
|
36
|
+
address: string;
|
|
37
|
+
} | {
|
|
38
|
+
kind: 'table';
|
|
39
|
+
} | {
|
|
40
|
+
kind: 'picture';
|
|
41
|
+
} | {
|
|
42
|
+
kind: 'textBox';
|
|
43
|
+
} | {
|
|
44
|
+
kind: 'element';
|
|
45
|
+
id: ElementId;
|
|
46
|
+
} | {
|
|
47
|
+
kind: 'revision';
|
|
48
|
+
id: RevisionId;
|
|
49
|
+
} | {
|
|
50
|
+
kind: 'comment';
|
|
51
|
+
id: CommentId;
|
|
52
|
+
} | {
|
|
53
|
+
kind: 'headerFooter';
|
|
54
|
+
};
|
|
55
|
+
/** A context menu item. */
|
|
56
|
+
export type MenuItem = {
|
|
57
|
+
kind: 'command';
|
|
58
|
+
command: CommandId;
|
|
59
|
+
label: string;
|
|
60
|
+
enabled: boolean;
|
|
61
|
+
checked?: boolean;
|
|
62
|
+
shortcut?: string;
|
|
63
|
+
action: MenuAction;
|
|
64
|
+
} | {
|
|
65
|
+
kind: 'suggestion';
|
|
66
|
+
label: string;
|
|
67
|
+
action: MenuAction;
|
|
68
|
+
} | {
|
|
69
|
+
kind: 'submenu';
|
|
70
|
+
label: string;
|
|
71
|
+
items: MenuItem[];
|
|
72
|
+
} | {
|
|
73
|
+
kind: 'separator';
|
|
74
|
+
};
|
|
75
|
+
declare const menuAction: unique symbol;
|
|
76
|
+
/** An opaque item action, only passed back to {@link Menus.invoke}. */
|
|
77
|
+
export type MenuAction = {
|
|
78
|
+
readonly [menuAction]: true;
|
|
79
|
+
};
|
|
80
|
+
/** The menus over a session. */
|
|
81
|
+
export declare function createMenus(s: Session): Menus;
|
|
82
|
+
export {};
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import type { Session } from '../editor.js';
|
|
2
|
+
import type { Color, HeadingId, Points, StyleId } from '../types.js';
|
|
3
|
+
/** The document's headings, for a navigation pane. */
|
|
4
|
+
export interface Navigation {
|
|
5
|
+
/** The headings, in document order. */
|
|
6
|
+
headings(): Promise<Heading[]>;
|
|
7
|
+
/** Selects and reveals a heading. */
|
|
8
|
+
select(heading: HeadingId): Promise<void>;
|
|
9
|
+
}
|
|
10
|
+
/** A heading. */
|
|
11
|
+
export interface Heading {
|
|
12
|
+
/** The heading. */
|
|
13
|
+
id: HeadingId;
|
|
14
|
+
/** Its outline level, from 1. */
|
|
15
|
+
level: number;
|
|
16
|
+
/** Its text. */
|
|
17
|
+
text: string;
|
|
18
|
+
/** Its page. */
|
|
19
|
+
page: number;
|
|
20
|
+
}
|
|
21
|
+
/** The document's styles, for a style gallery. */
|
|
22
|
+
export interface Styles {
|
|
23
|
+
/** The styles, optionally of one type. */
|
|
24
|
+
list(options?: {
|
|
25
|
+
type?: 'paragraph' | 'character' | 'table';
|
|
26
|
+
}): Promise<StyleInfo[]>;
|
|
27
|
+
}
|
|
28
|
+
/** A style. */
|
|
29
|
+
export interface StyleInfo {
|
|
30
|
+
/** The style. */
|
|
31
|
+
id: StyleId;
|
|
32
|
+
/** Its display name. */
|
|
33
|
+
name: string;
|
|
34
|
+
/** Its type. */
|
|
35
|
+
type: 'paragraph' | 'character' | 'table';
|
|
36
|
+
/** Built in. */
|
|
37
|
+
builtIn: boolean;
|
|
38
|
+
/** Shown in a style gallery (`w:qFormat`). */
|
|
39
|
+
quick: boolean;
|
|
40
|
+
/** The sort priority. */
|
|
41
|
+
priority: number;
|
|
42
|
+
/** Hidden from lists. */
|
|
43
|
+
hidden: boolean;
|
|
44
|
+
/** The style it is based on. */
|
|
45
|
+
basedOn: StyleId | null;
|
|
46
|
+
/** For drawing a gallery tile. */
|
|
47
|
+
preview: {
|
|
48
|
+
font: string;
|
|
49
|
+
size: Points;
|
|
50
|
+
bold: boolean;
|
|
51
|
+
italic: boolean;
|
|
52
|
+
color: Color | 'auto';
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
/** The headings over a session. */
|
|
56
|
+
export declare function createNavigation(s: Session): Navigation;
|
|
57
|
+
/** The styles over a session. */
|
|
58
|
+
export declare function createStyles(s: Session): Styles;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { Method } from '../transport/protocol.js';
|
|
2
|
+
/** The headings over a session. */
|
|
3
|
+
export function createNavigation(s) {
|
|
4
|
+
return {
|
|
5
|
+
headings: () => s.call(Method.Headings),
|
|
6
|
+
select: (heading) => s.call(Method.SelectHeading, heading),
|
|
7
|
+
};
|
|
8
|
+
}
|
|
9
|
+
/** The styles over a session. */
|
|
10
|
+
export function createStyles(s) {
|
|
11
|
+
return { list: (options) => s.call(Method.Styles, options?.type ?? null) };
|
|
12
|
+
}
|