@sametalmdr/word-editor 0.2.0-alpha → 0.3.0-alpha

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 (82) hide show
  1. package/CHANGELOG.md +108 -70
  2. package/LICENSE +21 -21
  3. package/README.md +286 -247
  4. package/dist/canvas/box-clipboard.js +238 -238
  5. package/dist/canvas/box-selection.js +80 -80
  6. package/dist/canvas/canvas-editor.js +502 -502
  7. package/dist/canvas/controller.js +717 -717
  8. package/dist/canvas/geometry.js +131 -131
  9. package/dist/canvas/gesture.d.ts +0 -1
  10. package/dist/canvas/gesture.js +289 -289
  11. package/dist/canvas/handles.js +212 -212
  12. package/dist/canvas/menu.js +82 -82
  13. package/dist/canvas/mode-controller.js +81 -81
  14. package/dist/canvas/nudge.js +108 -108
  15. package/dist/canvas/overlay.js +149 -149
  16. package/dist/canvas/snap.js +132 -132
  17. package/dist/canvas/viewport.js +112 -112
  18. package/dist/canvas/z-order.js +171 -171
  19. package/dist/commands/alignment.js +150 -150
  20. package/dist/commands/box.js +272 -272
  21. package/dist/commands/clipboard.js +93 -93
  22. package/dist/commands/graphemes.js +112 -112
  23. package/dist/commands/marks.js +153 -153
  24. package/dist/commands/paragraph-props.js +176 -176
  25. package/dist/commands/size.js +368 -368
  26. package/dist/commands/text.js +291 -291
  27. package/dist/docx.d.ts +1 -0
  28. package/dist/docx.js +15 -13
  29. package/dist/editor/editing-host.js +434 -434
  30. package/dist/element.js +41 -41
  31. package/dist/fonts/OFL-Carlito.txt +94 -0
  32. package/dist/fonts/calibri-metrics.d.ts +27 -0
  33. package/dist/fonts/calibri-metrics.js +88 -0
  34. package/dist/history/history.js +433 -433
  35. package/dist/index.js +63 -63
  36. package/dist/input/beforeinput.js +224 -224
  37. package/dist/input/clipboard.js +107 -107
  38. package/dist/input/composition.js +341 -341
  39. package/dist/input/keymap.js +54 -54
  40. package/dist/io/ooxml/custgeom.js +72 -72
  41. package/dist/io/ooxml/drawingml.js +232 -232
  42. package/dist/io/ooxml/edits.js +67 -67
  43. package/dist/io/ooxml/export-splice.js +880 -880
  44. package/dist/io/ooxml/export.js +365 -365
  45. package/dist/io/ooxml/fill.d.ts +93 -8
  46. package/dist/io/ooxml/fill.js +618 -562
  47. package/dist/io/ooxml/fit.d.ts +252 -0
  48. package/dist/io/ooxml/fit.js +598 -0
  49. package/dist/io/ooxml/import-gate.js +200 -200
  50. package/dist/io/ooxml/import.js +691 -691
  51. package/dist/io/ooxml/inflate.js +126 -126
  52. package/dist/io/ooxml/media.js +87 -87
  53. package/dist/io/ooxml/ns.d.ts +2 -0
  54. package/dist/io/ooxml/ns.js +26 -21
  55. package/dist/io/ooxml/numbering.js +290 -290
  56. package/dist/io/ooxml/opc-write.js +171 -171
  57. package/dist/io/ooxml/provenance.js +93 -93
  58. package/dist/io/ooxml/recipe.js +708 -708
  59. package/dist/io/ooxml/relationships.js +59 -59
  60. package/dist/io/ooxml/run-fonts.d.ts +89 -0
  61. package/dist/io/ooxml/run-fonts.js +378 -0
  62. package/dist/io/ooxml/slots.d.ts +4 -0
  63. package/dist/io/ooxml/slots.js +582 -581
  64. package/dist/io/ooxml/styles-resolve.js +257 -257
  65. package/dist/io/ooxml/units.js +43 -43
  66. package/dist/io/ooxml/value.js +120 -120
  67. package/dist/io/ooxml/xml-scan.js +616 -616
  68. package/dist/io/ooxml/zip-container.js +228 -228
  69. package/dist/io/ooxml/zip-reject.js +106 -106
  70. package/dist/measure/placement.js +83 -83
  71. package/dist/measure/report.js +75 -75
  72. package/dist/model/ids.js +70 -70
  73. package/dist/model/normalize.js +146 -146
  74. package/dist/model/position.js +283 -283
  75. package/dist/model/transaction.js +209 -209
  76. package/dist/platform/capabilities.js +25 -25
  77. package/dist/react/index.js +21 -21
  78. package/dist/selection/controller.js +315 -315
  79. package/dist/selection/dom-map.js +334 -334
  80. package/dist/state/editor-state.js +109 -109
  81. package/dist/styles.css +66 -66
  82. package/package.json +94 -93
