@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.
- package/CHANGELOG.md +108 -70
- package/LICENSE +21 -21
- package/README.md +286 -247
- package/dist/canvas/box-clipboard.js +238 -238
- package/dist/canvas/box-selection.js +80 -80
- package/dist/canvas/canvas-editor.js +502 -502
- package/dist/canvas/controller.js +717 -717
- package/dist/canvas/geometry.js +131 -131
- package/dist/canvas/gesture.d.ts +0 -1
- package/dist/canvas/gesture.js +289 -289
- package/dist/canvas/handles.js +212 -212
- package/dist/canvas/menu.js +82 -82
- package/dist/canvas/mode-controller.js +81 -81
- package/dist/canvas/nudge.js +108 -108
- package/dist/canvas/overlay.js +149 -149
- package/dist/canvas/snap.js +132 -132
- package/dist/canvas/viewport.js +112 -112
- package/dist/canvas/z-order.js +171 -171
- package/dist/commands/alignment.js +150 -150
- package/dist/commands/box.js +272 -272
- package/dist/commands/clipboard.js +93 -93
- package/dist/commands/graphemes.js +112 -112
- package/dist/commands/marks.js +153 -153
- package/dist/commands/paragraph-props.js +176 -176
- package/dist/commands/size.js +368 -368
- package/dist/commands/text.js +291 -291
- package/dist/docx.d.ts +1 -0
- package/dist/docx.js +15 -13
- package/dist/editor/editing-host.js +434 -434
- package/dist/element.js +41 -41
- package/dist/fonts/OFL-Carlito.txt +94 -0
- package/dist/fonts/calibri-metrics.d.ts +27 -0
- package/dist/fonts/calibri-metrics.js +88 -0
- package/dist/history/history.js +433 -433
- package/dist/index.js +63 -63
- package/dist/input/beforeinput.js +224 -224
- package/dist/input/clipboard.js +107 -107
- package/dist/input/composition.js +341 -341
- package/dist/input/keymap.js +54 -54
- package/dist/io/ooxml/custgeom.js +72 -72
- package/dist/io/ooxml/drawingml.js +232 -232
- package/dist/io/ooxml/edits.js +67 -67
- package/dist/io/ooxml/export-splice.js +880 -880
- package/dist/io/ooxml/export.js +365 -365
- package/dist/io/ooxml/fill.d.ts +93 -8
- package/dist/io/ooxml/fill.js +618 -562
- package/dist/io/ooxml/fit.d.ts +252 -0
- package/dist/io/ooxml/fit.js +598 -0
- package/dist/io/ooxml/import-gate.js +200 -200
- package/dist/io/ooxml/import.js +691 -691
- package/dist/io/ooxml/inflate.js +126 -126
- package/dist/io/ooxml/media.js +87 -87
- package/dist/io/ooxml/ns.d.ts +2 -0
- package/dist/io/ooxml/ns.js +26 -21
- package/dist/io/ooxml/numbering.js +290 -290
- package/dist/io/ooxml/opc-write.js +171 -171
- package/dist/io/ooxml/provenance.js +93 -93
- package/dist/io/ooxml/recipe.js +708 -708
- package/dist/io/ooxml/relationships.js +59 -59
- package/dist/io/ooxml/run-fonts.d.ts +89 -0
- package/dist/io/ooxml/run-fonts.js +378 -0
- package/dist/io/ooxml/slots.d.ts +4 -0
- package/dist/io/ooxml/slots.js +582 -581
- package/dist/io/ooxml/styles-resolve.js +257 -257
- package/dist/io/ooxml/units.js +43 -43
- package/dist/io/ooxml/value.js +120 -120
- package/dist/io/ooxml/xml-scan.js +616 -616
- package/dist/io/ooxml/zip-container.js +228 -228
- package/dist/io/ooxml/zip-reject.js +106 -106
- package/dist/measure/placement.js +83 -83
- package/dist/measure/report.js +75 -75
- package/dist/model/ids.js +70 -70
- package/dist/model/normalize.js +146 -146
- package/dist/model/position.js +283 -283
- package/dist/model/transaction.js +209 -209
- package/dist/platform/capabilities.js +25 -25
- package/dist/react/index.js +21 -21
- package/dist/selection/controller.js +315 -315
- package/dist/selection/dom-map.js +334 -334
- package/dist/state/editor-state.js +109 -109
- package/dist/styles.css +66 -66
- package/package.json +94 -93
package/dist/input/keymap.js
CHANGED
|
@@ -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
|
+
}
|