@docmentis/udoc-editor 0.8.7 → 0.8.8
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/dist/arrange.d.ts +3 -0
- package/dist/arrange.d.ts.map +1 -1
- package/dist/arrange.js +10 -12
- package/dist/arrange.js.map +1 -1
- package/dist/components/CropOverlay.d.ts +27 -0
- package/dist/components/CropOverlay.d.ts.map +1 -0
- package/dist/components/CropOverlay.js +126 -0
- package/dist/components/CropOverlay.js.map +1 -0
- package/dist/components/ImageSizeModal.d.ts +23 -0
- package/dist/components/ImageSizeModal.d.ts.map +1 -0
- package/dist/components/ImageSizeModal.js +189 -0
- package/dist/components/ImageSizeModal.js.map +1 -0
- package/dist/components/NewSlideModal.d.ts +7 -2
- package/dist/components/NewSlideModal.d.ts.map +1 -1
- package/dist/components/NewSlideModal.js +10 -3
- package/dist/components/NewSlideModal.js.map +1 -1
- package/dist/crop-box.d.ts +33 -0
- package/dist/crop-box.d.ts.map +1 -0
- package/dist/crop-box.js +107 -0
- package/dist/crop-box.js.map +1 -0
- package/dist/crop.d.ts +28 -0
- package/dist/crop.d.ts.map +1 -0
- package/dist/crop.js +260 -0
- package/dist/crop.js.map +1 -0
- package/dist/edit-mode.d.ts.map +1 -1
- package/dist/edit-mode.js +46 -3
- package/dist/edit-mode.js.map +1 -1
- package/dist/formatting-marks.d.ts +4 -5
- package/dist/formatting-marks.d.ts.map +1 -1
- package/dist/formatting-marks.js +4 -5
- package/dist/formatting-marks.js.map +1 -1
- package/dist/i18n/ar.d.ts.map +1 -1
- package/dist/i18n/ar.js +14 -0
- package/dist/i18n/ar.js.map +1 -1
- package/dist/i18n/de.d.ts.map +1 -1
- package/dist/i18n/de.js +14 -0
- package/dist/i18n/de.js.map +1 -1
- package/dist/i18n/en.d.ts.map +1 -1
- package/dist/i18n/en.js +14 -0
- package/dist/i18n/en.js.map +1 -1
- package/dist/i18n/es.d.ts.map +1 -1
- package/dist/i18n/es.js +14 -0
- package/dist/i18n/es.js.map +1 -1
- package/dist/i18n/fr.d.ts.map +1 -1
- package/dist/i18n/fr.js +14 -0
- package/dist/i18n/fr.js.map +1 -1
- package/dist/i18n/ja.d.ts.map +1 -1
- package/dist/i18n/ja.js +14 -0
- package/dist/i18n/ja.js.map +1 -1
- package/dist/i18n/ko.d.ts.map +1 -1
- package/dist/i18n/ko.js +14 -0
- package/dist/i18n/ko.js.map +1 -1
- package/dist/i18n/messages.d.ts +26 -0
- package/dist/i18n/messages.d.ts.map +1 -1
- package/dist/i18n/pt-BR.d.ts.map +1 -1
- package/dist/i18n/pt-BR.js +14 -0
- package/dist/i18n/pt-BR.js.map +1 -1
- package/dist/i18n/ru.d.ts.map +1 -1
- package/dist/i18n/ru.js +14 -0
- package/dist/i18n/ru.js.map +1 -1
- package/dist/i18n/zh-CN.d.ts.map +1 -1
- package/dist/i18n/zh-CN.js +14 -0
- package/dist/i18n/zh-CN.js.map +1 -1
- package/dist/i18n/zh-TW.d.ts.map +1 -1
- package/dist/i18n/zh-TW.js +14 -0
- package/dist/i18n/zh-TW.js.map +1 -1
- package/dist/icons.d.ts +8 -0
- package/dist/icons.d.ts.map +1 -1
- package/dist/icons.js +8 -0
- package/dist/icons.js.map +1 -1
- package/dist/image.d.ts +39 -0
- package/dist/image.d.ts.map +1 -0
- package/dist/image.js +203 -0
- package/dist/image.js.map +1 -0
- package/dist/insert.d.ts +3 -3
- package/dist/insert.d.ts.map +1 -1
- package/dist/insert.js +17 -7
- package/dist/insert.js.map +1 -1
- package/dist/markup.d.ts +23 -0
- package/dist/markup.d.ts.map +1 -0
- package/dist/markup.js +100 -0
- package/dist/markup.js.map +1 -0
- package/dist/menu-action.d.ts +6 -1
- package/dist/menu-action.d.ts.map +1 -1
- package/dist/menu-action.js +4 -1
- package/dist/menu-action.js.map +1 -1
- package/dist/new-slide.d.ts.map +1 -1
- package/dist/new-slide.js +8 -2
- package/dist/new-slide.js.map +1 -1
- package/dist/paint.d.ts +5 -1
- package/dist/paint.d.ts.map +1 -1
- package/dist/paint.js +27 -16
- package/dist/paint.js.map +1 -1
- package/dist/state.d.ts +24 -1
- package/dist/state.d.ts.map +1 -1
- package/dist/state.js +3 -0
- package/dist/state.js.map +1 -1
- package/dist/styles.d.ts.map +1 -1
- package/dist/styles.js +147 -1
- package/dist/styles.js.map +1 -1
- package/dist/tabs.d.ts +1 -1
- package/dist/tabs.d.ts.map +1 -1
- package/dist/tabs.js +50 -14
- package/dist/tabs.js.map +1 -1
- package/dist/text-format.js +7 -7
- package/dist/text-format.js.map +1 -1
- package/dist/tools.d.ts +3 -0
- package/dist/tools.d.ts.map +1 -1
- package/dist/tools.js +4 -2
- package/dist/tools.js.map +1 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/dist/worker/worker-source.js +1 -1
- package/package.json +3 -3
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"NewSlideModal.js","sourceRoot":"","sources":["../../src/components/NewSlideModal.ts"],"names":[],"mappings":"AAAA,gFAAgF;AAChF,gFAAgF;AAChF,gFAAgF;AAChF,wEAAwE;AACxE,EAAE;AACF,+EAA+E;AAC/E,iFAAiF;AACjF,gFAAgF;AAChF,iDAAiD;AACjD,EAAE;AACF,iFAAiF;AACjF,4EAA4E;AAC5E,gDAAgD;
|
|
1
|
+
{"version":3,"file":"NewSlideModal.js","sourceRoot":"","sources":["../../src/components/NewSlideModal.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/** The aspect the crop box keeps: none, the page's own, or a preset one —
|
|
2
|
+
* turned to the page's orientation. */
|
|
3
|
+
export type CropAspect = "free" | "original" | "square" | "4:3" | "16:9";
|
|
4
|
+
/** The crop box, as fractions of the page from its top-left corner. */
|
|
5
|
+
export interface CropBox {
|
|
6
|
+
x0: number;
|
|
7
|
+
y0: number;
|
|
8
|
+
x1: number;
|
|
9
|
+
y1: number;
|
|
10
|
+
}
|
|
11
|
+
/** What a press drags: a corner, an edge, or the whole box. */
|
|
12
|
+
export type CropHandle = "n" | "s" | "e" | "w" | "ne" | "nw" | "se" | "sw" | "move";
|
|
13
|
+
/** The whole page. */
|
|
14
|
+
export declare const WHOLE: CropBox;
|
|
15
|
+
/** The width-to-height ratio `aspect` keeps the box to on a page showing at
|
|
16
|
+
* `width` × `height` pixels, or null for none. A preset turns to the page's
|
|
17
|
+
* orientation, as a camera's does. */
|
|
18
|
+
export declare function aspectRatio(aspect: CropAspect, width: number, height: number): number | null;
|
|
19
|
+
/** `box` at a page `width` × `height`, or back to fractions of it. */
|
|
20
|
+
export declare function scaled(box: CropBox, width: number, height: number): CropBox;
|
|
21
|
+
/** The largest box of `ratio` inside `box`, about its centre. */
|
|
22
|
+
export declare function fitRatio(box: CropBox, ratio: number): CropBox;
|
|
23
|
+
/**
|
|
24
|
+
* `from` dragged by `handle` through `dx` × `dy`, all in pixels on a page
|
|
25
|
+
* `width` × `height`: kept inside the page and no narrower than `min`, and to
|
|
26
|
+
* `ratio` where it's set. A corner drags against the corner across from it; an
|
|
27
|
+
* edge against the edge across, the box widening about its middle the other
|
|
28
|
+
* way to keep a ratio.
|
|
29
|
+
*/
|
|
30
|
+
export declare function dragged(handle: CropHandle, from: CropBox, dx: number, dy: number, width: number, height: number, min: number, ratio: number | null): CropBox;
|
|
31
|
+
/** Whether `box` keeps the whole page. */
|
|
32
|
+
export declare function wholePage(box: CropBox): boolean;
|
|
33
|
+
//# sourceMappingURL=crop-box.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"crop-box.d.ts","sourceRoot":"","sources":["../src/crop-box.ts"],"names":[],"mappings":"AAGA;wCACwC;AACxC,MAAM,MAAM,UAAU,GAAG,MAAM,GAAG,UAAU,GAAG,QAAQ,GAAG,KAAK,GAAG,MAAM,CAAC;AAEzE,uEAAuE;AACvE,MAAM,WAAW,OAAO;IACpB,EAAE,EAAE,MAAM,CAAC;IACX,EAAE,EAAE,MAAM,CAAC;IACX,EAAE,EAAE,MAAM,CAAC;IACX,EAAE,EAAE,MAAM,CAAC;CACd;AAED,+DAA+D;AAC/D,MAAM,MAAM,UAAU,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,MAAM,CAAC;AAEpF,sBAAsB;AACtB,eAAO,MAAM,KAAK,EAAE,OAAwC,CAAC;AAa7D;;uCAEuC;AACvC,wBAAgB,WAAW,CAAC,MAAM,EAAE,UAAU,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAW5F;AAED,sEAAsE;AACtE,wBAAgB,MAAM,CAAC,GAAG,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAE3E;AAED,iEAAiE;AACjE,wBAAgB,QAAQ,CAAC,GAAG,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAQ7D;AAED;;;;;;GAMG;AACH,wBAAgB,OAAO,CACnB,MAAM,EAAE,UAAU,EAClB,IAAI,EAAE,OAAO,EACb,EAAE,EAAE,MAAM,EACV,EAAE,EAAE,MAAM,EACV,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,MAAM,EACd,GAAG,EAAE,MAAM,EACX,KAAK,EAAE,MAAM,GAAG,IAAI,GACrB,OAAO,CA6CT;AAED,0CAA0C;AAC1C,wBAAgB,SAAS,CAAC,GAAG,EAAE,OAAO,GAAG,OAAO,CAI/C"}
|
package/dist/crop-box.js
ADDED
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
/** The whole page. */
|
|
2
|
+
export const WHOLE = { x0: 0, y0: 0, x1: 1, y1: 1 };
|
|
3
|
+
/** How far from the page's edge, as a fraction of it, the box still counts as
|
|
4
|
+
* keeping the whole page. */
|
|
5
|
+
const WHOLE_EPSILON = 1e-4;
|
|
6
|
+
/** The preset aspects, wider than tall. */
|
|
7
|
+
const PRESET_ASPECTS = {
|
|
8
|
+
square: 1,
|
|
9
|
+
"4:3": 4 / 3,
|
|
10
|
+
"16:9": 16 / 9,
|
|
11
|
+
};
|
|
12
|
+
/** The width-to-height ratio `aspect` keeps the box to on a page showing at
|
|
13
|
+
* `width` × `height` pixels, or null for none. A preset turns to the page's
|
|
14
|
+
* orientation, as a camera's does. */
|
|
15
|
+
export function aspectRatio(aspect, width, height) {
|
|
16
|
+
switch (aspect) {
|
|
17
|
+
case "free":
|
|
18
|
+
return null;
|
|
19
|
+
case "original":
|
|
20
|
+
return width / height;
|
|
21
|
+
default: {
|
|
22
|
+
const ratio = PRESET_ASPECTS[aspect];
|
|
23
|
+
return width >= height ? ratio : 1 / ratio;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
/** `box` at a page `width` × `height`, or back to fractions of it. */
|
|
28
|
+
export function scaled(box, width, height) {
|
|
29
|
+
return { x0: box.x0 * width, y0: box.y0 * height, x1: box.x1 * width, y1: box.y1 * height };
|
|
30
|
+
}
|
|
31
|
+
/** The largest box of `ratio` inside `box`, about its centre. */
|
|
32
|
+
export function fitRatio(box, ratio) {
|
|
33
|
+
const cx = (box.x0 + box.x1) / 2;
|
|
34
|
+
const cy = (box.y0 + box.y1) / 2;
|
|
35
|
+
let w = box.x1 - box.x0;
|
|
36
|
+
let h = box.y1 - box.y0;
|
|
37
|
+
if (w / h > ratio)
|
|
38
|
+
w = h * ratio;
|
|
39
|
+
else
|
|
40
|
+
h = w / ratio;
|
|
41
|
+
return { x0: cx - w / 2, y0: cy - h / 2, x1: cx + w / 2, y1: cy + h / 2 };
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* `from` dragged by `handle` through `dx` × `dy`, all in pixels on a page
|
|
45
|
+
* `width` × `height`: kept inside the page and no narrower than `min`, and to
|
|
46
|
+
* `ratio` where it's set. A corner drags against the corner across from it; an
|
|
47
|
+
* edge against the edge across, the box widening about its middle the other
|
|
48
|
+
* way to keep a ratio.
|
|
49
|
+
*/
|
|
50
|
+
export function dragged(handle, from, dx, dy, width, height, min, ratio) {
|
|
51
|
+
const clamp = (v, lo, hi) => Math.min(Math.max(v, lo), Math.max(lo, hi));
|
|
52
|
+
if (handle === "move") {
|
|
53
|
+
const w = from.x1 - from.x0;
|
|
54
|
+
const h = from.y1 - from.y0;
|
|
55
|
+
const x0 = clamp(from.x0 + dx, 0, width - w);
|
|
56
|
+
const y0 = clamp(from.y0 + dy, 0, height - h);
|
|
57
|
+
return { x0, y0, x1: x0 + w, y1: y0 + h };
|
|
58
|
+
}
|
|
59
|
+
const west = handle.includes("w");
|
|
60
|
+
const east = handle.includes("e");
|
|
61
|
+
const north = handle.includes("n");
|
|
62
|
+
const south = handle.includes("s");
|
|
63
|
+
// The edges the handle moves, free.
|
|
64
|
+
const free = {
|
|
65
|
+
x0: west ? clamp(from.x0 + dx, 0, from.x1 - min) : from.x0,
|
|
66
|
+
x1: east ? clamp(from.x1 + dx, from.x0 + min, width) : from.x1,
|
|
67
|
+
y0: north ? clamp(from.y0 + dy, 0, from.y1 - min) : from.y0,
|
|
68
|
+
y1: south ? clamp(from.y1 + dy, from.y0 + min, height) : from.y1,
|
|
69
|
+
};
|
|
70
|
+
if (ratio === null)
|
|
71
|
+
return free;
|
|
72
|
+
const horizontal = west || east;
|
|
73
|
+
const vertical = north || south;
|
|
74
|
+
let w = free.x1 - free.x0;
|
|
75
|
+
let h = free.y1 - free.y0;
|
|
76
|
+
// The edge each axis holds still: the one across from the handle, or, on
|
|
77
|
+
// the axis an edge handle doesn't move, the box's middle.
|
|
78
|
+
const ax = west ? from.x1 : east ? from.x0 : (from.x0 + from.x1) / 2;
|
|
79
|
+
const ay = north ? from.y1 : south ? from.y0 : (from.y0 + from.y1) / 2;
|
|
80
|
+
if (horizontal && vertical) {
|
|
81
|
+
if (w / h > ratio)
|
|
82
|
+
w = h * ratio;
|
|
83
|
+
else
|
|
84
|
+
h = w / ratio;
|
|
85
|
+
}
|
|
86
|
+
else if (horizontal) {
|
|
87
|
+
h = w / ratio;
|
|
88
|
+
}
|
|
89
|
+
else {
|
|
90
|
+
w = h * ratio;
|
|
91
|
+
}
|
|
92
|
+
// The room the page leaves from the held edges, each way.
|
|
93
|
+
const maxW = west ? ax : east ? width - ax : 2 * Math.min(ax, width - ax);
|
|
94
|
+
const maxH = north ? ay : south ? height - ay : 2 * Math.min(ay, height - ay);
|
|
95
|
+
if (w > maxW)
|
|
96
|
+
[w, h] = [maxW, maxW / ratio];
|
|
97
|
+
if (h > maxH)
|
|
98
|
+
[w, h] = [maxH * ratio, maxH];
|
|
99
|
+
const x0 = west ? ax - w : east ? ax : ax - w / 2;
|
|
100
|
+
const y0 = north ? ay - h : south ? ay : ay - h / 2;
|
|
101
|
+
return { x0, y0, x1: x0 + w, y1: y0 + h };
|
|
102
|
+
}
|
|
103
|
+
/** Whether `box` keeps the whole page. */
|
|
104
|
+
export function wholePage(box) {
|
|
105
|
+
return (box.x0 <= WHOLE_EPSILON && box.y0 <= WHOLE_EPSILON && box.x1 >= 1 - WHOLE_EPSILON && box.y1 >= 1 - WHOLE_EPSILON);
|
|
106
|
+
}
|
|
107
|
+
//# sourceMappingURL=crop-box.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"crop-box.js","sourceRoot":"","sources":["../src/crop-box.ts"],"names":[],"mappings":"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"}
|
package/dist/crop.d.ts
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import type { CommandDef } from "@docmentis/udoc-ui/internal";
|
|
2
|
+
import type { CropAspect } from "./crop-box.js";
|
|
3
|
+
import type { EditHost } from "./edit-client.js";
|
|
4
|
+
import type { I18n, MessageKey } from "./i18n/index.js";
|
|
5
|
+
/** Crop mode: what the Home tab's crop controls and the keys call. */
|
|
6
|
+
export interface Crop {
|
|
7
|
+
/** Start cropping the current page — a no-op on a doc that isn't an
|
|
8
|
+
* image, or while cropping. */
|
|
9
|
+
start(): Promise<void>;
|
|
10
|
+
/** Crop the page to the box, and end crop mode. */
|
|
11
|
+
apply(): Promise<void>;
|
|
12
|
+
/** End crop mode, the page as it was. */
|
|
13
|
+
cancel(): void;
|
|
14
|
+
/** Take the page's crop away, its whole canvas showing again, and go on
|
|
15
|
+
* cropping it. */
|
|
16
|
+
reset(): Promise<void>;
|
|
17
|
+
/** Keep the box to `aspect`: the largest box of it in the one now. */
|
|
18
|
+
setAspect(aspect: CropAspect): void;
|
|
19
|
+
/** Enter applies and Escape cancels, while cropping. */
|
|
20
|
+
keydown(e: KeyboardEvent): void;
|
|
21
|
+
destroy(): void;
|
|
22
|
+
}
|
|
23
|
+
/** Crop mode over `host`, its words in `i18n`. */
|
|
24
|
+
export declare function createCrop(host: EditHost, i18n: I18n): Crop;
|
|
25
|
+
/** Crop mode's controls on the image Home tab — which, Home being contextual,
|
|
26
|
+
* show while it lasts — over `crop` once edit mode is mounted. */
|
|
27
|
+
export declare function cropCommands(crop: () => Crop | null): Readonly<Record<string, CommandDef<MessageKey>>>;
|
|
28
|
+
//# sourceMappingURL=crop.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"crop.d.ts","sourceRoot":"","sources":["../src/crop.ts"],"names":[],"mappings":"AAYA,OAAO,KAAK,EAAkB,UAAU,EAAqB,MAAM,6BAA6B,CAAC;AAGjG,OAAO,KAAK,EAAE,UAAU,EAAW,MAAM,eAAe,CAAC;AACzD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AACjD,OAAO,KAAK,EAAE,IAAI,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAYxD,sEAAsE;AACtE,MAAM,WAAW,IAAI;IACjB;oCACgC;IAChC,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACvB,mDAAmD;IACnD,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACvB,yCAAyC;IACzC,MAAM,IAAI,IAAI,CAAC;IACf;uBACmB;IACnB,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACvB,sEAAsE;IACtE,SAAS,CAAC,MAAM,EAAE,UAAU,GAAG,IAAI,CAAC;IACpC,wDAAwD;IACxD,OAAO,CAAC,CAAC,EAAE,aAAa,GAAG,IAAI,CAAC;IAChC,OAAO,IAAI,IAAI,CAAC;CACnB;AAuCD,kDAAkD;AAClD,wBAAgB,UAAU,CAAC,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,IAAI,GAAG,IAAI,CAoK3D;AAwBD;mEACmE;AACnE,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,IAAI,GAAG,IAAI,GAAG,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,UAAU,CAAC,CAAC,CAAC,CAuCtG"}
|
package/dist/crop.js
ADDED
|
@@ -0,0 +1,260 @@
|
|
|
1
|
+
import { ICON_CHECK, ICON_CLEAR, subscribeSelector } from "@docmentis/udoc-ui/internal";
|
|
2
|
+
import { cropOverlay } from "./components/CropOverlay.js";
|
|
3
|
+
import { aspectRatio, dragged, fitRatio, scaled, WHOLE, wholePage } from "./crop-box.js";
|
|
4
|
+
import { ICON_ASPECT_RATIO, ICON_CROP_RESET } from "./icons.js";
|
|
5
|
+
import { croppedPage, editPage, pagePixels } from "./image.js";
|
|
6
|
+
import { editAction } from "./menu-action.js";
|
|
7
|
+
import { editStateOf, updateEditState } from "./state.js";
|
|
8
|
+
/** The overlay crop mode registers. */
|
|
9
|
+
const OVERLAY_ID = "udoc:image-crop";
|
|
10
|
+
/** The narrowest the box gets, in CSS px on screen. */
|
|
11
|
+
const MIN_BOX_PX = 16;
|
|
12
|
+
/** The pixels the cropped page holds. */
|
|
13
|
+
function shownPixels(session) {
|
|
14
|
+
return pagePixels(session.info);
|
|
15
|
+
}
|
|
16
|
+
/** The ratio the session's aspect keeps the box to, or null for none. */
|
|
17
|
+
function sessionRatio(session) {
|
|
18
|
+
const { width, height } = shownPixels(session);
|
|
19
|
+
return aspectRatio(session.aspect, width, height);
|
|
20
|
+
}
|
|
21
|
+
/** Whether crop mode should end in `s`: the document, its type or the mode
|
|
22
|
+
* changed under it, or its page is gone. */
|
|
23
|
+
function cropEnds(s, page, generation) {
|
|
24
|
+
return (s.status !== "ready" ||
|
|
25
|
+
s.docGeneration !== generation ||
|
|
26
|
+
s.docType !== "image" ||
|
|
27
|
+
s.mode !== "edit" ||
|
|
28
|
+
page >= s.pageCount);
|
|
29
|
+
}
|
|
30
|
+
/** Crop mode over `host`, its words in `i18n`. */
|
|
31
|
+
export function createCrop(host, i18n) {
|
|
32
|
+
const { store, client } = host;
|
|
33
|
+
let session = null;
|
|
34
|
+
/** Mirror the session onto edit mode's state, which the Home tab reads. */
|
|
35
|
+
function publish() {
|
|
36
|
+
updateEditState(store, {
|
|
37
|
+
cropping: session
|
|
38
|
+
? { page: session.page, aspect: session.aspect, cropped: croppedPage(session.info) }
|
|
39
|
+
: null,
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
const overlay = cropOverlay({
|
|
43
|
+
i18n,
|
|
44
|
+
get page() {
|
|
45
|
+
return session?.page ?? -1;
|
|
46
|
+
},
|
|
47
|
+
box: () => session?.box ?? WHOLE,
|
|
48
|
+
label(box) {
|
|
49
|
+
if (!session)
|
|
50
|
+
return "";
|
|
51
|
+
const { width, height } = shownPixels(session);
|
|
52
|
+
return i18n.t("image.cropSize", {
|
|
53
|
+
width: Math.max(1, Math.round((box.x1 - box.x0) * width)),
|
|
54
|
+
height: Math.max(1, Math.round((box.y1 - box.y0) * height)),
|
|
55
|
+
});
|
|
56
|
+
},
|
|
57
|
+
view(view) {
|
|
58
|
+
if (session)
|
|
59
|
+
session.view = view;
|
|
60
|
+
},
|
|
61
|
+
drag(handle, from, dx, dy, keep) {
|
|
62
|
+
if (!session)
|
|
63
|
+
return from;
|
|
64
|
+
const { width, height } = shownPixels(session);
|
|
65
|
+
// The narrowest box, in the page's pixels, from its width on screen.
|
|
66
|
+
const min = session.view ? (MIN_BOX_PX * width) / session.view.width : 1;
|
|
67
|
+
const start = scaled(from, width, height);
|
|
68
|
+
const ratio = sessionRatio(session) ??
|
|
69
|
+
(keep && handle !== "move" ? (start.x1 - start.x0) / (start.y1 - start.y0) : null);
|
|
70
|
+
const box = dragged(handle, start, dx * width, dy * height, width, height, min, ratio);
|
|
71
|
+
session.box = scaled(box, 1 / width, 1 / height);
|
|
72
|
+
return session.box;
|
|
73
|
+
},
|
|
74
|
+
apply: () => void apply(),
|
|
75
|
+
});
|
|
76
|
+
/** Draw the overlay again — a box that changed with no frame painted. */
|
|
77
|
+
function redraw() {
|
|
78
|
+
if (session)
|
|
79
|
+
host.setOverlay(OVERLAY_ID, overlay, { aboveSelection: true });
|
|
80
|
+
}
|
|
81
|
+
function end() {
|
|
82
|
+
if (!session)
|
|
83
|
+
return;
|
|
84
|
+
session.unsubscribe();
|
|
85
|
+
session = null;
|
|
86
|
+
host.removeOverlay(OVERLAY_ID);
|
|
87
|
+
publish();
|
|
88
|
+
}
|
|
89
|
+
async function start() {
|
|
90
|
+
const state = store.getState();
|
|
91
|
+
if (session || state.docType !== "image" || state.status !== "ready")
|
|
92
|
+
return;
|
|
93
|
+
const page = state.pageIndex;
|
|
94
|
+
const info = await client.image.pageInfoByIndex(page);
|
|
95
|
+
if (!info || session)
|
|
96
|
+
return;
|
|
97
|
+
// The selection's handles would sit over the box.
|
|
98
|
+
client.clearSelection();
|
|
99
|
+
const generation = state.docGeneration;
|
|
100
|
+
const unsubs = [
|
|
101
|
+
subscribeSelector(store, (s) => cropEnds(s, page, generation), (ends) => {
|
|
102
|
+
if (ends)
|
|
103
|
+
end();
|
|
104
|
+
}),
|
|
105
|
+
// An undo, a peer's edit: the entry the box is measured in again.
|
|
106
|
+
client.onDocumentChanged(() => {
|
|
107
|
+
void client.image.pageInfoByIndex(page).then((fresh) => {
|
|
108
|
+
if (!session || !fresh)
|
|
109
|
+
return;
|
|
110
|
+
session.info = fresh;
|
|
111
|
+
publish();
|
|
112
|
+
});
|
|
113
|
+
}),
|
|
114
|
+
];
|
|
115
|
+
session = {
|
|
116
|
+
page,
|
|
117
|
+
info,
|
|
118
|
+
box: WHOLE,
|
|
119
|
+
aspect: "free",
|
|
120
|
+
view: null,
|
|
121
|
+
unsubscribe: () => {
|
|
122
|
+
for (const unsub of unsubs)
|
|
123
|
+
unsub();
|
|
124
|
+
},
|
|
125
|
+
};
|
|
126
|
+
publish();
|
|
127
|
+
redraw();
|
|
128
|
+
}
|
|
129
|
+
async function apply() {
|
|
130
|
+
const cropped = session;
|
|
131
|
+
if (!cropped)
|
|
132
|
+
return;
|
|
133
|
+
const { page, box } = cropped;
|
|
134
|
+
end();
|
|
135
|
+
if (wholePage(box))
|
|
136
|
+
return;
|
|
137
|
+
// In the page's points as it is now, which the box was drawn over; the
|
|
138
|
+
// engine snaps it to the page's pixels.
|
|
139
|
+
const info = await client.image.pageInfoByIndex(page);
|
|
140
|
+
if (!info)
|
|
141
|
+
return;
|
|
142
|
+
const rect = scaled(box, info.size.width, info.size.height);
|
|
143
|
+
await host.commit(() => client.execute(editPage({ cropPage: { id: info.id, rect } })));
|
|
144
|
+
}
|
|
145
|
+
async function reset() {
|
|
146
|
+
const cropped = session;
|
|
147
|
+
if (!cropped || !croppedPage(cropped.info))
|
|
148
|
+
return;
|
|
149
|
+
await host.commit(() => client.execute(editPage({ cropPage: { id: cropped.info.id, rect: null } })));
|
|
150
|
+
const info = await client.image.pageInfoByIndex(cropped.page);
|
|
151
|
+
if (session !== cropped || !info)
|
|
152
|
+
return;
|
|
153
|
+
cropped.info = info;
|
|
154
|
+
cropped.box = WHOLE;
|
|
155
|
+
cropped.aspect = "free";
|
|
156
|
+
publish();
|
|
157
|
+
redraw();
|
|
158
|
+
}
|
|
159
|
+
function setAspect(aspect) {
|
|
160
|
+
if (!session)
|
|
161
|
+
return;
|
|
162
|
+
session.aspect = aspect;
|
|
163
|
+
const ratio = sessionRatio(session);
|
|
164
|
+
if (ratio !== null) {
|
|
165
|
+
const { width, height } = shownPixels(session);
|
|
166
|
+
session.box = scaled(fitRatio(scaled(session.box, width, height), ratio), 1 / width, 1 / height);
|
|
167
|
+
}
|
|
168
|
+
publish();
|
|
169
|
+
redraw();
|
|
170
|
+
}
|
|
171
|
+
return {
|
|
172
|
+
start,
|
|
173
|
+
apply,
|
|
174
|
+
cancel: end,
|
|
175
|
+
reset,
|
|
176
|
+
setAspect,
|
|
177
|
+
keydown(e) {
|
|
178
|
+
// A key in a real field — a dialog's, a panel's — is the field's;
|
|
179
|
+
// the canvas's hidden text input, which edit mode keeps focused,
|
|
180
|
+
// is no field.
|
|
181
|
+
const target = e.target;
|
|
182
|
+
const field = target !== null &&
|
|
183
|
+
!target.classList.contains("udoc-ui__text-input") &&
|
|
184
|
+
(target.tagName === "INPUT" || target.tagName === "SELECT" || target.tagName === "TEXTAREA");
|
|
185
|
+
if (!session || e.defaultPrevented || field)
|
|
186
|
+
return;
|
|
187
|
+
if (e.key === "Enter") {
|
|
188
|
+
e.preventDefault();
|
|
189
|
+
void apply();
|
|
190
|
+
}
|
|
191
|
+
else if (e.key === "Escape") {
|
|
192
|
+
e.preventDefault();
|
|
193
|
+
end();
|
|
194
|
+
}
|
|
195
|
+
},
|
|
196
|
+
destroy: end,
|
|
197
|
+
};
|
|
198
|
+
}
|
|
199
|
+
/** Whether crop mode is on in `c`. */
|
|
200
|
+
function whenCropping(c) {
|
|
201
|
+
return editStateOf(c).cropping !== null;
|
|
202
|
+
}
|
|
203
|
+
/** The aspects the Aspect Ratio menu offers, and what it calls them. */
|
|
204
|
+
const ASPECTS = [
|
|
205
|
+
["free", "image.free"],
|
|
206
|
+
["original", "image.original"],
|
|
207
|
+
["square", "image.square"],
|
|
208
|
+
["4:3", null],
|
|
209
|
+
["16:9", null],
|
|
210
|
+
];
|
|
211
|
+
/** The Aspect Ratio menu: the aspect the box keeps, checked. */
|
|
212
|
+
const ASPECT_MENU = ASPECTS.map(([aspect, label]) => ({
|
|
213
|
+
action: editAction({ kind: "cropAspect", aspect }),
|
|
214
|
+
label: label ?? ["image.ratio", { ratio: aspect }],
|
|
215
|
+
enabledWhen: whenCropping,
|
|
216
|
+
activeWhen: (c) => editStateOf(c).cropping?.aspect === aspect,
|
|
217
|
+
}));
|
|
218
|
+
/** Crop mode's controls on the image Home tab — which, Home being contextual,
|
|
219
|
+
* show while it lasts — over `crop` once edit mode is mounted. */
|
|
220
|
+
export function cropCommands(crop) {
|
|
221
|
+
return {
|
|
222
|
+
cropAspect: {
|
|
223
|
+
id: "cropAspect",
|
|
224
|
+
label: "image.aspectRatio",
|
|
225
|
+
icon: ICON_ASPECT_RATIO,
|
|
226
|
+
group: "crop",
|
|
227
|
+
labeled: true,
|
|
228
|
+
run: { kind: "menu", menu: ASPECT_MENU },
|
|
229
|
+
enabledWhen: whenCropping,
|
|
230
|
+
},
|
|
231
|
+
cropReset: {
|
|
232
|
+
id: "cropReset",
|
|
233
|
+
label: "image.reset",
|
|
234
|
+
icon: ICON_CROP_RESET,
|
|
235
|
+
group: "crop",
|
|
236
|
+
labeled: true,
|
|
237
|
+
run: { kind: "action", press: () => void crop()?.reset() },
|
|
238
|
+
enabledWhen: (c) => editStateOf(c).cropping?.cropped === true,
|
|
239
|
+
},
|
|
240
|
+
cropCancel: {
|
|
241
|
+
id: "cropCancel",
|
|
242
|
+
label: "common.cancel",
|
|
243
|
+
icon: ICON_CLEAR,
|
|
244
|
+
group: "cropEnd",
|
|
245
|
+
labeled: true,
|
|
246
|
+
run: { kind: "action", press: () => crop()?.cancel() },
|
|
247
|
+
enabledWhen: whenCropping,
|
|
248
|
+
},
|
|
249
|
+
cropApply: {
|
|
250
|
+
id: "cropApply",
|
|
251
|
+
label: "image.apply",
|
|
252
|
+
icon: ICON_CHECK,
|
|
253
|
+
group: "cropEnd",
|
|
254
|
+
labeled: true,
|
|
255
|
+
run: { kind: "action", press: () => void crop()?.apply() },
|
|
256
|
+
enabledWhen: whenCropping,
|
|
257
|
+
},
|
|
258
|
+
};
|
|
259
|
+
}
|
|
260
|
+
//# sourceMappingURL=crop.js.map
|
package/dist/crop.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"crop.js","sourceRoot":"","sources":["../src/crop.ts"],"names":[],"mappings":"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"}
|
package/dist/edit-mode.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"edit-mode.d.ts","sourceRoot":"","sources":["../src/edit-mode.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,WAAW,EAAW,MAAM,6BAA6B,CAAC;AACxE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"edit-mode.d.ts","sourceRoot":"","sources":["../src/edit-mode.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,WAAW,EAAW,MAAM,6BAA6B,CAAC;AACxE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AA0BrD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AAS5C,6FAA6F;AAC7F,MAAM,WAAW,QAAS,SAAQ,WAAW;IACzC,8EAA8E;IAC9E,sBAAsB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAAC;IAC/C,kEAAkE;IAClE,YAAY,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAAC;IACrC,wDAAwD;IACxD,WAAW,IAAI,UAAU,CAAC;IAC1B,kDAAkD;IAClD,OAAO,CAAC,IAAI,EAAE,UAAU,GAAG,IAAI,CAAC;IAChC,uEAAuE;IACvE,WAAW,CAAC,KAAK,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CACtE;AA8ID,4CAA4C;AAC5C,wBAAgB,QAAQ,CAAC,OAAO,EAAE,iBAAiB,GAAG,QAAQ,CAiH7D"}
|
package/dist/edit-mode.js
CHANGED
|
@@ -2,16 +2,19 @@
|
|
|
2
2
|
import { selectionPaint, selectionTextFormat, subscribeSelector } from "@docmentis/udoc-ui/internal";
|
|
3
3
|
import { formatCommands } from "./commands.js";
|
|
4
4
|
import { CONTEXT_MENU, TABLE_CONTEXT_MENU } from "./context-menu.js";
|
|
5
|
+
import { cropCommands } from "./crop.js";
|
|
5
6
|
import { createGrips } from "./grips.js";
|
|
6
7
|
import { createModeSwitch } from "./components/ModeSwitch.js";
|
|
7
8
|
import { createPaintOptionsModal } from "./components/PaintOptionsModal.js";
|
|
8
9
|
import { EditClient } from "./edit-client.js";
|
|
9
10
|
import { FORMATTING_MARKS_COMMAND, formattingMarksKey, mountFormattingMarks, setShowFormattingMarks, } from "./formatting-marks.js";
|
|
10
11
|
import { createI18n, MESSAGE_PACKS } from "./i18n/index.js";
|
|
12
|
+
import { imageCommands, mountImageSize } from "./image.js";
|
|
11
13
|
import { insertCommands, insertImage, pickImage, place, placedShape } from "./insert.js";
|
|
12
14
|
import { runEditMenuAction } from "./menu-action.js";
|
|
13
15
|
import { mountNewSlide, newSlideCommand } from "./new-slide.js";
|
|
14
16
|
import { mountPageControls, PAGE_CONTROLS_SPACING, pageControlsShown } from "./page-controls.js";
|
|
17
|
+
import { selectionLine } from "./paint.js";
|
|
15
18
|
import { ALL_MODES, EDIT_MODE } from "./mode.js";
|
|
16
19
|
import { editState, INITIAL_EDIT_STATE, updateEditState } from "./state.js";
|
|
17
20
|
import { createRuler, rulerShown, setShowRuler } from "./ruler.js";
|
|
@@ -22,8 +25,10 @@ import { createEditTools } from "./tools.js";
|
|
|
22
25
|
/**
|
|
23
26
|
* Keep the document-derived parts of edit mode's state in step with the open
|
|
24
27
|
* document: the theme palette and font families pulled on open, the palette
|
|
25
|
-
* again per slide,
|
|
26
|
-
*
|
|
28
|
+
* again per slide, whether an image's current page takes markup as the
|
|
29
|
+
* current page changes, all cleared while nothing is open, and the
|
|
30
|
+
* selection's resolved format mirrored from each selection report. Returns the
|
|
31
|
+
* teardown.
|
|
27
32
|
*/
|
|
28
33
|
function mountDocumentState(host) {
|
|
29
34
|
const { store, client, edit } = host;
|
|
@@ -42,11 +47,31 @@ function mountDocumentState(host) {
|
|
|
42
47
|
updateEditState(store, { fontFamilies: await edit.fontFamilySummaries() });
|
|
43
48
|
updateEditState(store, { loadedFontFamilyNames: await edit.loadedFontFamilyNames() });
|
|
44
49
|
};
|
|
50
|
+
// Whether the current page of an image takes the shapes the Insert tab
|
|
51
|
+
// draws — read from the engine, which loads the page to say. Latest-wins:
|
|
52
|
+
// a read overtaken by the next drops its answer.
|
|
53
|
+
let markupReads = 0;
|
|
54
|
+
const refreshPageTakesMarkup = async () => {
|
|
55
|
+
const read = ++markupReads;
|
|
56
|
+
const { docType, pageIndex } = store.getState();
|
|
57
|
+
let takes = false;
|
|
58
|
+
if (docType === "image") {
|
|
59
|
+
const info = await client.image.pageInfoByIndex(pageIndex);
|
|
60
|
+
takes = info !== null && (await client.image.takesMarkup(info.id));
|
|
61
|
+
}
|
|
62
|
+
if (read === markupReads)
|
|
63
|
+
updateEditState(store, { pageTakesMarkup: takes });
|
|
64
|
+
};
|
|
45
65
|
const unsubs = [
|
|
46
66
|
// A document opening or closing drops the last one's palette and fonts.
|
|
47
67
|
subscribeSelector(store, (s) => s.status, (status) => {
|
|
48
68
|
if (status === "loading" || status === "empty") {
|
|
49
|
-
updateEditState(store, {
|
|
69
|
+
updateEditState(store, {
|
|
70
|
+
themePalette: null,
|
|
71
|
+
fontFamilies: [],
|
|
72
|
+
loadedFontFamilyNames: [],
|
|
73
|
+
pageTakesMarkup: false,
|
|
74
|
+
});
|
|
50
75
|
}
|
|
51
76
|
}),
|
|
52
77
|
// Each opened document: its palette and its font list — async, off the
|
|
@@ -54,7 +79,13 @@ function mountDocumentState(host) {
|
|
|
54
79
|
subscribeSelector(store, (s) => s.docGeneration, () => {
|
|
55
80
|
void refreshThemePalette();
|
|
56
81
|
void refreshFontFamilies();
|
|
82
|
+
void refreshPageTakesMarkup();
|
|
57
83
|
}),
|
|
84
|
+
// An image's page, another as the current one changes, or as pages
|
|
85
|
+
// come and go under it. What a page takes is its frames', which no
|
|
86
|
+
// edit changes, so an edit of the page itself asks nothing again.
|
|
87
|
+
subscribeSelector(store, (s) => s.pageIndex, () => void refreshPageTakesMarkup()),
|
|
88
|
+
subscribeSelector(store, (s) => s.pageCount, () => void refreshPageTakesMarkup()),
|
|
58
89
|
// Re-pull the theme palette when the viewed slide changes: a
|
|
59
90
|
// multi-master deck (or a slide with a `clrMapOvr`) re-themes per slide,
|
|
60
91
|
// so the picker's "Theme Colors" must track the current slide.
|
|
@@ -71,6 +102,7 @@ function mountDocumentState(host) {
|
|
|
71
102
|
selectionText: selectionTextFormat(state.properties),
|
|
72
103
|
selectionPaint: selectionPaint(state.properties),
|
|
73
104
|
selectionRuler: selectionRuler(state.properties),
|
|
105
|
+
selectionLine: selectionLine(state.properties),
|
|
74
106
|
})),
|
|
75
107
|
];
|
|
76
108
|
return () => {
|
|
@@ -117,6 +149,7 @@ export function editMode(options) {
|
|
|
117
149
|
let host = null;
|
|
118
150
|
let tools = null;
|
|
119
151
|
let newSlide = null;
|
|
152
|
+
let imageSize = null;
|
|
120
153
|
const grips = createGrips(() => tools);
|
|
121
154
|
const ruler = createRuler(() => host);
|
|
122
155
|
const mountedTools = () => {
|
|
@@ -144,11 +177,17 @@ export function editMode(options) {
|
|
|
144
177
|
if (host)
|
|
145
178
|
pickImage(host);
|
|
146
179
|
}),
|
|
180
|
+
...imageCommands(() => host, {
|
|
181
|
+
crop: () => void tools?.crop.start(),
|
|
182
|
+
resize: () => void imageSize?.open(),
|
|
183
|
+
}),
|
|
184
|
+
...cropCommands(() => tools?.crop ?? null),
|
|
147
185
|
},
|
|
148
186
|
spacing: (state) => (showPageControls && pageControlsShown(state) ? PAGE_CONTROLS_SPACING : null),
|
|
149
187
|
keydown(e) {
|
|
150
188
|
if (host)
|
|
151
189
|
formattingMarksKey(e, host.store);
|
|
190
|
+
tools?.crop.keydown(e);
|
|
152
191
|
},
|
|
153
192
|
menuAction(action) {
|
|
154
193
|
if (tools)
|
|
@@ -177,7 +216,10 @@ export function editMode(options) {
|
|
|
177
216
|
const unmountPageControls = showPageControls ? mountPageControls(mounted, i18n) : null;
|
|
178
217
|
const unmountFormattingMarks = mountFormattingMarks(mounted);
|
|
179
218
|
newSlide = mountNewSlide(mounted, i18n);
|
|
219
|
+
imageSize = mountImageSize(mounted, i18n);
|
|
180
220
|
return () => {
|
|
221
|
+
imageSize?.destroy();
|
|
222
|
+
imageSize = null;
|
|
181
223
|
newSlide?.destroy();
|
|
182
224
|
newSlide = null;
|
|
183
225
|
unmountFormattingMarks();
|
|
@@ -185,6 +227,7 @@ export function editMode(options) {
|
|
|
185
227
|
unmountEditingView();
|
|
186
228
|
unmountDocumentState();
|
|
187
229
|
tools?.clipboard.destroy();
|
|
230
|
+
tools?.crop.destroy();
|
|
188
231
|
paintOptionsModal.destroy();
|
|
189
232
|
modeSwitch.destroy();
|
|
190
233
|
tools = null;
|