@docmentis/udoc-editor 0.0.0-stage → 0.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE-APACHE +202 -0
- package/LICENSE-MIT +21 -0
- package/README.md +47 -2
- package/dist/arrange.d.ts +37 -0
- package/dist/arrange.d.ts.map +1 -0
- package/dist/arrange.js +431 -0
- package/dist/arrange.js.map +1 -0
- package/dist/clipboard.d.ts +12 -0
- package/dist/clipboard.d.ts.map +1 -0
- package/dist/clipboard.js +101 -0
- package/dist/clipboard.js.map +1 -0
- package/dist/commands.d.ts +12 -0
- package/dist/commands.d.ts.map +1 -0
- package/dist/commands.js +225 -0
- package/dist/commands.js.map +1 -0
- package/dist/components/ComboBox.d.ts +38 -0
- package/dist/components/ComboBox.d.ts.map +1 -0
- package/dist/components/ComboBox.js +57 -0
- package/dist/components/ComboBox.js.map +1 -0
- package/dist/components/ModeSwitch.d.ts +15 -0
- package/dist/components/ModeSwitch.d.ts.map +1 -0
- package/dist/components/ModeSwitch.js +94 -0
- package/dist/components/ModeSwitch.js.map +1 -0
- package/dist/components/NewSlideModal.d.ts +41 -0
- package/dist/components/NewSlideModal.d.ts.map +1 -0
- package/dist/components/NewSlideModal.js +136 -0
- package/dist/components/NewSlideModal.js.map +1 -0
- package/dist/components/PageControls.d.ts +78 -0
- package/dist/components/PageControls.d.ts.map +1 -0
- package/dist/components/PageControls.js +201 -0
- package/dist/components/PageControls.js.map +1 -0
- package/dist/components/PageSettingsModal.d.ts +27 -0
- package/dist/components/PageSettingsModal.d.ts.map +1 -0
- package/dist/components/PageSettingsModal.js +273 -0
- package/dist/components/PageSettingsModal.js.map +1 -0
- package/dist/components/PaintOptionsModal.d.ts +19 -0
- package/dist/components/PaintOptionsModal.d.ts.map +1 -0
- package/dist/components/PaintOptionsModal.js +103 -0
- package/dist/components/PaintOptionsModal.js.map +1 -0
- package/dist/components/TextControls.d.ts +49 -0
- package/dist/components/TextControls.d.ts.map +1 -0
- package/dist/components/TextControls.js +452 -0
- package/dist/components/TextControls.js.map +1 -0
- package/dist/context-menu.d.ts +46 -0
- package/dist/context-menu.d.ts.map +1 -0
- package/dist/context-menu.js +144 -0
- package/dist/context-menu.js.map +1 -0
- package/dist/edit-client.d.ts +121 -0
- package/dist/edit-client.d.ts.map +1 -0
- package/dist/edit-client.js +154 -0
- package/dist/edit-client.js.map +1 -0
- package/dist/edit-command.d.ts +7 -0
- package/dist/edit-command.d.ts.map +1 -0
- package/dist/edit-command.js +18 -0
- package/dist/edit-command.js.map +1 -0
- package/dist/edit-mode.d.ts +19 -0
- package/dist/edit-mode.d.ts.map +1 -0
- package/dist/edit-mode.js +214 -0
- package/dist/edit-mode.js.map +1 -0
- package/dist/editor.d.ts +101 -0
- package/dist/editor.d.ts.map +1 -0
- package/dist/editor.js +101 -0
- package/dist/editor.js.map +1 -0
- package/dist/fonts/faces.d.ts +28 -0
- package/dist/fonts/faces.d.ts.map +1 -0
- package/dist/fonts/faces.js +38 -0
- package/dist/fonts/faces.js.map +1 -0
- package/dist/fonts/preview.d.ts +98 -0
- package/dist/fonts/preview.d.ts.map +1 -0
- package/dist/fonts/preview.js +149 -0
- package/dist/fonts/preview.js.map +1 -0
- package/dist/formatting-marks.d.ts +23 -0
- package/dist/formatting-marks.d.ts.map +1 -0
- package/dist/formatting-marks.js +55 -0
- package/dist/formatting-marks.js.map +1 -0
- package/dist/grips.d.ts +14 -0
- package/dist/grips.d.ts.map +1 -0
- package/dist/grips.js +459 -0
- package/dist/grips.js.map +1 -0
- package/dist/i18n/ar.d.ts +4 -0
- package/dist/i18n/ar.d.ts.map +1 -0
- package/dist/i18n/ar.js +175 -0
- package/dist/i18n/ar.js.map +1 -0
- package/dist/i18n/de.d.ts +4 -0
- package/dist/i18n/de.d.ts.map +1 -0
- package/dist/i18n/de.js +175 -0
- package/dist/i18n/de.js.map +1 -0
- package/dist/i18n/en.d.ts +5 -0
- package/dist/i18n/en.d.ts.map +1 -0
- package/dist/i18n/en.js +176 -0
- package/dist/i18n/en.js.map +1 -0
- package/dist/i18n/es.d.ts +4 -0
- package/dist/i18n/es.d.ts.map +1 -0
- package/dist/i18n/es.js +175 -0
- package/dist/i18n/es.js.map +1 -0
- package/dist/i18n/fr.d.ts +4 -0
- package/dist/i18n/fr.d.ts.map +1 -0
- package/dist/i18n/fr.js +175 -0
- package/dist/i18n/fr.js.map +1 -0
- package/dist/i18n/index.d.ts +21 -0
- package/dist/i18n/index.d.ts.map +1 -0
- package/dist/i18n/index.js +42 -0
- package/dist/i18n/index.js.map +1 -0
- package/dist/i18n/ja.d.ts +4 -0
- package/dist/i18n/ja.d.ts.map +1 -0
- package/dist/i18n/ja.js +175 -0
- package/dist/i18n/ja.js.map +1 -0
- package/dist/i18n/ko.d.ts +4 -0
- package/dist/i18n/ko.d.ts.map +1 -0
- package/dist/i18n/ko.js +175 -0
- package/dist/i18n/ko.js.map +1 -0
- package/dist/i18n/messages.d.ts +316 -0
- package/dist/i18n/messages.d.ts.map +1 -0
- package/dist/i18n/messages.js +2 -0
- package/dist/i18n/messages.js.map +1 -0
- package/dist/i18n/pt-BR.d.ts +4 -0
- package/dist/i18n/pt-BR.d.ts.map +1 -0
- package/dist/i18n/pt-BR.js +175 -0
- package/dist/i18n/pt-BR.js.map +1 -0
- package/dist/i18n/ru.d.ts +4 -0
- package/dist/i18n/ru.d.ts.map +1 -0
- package/dist/i18n/ru.js +175 -0
- package/dist/i18n/ru.js.map +1 -0
- package/dist/i18n/zh-CN.d.ts +4 -0
- package/dist/i18n/zh-CN.d.ts.map +1 -0
- package/dist/i18n/zh-CN.js +175 -0
- package/dist/i18n/zh-CN.js.map +1 -0
- package/dist/i18n/zh-TW.d.ts +4 -0
- package/dist/i18n/zh-TW.d.ts.map +1 -0
- package/dist/i18n/zh-TW.js +175 -0
- package/dist/i18n/zh-TW.js.map +1 -0
- package/dist/icons.d.ts +97 -0
- package/dist/icons.d.ts.map +1 -0
- package/dist/icons.js +103 -0
- package/dist/icons.js.map +1 -0
- package/dist/index.d.ts +9 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +14 -0
- package/dist/index.js.map +1 -0
- package/dist/insert.d.ts +21 -0
- package/dist/insert.d.ts.map +1 -0
- package/dist/insert.js +129 -0
- package/dist/insert.js.map +1 -0
- package/dist/menu-action.d.ts +73 -0
- package/dist/menu-action.d.ts.map +1 -0
- package/dist/menu-action.js +89 -0
- package/dist/menu-action.js.map +1 -0
- package/dist/mode.d.ts +21 -0
- package/dist/mode.d.ts.map +1 -0
- package/dist/mode.js +17 -0
- package/dist/mode.js.map +1 -0
- package/dist/new-slide.d.ts +21 -0
- package/dist/new-slide.d.ts.map +1 -0
- package/dist/new-slide.js +63 -0
- package/dist/new-slide.js.map +1 -0
- package/dist/page-controls.d.ts +20 -0
- package/dist/page-controls.d.ts.map +1 -0
- package/dist/page-controls.js +99 -0
- package/dist/page-controls.js.map +1 -0
- package/dist/paint.d.ts +52 -0
- package/dist/paint.d.ts.map +1 -0
- package/dist/paint.js +262 -0
- package/dist/paint.js.map +1 -0
- package/dist/ruler.d.ts +10 -0
- package/dist/ruler.d.ts.map +1 -0
- package/dist/ruler.js +97 -0
- package/dist/ruler.js.map +1 -0
- package/dist/state.d.ts +85 -0
- package/dist/state.d.ts.map +1 -0
- package/dist/state.js +28 -0
- package/dist/state.js.map +1 -0
- package/dist/styles.d.ts +2 -0
- package/dist/styles.d.ts.map +1 -0
- package/dist/styles.js +758 -0
- package/dist/styles.js.map +1 -0
- package/dist/tabs.d.ts +11 -0
- package/dist/tabs.d.ts.map +1 -0
- package/dist/tabs.js +153 -0
- package/dist/tabs.js.map +1 -0
- package/dist/text-format.d.ts +114 -0
- package/dist/text-format.d.ts.map +1 -0
- package/dist/text-format.js +315 -0
- package/dist/text-format.js.map +1 -0
- package/dist/tools.d.ts +35 -0
- package/dist/tools.d.ts.map +1 -0
- package/dist/tools.js +41 -0
- package/dist/tools.js.map +1 -0
- package/dist/version.d.ts +2 -0
- package/dist/version.d.ts.map +1 -0
- package/dist/version.js +7 -0
- package/dist/version.js.map +1 -0
- package/dist/worker/handlers.d.ts +11 -0
- package/dist/worker/handlers.d.ts.map +1 -0
- package/dist/worker/handlers.js +127 -0
- package/dist/worker/handlers.js.map +1 -0
- package/dist/worker/protocol.d.ts +190 -0
- package/dist/worker/protocol.d.ts.map +1 -0
- package/dist/worker/protocol.js +2 -0
- package/dist/worker/protocol.js.map +1 -0
- package/dist/worker/worker-source.d.ts +3 -0
- package/dist/worker/worker-source.d.ts.map +1 -0
- package/dist/worker/worker-source.js +11 -0
- package/dist/worker/worker.d.ts +2 -0
- package/dist/worker/worker.d.ts.map +1 -0
- package/dist/worker/worker.js +6 -0
- package/dist/worker/worker.js.map +1 -0
- package/package.json +69 -5
package/dist/insert.js
ADDED
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
// The Insert tab's commands: Shapes on a PDF, placed by a pointer gesture the
|
|
2
|
+
// canvas carries out, and Image on a slide deck, asked for and inserted at once.
|
|
3
|
+
import { ICON_SUBTOOL_ARROW, ICON_SUBTOOL_ELLIPSE, ICON_SUBTOOL_LINE, ICON_SUBTOOL_RECTANGLE, SHAPE_STROKE, SHAPE_STROKE_WIDTH, segmentsFor, } from "@docmentis/udoc-ui/internal";
|
|
4
|
+
import { EditCommand } from "./edit-command.js";
|
|
5
|
+
import { ICON_IMAGE } from "./icons.js";
|
|
6
|
+
/** A placed shape's fill — translucent blue (filled shapes only). */
|
|
7
|
+
const FILL = { components: [0.26, 0.55, 0.96], colorSpace: "srgb" };
|
|
8
|
+
/** A placed shape's fill opacity. */
|
|
9
|
+
const FILL_ALPHA = 0.18;
|
|
10
|
+
/** The shapes the Insert tab places, as the shell carries their place tools. */
|
|
11
|
+
const SHAPES = new Set(["rectangle", "ellipse", "line", "arrow"]);
|
|
12
|
+
/** Shapes offered by the Insert tab's shape picker (`insertShape`). */
|
|
13
|
+
const SHAPE_OPTIONS = [
|
|
14
|
+
["rectangle", ICON_SUBTOOL_RECTANGLE, "shape.rectangle"],
|
|
15
|
+
["ellipse", ICON_SUBTOOL_ELLIPSE, "shape.ellipse"],
|
|
16
|
+
["line", ICON_SUBTOOL_LINE, "shape.line"],
|
|
17
|
+
["arrow", ICON_SUBTOOL_ARROW, "shape.arrow"],
|
|
18
|
+
].map(([shape, icon, label]) => ({ tool: { kind: "extension", tool: shape }, icon, label }));
|
|
19
|
+
/**
|
|
20
|
+
* The model `GraphicsObject` for `shape` spanning the drag from `p0` to `p1`
|
|
21
|
+
* (page-local document points), ready to drop into an `InsertObjects` command's
|
|
22
|
+
* `objects`. The object carries **no `id`** — the `InsertObjects` command mints
|
|
23
|
+
* one on insert, so the host never allocates ids. Rectangle and ellipse use the
|
|
24
|
+
* box of the two points; line and arrow run `p0 → p1`, so the direction is
|
|
25
|
+
* preserved. Filled shapes (rectangle / ellipse) get the translucent fill +
|
|
26
|
+
* solid stroke; open shapes (line / arrow) are stroke only.
|
|
27
|
+
*/
|
|
28
|
+
function shapeObject(shape, p0, p1) {
|
|
29
|
+
const filled = shape === "rectangle" || shape === "ellipse";
|
|
30
|
+
const object = {
|
|
31
|
+
transform: { scaleX: 1, skewY: 0, skewX: 0, scaleY: 1, translateX: 0, translateY: 0 },
|
|
32
|
+
clips: [],
|
|
33
|
+
optionalContent: [],
|
|
34
|
+
content: {
|
|
35
|
+
path: {
|
|
36
|
+
path: { segments: segmentsFor(shape, p0, p1) },
|
|
37
|
+
windingRule: "nonZero",
|
|
38
|
+
nonstrokingStyle: { brush: { solid: FILL }, alpha: FILL_ALPHA, overprint: false },
|
|
39
|
+
strokingStyle: {
|
|
40
|
+
brush: { solid: SHAPE_STROKE },
|
|
41
|
+
alpha: 1.0,
|
|
42
|
+
overprint: false,
|
|
43
|
+
line: {
|
|
44
|
+
width: SHAPE_STROKE_WIDTH,
|
|
45
|
+
lineCap: "butt",
|
|
46
|
+
lineJoin: "miter",
|
|
47
|
+
miterLimit: 10.0,
|
|
48
|
+
dashArray: null,
|
|
49
|
+
dashOffset: 0.0,
|
|
50
|
+
},
|
|
51
|
+
},
|
|
52
|
+
fill: filled,
|
|
53
|
+
stroke: true,
|
|
54
|
+
renderStyle: {
|
|
55
|
+
blendMode: "normal",
|
|
56
|
+
alphaIsShape: false,
|
|
57
|
+
overprintMode: "default",
|
|
58
|
+
renderingIntent: "relativeColorimetric",
|
|
59
|
+
},
|
|
60
|
+
softMask: null,
|
|
61
|
+
},
|
|
62
|
+
},
|
|
63
|
+
};
|
|
64
|
+
return object;
|
|
65
|
+
}
|
|
66
|
+
/** The shape the Insert tab's place `tool` drags out. */
|
|
67
|
+
export function placedShape(tool) {
|
|
68
|
+
return SHAPES.has(tool) ? tool : null;
|
|
69
|
+
}
|
|
70
|
+
/** Place the Insert tab's `tool` on page `page`, spanning the page-local points
|
|
71
|
+
* `p0 → p1`: a shape as a page object, on top of the page — the engine mints
|
|
72
|
+
* its id and selects it. A no-op for a page with no id (no document, or not a
|
|
73
|
+
* PDF). */
|
|
74
|
+
export async function place(host, tool, page, p0, p1) {
|
|
75
|
+
const shape = placedShape(tool);
|
|
76
|
+
if (!shape || host.store.getState().status !== "ready")
|
|
77
|
+
return;
|
|
78
|
+
const pageId = await host.client.portable.pageIdByIndex(page);
|
|
79
|
+
if (pageId === undefined)
|
|
80
|
+
return;
|
|
81
|
+
await host.commit(() => host.client.execute(EditCommand.insertObjects(pageId, [shapeObject(shape, p0, p1)])));
|
|
82
|
+
}
|
|
83
|
+
/** Insert the image file `bytes` as a picture on the current slide, centred
|
|
84
|
+
* and scaled down to fit, then selected — a committing edit, so the picture's
|
|
85
|
+
* selection rides back. */
|
|
86
|
+
export function insertImage(host, bytes, contentType) {
|
|
87
|
+
return host.commit(() => host.edit.insertImage(bytes, contentType));
|
|
88
|
+
}
|
|
89
|
+
/** Ask for an image file and {@link insertImage} it. The engine reads the
|
|
90
|
+
* file's size and format from its bytes; the browser's MIME type rides along,
|
|
91
|
+
* empty when it has none. */
|
|
92
|
+
export function pickImage(host) {
|
|
93
|
+
const input = document.createElement("input");
|
|
94
|
+
input.type = "file";
|
|
95
|
+
input.accept = "image/*";
|
|
96
|
+
input.addEventListener("change", () => {
|
|
97
|
+
const file = input.files?.[0];
|
|
98
|
+
if (!file)
|
|
99
|
+
return;
|
|
100
|
+
void file
|
|
101
|
+
.arrayBuffer()
|
|
102
|
+
.then((buffer) => insertImage(host, new Uint8Array(buffer), file.type))
|
|
103
|
+
.catch((error) => console.error("udoc: inserting the image failed", error));
|
|
104
|
+
});
|
|
105
|
+
input.click();
|
|
106
|
+
}
|
|
107
|
+
/** The Insert tab's commands, Image asking for its file with `pickImage`. */
|
|
108
|
+
export function insertCommands(pickImage) {
|
|
109
|
+
return {
|
|
110
|
+
insertImage: {
|
|
111
|
+
id: "insertImage",
|
|
112
|
+
label: "command.insertImage",
|
|
113
|
+
icon: ICON_IMAGE,
|
|
114
|
+
group: "insert",
|
|
115
|
+
labeled: true,
|
|
116
|
+
run: { kind: "action", press: pickImage },
|
|
117
|
+
enabledWhen: (c) => c.ready && c.docType === "presentation",
|
|
118
|
+
},
|
|
119
|
+
insertShape: {
|
|
120
|
+
id: "insertShape",
|
|
121
|
+
label: "command.insertShape",
|
|
122
|
+
icon: ICON_SUBTOOL_RECTANGLE,
|
|
123
|
+
group: "insert",
|
|
124
|
+
run: { kind: "armPicker", options: SHAPE_OPTIONS },
|
|
125
|
+
enabledWhen: (c) => c.ready && c.docType === "portable",
|
|
126
|
+
},
|
|
127
|
+
};
|
|
128
|
+
}
|
|
129
|
+
//# sourceMappingURL=insert.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"insert.js","sourceRoot":"","sources":["../src/insert.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import type { TableSelectionEdit } from "@docmentis/udoc-wasm";
|
|
2
|
+
import type { AlignEdge, EditAxis, MenuAction, TextParagraphAlign, ZOrder } from "@docmentis/udoc-ui/internal";
|
|
3
|
+
import type { ClipboardOp, TableSelectScope } from "./context-menu.js";
|
|
4
|
+
import type { ParagraphSpaceEdge } from "./text-format.js";
|
|
5
|
+
import type { EditTools } from "./tools.js";
|
|
6
|
+
/**
|
|
7
|
+
* What activating one of edit mode's menu rows does. Each variant carries its
|
|
8
|
+
* full payload, so the handler is a switch on `kind` with no side lookup
|
|
9
|
+
* tables. `reorder` is the Arrange dropdown's z-order; `align` / `distribute`
|
|
10
|
+
* / `flip` / `rotate` the Align and Rotate dropdowns; `alignToPage` the Align
|
|
11
|
+
* dropdown's reference toggle (a UI flag, not a document edit). `clipboard` /
|
|
12
|
+
* `delete` are the context menu's acts on the selection, and `selectTable` /
|
|
13
|
+
* `tableEdit` its rows over a table.
|
|
14
|
+
*
|
|
15
|
+
* The first five are the paragraph menus' rows. `indent` carries a *step*, not
|
|
16
|
+
* a measure: an indent is relative per paragraph — a selection spanning two
|
|
17
|
+
* levels keeps their offset instead of flattening to one — so the engine owns
|
|
18
|
+
* what one step means (the list level of a listed paragraph, the left indent of
|
|
19
|
+
* any other), and the menu only says which way.
|
|
20
|
+
*/
|
|
21
|
+
export type EditMenuAction = {
|
|
22
|
+
kind: "widthScale";
|
|
23
|
+
scale: number;
|
|
24
|
+
} | {
|
|
25
|
+
kind: "paragraphAlign";
|
|
26
|
+
align: TextParagraphAlign;
|
|
27
|
+
} | {
|
|
28
|
+
kind: "indent";
|
|
29
|
+
delta: number;
|
|
30
|
+
} | {
|
|
31
|
+
kind: "lineSpacing";
|
|
32
|
+
lines: number;
|
|
33
|
+
} | {
|
|
34
|
+
kind: "paragraphSpace";
|
|
35
|
+
edge: ParagraphSpaceEdge;
|
|
36
|
+
} | {
|
|
37
|
+
kind: "reorder";
|
|
38
|
+
order: ZOrder;
|
|
39
|
+
} | {
|
|
40
|
+
kind: "group";
|
|
41
|
+
} | {
|
|
42
|
+
kind: "ungroup";
|
|
43
|
+
} | {
|
|
44
|
+
kind: "align";
|
|
45
|
+
edge: AlignEdge;
|
|
46
|
+
} | {
|
|
47
|
+
kind: "alignToPage";
|
|
48
|
+
} | {
|
|
49
|
+
kind: "distribute";
|
|
50
|
+
axis: EditAxis;
|
|
51
|
+
} | {
|
|
52
|
+
kind: "flip";
|
|
53
|
+
axis: EditAxis;
|
|
54
|
+
} | {
|
|
55
|
+
kind: "rotate";
|
|
56
|
+
angle: number;
|
|
57
|
+
} | {
|
|
58
|
+
kind: "clipboard";
|
|
59
|
+
op: ClipboardOp;
|
|
60
|
+
} | {
|
|
61
|
+
kind: "delete";
|
|
62
|
+
} | {
|
|
63
|
+
kind: "selectTable";
|
|
64
|
+
scope: TableSelectScope;
|
|
65
|
+
} | {
|
|
66
|
+
kind: "tableEdit";
|
|
67
|
+
edit: TableSelectionEdit;
|
|
68
|
+
};
|
|
69
|
+
/** `action` as a shell {@link MenuAction}: carried as the extension's own. */
|
|
70
|
+
export declare function editAction(action: EditMenuAction): MenuAction;
|
|
71
|
+
/** Run one of edit mode's menu rows' intents on the current selection. */
|
|
72
|
+
export declare function runEditMenuAction(tools: EditTools, action: EditMenuAction): void;
|
|
73
|
+
//# sourceMappingURL=menu-action.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"menu-action.d.ts","sourceRoot":"","sources":["../src/menu-action.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAC/D,OAAO,KAAK,EAAE,SAAS,EAAE,QAAQ,EAAE,UAAU,EAAE,kBAAkB,EAAE,MAAM,EAAE,MAAM,6BAA6B,CAAC;AAC/G,OAAO,KAAK,EAAE,WAAW,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAEvE,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AAC3D,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAE5C;;;;;;;;;;;;;;GAcG;AACH,MAAM,MAAM,cAAc,GACpB;IAAE,IAAI,EAAE,YAAY,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GACrC;IAAE,IAAI,EAAE,gBAAgB,CAAC;IAAC,KAAK,EAAE,kBAAkB,CAAA;CAAE,GACrD;IAAE,IAAI,EAAE,QAAQ,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GACjC;IAAE,IAAI,EAAE,aAAa,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GACtC;IAAE,IAAI,EAAE,gBAAgB,CAAC;IAAC,IAAI,EAAE,kBAAkB,CAAA;CAAE,GACpD;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GAClC;IAAE,IAAI,EAAE,OAAO,CAAA;CAAE,GACjB;IAAE,IAAI,EAAE,SAAS,CAAA;CAAE,GACnB;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,IAAI,EAAE,SAAS,CAAA;CAAE,GAClC;IAAE,IAAI,EAAE,aAAa,CAAA;CAAE,GACvB;IAAE,IAAI,EAAE,YAAY,CAAC;IAAC,IAAI,EAAE,QAAQ,CAAA;CAAE,GACtC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,QAAQ,CAAA;CAAE,GAChC;IAAE,IAAI,EAAE,QAAQ,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GACjC;IAAE,IAAI,EAAE,WAAW,CAAC;IAAC,EAAE,EAAE,WAAW,CAAA;CAAE,GACtC;IAAE,IAAI,EAAE,QAAQ,CAAA;CAAE,GAClB;IAAE,IAAI,EAAE,aAAa,CAAC;IAAC,KAAK,EAAE,gBAAgB,CAAA;CAAE,GAChD;IAAE,IAAI,EAAE,WAAW,CAAC;IAAC,IAAI,EAAE,kBAAkB,CAAA;CAAE,CAAC;AAEtD,8EAA8E;AAC9E,wBAAgB,UAAU,CAAC,MAAM,EAAE,cAAc,GAAG,UAAU,CAE7D;AAED,0EAA0E;AAC1E,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,SAAS,EAAE,MAAM,EAAE,cAAc,GAAG,IAAI,CAiFhF"}
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import { editState, updateEditState } from "./state.js";
|
|
2
|
+
/** `action` as a shell {@link MenuAction}: carried as the extension's own. */
|
|
3
|
+
export function editAction(action) {
|
|
4
|
+
return { kind: "extension", action };
|
|
5
|
+
}
|
|
6
|
+
/** Run one of edit mode's menu rows' intents on the current selection. */
|
|
7
|
+
export function runEditMenuAction(tools, action) {
|
|
8
|
+
const { arrange, text, clipboard, host } = tools;
|
|
9
|
+
switch (action.kind) {
|
|
10
|
+
case "reorder":
|
|
11
|
+
void arrange.reorderSelection(action.order);
|
|
12
|
+
break;
|
|
13
|
+
case "group":
|
|
14
|
+
void arrange.groupSelection();
|
|
15
|
+
break;
|
|
16
|
+
case "ungroup":
|
|
17
|
+
void arrange.ungroupSelection();
|
|
18
|
+
break;
|
|
19
|
+
case "align":
|
|
20
|
+
void arrange.alignSelection(action.edge);
|
|
21
|
+
break;
|
|
22
|
+
case "distribute":
|
|
23
|
+
void arrange.distributeSelection(action.axis);
|
|
24
|
+
break;
|
|
25
|
+
case "flip":
|
|
26
|
+
void arrange.flipSelection(action.axis);
|
|
27
|
+
break;
|
|
28
|
+
case "rotate":
|
|
29
|
+
void arrange.rotateSelectionEach(action.angle);
|
|
30
|
+
break;
|
|
31
|
+
case "alignToPage":
|
|
32
|
+
updateEditState(host.store, { alignToPage: !editState(host.store.getState()).alignToPage });
|
|
33
|
+
break;
|
|
34
|
+
case "widthScale":
|
|
35
|
+
void text.setCharacterProperties([{ widthScale: action.scale }]);
|
|
36
|
+
break;
|
|
37
|
+
case "paragraphAlign":
|
|
38
|
+
void text.setParagraphProperties([{ align: action.align }]);
|
|
39
|
+
break;
|
|
40
|
+
case "lineSpacing":
|
|
41
|
+
void text.setParagraphProperties([{ lineSpacing: { percent: action.lines } }]);
|
|
42
|
+
break;
|
|
43
|
+
case "paragraphSpace":
|
|
44
|
+
void text.toggleParagraphSpace(action.edge);
|
|
45
|
+
break;
|
|
46
|
+
case "indent":
|
|
47
|
+
void text.indentSelection(action.delta);
|
|
48
|
+
break;
|
|
49
|
+
case "clipboard":
|
|
50
|
+
switch (action.op) {
|
|
51
|
+
case "cut":
|
|
52
|
+
clipboard.cut();
|
|
53
|
+
break;
|
|
54
|
+
case "paste":
|
|
55
|
+
void clipboard.paste();
|
|
56
|
+
break;
|
|
57
|
+
}
|
|
58
|
+
break;
|
|
59
|
+
case "delete":
|
|
60
|
+
void host.deleteSelection();
|
|
61
|
+
break;
|
|
62
|
+
case "selectTable":
|
|
63
|
+
// Presence, not an edit: the three widenings re-state what is
|
|
64
|
+
// picked inside the table and report fresh geometry, so they go
|
|
65
|
+
// straight to the client rather than through the edit path.
|
|
66
|
+
switch (action.scope) {
|
|
67
|
+
case "rows":
|
|
68
|
+
host.client.selectTableRows();
|
|
69
|
+
break;
|
|
70
|
+
case "columns":
|
|
71
|
+
host.client.selectTableColumns();
|
|
72
|
+
break;
|
|
73
|
+
case "table":
|
|
74
|
+
host.client.selectTable();
|
|
75
|
+
break;
|
|
76
|
+
}
|
|
77
|
+
break;
|
|
78
|
+
case "tableEdit": {
|
|
79
|
+
// A structural edit on the table the selection sits in — one
|
|
80
|
+
// committing edit like any other. The engine binds it to the
|
|
81
|
+
// innermost table the selection is in; its kind (`deleteRows`, not
|
|
82
|
+
// `delete`) is what keeps it off the frame around that table.
|
|
83
|
+
const { edit } = action;
|
|
84
|
+
void host.commit(() => host.client.executeOnSelection(edit));
|
|
85
|
+
break;
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
//# sourceMappingURL=menu-action.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"menu-action.js","sourceRoot":"","sources":["../src/menu-action.ts"],"names":[],"mappings":"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"}
|
package/dist/mode.d.ts
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { Feature } from "@docmentis/udoc-wasm";
|
|
2
|
+
/**
|
|
3
|
+
* The editor's top-level mode — what the user is doing *to* the document. Mode
|
|
4
|
+
* scopes which commands the toolbar offers and how the pointer behaves; it is
|
|
5
|
+
* usually fixed by the host before the editor is shown.
|
|
6
|
+
*
|
|
7
|
+
* - `view` — reading: navigation, filling in a form, and a PDF's annotations
|
|
8
|
+
* (its Annotate tab).
|
|
9
|
+
* - `edit` — full content authoring (Office "select + insert" model).
|
|
10
|
+
*/
|
|
11
|
+
export type EditorMode = "view" | "edit";
|
|
12
|
+
/** Canonical render order for the mode switcher. */
|
|
13
|
+
export declare const ALL_MODES: readonly EditorMode[];
|
|
14
|
+
/** Whether a session entitled to `features` may be in `mode`. */
|
|
15
|
+
export declare function modeEntitled(mode: EditorMode, features: readonly Feature[]): boolean;
|
|
16
|
+
/** Edit mode, as the shell knows it: its id and the feature it needs. */
|
|
17
|
+
export declare const EDIT_MODE: {
|
|
18
|
+
readonly id: "edit";
|
|
19
|
+
readonly feature: Feature;
|
|
20
|
+
};
|
|
21
|
+
//# sourceMappingURL=mode.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mode.d.ts","sourceRoot":"","sources":["../src/mode.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,sBAAsB,CAAC;AAEpD;;;;;;;;GAQG;AACH,MAAM,MAAM,UAAU,GAAG,MAAM,GAAG,MAAM,CAAC;AAEzC,oDAAoD;AACpD,eAAO,MAAM,SAAS,EAAE,SAAS,UAAU,EAAqB,CAAC;AAUjE,iEAAiE;AACjE,wBAAgB,YAAY,CAAC,IAAI,EAAE,UAAU,EAAE,QAAQ,EAAE,SAAS,OAAO,EAAE,GAAG,OAAO,CAGpF;AAED,yEAAyE;AACzE,eAAO,MAAM,SAAS;;;CAAwD,CAAC"}
|
package/dist/mode.js
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/** Canonical render order for the mode switcher. */
|
|
2
|
+
export const ALL_MODES = ["view", "edit"];
|
|
3
|
+
/** The feature each mode needs, or null for one every session may use. View's
|
|
4
|
+
* own edits — a form's fields, a PDF's annotations — are gated where they
|
|
5
|
+
* start, not by the mode. */
|
|
6
|
+
const MODE_FEATURES = {
|
|
7
|
+
view: null,
|
|
8
|
+
edit: "editing",
|
|
9
|
+
};
|
|
10
|
+
/** Whether a session entitled to `features` may be in `mode`. */
|
|
11
|
+
export function modeEntitled(mode, features) {
|
|
12
|
+
const feature = MODE_FEATURES[mode];
|
|
13
|
+
return feature === null || features.includes(feature);
|
|
14
|
+
}
|
|
15
|
+
/** Edit mode, as the shell knows it: its id and the feature it needs. */
|
|
16
|
+
export const EDIT_MODE = { id: "edit", feature: MODE_FEATURES.edit };
|
|
17
|
+
//# sourceMappingURL=mode.js.map
|
package/dist/mode.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mode.js","sourceRoot":"","sources":["../src/mode.ts"],"names":[],"mappings":"AAcA,oDAAoD;AACpD,MAAM,CAAC,MAAM,SAAS,GAA0B,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;AAEjE;;8BAE8B;AAC9B,MAAM,aAAa,GAAuC;IACtD,IAAI,EAAE,IAAI;IACV,IAAI,EAAE,SAAS;CAClB,CAAC;AAEF,iEAAiE;AACjE,MAAM,UAAU,YAAY,CAAC,IAAgB,EAAE,QAA4B;IACvE,MAAM,OAAO,GAAG,aAAa,CAAC,IAAI,CAAC,CAAC;IACpC,OAAO,OAAO,KAAK,IAAI,IAAI,QAAQ,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;AAC1D,CAAC;AAED,yEAAyE;AACzE,MAAM,CAAC,MAAM,SAAS,GAAG,EAAE,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,aAAa,CAAC,IAAK,EAAW,CAAC"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { CommandDef } from "@docmentis/udoc-ui/internal";
|
|
2
|
+
import type { EditHost } from "./edit-client.js";
|
|
3
|
+
import type { I18n, MessageKey } from "./i18n/index.js";
|
|
4
|
+
/** The layout picker, mounted into a shell. */
|
|
5
|
+
export interface NewSlide {
|
|
6
|
+
/** Open the picker for a new slide after the current one. */
|
|
7
|
+
open(): Promise<void>;
|
|
8
|
+
destroy(): void;
|
|
9
|
+
}
|
|
10
|
+
/** Mount the layout picker into `host` — once, re-seeded with the current
|
|
11
|
+
* layout roster each open. */
|
|
12
|
+
export declare function mountNewSlide(host: EditHost, i18n: I18n): NewSlide;
|
|
13
|
+
/**
|
|
14
|
+
* The New Slide command, opening the picker with `open` — a document-level
|
|
15
|
+
* action shown only with nothing selected: it sits where the selection's
|
|
16
|
+
* property controls go, so it shows on the empty canvas and yields to those
|
|
17
|
+
* controls the moment a shape or text is selected. Labeled, as its page-add
|
|
18
|
+
* glyph reads "slide" only once you know.
|
|
19
|
+
*/
|
|
20
|
+
export declare function newSlideCommand(open: () => void): CommandDef<MessageKey>;
|
|
21
|
+
//# sourceMappingURL=new-slide.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"new-slide.d.ts","sourceRoot":"","sources":["../src/new-slide.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,6BAA6B,CAAC;AAC9D,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAGjD,OAAO,KAAK,EAAE,IAAI,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAUxD,+CAA+C;AAC/C,MAAM,WAAW,QAAQ;IACrB,6DAA6D;IAC7D,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACtB,OAAO,IAAI,IAAI,CAAC;CACnB;AAED;+BAC+B;AAC/B,wBAAgB,aAAa,CAAC,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,IAAI,GAAG,QAAQ,CAmClE;AAED;;;;;;GAMG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,IAAI,GAAG,UAAU,CAAC,UAAU,CAAC,CAUxE"}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import { createNewSlideModal } from "./components/NewSlideModal.js";
|
|
2
|
+
import { ICON_PAGE_ADD } from "./icons.js";
|
|
3
|
+
/** Create a slide at `index` (clamped), seeded with its layout's content
|
|
4
|
+
* placeholders. `layout` is the slide-layout id to build on; omit it to copy
|
|
5
|
+
* the neighbor slide's layout. */
|
|
6
|
+
function createSlide(index, layout) {
|
|
7
|
+
return { presentation: { insertSlide: layout == null ? { index } : { index, layout } } };
|
|
8
|
+
}
|
|
9
|
+
/** Mount the layout picker into `host` — once, re-seeded with the current
|
|
10
|
+
* layout roster each open. */
|
|
11
|
+
export function mountNewSlide(host, i18n) {
|
|
12
|
+
const modal = createNewSlideModal(i18n);
|
|
13
|
+
modal.mount(host.root);
|
|
14
|
+
const execute = (command) => host.commit(() => host.client.execute(command));
|
|
15
|
+
return {
|
|
16
|
+
// Pull every slide master's summary, flatten it to pickable options
|
|
17
|
+
// (each slide layout previews on its slide master's plane at page
|
|
18
|
+
// `1 + its index`), and open. Falls back to the copy-neighbor default
|
|
19
|
+
// when no slide layouts are available. The 0-based page index nearest
|
|
20
|
+
// the viewport top is the current slide; +1 lands the new slide right
|
|
21
|
+
// after it, PowerPoint-style.
|
|
22
|
+
async open() {
|
|
23
|
+
const insertIndex = host.store.getState().pageIndex + 1;
|
|
24
|
+
const slideMasters = await host.edit.slideMastersSummary();
|
|
25
|
+
const options = slideMasters.flatMap((slideMaster) => slideMaster.slideLayouts.map((slideLayout, index) => ({
|
|
26
|
+
layout: slideLayout.id,
|
|
27
|
+
plane: slideMaster.plane,
|
|
28
|
+
page: index + 1,
|
|
29
|
+
name: slideLayout.name,
|
|
30
|
+
})));
|
|
31
|
+
if (options.length === 0) {
|
|
32
|
+
void execute(createSlide(insertIndex));
|
|
33
|
+
return;
|
|
34
|
+
}
|
|
35
|
+
modal.open({
|
|
36
|
+
insertIndex,
|
|
37
|
+
options,
|
|
38
|
+
renderPreview: (plane, page, scale) => host.client.renderPagePreview(plane, page, scale),
|
|
39
|
+
onPick: (layout) => void execute(createSlide(insertIndex, layout)),
|
|
40
|
+
});
|
|
41
|
+
},
|
|
42
|
+
destroy: () => modal.destroy(),
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* The New Slide command, opening the picker with `open` — a document-level
|
|
47
|
+
* action shown only with nothing selected: it sits where the selection's
|
|
48
|
+
* property controls go, so it shows on the empty canvas and yields to those
|
|
49
|
+
* controls the moment a shape or text is selected. Labeled, as its page-add
|
|
50
|
+
* glyph reads "slide" only once you know.
|
|
51
|
+
*/
|
|
52
|
+
export function newSlideCommand(open) {
|
|
53
|
+
return {
|
|
54
|
+
id: "createSlide",
|
|
55
|
+
label: "command.createSlide",
|
|
56
|
+
icon: ICON_PAGE_ADD,
|
|
57
|
+
group: "slide",
|
|
58
|
+
labeled: true,
|
|
59
|
+
run: { kind: "action", press: open },
|
|
60
|
+
enabledWhen: (c) => c.ready && c.selection.count === 0,
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
//# sourceMappingURL=new-slide.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"new-slide.js","sourceRoot":"","sources":["../src/new-slide.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,mBAAmB,EAAE,MAAM,+BAA+B,CAAC;AAGpE,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAE3C;;mCAEmC;AACnC,SAAS,WAAW,CAAC,KAAa,EAAE,MAAe;IAC/C,OAAO,EAAE,YAAY,EAAE,EAAE,WAAW,EAAE,MAAM,IAAI,IAAI,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC;AAC7F,CAAC;AASD;+BAC+B;AAC/B,MAAM,UAAU,aAAa,CAAC,IAAc,EAAE,IAAU;IACpD,MAAM,KAAK,GAAG,mBAAmB,CAAC,IAAI,CAAC,CAAC;IACxC,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACvB,MAAM,OAAO,GAAG,CAAC,OAAoB,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC;IAC1F,OAAO;QACH,oEAAoE;QACpE,kEAAkE;QAClE,sEAAsE;QACtE,sEAAsE;QACtE,sEAAsE;QACtE,8BAA8B;QAC9B,KAAK,CAAC,IAAI;YACN,MAAM,WAAW,GAAG,IAAI,CAAC,KAAK,CAAC,QAAQ,EAAE,CAAC,SAAS,GAAG,CAAC,CAAC;YACxD,MAAM,YAAY,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,mBAAmB,EAAE,CAAC;YAC3D,MAAM,OAAO,GAAmB,YAAY,CAAC,OAAO,CAAC,CAAC,WAAW,EAAE,EAAE,CACjE,WAAW,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC,WAAW,EAAE,KAAK,EAAE,EAAE,CAAC,CAAC;gBAClD,MAAM,EAAE,WAAW,CAAC,EAAE;gBACtB,KAAK,EAAE,WAAW,CAAC,KAAK;gBACxB,IAAI,EAAE,KAAK,GAAG,CAAC;gBACf,IAAI,EAAE,WAAW,CAAC,IAAI;aACzB,CAAC,CAAC,CACN,CAAC;YACF,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBACvB,KAAK,OAAO,CAAC,WAAW,CAAC,WAAW,CAAC,CAAC,CAAC;gBACvC,OAAO;YACX,CAAC;YACD,KAAK,CAAC,IAAI,CAAC;gBACP,WAAW;gBACX,OAAO;gBACP,aAAa,EAAE,CAAC,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,iBAAiB,CAAC,KAAK,EAAE,IAAI,EAAE,KAAK,CAAC;gBACxF,MAAM,EAAE,CAAC,MAAM,EAAE,EAAE,CAAC,KAAK,OAAO,CAAC,WAAW,CAAC,WAAW,EAAE,MAAM,CAAC,CAAC;aACrE,CAAC,CAAC;QACP,CAAC;QACD,OAAO,EAAE,GAAG,EAAE,CAAC,KAAK,CAAC,OAAO,EAAE;KACjC,CAAC;AACN,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,eAAe,CAAC,IAAgB;IAC5C,OAAO;QACH,EAAE,EAAE,aAAa;QACjB,KAAK,EAAE,qBAAqB;QAC5B,IAAI,EAAE,aAAa;QACnB,KAAK,EAAE,OAAO;QACd,OAAO,EAAE,IAAI;QACb,GAAG,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,IAAI,EAAE;QACpC,WAAW,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC,SAAS,CAAC,KAAK,KAAK,CAAC;KACzD,CAAC;AACN,CAAC"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { PageSpacing, UIShellHost, UIState } from "@docmentis/udoc-ui/internal";
|
|
2
|
+
import type { I18n } from "./i18n/index.js";
|
|
3
|
+
/**
|
|
4
|
+
* The spacing the page controls show with. The insert strip is sized from the
|
|
5
|
+
* gap × the frame scale, so it fills the gap at every zoom. The paddings are
|
|
6
|
+
* screen-fixed (CSS px), so the rail in the right padding stays a constant size
|
|
7
|
+
* on screen — the side paddings are wide enough that the rail (offset + ~26px)
|
|
8
|
+
* clears the virtual scrollbar at fit-width.
|
|
9
|
+
*/
|
|
10
|
+
export declare const PAGE_CONTROLS_SPACING: PageSpacing;
|
|
11
|
+
/**
|
|
12
|
+
* Whether the page controls show in `s`: in edit mode, for a doc type whose
|
|
13
|
+
* pages reorder ({@link PAGE_CONTROLLED}), in the continuous single-page
|
|
14
|
+
* arrangement — where the gaps they live in exist, and no facing page sits
|
|
15
|
+
* where the rail goes.
|
|
16
|
+
*/
|
|
17
|
+
export declare function pageControlsShown(s: UIState): boolean;
|
|
18
|
+
/** Mount the page controls into `host`, shown while {@link pageControlsShown}; returns the teardown. */
|
|
19
|
+
export declare function mountPageControls(host: UIShellHost, i18n: I18n): () => void;
|
|
20
|
+
//# sourceMappingURL=page-controls.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"page-controls.d.ts","sourceRoot":"","sources":["../src/page-controls.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,WAAW,EAAE,WAAW,EAAE,OAAO,EAAE,MAAM,6BAA6B,CAAC;AAGrF,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,iBAAiB,CAAC;AAM5C;;;;;;GAMG;AACH,eAAO,MAAM,qBAAqB,EAAE,WAGnC,CAAC;AAqCF;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,CAAC,EAAE,OAAO,GAAG,OAAO,CAQrD;AAED,wGAAwG;AACxG,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,WAAW,EAAE,IAAI,EAAE,IAAI,GAAG,MAAM,IAAI,CAyD3E"}
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
import { arrangementFor, subscribeSelector } from "@docmentis/udoc-ui/internal";
|
|
2
|
+
import { pageActions, pageInserts } from "./components/PageControls.js";
|
|
3
|
+
import { createPageSettingsModal } from "./components/PageSettingsModal.js";
|
|
4
|
+
/** The gap between pages, which the insert strip lives in: page-fixed
|
|
5
|
+
* (document points), so it reads as part of the paper. */
|
|
6
|
+
const GAP_PT = 24;
|
|
7
|
+
/**
|
|
8
|
+
* The spacing the page controls show with. The insert strip is sized from the
|
|
9
|
+
* gap × the frame scale, so it fills the gap at every zoom. The paddings are
|
|
10
|
+
* screen-fixed (CSS px), so the rail in the right padding stays a constant size
|
|
11
|
+
* on screen — the side paddings are wide enough that the rail (offset + ~26px)
|
|
12
|
+
* clears the virtual scrollbar at fit-width.
|
|
13
|
+
*/
|
|
14
|
+
export const PAGE_CONTROLS_SPACING = {
|
|
15
|
+
padding: { top: { px: 36 }, right: { px: 48 }, bottom: { px: 36 }, left: { px: 48 } },
|
|
16
|
+
gap: { horizontal: GAP_PT, vertical: GAP_PT },
|
|
17
|
+
};
|
|
18
|
+
/** The `UDocCommand` for a page-structure edit. */
|
|
19
|
+
function pageCommand(edit) {
|
|
20
|
+
switch (edit.kind) {
|
|
21
|
+
case "insert":
|
|
22
|
+
return { portable: { insertPage: { index: edit.index } } };
|
|
23
|
+
case "delete":
|
|
24
|
+
return { portable: { deletePage: { index: edit.index } } };
|
|
25
|
+
case "reorder":
|
|
26
|
+
return { portable: { reorderPage: { from: edit.from, to: edit.to } } };
|
|
27
|
+
case "rotate":
|
|
28
|
+
return { portable: { rotatePage: { index: edit.index, clockwise: edit.clockwise } } };
|
|
29
|
+
case "resize":
|
|
30
|
+
return {
|
|
31
|
+
portable: { resizePage: { index: edit.index, size: { width: edit.width, height: edit.height } } },
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
/** The doc types whose pages the page controls move, rotate, delete and
|
|
36
|
+
* insert: the paginated, page-reorderable ones — PDF today. */
|
|
37
|
+
const PAGE_CONTROLLED = new Set(["portable"]);
|
|
38
|
+
/**
|
|
39
|
+
* Whether the page controls show in `s`: in edit mode, for a doc type whose
|
|
40
|
+
* pages reorder ({@link PAGE_CONTROLLED}), in the continuous single-page
|
|
41
|
+
* arrangement — where the gaps they live in exist, and no facing page sits
|
|
42
|
+
* where the rail goes.
|
|
43
|
+
*/
|
|
44
|
+
export function pageControlsShown(s) {
|
|
45
|
+
return (s.mode === "edit" &&
|
|
46
|
+
s.scrollMode === "continuous" &&
|
|
47
|
+
arrangementFor(s).layoutMode === "singlePage" &&
|
|
48
|
+
s.docType !== null &&
|
|
49
|
+
PAGE_CONTROLLED.has(s.docType));
|
|
50
|
+
}
|
|
51
|
+
/** Mount the page controls into `host`, shown while {@link pageControlsShown}; returns the teardown. */
|
|
52
|
+
export function mountPageControls(host, i18n) {
|
|
53
|
+
// Mounted once and reused for whichever page's "more" button is clicked.
|
|
54
|
+
const settings = createPageSettingsModal(i18n);
|
|
55
|
+
settings.mount(host.root);
|
|
56
|
+
const pageEditAt = (edit) => host.commit(() => host.client.execute(pageCommand(edit)));
|
|
57
|
+
const composedPageCount = () => host.store.getState().composedPageCount;
|
|
58
|
+
function show(shown) {
|
|
59
|
+
if (!shown) {
|
|
60
|
+
host.removeOverlay("udoc:page-insert");
|
|
61
|
+
host.removeOverlay("udoc:page-actions");
|
|
62
|
+
return;
|
|
63
|
+
}
|
|
64
|
+
host.setOverlay("udoc:page-insert", pageInserts({
|
|
65
|
+
i18n,
|
|
66
|
+
gapPt: GAP_PT,
|
|
67
|
+
composedPageCount,
|
|
68
|
+
onInsert: (index) => void pageEditAt({ kind: "insert", index }),
|
|
69
|
+
// Yield the gap where a selection's resize/rotate handles
|
|
70
|
+
// floated into it, so the insert strip never sits under them.
|
|
71
|
+
keepOut: () => host.selectionKeepOut(),
|
|
72
|
+
}));
|
|
73
|
+
// Registered after the insert strips so the rail stacks above them —
|
|
74
|
+
// they share the inter-page gap.
|
|
75
|
+
host.setOverlay("udoc:page-actions", pageActions({
|
|
76
|
+
i18n,
|
|
77
|
+
composedPageCount,
|
|
78
|
+
hoveredPage: () => host.hoveredPage(),
|
|
79
|
+
onMoveUp: (index) => void pageEditAt({ kind: "reorder", from: index, to: index - 1 }),
|
|
80
|
+
onMoveDown: (index) => void pageEditAt({ kind: "reorder", from: index, to: index + 1 }),
|
|
81
|
+
onRotate: (index, clockwise) => void pageEditAt({ kind: "rotate", index, clockwise }),
|
|
82
|
+
onDelete: (index) => void pageEditAt({ kind: "delete", index }),
|
|
83
|
+
onOpenSettings: (index, size) => settings.open({
|
|
84
|
+
index,
|
|
85
|
+
width: size.width,
|
|
86
|
+
height: size.height,
|
|
87
|
+
onResize: (width, height) => void pageEditAt({ kind: "resize", index, width, height }),
|
|
88
|
+
onRotate: (clockwise) => void pageEditAt({ kind: "rotate", index, clockwise }),
|
|
89
|
+
}),
|
|
90
|
+
}));
|
|
91
|
+
}
|
|
92
|
+
show(pageControlsShown(host.store.getState()));
|
|
93
|
+
const unsubscribe = subscribeSelector(host.store, pageControlsShown, show);
|
|
94
|
+
return () => {
|
|
95
|
+
unsubscribe();
|
|
96
|
+
settings.destroy();
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
//# sourceMappingURL=page-controls.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"page-controls.js","sourceRoot":"","sources":["../src/page-controls.ts"],"names":[],"mappings":"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"}
|
package/dist/paint.d.ts
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import type { PaintColor, PaintFill } from "@docmentis/udoc-wasm";
|
|
2
|
+
import type { LineDash, PaintChannel, PaintSpec, RibbonControl, RibbonControlEnv, StrokeStyle, UIShellHost } from "@docmentis/udoc-ui/internal";
|
|
3
|
+
import type { EditTools } from "./tools.js";
|
|
4
|
+
/** A picker paint as a `PaintColor`, or `null` for "no fill": a solid sRGB
|
|
5
|
+
* color, or a theme pick kept as a `schemeClr` reference with its tint/shade
|
|
6
|
+
* transforms so it re-themes. The shared color construction behind
|
|
7
|
+
* {@link paintToDrawingFill} and the text highlight (a bare color). */
|
|
8
|
+
export declare function paintToDrawingColor(paint: PaintSpec): PaintColor | null;
|
|
9
|
+
/** A picker paint as a `PaintFill`: a solid / theme color wrapped as a solid
|
|
10
|
+
* fill, or explicit `"none"` for "no fill". */
|
|
11
|
+
export declare function paintToDrawingFill(paint: PaintSpec): PaintFill;
|
|
12
|
+
/** A composed stroke the Line picker applies: its color plus the weight and
|
|
13
|
+
* dash from the Weight / Dashes fly-outs. The shell lowers it to the doc type's
|
|
14
|
+
* outline model (`DrawingML` `Line` / PDF stroking style). */
|
|
15
|
+
export interface StrokeSpec {
|
|
16
|
+
paint: PaintSpec;
|
|
17
|
+
/** Stroke weight in points. */
|
|
18
|
+
weight: number;
|
|
19
|
+
dash: LineDash;
|
|
20
|
+
}
|
|
21
|
+
/** The Fill / Line edits of the selection, on the shell `host` lends. */
|
|
22
|
+
export declare function createPaintEdits(host: UIShellHost): {
|
|
23
|
+
fillSelection: (paint: PaintSpec) => Promise<void>;
|
|
24
|
+
strokeSelection: (stroke: StrokeSpec) => Promise<void>;
|
|
25
|
+
};
|
|
26
|
+
/** The Fill / Line edits {@link createPaintEdits} makes. */
|
|
27
|
+
export type PaintEdits = ReturnType<typeof createPaintEdits>;
|
|
28
|
+
/**
|
|
29
|
+
* The last picks — edit mode's write-side memory: the color per channel that the
|
|
30
|
+
* composed stroke re-sends when only its weight / dash change (the engine sets
|
|
31
|
+
* the outline as one thing), and the weight / dash the Line panel marks. Not
|
|
32
|
+
* shown on the triggers, which mirror the *selection*.
|
|
33
|
+
*/
|
|
34
|
+
export interface PaintMemory {
|
|
35
|
+
readonly lastPaint: Record<PaintChannel, PaintSpec>;
|
|
36
|
+
readonly lastStroke: StrokeStyle;
|
|
37
|
+
}
|
|
38
|
+
/** A {@link PaintMemory} at its defaults. */
|
|
39
|
+
export declare function createPaintMemory(): PaintMemory;
|
|
40
|
+
/**
|
|
41
|
+
* A Fill / Line / Text Color dropdown of `channel`, for command `id` drawn with
|
|
42
|
+
* `icon`: the channel glyph over a color bar reflecting the *selection's* color,
|
|
43
|
+
* the caret opening the color panel (rebuilt on each open). A mirror — clicking
|
|
44
|
+
* always opens the picker (no last-color re-apply); each render keeps the
|
|
45
|
+
* swatch in sync with the selection.
|
|
46
|
+
*/
|
|
47
|
+
export declare function paintControl(env: RibbonControlEnv, command: {
|
|
48
|
+
id: string;
|
|
49
|
+
icon: string;
|
|
50
|
+
channel: PaintChannel;
|
|
51
|
+
}, tools: EditTools): RibbonControl;
|
|
52
|
+
//# sourceMappingURL=paint.d.ts.map
|