@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
|
@@ -1,109 +1,109 @@
|
|
|
1
|
-
import { createContainer, createDoc, createParagraph, createRun } from "../model/node.js";
|
|
2
|
-
import { collapsedSelection, createPosition, isCollapsed } from "../model/position.js";
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* Everything the editor knows, as plain data. Holds no DOM references — the
|
|
6
|
-
* renderer and selection controller project it, they do not own it.
|
|
7
|
-
*
|
|
8
|
-
* @typedef {object} EditorState
|
|
9
|
-
* @property {import("../model/node.js").Doc} doc
|
|
10
|
-
* @property {import("../model/position.js").Selection} selection
|
|
11
|
-
* @property {import("../model/node.js").Marks | null} storedMarks
|
|
12
|
-
* Pending formatting at a collapsed cursor: press Ctrl+B with nothing selected
|
|
13
|
-
* and the *next* typed text uses these marks instead of inheriting from the
|
|
14
|
-
* position. `null` means "inherit".
|
|
15
|
-
*/
|
|
16
|
-
|
|
17
|
-
/**
|
|
18
|
-
* @param {import("../model/node.js").Doc} doc
|
|
19
|
-
* @param {import("../model/position.js").Selection} [selection]
|
|
20
|
-
* @returns {EditorState}
|
|
21
|
-
*/
|
|
22
|
-
export function createEditorState(doc, selection) {
|
|
23
|
-
const firstContainer = doc.content[0];
|
|
24
|
-
return {
|
|
25
|
-
doc,
|
|
26
|
-
selection:
|
|
27
|
-
selection ??
|
|
28
|
-
collapsedSelection(createPosition(firstContainer.id, firstContainer.content[0].id, 0)),
|
|
29
|
-
storedMarks: null,
|
|
30
|
-
};
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
/**
|
|
34
|
-
* A document holding one container with one empty paragraph. The container has
|
|
35
|
-
* no layout entry — it is content, not a positioned box; geometry arrives from
|
|
36
|
-
* DOCX import or from `createBox`.
|
|
37
|
-
* @param {import("../model/ids.js").IdFactory} ids
|
|
38
|
-
* @returns {import("../model/node.js").Doc}
|
|
39
|
-
*/
|
|
40
|
-
export function createEmptyDoc(ids) {
|
|
41
|
-
const docId = ids.next();
|
|
42
|
-
const containerId = ids.next();
|
|
43
|
-
return createDoc(docId, [
|
|
44
|
-
createContainer(containerId, [createParagraph(ids.next(), [createRun("")])]),
|
|
45
|
-
]);
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
/**
|
|
49
|
-
* Folds a transaction into the state.
|
|
50
|
-
*
|
|
51
|
-
* `storedMarks` is cleared unless the transaction sets it explicitly. The rules,
|
|
52
|
-
* in order:
|
|
53
|
-
* 1. an explicit value on the transaction wins;
|
|
54
|
-
* 2. undo/redo clears it — pending formatting from before the undo is stale;
|
|
55
|
-
* 3. any transaction that changed the document consumed it;
|
|
56
|
-
* 4. otherwise it carries over;
|
|
57
|
-
* 5. and it never survives a non-collapsed selection.
|
|
58
|
-
*
|
|
59
|
-
* The remaining clearing rule — a user-driven selection change — lives in
|
|
60
|
-
* `selection/controller.js` (`withSelection`'s default, no `keepStoredMarks`),
|
|
61
|
-
* because only that layer can tell a real cursor move from our own
|
|
62
|
-
* programmatic restore. ⚠ "...and blur" — BUGÜN DOĞRU DEĞİL, bkz.
|
|
63
|
-
* `docs/SESSION-LOG.md` Ek 56: no blur-triggered clearing exists anywhere
|
|
64
|
-
* (`grep -n "blur" src/selection/controller.js` is empty) — measured harmless
|
|
65
|
-
* in practice (`handleSelectionChange`'s own "outside the editor" guard
|
|
66
|
-
* already keeps a blur from corrupting `state.selection` at all, so
|
|
67
|
-
* `storedMarks` never needed a separate rule for it), but the sentence itself
|
|
68
|
-
* was always aspirational, not a description of real code.
|
|
69
|
-
*
|
|
70
|
-
* @param {EditorState} state
|
|
71
|
-
* @param {import("../model/transaction.js").Transaction} tr
|
|
72
|
-
* @returns {EditorState}
|
|
73
|
-
*/
|
|
74
|
-
export function applyTransaction(state, tr) {
|
|
75
|
-
/** @type {import("../model/node.js").Marks | null} */
|
|
76
|
-
let storedMarks;
|
|
77
|
-
|
|
78
|
-
if (tr.storedMarks !== undefined) {
|
|
79
|
-
storedMarks = tr.storedMarks;
|
|
80
|
-
} else if (tr.origin === "history" || tr.steps.length > 0) {
|
|
81
|
-
storedMarks = null;
|
|
82
|
-
} else {
|
|
83
|
-
storedMarks = state.storedMarks;
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
if (storedMarks !== null && !isCollapsed(tr.selectionAfter)) {
|
|
87
|
-
storedMarks = null;
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
return { doc: tr.doc, selection: tr.selectionAfter, storedMarks };
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
/**
|
|
94
|
-
* Replaces the selection without touching the document. Used when adopting a
|
|
95
|
-
* selection the browser already applied, so it deliberately produces no
|
|
96
|
-
* transaction and no history entry.
|
|
97
|
-
* @param {EditorState} state
|
|
98
|
-
* @param {import("../model/position.js").Selection} selection
|
|
99
|
-
* @param {{ keepStoredMarks?: boolean }} [options]
|
|
100
|
-
* @returns {EditorState}
|
|
101
|
-
*/
|
|
102
|
-
export function withSelection(state, selection, options = {}) {
|
|
103
|
-
const keep = options.keepStoredMarks === true && isCollapsed(selection);
|
|
104
|
-
return {
|
|
105
|
-
doc: state.doc,
|
|
106
|
-
selection,
|
|
107
|
-
storedMarks: keep ? state.storedMarks : null,
|
|
108
|
-
};
|
|
109
|
-
}
|
|
1
|
+
import { createContainer, createDoc, createParagraph, createRun } from "../model/node.js";
|
|
2
|
+
import { collapsedSelection, createPosition, isCollapsed } from "../model/position.js";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Everything the editor knows, as plain data. Holds no DOM references — the
|
|
6
|
+
* renderer and selection controller project it, they do not own it.
|
|
7
|
+
*
|
|
8
|
+
* @typedef {object} EditorState
|
|
9
|
+
* @property {import("../model/node.js").Doc} doc
|
|
10
|
+
* @property {import("../model/position.js").Selection} selection
|
|
11
|
+
* @property {import("../model/node.js").Marks | null} storedMarks
|
|
12
|
+
* Pending formatting at a collapsed cursor: press Ctrl+B with nothing selected
|
|
13
|
+
* and the *next* typed text uses these marks instead of inheriting from the
|
|
14
|
+
* position. `null` means "inherit".
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* @param {import("../model/node.js").Doc} doc
|
|
19
|
+
* @param {import("../model/position.js").Selection} [selection]
|
|
20
|
+
* @returns {EditorState}
|
|
21
|
+
*/
|
|
22
|
+
export function createEditorState(doc, selection) {
|
|
23
|
+
const firstContainer = doc.content[0];
|
|
24
|
+
return {
|
|
25
|
+
doc,
|
|
26
|
+
selection:
|
|
27
|
+
selection ??
|
|
28
|
+
collapsedSelection(createPosition(firstContainer.id, firstContainer.content[0].id, 0)),
|
|
29
|
+
storedMarks: null,
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* A document holding one container with one empty paragraph. The container has
|
|
35
|
+
* no layout entry — it is content, not a positioned box; geometry arrives from
|
|
36
|
+
* DOCX import or from `createBox`.
|
|
37
|
+
* @param {import("../model/ids.js").IdFactory} ids
|
|
38
|
+
* @returns {import("../model/node.js").Doc}
|
|
39
|
+
*/
|
|
40
|
+
export function createEmptyDoc(ids) {
|
|
41
|
+
const docId = ids.next();
|
|
42
|
+
const containerId = ids.next();
|
|
43
|
+
return createDoc(docId, [
|
|
44
|
+
createContainer(containerId, [createParagraph(ids.next(), [createRun("")])]),
|
|
45
|
+
]);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Folds a transaction into the state.
|
|
50
|
+
*
|
|
51
|
+
* `storedMarks` is cleared unless the transaction sets it explicitly. The rules,
|
|
52
|
+
* in order:
|
|
53
|
+
* 1. an explicit value on the transaction wins;
|
|
54
|
+
* 2. undo/redo clears it — pending formatting from before the undo is stale;
|
|
55
|
+
* 3. any transaction that changed the document consumed it;
|
|
56
|
+
* 4. otherwise it carries over;
|
|
57
|
+
* 5. and it never survives a non-collapsed selection.
|
|
58
|
+
*
|
|
59
|
+
* The remaining clearing rule — a user-driven selection change — lives in
|
|
60
|
+
* `selection/controller.js` (`withSelection`'s default, no `keepStoredMarks`),
|
|
61
|
+
* because only that layer can tell a real cursor move from our own
|
|
62
|
+
* programmatic restore. ⚠ "...and blur" — BUGÜN DOĞRU DEĞİL, bkz.
|
|
63
|
+
* `docs/SESSION-LOG.md` Ek 56: no blur-triggered clearing exists anywhere
|
|
64
|
+
* (`grep -n "blur" src/selection/controller.js` is empty) — measured harmless
|
|
65
|
+
* in practice (`handleSelectionChange`'s own "outside the editor" guard
|
|
66
|
+
* already keeps a blur from corrupting `state.selection` at all, so
|
|
67
|
+
* `storedMarks` never needed a separate rule for it), but the sentence itself
|
|
68
|
+
* was always aspirational, not a description of real code.
|
|
69
|
+
*
|
|
70
|
+
* @param {EditorState} state
|
|
71
|
+
* @param {import("../model/transaction.js").Transaction} tr
|
|
72
|
+
* @returns {EditorState}
|
|
73
|
+
*/
|
|
74
|
+
export function applyTransaction(state, tr) {
|
|
75
|
+
/** @type {import("../model/node.js").Marks | null} */
|
|
76
|
+
let storedMarks;
|
|
77
|
+
|
|
78
|
+
if (tr.storedMarks !== undefined) {
|
|
79
|
+
storedMarks = tr.storedMarks;
|
|
80
|
+
} else if (tr.origin === "history" || tr.steps.length > 0) {
|
|
81
|
+
storedMarks = null;
|
|
82
|
+
} else {
|
|
83
|
+
storedMarks = state.storedMarks;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
if (storedMarks !== null && !isCollapsed(tr.selectionAfter)) {
|
|
87
|
+
storedMarks = null;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
return { doc: tr.doc, selection: tr.selectionAfter, storedMarks };
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* Replaces the selection without touching the document. Used when adopting a
|
|
95
|
+
* selection the browser already applied, so it deliberately produces no
|
|
96
|
+
* transaction and no history entry.
|
|
97
|
+
* @param {EditorState} state
|
|
98
|
+
* @param {import("../model/position.js").Selection} selection
|
|
99
|
+
* @param {{ keepStoredMarks?: boolean }} [options]
|
|
100
|
+
* @returns {EditorState}
|
|
101
|
+
*/
|
|
102
|
+
export function withSelection(state, selection, options = {}) {
|
|
103
|
+
const keep = options.keepStoredMarks === true && isCollapsed(selection);
|
|
104
|
+
return {
|
|
105
|
+
doc: state.doc,
|
|
106
|
+
selection,
|
|
107
|
+
storedMarks: keep ? state.storedMarks : null,
|
|
108
|
+
};
|
|
109
|
+
}
|
package/dist/styles.css
CHANGED
|
@@ -1,66 +1,66 @@
|
|
|
1
|
-
/* word-editor styles.
|
|
2
|
-
*
|
|
3
|
-
* Screen styling is deliberately NOT here: how a page surface looks (paper
|
|
4
|
-
* colour, shadow, gutter) is the host's decision, and the renderer writes
|
|
5
|
-
* every box's geometry as inline style from the layout axis. Anything this
|
|
6
|
-
* file said about position/size would fight it.
|
|
7
|
-
*
|
|
8
|
-
* What IS here is Tier 0 print (ARCHITECTURE.md §7) and the numPr marker rule
|
|
9
|
-
* below — both ship with the package because they are PRODUCT concerns
|
|
10
|
-
* (printing correctly; a bulleted paragraph looking bulleted), not demo ones.
|
|
11
|
-
* The numPr rule is NOT print-only: without it, on screen too, a numPr
|
|
12
|
-
* paragraph renders with no visible marker at all.
|
|
13
|
-
*/
|
|
14
|
-
|
|
15
|
-
/* --- numPr markers (bullets / ordinal-format placeholders) --------------
|
|
16
|
-
*
|
|
17
|
-
* `dom.js`'s `applyParagraphStyle` writes `data-we-marker` + this class on a
|
|
18
|
-
* numPr paragraph's own <p> — never a child node (see dom.js's own comment
|
|
19
|
-
* on NUM_MARKER_KEY for why: a real child would shift renderer.js's
|
|
20
|
-
* runIndex-based tier-2 fast path and inflate dom-map.js's caret offsets,
|
|
21
|
-
* both of which walk/index a paragraph's children with no marker-awareness
|
|
22
|
-
* at all). `content: attr(...)` is CSS generated content — by spec, never a
|
|
23
|
-
* DOM node, so neither of those is ever at risk from it.
|
|
24
|
-
*/
|
|
25
|
-
.we-num-marker::before {
|
|
26
|
-
content: attr(data-we-marker);
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
/* --- Tier 0 PDF: the BROWSER's print-to-PDF, not our writer -------------
|
|
30
|
-
*
|
|
31
|
-
* Tier 0 is `window.print()` + this stylesheet; the user picks "Save as PDF".
|
|
32
|
-
* Tier 1 (our own writer, embedded fonts, ARCHITECTURE §7) is still P7 — this
|
|
33
|
-
* file makes no claim about font embedding or byte-level output.
|
|
34
|
-
*
|
|
35
|
-
* The SHEET size is not set here on purpose. `@page` is static CSS and cannot
|
|
36
|
-
* read `doc.page`, and the corpus is not one size: 43 of 46 documents are A4
|
|
37
|
-
* portrait, one is A4 LANDSCAPE and one is A5 (docs/viewer-measurement.md §4).
|
|
38
|
-
* A hardcoded `size: A4` would mis-fit the last two. The host writes a
|
|
39
|
-
* per-document rule instead:
|
|
40
|
-
*
|
|
41
|
-
* @media print { @page { size: <doc.page.width>pt <doc.page.height>pt;
|
|
42
|
-
* margin: 0; } }
|
|
43
|
-
*
|
|
44
|
-
* See examples/static/viewer.html's setPrintPageSize() for a working one.
|
|
45
|
-
*/
|
|
46
|
-
@media print {
|
|
47
|
-
.we-page {
|
|
48
|
-
/* Screen affordances that must not reach paper. */
|
|
49
|
-
box-shadow: none;
|
|
50
|
-
margin: 0;
|
|
51
|
-
/* One document page per sheet. Both spellings: the older
|
|
52
|
-
* page-break-after is still what some engines honour. */
|
|
53
|
-
break-after: page;
|
|
54
|
-
page-break-after: always;
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
.we-page:last-child {
|
|
58
|
-
break-after: auto;
|
|
59
|
-
page-break-after: auto;
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
/* Boxes are absolutely positioned inside .we-page and their geometry is
|
|
63
|
-
* inline style from the renderer. NOTHING here may touch position, size or
|
|
64
|
-
* z-index — the only thing Tier 0 promises is that paper matches screen,
|
|
65
|
-
* and a rule that nudged a box would break exactly that. */
|
|
66
|
-
}
|
|
1
|
+
/* word-editor styles.
|
|
2
|
+
*
|
|
3
|
+
* Screen styling is deliberately NOT here: how a page surface looks (paper
|
|
4
|
+
* colour, shadow, gutter) is the host's decision, and the renderer writes
|
|
5
|
+
* every box's geometry as inline style from the layout axis. Anything this
|
|
6
|
+
* file said about position/size would fight it.
|
|
7
|
+
*
|
|
8
|
+
* What IS here is Tier 0 print (ARCHITECTURE.md §7) and the numPr marker rule
|
|
9
|
+
* below — both ship with the package because they are PRODUCT concerns
|
|
10
|
+
* (printing correctly; a bulleted paragraph looking bulleted), not demo ones.
|
|
11
|
+
* The numPr rule is NOT print-only: without it, on screen too, a numPr
|
|
12
|
+
* paragraph renders with no visible marker at all.
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
/* --- numPr markers (bullets / ordinal-format placeholders) --------------
|
|
16
|
+
*
|
|
17
|
+
* `dom.js`'s `applyParagraphStyle` writes `data-we-marker` + this class on a
|
|
18
|
+
* numPr paragraph's own <p> — never a child node (see dom.js's own comment
|
|
19
|
+
* on NUM_MARKER_KEY for why: a real child would shift renderer.js's
|
|
20
|
+
* runIndex-based tier-2 fast path and inflate dom-map.js's caret offsets,
|
|
21
|
+
* both of which walk/index a paragraph's children with no marker-awareness
|
|
22
|
+
* at all). `content: attr(...)` is CSS generated content — by spec, never a
|
|
23
|
+
* DOM node, so neither of those is ever at risk from it.
|
|
24
|
+
*/
|
|
25
|
+
.we-num-marker::before {
|
|
26
|
+
content: attr(data-we-marker);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/* --- Tier 0 PDF: the BROWSER's print-to-PDF, not our writer -------------
|
|
30
|
+
*
|
|
31
|
+
* Tier 0 is `window.print()` + this stylesheet; the user picks "Save as PDF".
|
|
32
|
+
* Tier 1 (our own writer, embedded fonts, ARCHITECTURE §7) is still P7 — this
|
|
33
|
+
* file makes no claim about font embedding or byte-level output.
|
|
34
|
+
*
|
|
35
|
+
* The SHEET size is not set here on purpose. `@page` is static CSS and cannot
|
|
36
|
+
* read `doc.page`, and the corpus is not one size: 43 of 46 documents are A4
|
|
37
|
+
* portrait, one is A4 LANDSCAPE and one is A5 (docs/viewer-measurement.md §4).
|
|
38
|
+
* A hardcoded `size: A4` would mis-fit the last two. The host writes a
|
|
39
|
+
* per-document rule instead:
|
|
40
|
+
*
|
|
41
|
+
* @media print { @page { size: <doc.page.width>pt <doc.page.height>pt;
|
|
42
|
+
* margin: 0; } }
|
|
43
|
+
*
|
|
44
|
+
* See examples/static/viewer.html's setPrintPageSize() for a working one.
|
|
45
|
+
*/
|
|
46
|
+
@media print {
|
|
47
|
+
.we-page {
|
|
48
|
+
/* Screen affordances that must not reach paper. */
|
|
49
|
+
box-shadow: none;
|
|
50
|
+
margin: 0;
|
|
51
|
+
/* One document page per sheet. Both spellings: the older
|
|
52
|
+
* page-break-after is still what some engines honour. */
|
|
53
|
+
break-after: page;
|
|
54
|
+
page-break-after: always;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
.we-page:last-child {
|
|
58
|
+
break-after: auto;
|
|
59
|
+
page-break-after: auto;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/* Boxes are absolutely positioned inside .we-page and their geometry is
|
|
63
|
+
* inline style from the renderer. NOTHING here may touch position, size or
|
|
64
|
+
* z-index — the only thing Tier 0 promises is that paper matches screen,
|
|
65
|
+
* and a rule that nudged a box would break exactly that. */
|
|
66
|
+
}
|
package/package.json
CHANGED
|
@@ -1,93 +1,94 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "@sametalmdr/word-editor",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "Page-canvas editor for absolutely positioned DOCX text boxes, and a DOM-free DOCX template filler. Zero runtime dependencies.",
|
|
5
|
-
"license": "MIT",
|
|
6
|
-
"type": "module",
|
|
7
|
-
"sideEffects": false,
|
|
8
|
-
"author": "Alrosoft Ltd",
|
|
9
|
-
"keywords": [
|
|
10
|
-
"editor",
|
|
11
|
-
"word-processor",
|
|
12
|
-
"wysiwyg",
|
|
13
|
-
"docx",
|
|
14
|
-
"docx-template"
|
|
15
|
-
],
|
|
16
|
-
"files": [
|
|
17
|
-
"dist",
|
|
18
|
-
"README.md",
|
|
19
|
-
"LICENSE",
|
|
20
|
-
"CHANGELOG.md"
|
|
21
|
-
],
|
|
22
|
-
"exports": {
|
|
23
|
-
".": {
|
|
24
|
-
"types": "./dist/index.d.ts",
|
|
25
|
-
"default": "./dist/index.js"
|
|
26
|
-
},
|
|
27
|
-
"./element": {
|
|
28
|
-
"types": "./dist/element.d.ts",
|
|
29
|
-
"default": "./dist/element.js"
|
|
30
|
-
},
|
|
31
|
-
"./docx": {
|
|
32
|
-
"types": "./dist/docx.d.ts",
|
|
33
|
-
"default": "./dist/docx.js"
|
|
34
|
-
},
|
|
35
|
-
"./react": {
|
|
36
|
-
"types": "./dist/react/index.d.ts",
|
|
37
|
-
"default": "./dist/react/index.js"
|
|
38
|
-
},
|
|
39
|
-
"./styles.css": "./dist/styles.css"
|
|
40
|
-
},
|
|
41
|
-
"types": "./dist/index.d.ts",
|
|
42
|
-
"main": "./dist/index.js",
|
|
43
|
-
"dependencies": {},
|
|
44
|
-
"publishConfig": {
|
|
45
|
-
"access": "public"
|
|
46
|
-
},
|
|
47
|
-
"peerDependencies": {
|
|
48
|
-
"react": ">=18"
|
|
49
|
-
},
|
|
50
|
-
"peerDependenciesMeta": {
|
|
51
|
-
"react": {
|
|
52
|
-
"optional": true
|
|
53
|
-
}
|
|
54
|
-
},
|
|
55
|
-
"devDependencies": {
|
|
56
|
-
"@types/react": "^18.3.3",
|
|
57
|
-
"docxtemplater": "3.50.0",
|
|
58
|
-
"pizzip": "3.1.7",
|
|
59
|
-
"react": "^18.3.1",
|
|
60
|
-
"typescript": "^5.5.4"
|
|
61
|
-
},
|
|
62
|
-
"scripts": {
|
|
63
|
-
"test": "node scripts/test-clean.js",
|
|
64
|
-
"build": "node scripts/build.js",
|
|
65
|
-
"prepack": "npm run build",
|
|
66
|
-
"pack:smoke": "node scripts/pack-smoke.mjs",
|
|
67
|
-
"check": "tsc --noEmit -p tsconfig.json && tsc -p tsconfig.templates.json",
|
|
68
|
-
"verify": "node scripts/verify.js",
|
|
69
|
-
"templates:manifest": "node scripts/templates/manifest.mjs",
|
|
70
|
-
"templates:build": "node scripts/templates/build.mjs",
|
|
71
|
-
"
|
|
72
|
-
"corpus:
|
|
73
|
-
"corpus:
|
|
74
|
-
"corpus:
|
|
75
|
-
"corpus:
|
|
76
|
-
"corpus:
|
|
77
|
-
"corpus:
|
|
78
|
-
"corpus:
|
|
79
|
-
"corpus:
|
|
80
|
-
"corpus:
|
|
81
|
-
"
|
|
82
|
-
"
|
|
83
|
-
"
|
|
84
|
-
"
|
|
85
|
-
"
|
|
86
|
-
"e2e:
|
|
87
|
-
"e2e:
|
|
88
|
-
"e2e:
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"name": "@sametalmdr/word-editor",
|
|
3
|
+
"version": "0.3.0-alpha",
|
|
4
|
+
"description": "Page-canvas editor for absolutely positioned DOCX text boxes, and a DOM-free DOCX template filler. Zero runtime dependencies.",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"type": "module",
|
|
7
|
+
"sideEffects": false,
|
|
8
|
+
"author": "Alrosoft Ltd",
|
|
9
|
+
"keywords": [
|
|
10
|
+
"editor",
|
|
11
|
+
"word-processor",
|
|
12
|
+
"wysiwyg",
|
|
13
|
+
"docx",
|
|
14
|
+
"docx-template"
|
|
15
|
+
],
|
|
16
|
+
"files": [
|
|
17
|
+
"dist",
|
|
18
|
+
"README.md",
|
|
19
|
+
"LICENSE",
|
|
20
|
+
"CHANGELOG.md"
|
|
21
|
+
],
|
|
22
|
+
"exports": {
|
|
23
|
+
".": {
|
|
24
|
+
"types": "./dist/index.d.ts",
|
|
25
|
+
"default": "./dist/index.js"
|
|
26
|
+
},
|
|
27
|
+
"./element": {
|
|
28
|
+
"types": "./dist/element.d.ts",
|
|
29
|
+
"default": "./dist/element.js"
|
|
30
|
+
},
|
|
31
|
+
"./docx": {
|
|
32
|
+
"types": "./dist/docx.d.ts",
|
|
33
|
+
"default": "./dist/docx.js"
|
|
34
|
+
},
|
|
35
|
+
"./react": {
|
|
36
|
+
"types": "./dist/react/index.d.ts",
|
|
37
|
+
"default": "./dist/react/index.js"
|
|
38
|
+
},
|
|
39
|
+
"./styles.css": "./dist/styles.css"
|
|
40
|
+
},
|
|
41
|
+
"types": "./dist/index.d.ts",
|
|
42
|
+
"main": "./dist/index.js",
|
|
43
|
+
"dependencies": {},
|
|
44
|
+
"publishConfig": {
|
|
45
|
+
"access": "public"
|
|
46
|
+
},
|
|
47
|
+
"peerDependencies": {
|
|
48
|
+
"react": ">=18"
|
|
49
|
+
},
|
|
50
|
+
"peerDependenciesMeta": {
|
|
51
|
+
"react": {
|
|
52
|
+
"optional": true
|
|
53
|
+
}
|
|
54
|
+
},
|
|
55
|
+
"devDependencies": {
|
|
56
|
+
"@types/react": "^18.3.3",
|
|
57
|
+
"docxtemplater": "3.50.0",
|
|
58
|
+
"pizzip": "3.1.7",
|
|
59
|
+
"react": "^18.3.1",
|
|
60
|
+
"typescript": "^5.5.4"
|
|
61
|
+
},
|
|
62
|
+
"scripts": {
|
|
63
|
+
"test": "node scripts/test-clean.js",
|
|
64
|
+
"build": "node scripts/build.js",
|
|
65
|
+
"prepack": "npm run build",
|
|
66
|
+
"pack:smoke": "node scripts/pack-smoke.mjs",
|
|
67
|
+
"check": "tsc --noEmit -p tsconfig.json && tsc -p tsconfig.templates.json",
|
|
68
|
+
"verify": "node scripts/verify.js",
|
|
69
|
+
"templates:manifest": "node scripts/templates/manifest.mjs",
|
|
70
|
+
"templates:build": "node scripts/templates/build.mjs",
|
|
71
|
+
"fonts:widths": "py -X utf8 scripts/fonts/widths.py",
|
|
72
|
+
"corpus:manifest": "node scripts/corpus-manifest.js",
|
|
73
|
+
"corpus:verify": "node scripts/verify-corpus.js",
|
|
74
|
+
"corpus:check": "node scripts/corpus-check.js",
|
|
75
|
+
"corpus:names": "node scripts/corpus-names.js",
|
|
76
|
+
"corpus:pages": "node scripts/corpus-pages.js",
|
|
77
|
+
"corpus:paraprops": "python scripts/measure-paragraph-properties.py",
|
|
78
|
+
"corpus:styleinherit": "python scripts/measure-style-inheritance.py",
|
|
79
|
+
"corpus:bodypr": "python scripts/measure-body-properties.py",
|
|
80
|
+
"corpus:slots": "python scripts/measure-fill-slots.py",
|
|
81
|
+
"corpus:canvas": "node scripts/corpus-to-canvas.js",
|
|
82
|
+
"probe:report": "node scripts/probe-report.js",
|
|
83
|
+
"mutate": "node scripts/mutate.js",
|
|
84
|
+
"ci": "npm run check && npm run build && npm test && npm run verify && npm run corpus:verify",
|
|
85
|
+
"serve": "node scripts/serve-examples.js",
|
|
86
|
+
"e2e:stage": "node scripts/e2e/stage.mjs",
|
|
87
|
+
"e2e:sink": "node scripts/e2e/sink.mjs",
|
|
88
|
+
"e2e:word": "node scripts/e2e/run-word.mjs",
|
|
89
|
+
"e2e:seal": "node scripts/e2e/seal-evidence.mjs"
|
|
90
|
+
},
|
|
91
|
+
"engines": {
|
|
92
|
+
"node": "^20.12.0 || >=21.2.0"
|
|
93
|
+
}
|
|
94
|
+
}
|