@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.
Files changed (207) hide show
  1. package/LICENSE-APACHE +202 -0
  2. package/LICENSE-MIT +21 -0
  3. package/README.md +47 -2
  4. package/dist/arrange.d.ts +37 -0
  5. package/dist/arrange.d.ts.map +1 -0
  6. package/dist/arrange.js +431 -0
  7. package/dist/arrange.js.map +1 -0
  8. package/dist/clipboard.d.ts +12 -0
  9. package/dist/clipboard.d.ts.map +1 -0
  10. package/dist/clipboard.js +101 -0
  11. package/dist/clipboard.js.map +1 -0
  12. package/dist/commands.d.ts +12 -0
  13. package/dist/commands.d.ts.map +1 -0
  14. package/dist/commands.js +225 -0
  15. package/dist/commands.js.map +1 -0
  16. package/dist/components/ComboBox.d.ts +38 -0
  17. package/dist/components/ComboBox.d.ts.map +1 -0
  18. package/dist/components/ComboBox.js +57 -0
  19. package/dist/components/ComboBox.js.map +1 -0
  20. package/dist/components/ModeSwitch.d.ts +15 -0
  21. package/dist/components/ModeSwitch.d.ts.map +1 -0
  22. package/dist/components/ModeSwitch.js +94 -0
  23. package/dist/components/ModeSwitch.js.map +1 -0
  24. package/dist/components/NewSlideModal.d.ts +41 -0
  25. package/dist/components/NewSlideModal.d.ts.map +1 -0
  26. package/dist/components/NewSlideModal.js +136 -0
  27. package/dist/components/NewSlideModal.js.map +1 -0
  28. package/dist/components/PageControls.d.ts +78 -0
  29. package/dist/components/PageControls.d.ts.map +1 -0
  30. package/dist/components/PageControls.js +201 -0
  31. package/dist/components/PageControls.js.map +1 -0
  32. package/dist/components/PageSettingsModal.d.ts +27 -0
  33. package/dist/components/PageSettingsModal.d.ts.map +1 -0
  34. package/dist/components/PageSettingsModal.js +273 -0
  35. package/dist/components/PageSettingsModal.js.map +1 -0
  36. package/dist/components/PaintOptionsModal.d.ts +19 -0
  37. package/dist/components/PaintOptionsModal.d.ts.map +1 -0
  38. package/dist/components/PaintOptionsModal.js +103 -0
  39. package/dist/components/PaintOptionsModal.js.map +1 -0
  40. package/dist/components/TextControls.d.ts +49 -0
  41. package/dist/components/TextControls.d.ts.map +1 -0
  42. package/dist/components/TextControls.js +452 -0
  43. package/dist/components/TextControls.js.map +1 -0
  44. package/dist/context-menu.d.ts +46 -0
  45. package/dist/context-menu.d.ts.map +1 -0
  46. package/dist/context-menu.js +144 -0
  47. package/dist/context-menu.js.map +1 -0
  48. package/dist/edit-client.d.ts +121 -0
  49. package/dist/edit-client.d.ts.map +1 -0
  50. package/dist/edit-client.js +154 -0
  51. package/dist/edit-client.js.map +1 -0
  52. package/dist/edit-command.d.ts +7 -0
  53. package/dist/edit-command.d.ts.map +1 -0
  54. package/dist/edit-command.js +18 -0
  55. package/dist/edit-command.js.map +1 -0
  56. package/dist/edit-mode.d.ts +19 -0
  57. package/dist/edit-mode.d.ts.map +1 -0
  58. package/dist/edit-mode.js +214 -0
  59. package/dist/edit-mode.js.map +1 -0
  60. package/dist/editor.d.ts +101 -0
  61. package/dist/editor.d.ts.map +1 -0
  62. package/dist/editor.js +101 -0
  63. package/dist/editor.js.map +1 -0
  64. package/dist/fonts/faces.d.ts +28 -0
  65. package/dist/fonts/faces.d.ts.map +1 -0
  66. package/dist/fonts/faces.js +38 -0
  67. package/dist/fonts/faces.js.map +1 -0
  68. package/dist/fonts/preview.d.ts +98 -0
  69. package/dist/fonts/preview.d.ts.map +1 -0
  70. package/dist/fonts/preview.js +149 -0
  71. package/dist/fonts/preview.js.map +1 -0
  72. package/dist/formatting-marks.d.ts +23 -0
  73. package/dist/formatting-marks.d.ts.map +1 -0
  74. package/dist/formatting-marks.js +55 -0
  75. package/dist/formatting-marks.js.map +1 -0
  76. package/dist/grips.d.ts +14 -0
  77. package/dist/grips.d.ts.map +1 -0
  78. package/dist/grips.js +459 -0
  79. package/dist/grips.js.map +1 -0
  80. package/dist/i18n/ar.d.ts +4 -0
  81. package/dist/i18n/ar.d.ts.map +1 -0
  82. package/dist/i18n/ar.js +175 -0
  83. package/dist/i18n/ar.js.map +1 -0
  84. package/dist/i18n/de.d.ts +4 -0
  85. package/dist/i18n/de.d.ts.map +1 -0
  86. package/dist/i18n/de.js +175 -0
  87. package/dist/i18n/de.js.map +1 -0
  88. package/dist/i18n/en.d.ts +5 -0
  89. package/dist/i18n/en.d.ts.map +1 -0
  90. package/dist/i18n/en.js +176 -0
  91. package/dist/i18n/en.js.map +1 -0
  92. package/dist/i18n/es.d.ts +4 -0
  93. package/dist/i18n/es.d.ts.map +1 -0
  94. package/dist/i18n/es.js +175 -0
  95. package/dist/i18n/es.js.map +1 -0
  96. package/dist/i18n/fr.d.ts +4 -0
  97. package/dist/i18n/fr.d.ts.map +1 -0
  98. package/dist/i18n/fr.js +175 -0
  99. package/dist/i18n/fr.js.map +1 -0
  100. package/dist/i18n/index.d.ts +21 -0
  101. package/dist/i18n/index.d.ts.map +1 -0
  102. package/dist/i18n/index.js +42 -0
  103. package/dist/i18n/index.js.map +1 -0
  104. package/dist/i18n/ja.d.ts +4 -0
  105. package/dist/i18n/ja.d.ts.map +1 -0
  106. package/dist/i18n/ja.js +175 -0
  107. package/dist/i18n/ja.js.map +1 -0
  108. package/dist/i18n/ko.d.ts +4 -0
  109. package/dist/i18n/ko.d.ts.map +1 -0
  110. package/dist/i18n/ko.js +175 -0
  111. package/dist/i18n/ko.js.map +1 -0
  112. package/dist/i18n/messages.d.ts +316 -0
  113. package/dist/i18n/messages.d.ts.map +1 -0
  114. package/dist/i18n/messages.js +2 -0
  115. package/dist/i18n/messages.js.map +1 -0
  116. package/dist/i18n/pt-BR.d.ts +4 -0
  117. package/dist/i18n/pt-BR.d.ts.map +1 -0
  118. package/dist/i18n/pt-BR.js +175 -0
  119. package/dist/i18n/pt-BR.js.map +1 -0
  120. package/dist/i18n/ru.d.ts +4 -0
  121. package/dist/i18n/ru.d.ts.map +1 -0
  122. package/dist/i18n/ru.js +175 -0
  123. package/dist/i18n/ru.js.map +1 -0
  124. package/dist/i18n/zh-CN.d.ts +4 -0
  125. package/dist/i18n/zh-CN.d.ts.map +1 -0
  126. package/dist/i18n/zh-CN.js +175 -0
  127. package/dist/i18n/zh-CN.js.map +1 -0
  128. package/dist/i18n/zh-TW.d.ts +4 -0
  129. package/dist/i18n/zh-TW.d.ts.map +1 -0
  130. package/dist/i18n/zh-TW.js +175 -0
  131. package/dist/i18n/zh-TW.js.map +1 -0
  132. package/dist/icons.d.ts +97 -0
  133. package/dist/icons.d.ts.map +1 -0
  134. package/dist/icons.js +103 -0
  135. package/dist/icons.js.map +1 -0
  136. package/dist/index.d.ts +9 -0
  137. package/dist/index.d.ts.map +1 -0
  138. package/dist/index.js +14 -0
  139. package/dist/index.js.map +1 -0
  140. package/dist/insert.d.ts +21 -0
  141. package/dist/insert.d.ts.map +1 -0
  142. package/dist/insert.js +129 -0
  143. package/dist/insert.js.map +1 -0
  144. package/dist/menu-action.d.ts +73 -0
  145. package/dist/menu-action.d.ts.map +1 -0
  146. package/dist/menu-action.js +89 -0
  147. package/dist/menu-action.js.map +1 -0
  148. package/dist/mode.d.ts +21 -0
  149. package/dist/mode.d.ts.map +1 -0
  150. package/dist/mode.js +17 -0
  151. package/dist/mode.js.map +1 -0
  152. package/dist/new-slide.d.ts +21 -0
  153. package/dist/new-slide.d.ts.map +1 -0
  154. package/dist/new-slide.js +63 -0
  155. package/dist/new-slide.js.map +1 -0
  156. package/dist/page-controls.d.ts +20 -0
  157. package/dist/page-controls.d.ts.map +1 -0
  158. package/dist/page-controls.js +99 -0
  159. package/dist/page-controls.js.map +1 -0
  160. package/dist/paint.d.ts +52 -0
  161. package/dist/paint.d.ts.map +1 -0
  162. package/dist/paint.js +262 -0
  163. package/dist/paint.js.map +1 -0
  164. package/dist/ruler.d.ts +10 -0
  165. package/dist/ruler.d.ts.map +1 -0
  166. package/dist/ruler.js +97 -0
  167. package/dist/ruler.js.map +1 -0
  168. package/dist/state.d.ts +85 -0
  169. package/dist/state.d.ts.map +1 -0
  170. package/dist/state.js +28 -0
  171. package/dist/state.js.map +1 -0
  172. package/dist/styles.d.ts +2 -0
  173. package/dist/styles.d.ts.map +1 -0
  174. package/dist/styles.js +758 -0
  175. package/dist/styles.js.map +1 -0
  176. package/dist/tabs.d.ts +11 -0
  177. package/dist/tabs.d.ts.map +1 -0
  178. package/dist/tabs.js +153 -0
  179. package/dist/tabs.js.map +1 -0
  180. package/dist/text-format.d.ts +114 -0
  181. package/dist/text-format.d.ts.map +1 -0
  182. package/dist/text-format.js +315 -0
  183. package/dist/text-format.js.map +1 -0
  184. package/dist/tools.d.ts +35 -0
  185. package/dist/tools.d.ts.map +1 -0
  186. package/dist/tools.js +41 -0
  187. package/dist/tools.js.map +1 -0
  188. package/dist/version.d.ts +2 -0
  189. package/dist/version.d.ts.map +1 -0
  190. package/dist/version.js +7 -0
  191. package/dist/version.js.map +1 -0
  192. package/dist/worker/handlers.d.ts +11 -0
  193. package/dist/worker/handlers.d.ts.map +1 -0
  194. package/dist/worker/handlers.js +127 -0
  195. package/dist/worker/handlers.js.map +1 -0
  196. package/dist/worker/protocol.d.ts +190 -0
  197. package/dist/worker/protocol.d.ts.map +1 -0
  198. package/dist/worker/protocol.js +2 -0
  199. package/dist/worker/protocol.js.map +1 -0
  200. package/dist/worker/worker-source.d.ts +3 -0
  201. package/dist/worker/worker-source.d.ts.map +1 -0
  202. package/dist/worker/worker-source.js +11 -0
  203. package/dist/worker/worker.d.ts +2 -0
  204. package/dist/worker/worker.d.ts.map +1 -0
  205. package/dist/worker/worker.js +6 -0
  206. package/dist/worker/worker.js.map +1 -0
  207. package/package.json +69 -5