@@ -1,54 +1,54 @@
1
- /**
2
- * `keydown` handling for P1 — which is to say, almost none.
3
- *
4
- * Native caret movement gets bidi, grapheme clusters, and line wrapping right
5
- * for free; writing that ourselves is exactly the line-breaking work
6
- * ARCHITECTURE.md §3.4 refuses to redo. So these keys are left alone entirely —
7
- * no `preventDefault()`, no dispatch. The browser moves the caret, fires
8
- * `selectionchange`, and `selection/controller.js` adopts the result.
9
- *
10
- * Formatting (Ctrl+B) and undo (Ctrl+Z) are **not** handled here either: the
11
- * browser turns those into `beforeinput` events with `inputType: "formatBold"` /
12
- * `"historyUndo"`, which `input/beforeinput.js` dispatches. Handling them again
13
- * at the `keydown` level would just be a second, redundant path.
14
- *
15
- * @param {import("./beforeinput.js").InputEventLike & { key?: string }} event
16
- * @returns {void}
17
- */
18
- export function handleKeyDown(event) {
19
- // Intentionally empty for P1. Kept as a named seam — not because this file
20
- // needs to do anything today, but so a later addition (Escape cancelling a
21
- // composition, for instance) has an obvious, already-wired home instead of a
22
- // new listener bolted on elsewhere.
23
- void event;
24
- }
25
-
26
- /** Keys whose native behaviour we rely on and never intercept. */
27
- export const NAVIGATION_KEYS = new Set([
28
- "ArrowLeft",
29
- "ArrowRight",
30
- "ArrowUp",
31
- "ArrowDown",
32
- "Home",
33
- "End",
34
- "PageUp",
35
- "PageDown",
36
- ]);
37
-
38
- /**
39
- * @param {{ key?: string }} event
40
- * @returns {boolean}
41
- */
42
- export function isNavigationKey(event) {
43
- return event.key !== undefined && NAVIGATION_KEYS.has(event.key);
44
- }
45
-
46
- /**
47
- * Tab is left to move focus out of the editor (a11y — WCAG 2.1.2, "no
48
- * keyboard trap"). P1 has no tab stops of its own to intercept it for.
49
- * @param {{ key?: string }} event
50
- * @returns {boolean}
51
- */
52
- export function isTabKey(event) {
53
- return event.key === "Tab";
54
- }
1
+ /**
2
+ * `keydown` handling for P1 — which is to say, almost none.
3
+ *
4
+ * Native caret movement gets bidi, grapheme clusters, and line wrapping right
5
+ * for free; writing that ourselves is exactly the line-breaking work
6
+ * ARCHITECTURE.md §3.4 refuses to redo. So these keys are left alone entirely —
7
+ * no `preventDefault()`, no dispatch. The browser moves the caret, fires
8
+ * `selectionchange`, and `selection/controller.js` adopts the result.
9
+ *
10
+ * Formatting (Ctrl+B) and undo (Ctrl+Z) are **not** handled here either: the
11
+ * browser turns those into `beforeinput` events with `inputType: "formatBold"` /
12
+ * `"historyUndo"`, which `input/beforeinput.js` dispatches. Handling them again
13
+ * at the `keydown` level would just be a second, redundant path.
14
+ *
15
+ * @param {import("./beforeinput.js").InputEventLike & { key?: string }} event
16
+ * @returns {void}
17
+ */
18
+ export function handleKeyDown(event) {
19
+ // Intentionally empty for P1. Kept as a named seam — not because this file
20
+ // needs to do anything today, but so a later addition (Escape cancelling a
21
+ // composition, for instance) has an obvious, already-wired home instead of a
22
+ // new listener bolted on elsewhere.
23
+ void event;
24
+ }
25
+
26
+ /** Keys whose native behaviour we rely on and never intercept. */
27
+ export const NAVIGATION_KEYS = new Set([
28
+ "ArrowLeft",
29
+ "ArrowRight",
30
+ "ArrowUp",
31
+ "ArrowDown",
32
+ "Home",
33
+ "End",
34
+ "PageUp",
35
+ "PageDown",
36
+ ]);
37
+
38
+ /**
39
+ * @param {{ key?: string }} event
40
+ * @returns {boolean}
41
+ */
42
+ export function isNavigationKey(event) {
43
+ return event.key !== undefined && NAVIGATION_KEYS.has(event.key);
44
+ }
45
+
46
+ /**
47
+ * Tab is left to move focus out of the editor (a11y — WCAG 2.1.2, "no
48
+ * keyboard trap"). P1 has no tab stops of its own to intercept it for.
49
+ * @param {{ key?: string }} event
50
+ * @returns {boolean}
51
+ */
52
+ export function isTabKey(event) {
53
+ return event.key === "Tab";
54
+ }
@@ -1,72 +1,72 @@
1
- // a:custGeom -> DecorationPath[]. Ported from decoration_paths(): the corpus
2
- // uses only moveTo/lnTo/close (docs/corpus-inventory.md Bölüm 7 — 0/7,521
3
- // curve commands measured); anything else is skipped and named in the
4
- // returned `unsupported` set rather than guessed at, exactly like the
5
- // reference script's own `unsupported_commands` report.
6
-
7
- import { getAttr, findChild } from "./xml-scan.js";
8
- import { A_NS } from "./ns.js";
9
-
10
- /**
11
- * @typedef {object} ParsedPath
12
- * @property {number} w
13
- * @property {number} h
14
- * @property {boolean} closed
15
- * @property {{kind: "move" | "line", x: number, y: number}[]} commands
16
- */
17
-
18
- /**
19
- * @param {import("./xml-scan.js").XmlElement | undefined} spPr
20
- * @returns {{ paths: ParsedPath[], unsupported: Set<string> }}
21
- */
22
- export function decorationPaths(spPr) {
23
- /** @type {Set<string>} */
24
- const unsupported = new Set();
25
- if (!spPr) return { paths: [], unsupported };
26
- const cust = findChild(spPr, A_NS, "custGeom");
27
- if (!cust) return { paths: [], unsupported };
28
- const pathLst = findChild(cust, A_NS, "pathLst");
29
- if (!pathLst) return { paths: [], unsupported };
30
-
31
- /** @type {ParsedPath[]} */
32
- const out = [];
33
- for (const path of pathLst.children) {
34
- if (path.kind !== "element" || path.uri !== A_NS || path.localName !== "path") continue;
35
- /** @type {{kind: "move" | "line", x: number, y: number}[]} */
36
- const commands = [];
37
- let closed = false;
38
- for (const child of path.children) {
39
- if (child.kind !== "element") continue;
40
- // Matches by LOCAL NAME only, ignoring the namespace URI — ported
41
- // verbatim from decoration_paths()'s `child.tag.split("}")[-1]`, which
42
- // is itself namespace-blind. Not spec-correct in the abstract, but
43
- // this is deliberately what parity means: replicate the algorithm,
44
- // not a more-careful reinterpretation of it.
45
- if (child.localName === "moveTo" || child.localName === "lnTo") {
46
- const pt = findChild(child, A_NS, "pt");
47
- if (!pt) continue;
48
- const x = getAttr(pt, "", "x");
49
- const y = getAttr(pt, "", "y");
50
- if (x === undefined || y === undefined) continue;
51
- commands.push({
52
- kind: child.localName === "moveTo" ? "move" : "line",
53
- x: Number.parseInt(x, 10),
54
- y: Number.parseInt(y, 10),
55
- });
56
- } else if (child.localName === "close") {
57
- closed = true;
58
- } else {
59
- unsupported.add(child.localName);
60
- }
61
- }
62
- if (commands.length > 0) {
63
- out.push({
64
- w: Number.parseInt(getAttr(path, "", "w") ?? "0", 10),
65
- h: Number.parseInt(getAttr(path, "", "h") ?? "0", 10),
66
- closed,
67
- commands,
68
- });
69
- }
70
- }
71
- return { paths: out, unsupported };
72
- }
1
+ // a:custGeom -> DecorationPath[]. Ported from decoration_paths(): the corpus
2
+ // uses only moveTo/lnTo/close (docs/corpus-inventory.md Bölüm 7 — 0/7,521
3
+ // curve commands measured); anything else is skipped and named in the
4
+ // returned `unsupported` set rather than guessed at, exactly like the
5
+ // reference script's own `unsupported_commands` report.
6
+
7
+ import { getAttr, findChild } from "./xml-scan.js";
8
+ import { A_NS } from "./ns.js";
9
+
10
+ /**
11
+ * @typedef {object} ParsedPath
12
+ * @property {number} w
13
+ * @property {number} h
14
+ * @property {boolean} closed
15
+ * @property {{kind: "move" | "line", x: number, y: number}[]} commands
16
+ */
17
+
18
+ /**
19
+ * @param {import("./xml-scan.js").XmlElement | undefined} spPr
20
+ * @returns {{ paths: ParsedPath[], unsupported: Set<string> }}
21
+ */
22
+ export function decorationPaths(spPr) {
23
+ /** @type {Set<string>} */
24
+ const unsupported = new Set();
25
+ if (!spPr) return { paths: [], unsupported };
26
+ const cust = findChild(spPr, A_NS, "custGeom");
27
+ if (!cust) return { paths: [], unsupported };
28
+ const pathLst = findChild(cust, A_NS, "pathLst");
29
+ if (!pathLst) return { paths: [], unsupported };
30
+
31
+ /** @type {ParsedPath[]} */
32
+ const out = [];
33
+ for (const path of pathLst.children) {
34
+ if (path.kind !== "element" || path.uri !== A_NS || path.localName !== "path") continue;
35
+ /** @type {{kind: "move" | "line", x: number, y: number}[]} */
36
+ const commands = [];
37
+ let closed = false;
38
+ for (const child of path.children) {
39
+ if (child.kind !== "element") continue;
40
+ // Matches by LOCAL NAME only, ignoring the namespace URI — ported
41
+ // verbatim from decoration_paths()'s `child.tag.split("}")[-1]`, which
42
+ // is itself namespace-blind. Not spec-correct in the abstract, but
43
+ // this is deliberately what parity means: replicate the algorithm,
44
+ // not a more-careful reinterpretation of it.
45
+ if (child.localName === "moveTo" || child.localName === "lnTo") {
46
+ const pt = findChild(child, A_NS, "pt");
47
+ if (!pt) continue;
48
+ const x = getAttr(pt, "", "x");
49
+ const y = getAttr(pt, "", "y");
50
+ if (x === undefined || y === undefined) continue;
51
+ commands.push({
52
+ kind: child.localName === "moveTo" ? "move" : "line",
53
+ x: Number.parseInt(x, 10),
54
+ y: Number.parseInt(y, 10),
55
+ });
56
+ } else if (child.localName === "close") {
57
+ closed = true;
58
+ } else {
59
+ unsupported.add(child.localName);
60
+ }
61
+ }
62
+ if (commands.length > 0) {
63
+ out.push({
64
+ w: Number.parseInt(getAttr(path, "", "w") ?? "0", 10),
65
+ h: Number.parseInt(getAttr(path, "", "h") ?? "0", 10),
66
+ closed,
67
+ commands,
68
+ });
69
+ }
70
+ }
71
+ return { paths: out, unsupported };
72
+ }