@@ -0,0 +1,149 @@
1
+ /**
2
+ * Font **specimens** — a family's name drawn in its own typeface, so the picker
3
+ * shows the face instead of naming it.
4
+ *
5
+ * Two paths, and a family's `sourceType` picks which. Most families the browser
6
+ * can draw itself: a `Local` one it already answers to by name, a `Url` one it
7
+ * loads as a `FontFace`, a `Google` one it pulls from the css2 API. Those rows
8
+ * stay live text — they restyle with the theme, ellipse when the panel is
9
+ * narrow, and read out to a screen reader — and this module's whole job for them
10
+ * is to get the face into `document.fonts` and let the browser repaint on its
11
+ * own.
12
+ *
13
+ * The rest — `Embedded`, `OfficeCompatible`, `AdobeStandard` — have no bytes
14
+ * outside wasm, so nothing here can name them. Those come back from the engine
15
+ * as a PNG **alpha mask** and are held as object URLs for a CSS `mask-image`
16
+ * over `currentColor`: the specimen then takes the theme's text color, and a
17
+ * light/dark switch needs no redraw.
18
+ *
19
+ * A `Url` family's address is **not** in its source type — the tag carries no
20
+ * data at all — so the host supplies it from the same list it registered with
21
+ * `registerUrlFonts`. It is the only side that ever had it.
22
+ *
23
+ * Every family is worked on **once**. The picker asks for its visible window on
24
+ * every scroll step, so `request` has to be cheap to re-call — it is the only
25
+ * thing standing between a flick through ~2000 families and a request storm.
26
+ */
27
+ /**
28
+ * Families per css2 request. One request per visible window beats one per row,
29
+ * and Google serves as many families as the URL holds — this keeps it well
30
+ * inside the ~2000-character limit proxies and browsers agree on, with room for
31
+ * the `text=` list.
32
+ */
33
+ const GOOGLE_BATCH = 24;
34
+ /** Whether the engine has to draw this family — nothing outside wasm holds its
35
+ * bytes. The complement of the three the browser can load itself. */
36
+ export function isEngineDrawn(sourceType) {
37
+ return sourceType === "embedded" || sourceType === "officeCompatible" || sourceType === "adobeStandard";
38
+ }
39
+ export function createFontPreviewLoader(options) {
40
+ /** Families already worked on — the whole request-storm guard. */
41
+ const seen = new Set();
42
+ const specimens = new Map();
43
+ /** Whether an `onSpecimens` notification is already queued. */
44
+ let notifying = false;
45
+ // One notification per burst: a window of ~18 rows lands as ~18 separate
46
+ // promises, and re-rendering the list once for all of them beats 18 times.
47
+ const notify = () => {
48
+ if (notifying)
49
+ return;
50
+ notifying = true;
51
+ queueMicrotask(() => {
52
+ notifying = false;
53
+ options.onSpecimens();
54
+ });
55
+ };
56
+ const drawInEngine = (family) => {
57
+ void options
58
+ .render(family, options.size)
59
+ .then((image) => {
60
+ if (!image)
61
+ return;
62
+ const url = URL.createObjectURL(new Blob([image.png], { type: "image/png" }));
63
+ specimens.set(family, {
64
+ url,
65
+ width: image.width,
66
+ height: image.height,
67
+ bleed: image.bleed,
68
+ });
69
+ notify();
70
+ })
71
+ .catch(() => {
72
+ // The worker is gone or the document closed. The row keeps the
73
+ // plain name, which is what it showed before this landed.
74
+ });
75
+ };
76
+ const loadUrlFace = (family, url) => {
77
+ // A quoted string, not a bare token: family names carry spaces.
78
+ const face = new FontFace(family, `url("${url.replace(/["\\]/g, "\\$&")}")`);
79
+ void face
80
+ .load()
81
+ .then((loaded) => document.fonts.add(loaded))
82
+ .catch(() => {
83
+ // A 404 or a font the browser can't parse. The row falls back to
84
+ // the UI face, which is what it already shows.
85
+ });
86
+ };
87
+ // One stylesheet for the whole batch. `text=` narrows each face to the
88
+ // characters actually drawn — the union of the batch's names — so a window
89
+ // of two dozen specimens costs a few kilobytes rather than two dozen full
90
+ // Latin subsets.
91
+ const loadGoogleFaces = (families) => {
92
+ for (let at = 0; at < families.length; at += GOOGLE_BATCH) {
93
+ const batch = families.slice(at, at + GOOGLE_BATCH);
94
+ const text = [...new Set(batch.join(""))].join("");
95
+ const query = batch.map((name) => `family=${encodeURIComponent(name)}`).join("&");
96
+ const link = document.createElement("link");
97
+ link.rel = "stylesheet";
98
+ link.href = `${options.googleFontEndpoint}?${query}&text=${encodeURIComponent(text)}&display=swap`;
99
+ document.head.appendChild(link);
100
+ }
101
+ };
102
+ return {
103
+ request(families) {
104
+ const google = [];
105
+ for (const { family, sourceType } of families) {
106
+ if (seen.has(family))
107
+ continue;
108
+ seen.add(family);
109
+ switch (sourceType) {
110
+ case "google":
111
+ google.push(family);
112
+ break;
113
+ case "url": {
114
+ // Only the host ever knew the address; a tag carries none.
115
+ const url = options.urls?.get(family);
116
+ if (url)
117
+ loadUrlFace(family, url);
118
+ break;
119
+ }
120
+ case "local":
121
+ // The host registered these bytes, so its own text stack
122
+ // already answers to the name — naming the family in CSS
123
+ // is the whole of the work. A host that registered an
124
+ // upload rather than an installed face registers the same
125
+ // buffer as a `FontFace` under the same name, and this
126
+ // stays true.
127
+ break;
128
+ default:
129
+ drawInEngine(family);
130
+ break;
131
+ }
132
+ }
133
+ if (google.length > 0)
134
+ loadGoogleFaces(google);
135
+ },
136
+ specimen(family) {
137
+ return specimens.get(family);
138
+ },
139
+ };
140
+ }
141
+ /**
142
+ * `family` as a CSS `font-family` value, quoted and escaped — the form to drop
143
+ * into a style attribute. A family name is arbitrary text (it comes out of a
144
+ * document's font table), so it can't be interpolated raw.
145
+ */
146
+ export function cssFontFamily(family) {
147
+ return `"${family.replace(/["\\]/g, "\\$&")}"`;
148
+ }
149
+ //# sourceMappingURL=preview.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"preview.js","sourceRoot":"","sources":["../../src/fonts/preview.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,23 @@
1
+ import type { Action, CommandDef, Store, UIState } from "@docmentis/udoc-ui/internal";
2
+ import type { EditHost } from "./edit-client.js";
3
+ import type { MessageKey } from "./i18n/index.js";
4
+ /** Show or hide the marks in `store` — a user preference, kept across documents. */
5
+ export declare function setShowFormattingMarks(store: Store<UIState, Action>, visible: boolean): void;
6
+ /**
7
+ * The Show Formatting Marks toggle — a view toggle, not an edit, so it is live
8
+ * whatever is selected: the one Text-tab control no selection greys, fenced off
9
+ * in a group of its own, and shown on the contextual Home in every state. Gated
10
+ * on the doc type instead: every doc type's Home carries the text commands, and
11
+ * the toggle is Word's — only wordprocessing text shows marks.
12
+ */
13
+ export declare const FORMATTING_MARKS_COMMAND: CommandDef<MessageKey>;
14
+ /**
15
+ * Word's Ctrl+Shift+8, flipping the marks where the ribbon's toggle is: edit
16
+ * mode on a wordprocessing document. Matched by the key's place rather than its
17
+ * character, which Shift makes `*` on a US layout and something else elsewhere.
18
+ */
19
+ export declare function formattingMarksKey(e: KeyboardEvent, store: Store<UIState, Action>): void;
20
+ /** Keep the engine drawing the marks while {@link marksShown}; returns the
21
+ * teardown. Sticky in the worker across re-opens, so pushed at once too. */
22
+ export declare function mountFormattingMarks(host: EditHost): () => void;
23
+ //# sourceMappingURL=formatting-marks.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"formatting-marks.d.ts","sourceRoot":"","sources":["../src/formatting-marks.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,MAAM,EAAE,UAAU,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,6BAA6B,CAAC;AAEtF,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AACjD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAYlD,oFAAoF;AACpF,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,KAAK,CAAC,OAAO,EAAE,MAAM,CAAC,EAAE,OAAO,EAAE,OAAO,GAAG,IAAI,CAE5F;AAED;;;;;;GAMG;AACH,eAAO,MAAM,wBAAwB,EAAE,UAAU,CAAC,UAAU,CAY3D,CAAC;AAEF;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,CAAC,EAAE,aAAa,EAAE,KAAK,EAAE,KAAK,CAAC,OAAO,EAAE,MAAM,CAAC,GAAG,IAAI,CAMxF;AAED;6EAC6E;AAC7E,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,QAAQ,GAAG,MAAM,IAAI,CAG/D"}
@@ -0,0 +1,55 @@
1
+ import { subscribeSelector } from "@docmentis/udoc-ui/internal";
2
+ import { ICON_FORMATTING_MARKS } from "./icons.js";
3
+ import { editState, updateEditState } from "./state.js";
4
+ /** Whether the engine draws the marks in `s`: editing chrome like the
5
+ * placeholder prompts, so edit mode only; and only on the doc type carrying
6
+ * the toggle, since a deck's or a spreadsheet's text composes through the same
7
+ * engine and would show marks with no toggle to hide them. */
8
+ function marksShown(s) {
9
+ return editState(s).showFormattingMarks && s.mode === "edit" && s.docType === "wordprocessing";
10
+ }
11
+ /** Show or hide the marks in `store` — a user preference, kept across documents. */
12
+ export function setShowFormattingMarks(store, visible) {
13
+ updateEditState(store, { showFormattingMarks: visible });
14
+ }
15
+ /**
16
+ * The Show Formatting Marks toggle — a view toggle, not an edit, so it is live
17
+ * whatever is selected: the one Text-tab control no selection greys, fenced off
18
+ * in a group of its own, and shown on the contextual Home in every state. Gated
19
+ * on the doc type instead: every doc type's Home carries the text commands, and
20
+ * the toggle is Word's — only wordprocessing text shows marks.
21
+ */
22
+ export const FORMATTING_MARKS_COMMAND = {
23
+ id: "formattingMarks",
24
+ label: "command.formattingMarks",
25
+ icon: ICON_FORMATTING_MARKS,
26
+ group: "formattingMarks",
27
+ run: {
28
+ kind: "toggle",
29
+ pressed: (s) => editState(s).showFormattingMarks,
30
+ press: (store) => setShowFormattingMarks(store, !editState(store.getState()).showFormattingMarks),
31
+ },
32
+ shortcut: { key: "8", shift: true },
33
+ enabledWhen: (c) => c.ready && c.docType === "wordprocessing",
34
+ };
35
+ /**
36
+ * Word's Ctrl+Shift+8, flipping the marks where the ribbon's toggle is: edit
37
+ * mode on a wordprocessing document. Matched by the key's place rather than its
38
+ * character, which Shift makes `*` on a US layout and something else elsewhere.
39
+ */
40
+ export function formattingMarksKey(e, store) {
41
+ if (!((e.ctrlKey || e.metaKey) && e.shiftKey && e.code === "Digit8"))
42
+ return;
43
+ const state = store.getState();
44
+ if (state.mode !== "edit" || state.docType !== "wordprocessing")
45
+ return;
46
+ e.preventDefault();
47
+ setShowFormattingMarks(store, !editState(state).showFormattingMarks);
48
+ }
49
+ /** Keep the engine drawing the marks while {@link marksShown}; returns the
50
+ * teardown. Sticky in the worker across re-opens, so pushed at once too. */
51
+ export function mountFormattingMarks(host) {
52
+ host.edit.setFormattingMarks(marksShown(host.store.getState()));
53
+ return subscribeSelector(host.store, marksShown, (on) => host.edit.setFormattingMarks(on));
54
+ }
55
+ //# sourceMappingURL=formatting-marks.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"formatting-marks.js","sourceRoot":"","sources":["../src/formatting-marks.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,iBAAiB,EAAE,MAAM,6BAA6B,CAAC;AAGhE,OAAO,EAAE,qBAAqB,EAAE,MAAM,YAAY,CAAC;AACnD,OAAO,EAAE,SAAS,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAExD;;;+DAG+D;AAC/D,SAAS,UAAU,CAAC,CAAU;IAC1B,OAAO,SAAS,CAAC,CAAC,CAAC,CAAC,mBAAmB,IAAI,CAAC,CAAC,IAAI,KAAK,MAAM,IAAI,CAAC,CAAC,OAAO,KAAK,gBAAgB,CAAC;AACnG,CAAC;AAED,oFAAoF;AACpF,MAAM,UAAU,sBAAsB,CAAC,KAA6B,EAAE,OAAgB;IAClF,eAAe,CAAC,KAAK,EAAE,EAAE,mBAAmB,EAAE,OAAO,EAAE,CAAC,CAAC;AAC7D,CAAC;AAED;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,wBAAwB,GAA2B;IAC5D,EAAE,EAAE,iBAAiB;IACrB,KAAK,EAAE,yBAAyB;IAChC,IAAI,EAAE,qBAAqB;IAC3B,KAAK,EAAE,iBAAiB;IACxB,GAAG,EAAE;QACD,IAAI,EAAE,QAAQ;QACd,OAAO,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,mBAAmB;QAChD,KAAK,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,sBAAsB,CAAC,KAAK,EAAE,CAAC,SAAS,CAAC,KAAK,CAAC,QAAQ,EAAE,CAAC,CAAC,mBAAmB,CAAC;KACpG;IACD,QAAQ,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE,KAAK,EAAE,IAAI,EAAE;IACnC,WAAW,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC,OAAO,KAAK,gBAAgB;CAChE,CAAC;AAEF;;;;GAIG;AACH,MAAM,UAAU,kBAAkB,CAAC,CAAgB,EAAE,KAA6B;IAC9E,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,IAAI,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,QAAQ,IAAI,CAAC,CAAC,IAAI,KAAK,QAAQ,CAAC;QAAE,OAAO;IAC7E,MAAM,KAAK,GAAG,KAAK,CAAC,QAAQ,EAAE,CAAC;IAC/B,IAAI,KAAK,CAAC,IAAI,KAAK,MAAM,IAAI,KAAK,CAAC,OAAO,KAAK,gBAAgB;QAAE,OAAO;IACxE,CAAC,CAAC,cAAc,EAAE,CAAC;IACnB,sBAAsB,CAAC,KAAK,EAAE,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,mBAAmB,CAAC,CAAC;AACzE,CAAC;AAED;6EAC6E;AAC7E,MAAM,UAAU,oBAAoB,CAAC,IAAc;IAC/C,IAAI,CAAC,IAAI,CAAC,kBAAkB,CAAC,UAAU,CAAC,IAAI,CAAC,KAAK,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC;IAChE,OAAO,iBAAiB,CAAC,IAAI,CAAC,KAAK,EAAE,UAAU,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,kBAAkB,CAAC,EAAE,CAAC,CAAC,CAAC;AAC/F,CAAC"}
@@ -0,0 +1,14 @@
1
+ import type { CanvasGesture, CanvasGestureHost, SelectionChrome } from "@docmentis/udoc-ui/internal";
2
+ import type { EditTools } from "./tools.js";
3
+ /** Edit mode's grips: the chrome udoc-ui draws, and the canvas's calls on them. */
4
+ export interface Grips {
5
+ readonly chrome: SelectionChrome;
6
+ /** The drag a press at canvas-local `(x, y)` starts on a grip, or null off
7
+ * every grip. */
8
+ press(x: number, y: number, canvas: CanvasGestureHost): CanvasGesture | null;
9
+ /** The resting cursor over a grip at `(x, y)`, or null off every grip. */
10
+ cursor(x: number, y: number): string | null;
11
+ }
12
+ /** The grips, editing through `tools` — null until edit mode is mounted. */
13
+ export declare function createGrips(tools: () => EditTools | null): Grips;
14
+ //# sourceMappingURL=grips.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"grips.d.ts","sourceRoot":"","sources":["../src/grips.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAER,aAAa,EACb,iBAAiB,EAGjB,eAAe,EAGlB,MAAM,6BAA6B,CAAC;AACrC,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AA0H5C,mFAAmF;AACnF,MAAM,WAAW,KAAK;IAClB,QAAQ,CAAC,MAAM,EAAE,eAAe,CAAC;IACjC;sBACkB;IAClB,KAAK,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,iBAAiB,GAAG,aAAa,GAAG,IAAI,CAAC;IAC7E,0EAA0E;IAC1E,MAAM,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAAC;CAC/C;AAED,4EAA4E;AAC5E,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,SAAS,GAAG,IAAI,GAAG,KAAK,CA2WhE"}