@quillmark/svelte 0.2.0 → 0.3.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.
- package/README.md +2 -2
- package/THEMING.md +11 -7
- package/dist/core/address.d.ts +7 -7
- package/dist/core/address.js +6 -6
- package/dist/core/bloom.d.ts +5 -5
- package/dist/core/bloom.js +8 -8
- package/dist/core/codec/anchor.d.ts +1 -1
- package/dist/core/codec/anchor.js +1 -1
- package/dist/core/codec/atoms.d.ts +10 -0
- package/dist/core/codec/atoms.js +78 -0
- package/dist/core/codec/clipboard.d.ts +59 -0
- package/dist/core/codec/clipboard.js +202 -0
- package/dist/core/codec/code.d.ts +1 -1
- package/dist/core/codec/code.js +4 -4
- package/dist/core/codec/decode.d.ts +1 -1
- package/dist/core/codec/decode.js +8 -8
- package/dist/core/codec/encode.d.ts +4 -4
- package/dist/core/codec/encode.js +10 -10
- package/dist/core/codec/field.d.ts +21 -26
- package/dist/core/codec/field.js +33 -32
- package/dist/core/codec/index.js +5 -8
- package/dist/core/codec/inputrules.js +56 -18
- package/dist/core/codec/islands.d.ts +11 -7
- package/dist/core/codec/islands.js +16 -10
- package/dist/core/codec/keymap.d.ts +5 -6
- package/dist/core/codec/keymap.js +8 -7
- package/dist/core/codec/lists.d.ts +3 -3
- package/dist/core/codec/lists.js +32 -13
- package/dist/core/codec/marks.d.ts +1 -1
- package/dist/core/codec/marks.js +1 -1
- package/dist/core/codec/positions.js +1 -1
- package/dist/core/codec/prose.css +230 -215
- package/dist/core/codec/schema.js +4 -4
- package/dist/core/codec/slash.d.ts +39 -41
- package/dist/core/codec/slash.js +0 -0
- package/dist/core/codec/table-view.d.ts +12 -16
- package/dist/core/codec/table-view.js +488 -292
- package/dist/core/codec/table.d.ts +42 -15
- package/dist/core/codec/table.js +70 -26
- package/dist/core/errors.d.ts +5 -5
- package/dist/core/index.js +2 -2
- package/dist/core/lifecycle.js +1 -1
- package/dist/core/rebind.svelte.d.ts +2 -2
- package/dist/core/rebind.svelte.js +4 -4
- package/dist/core/teardown.d.ts +1 -1
- package/dist/core/teardown.js +1 -1
- package/dist/core/theme.css +144 -54
- package/dist/preset/index.css +1 -1
- package/dist/preset/recipes.css +31 -29
- package/dist/preset/scale.css +36 -25
- package/dist/preview/Preview.svelte +12 -10
- package/dist/preview/Preview.svelte.d.ts +3 -3
- package/dist/preview/bridge.js +4 -4
- package/dist/preview/controller.js +3 -3
- package/dist/preview/geometry.d.ts +2 -2
- package/dist/preview/geometry.js +2 -2
- package/dist/preview/index.js +3 -3
- package/dist/preview/overlay.d.ts +1 -1
- package/dist/preview/overlay.js +3 -3
- package/dist/preview/paint.js +15 -17
- package/dist/visual/ArrayField.svelte +80 -66
- package/dist/visual/ArrayField.svelte.d.ts +1 -1
- package/dist/visual/BooleanField.svelte +8 -6
- package/dist/visual/BooleanField.svelte.d.ts +2 -2
- package/dist/visual/Card.svelte +151 -325
- package/dist/visual/Card.svelte.d.ts +2 -6
- package/dist/visual/CardControls.svelte +1 -1
- package/dist/visual/DateField.svelte +19 -19
- package/dist/visual/DateField.svelte.d.ts +3 -3
- package/dist/visual/DiagnosticList.svelte +1 -1
- package/dist/visual/EnumField.svelte +16 -16
- package/dist/visual/EnumField.svelte.d.ts +2 -2
- package/dist/visual/Field.svelte +128 -115
- package/dist/visual/Field.svelte.d.ts +1 -1
- package/dist/visual/FieldHint.svelte +24 -42
- package/dist/visual/FieldHint.svelte.d.ts +1 -1
- package/dist/visual/FieldLabel.svelte +8 -8
- package/dist/visual/FormatPopover.svelte +80 -35
- package/dist/visual/NumberField.svelte +5 -5
- package/dist/visual/NumberField.svelte.d.ts +1 -1
- package/dist/visual/ObjectField.svelte +9 -9
- package/dist/visual/ObjectField.svelte.d.ts +1 -1
- package/dist/visual/ProseArrayElement.svelte +11 -13
- package/dist/visual/ProseArrayElement.svelte.d.ts +1 -1
- package/dist/visual/ProseField.svelte +53 -84
- package/dist/visual/ProseField.svelte.d.ts +12 -17
- package/dist/visual/SlashMenu.svelte +42 -16
- package/dist/visual/TextField.svelte +5 -5
- package/dist/visual/TextField.svelte.d.ts +1 -1
- package/dist/visual/TipsCard.svelte +43 -28
- package/dist/visual/VisualEditor.svelte +6 -6
- package/dist/visual/VisualEditorInner.svelte +122 -129
- package/dist/visual/controls.css +74 -30
- package/dist/visual/diagnostics.d.ts +5 -5
- package/dist/visual/diagnostics.js +3 -3
- package/dist/visual/domid.js +3 -3
- package/dist/visual/ext.d.ts +1 -1
- package/dist/visual/ext.js +1 -1
- package/dist/visual/icons/nodes.d.ts +3 -0
- package/dist/visual/icons/nodes.js +2 -1
- package/dist/visual/index.js +4 -4
- package/dist/visual/leaves.d.ts +3 -3
- package/dist/visual/leaves.js +1 -1
- package/dist/visual/links.d.ts +24 -0
- package/dist/visual/links.js +67 -0
- package/dist/visual/props.d.ts +8 -8
- package/dist/visual/signals.d.ts +6 -6
- package/dist/visual/strings.d.ts +14 -19
- package/dist/visual/strings.js +5 -7
- package/dist/visual/structure.d.ts +24 -17
- package/dist/visual/structure.js +8 -8
- package/dist/visual/synced.svelte.d.ts +1 -1
- package/dist/visual/synced.svelte.js +4 -4
- package/dist/visual/tips.d.ts +2 -2
- package/dist/visual/tips.js +3 -3
- package/package.json +1 -1
|
@@ -8,14 +8,18 @@ export declare const ALIGNS: readonly TableAlign[];
|
|
|
8
8
|
/** The zero cell: empty text, no marks. */
|
|
9
9
|
export declare function emptyCell(): TableCell;
|
|
10
10
|
/**
|
|
11
|
-
* The row index space the chrome and the ops share: **0 is the header**, 1…n the
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
* deletes
|
|
11
|
+
* The row index space the chrome and the ops share: **0 is the header**, 1…n the body
|
|
12
|
+
* rows. The split is how a table is stored, not a rank the ops answer to: a row op
|
|
13
|
+
* works {@link allRows} and whichever row lands at index 0 is the header afterwards,
|
|
14
|
+
* so index 0 moves and deletes like any other. The one row the model refuses is the
|
|
15
|
+
* last, there being no table under it.
|
|
15
16
|
*/
|
|
16
17
|
export declare function rowCount(props: TableProps): number;
|
|
17
18
|
/** The cells of row `r` in that space. */
|
|
18
19
|
export declare function rowCells(props: TableProps, r: number): TableCell[];
|
|
20
|
+
/** Whether a row holds no text, which is what tells a row on offer from one taken up
|
|
21
|
+
* (`table-view.ts` §`step`). Text alone: a mark over none is nothing a writer can see. */
|
|
22
|
+
export declare function rowEmpty(props: TableProps, r: number): boolean;
|
|
19
23
|
/** The cell at `(row, column)`, or the zero cell where the rectangle does not reach. */
|
|
20
24
|
export declare function cellAt(props: TableProps, r: number, c: number): TableCell;
|
|
21
25
|
/** The table's column count: the one number `header`, every row and `aligns` share. */
|
|
@@ -27,6 +31,13 @@ export declare function columnCount(props: TableProps): number;
|
|
|
27
31
|
* back, and a table is never narrower than one column.
|
|
28
32
|
*/
|
|
29
33
|
export declare function normalizeTable(props: TableProps): TableProps;
|
|
34
|
+
/**
|
|
35
|
+
* The rows as one list, header first: the space a row op works in. `header` is a
|
|
36
|
+
* separate field because a table always has one and `header: []` is not a table — a
|
|
37
|
+
* storage shape, not a rank a row op has to know about. Reading it as one list is what
|
|
38
|
+
* lets move and delete treat every row alike, and {@link fromRows} splits it back.
|
|
39
|
+
*/
|
|
40
|
+
export declare function allRows(props: TableProps): TableCell[][];
|
|
30
41
|
/** A fresh table: a header plus `bodyRows` empty rows, every column unaligned.
|
|
31
42
|
* Growth is cheap (Tab at the last cell appends a row), so the default is small. */
|
|
32
43
|
export declare function newTable(cols?: number, bodyRows?: number): TableProps;
|
|
@@ -34,32 +45,48 @@ export declare function newTable(cols?: number, bodyRows?: number): TableProps;
|
|
|
34
45
|
export declare function withCell(props: TableProps, r: number, c: number, cell: TableCell): TableProps;
|
|
35
46
|
/** A new empty body row below row `r` (row 0, the header, opens the first body row). */
|
|
36
47
|
export declare function insertRow(props: TableProps, r: number): TableProps;
|
|
37
|
-
/** Drop
|
|
38
|
-
* table
|
|
48
|
+
/** Drop row `r`, the header included: the row left at index 0 is the header, which is
|
|
49
|
+
* how a table whose first row went still has one. A no-op at the last row, that being
|
|
50
|
+
* the removal of the table rather than of a row, and the island's own to answer. */
|
|
39
51
|
export declare function deleteRow(props: TableProps, r: number): TableProps;
|
|
40
52
|
/** A new empty column after column `c`. */
|
|
41
53
|
export declare function insertColumn(props: TableProps, c: number): TableProps;
|
|
42
54
|
/** Drop column `c`; a no-op at one column (a table has at least one). */
|
|
43
55
|
export declare function deleteColumn(props: TableProps, c: number): TableProps;
|
|
44
|
-
/**
|
|
45
|
-
*
|
|
46
|
-
*
|
|
47
|
-
*
|
|
56
|
+
/** Row `r` moved by `by` places, clamped: a drag that leaves the rectangle is a no-op
|
|
57
|
+
* rather than an error, since the drop target is geometry and geometry runs past the
|
|
58
|
+
* last row. The header travels like any other row, and so does the row that displaces
|
|
59
|
+
* it: being the header is holding index 0, which a move is free to hand over. */
|
|
48
60
|
export declare function moveRow(props: TableProps, r: number, by: number): TableProps;
|
|
49
61
|
/** Column `c` moved by `by` places, clamped. `aligns` travels with the column: an
|
|
50
62
|
* alignment is the column's property, so a move that left it behind would retint the
|
|
51
63
|
* column that took the index. */
|
|
52
64
|
export declare function moveColumn(props: TableProps, c: number, by: number): TableProps;
|
|
53
|
-
/**
|
|
54
|
-
*
|
|
55
|
-
*
|
|
56
|
-
|
|
65
|
+
/**
|
|
66
|
+
* Every cell in the inclusive rectangle emptied, alignment kept: what a delete gesture
|
|
67
|
+
* means over a block of cells that covers no whole rank. A rectangle spanning one axis
|
|
68
|
+
* covers ranks and deletes them, and one spanning both is the table itself, so what
|
|
69
|
+
* reaches here is a proper sub-rectangle and the shape it leaves is the shape it found.
|
|
70
|
+
*
|
|
71
|
+
* Alignment is the column's rather than the cells', so it survives a clear that spans one.
|
|
72
|
+
*/
|
|
73
|
+
export declare function clearCells(props: TableProps, r0: number, c0: number, r1: number, c1: number): TableProps;
|
|
74
|
+
/**
|
|
75
|
+
* A rectangle written in at `(r, c)`, the table growing to hold whatever runs past its
|
|
76
|
+
* edges: what a paste into a cell means (`clipboard.ts`). The alternative is clipping
|
|
77
|
+
* to the rectangle that is there, which silently drops the tail of what the author
|
|
78
|
+
* copied; growth drops nothing and every added rank is one the ops already remove.
|
|
79
|
+
*
|
|
80
|
+
* `aligns` is the table's own throughout: a column keeps its alignment under a paste,
|
|
81
|
+
* and a column the paste added arrives `none` like any other fresh one.
|
|
82
|
+
*/
|
|
83
|
+
export declare function pasteCells(props: TableProps, r: number, c: number, block: TableCell[][]): TableProps;
|
|
57
84
|
/** Set column `c`'s alignment: the one table capability the content round-trips
|
|
58
85
|
* today and nothing in the editor could reach. */
|
|
59
86
|
export declare function setAlign(props: TableProps, c: number, align: TableAlign): TableProps;
|
|
60
87
|
/**
|
|
61
88
|
* A cell as a one-line `Content`: what `decode` takes under the inline schema. The
|
|
62
|
-
* cell's marks
|
|
89
|
+
* cell's marks are that content's marks, because both are offsets into the same
|
|
63
90
|
* text: the cell-local coordinate space is a `Content`'s coordinate space with
|
|
64
91
|
* one line in it.
|
|
65
92
|
*/
|
package/dist/core/codec/table.js
CHANGED
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
// doc) and the rectangularizing constructors every row and column op goes through
|
|
3
3
|
// (CODEC §Islands, §"The table island").
|
|
4
4
|
//
|
|
5
|
-
// `TableProps` normalizes to
|
|
5
|
+
// `TableProps` normalizes to one column count shared by `header`, every row, and
|
|
6
6
|
// `aligns`, so a ragged table is not a state the content can hold. The editor keeps
|
|
7
|
-
// its optimistic PM and re-hydrates only on an
|
|
7
|
+
// its optimistic PM and re-hydrates only on an external change (CODEC
|
|
8
8
|
// §Reconciliation), so an op that emitted a ragged table would leave the store
|
|
9
9
|
// rectangularized and PM ragged with no error channel and no repair. Every
|
|
10
10
|
// constructor here therefore ends in {@link normalizeTable}, and a caller reaches
|
|
@@ -26,10 +26,11 @@ export function emptyCell() {
|
|
|
26
26
|
return { text: '', marks: [] };
|
|
27
27
|
}
|
|
28
28
|
/**
|
|
29
|
-
* The row index space the chrome and the ops share: **0 is the header**, 1…n the
|
|
30
|
-
*
|
|
31
|
-
*
|
|
32
|
-
* deletes
|
|
29
|
+
* The row index space the chrome and the ops share: **0 is the header**, 1…n the body
|
|
30
|
+
* rows. The split is how a table is stored, not a rank the ops answer to: a row op
|
|
31
|
+
* works {@link allRows} and whichever row lands at index 0 is the header afterwards,
|
|
32
|
+
* so index 0 moves and deletes like any other. The one row the model refuses is the
|
|
33
|
+
* last, there being no table under it.
|
|
33
34
|
*/
|
|
34
35
|
export function rowCount(props) {
|
|
35
36
|
return props.rows.length + 1;
|
|
@@ -38,6 +39,11 @@ export function rowCount(props) {
|
|
|
38
39
|
export function rowCells(props, r) {
|
|
39
40
|
return r === 0 ? props.header : (props.rows[r - 1] ?? []);
|
|
40
41
|
}
|
|
42
|
+
/** Whether a row holds no text, which is what tells a row on offer from one taken up
|
|
43
|
+
* (`table-view.ts` §`step`). Text alone: a mark over none is nothing a writer can see. */
|
|
44
|
+
export function rowEmpty(props, r) {
|
|
45
|
+
return rowCells(props, r).every((cell) => cell.text === '');
|
|
46
|
+
}
|
|
41
47
|
/** The cell at `(row, column)`, or the zero cell where the rectangle does not reach. */
|
|
42
48
|
export function cellAt(props, r, c) {
|
|
43
49
|
return rowCells(props, r)[c] ?? emptyCell();
|
|
@@ -61,6 +67,22 @@ export function normalizeTable(props) {
|
|
|
61
67
|
aligns: Array.from({ length: cols }, (_, c) => props.aligns[c] ?? 'none')
|
|
62
68
|
};
|
|
63
69
|
}
|
|
70
|
+
/**
|
|
71
|
+
* The rows as one list, header first: the space a row op works in. `header` is a
|
|
72
|
+
* separate field because a table always has one and `header: []` is not a table — a
|
|
73
|
+
* storage shape, not a rank a row op has to know about. Reading it as one list is what
|
|
74
|
+
* lets move and delete treat every row alike, and {@link fromRows} splits it back.
|
|
75
|
+
*/
|
|
76
|
+
export function allRows(props) {
|
|
77
|
+
return [props.header, ...props.rows];
|
|
78
|
+
}
|
|
79
|
+
/** A flat list back into the stored shape: whatever sits at index 0 is the header, by
|
|
80
|
+
* position rather than by having been one. No caller passes an empty list — every op
|
|
81
|
+
* that could reach one refuses the last row first. */
|
|
82
|
+
function fromRows(rows, aligns) {
|
|
83
|
+
const [header = [], ...rest] = rows;
|
|
84
|
+
return normalizeTable({ header, rows: rest, aligns });
|
|
85
|
+
}
|
|
64
86
|
/** A fresh table: a header plus `bodyRows` empty rows, every column unaligned.
|
|
65
87
|
* Growth is cheap (Tab at the last cell appends a row), so the default is small. */
|
|
66
88
|
export function newTable(cols = 3, bodyRows = 2) {
|
|
@@ -88,12 +110,14 @@ export function insertRow(props, r) {
|
|
|
88
110
|
rows: [...props.rows.slice(0, at), fresh, ...props.rows.slice(at)]
|
|
89
111
|
});
|
|
90
112
|
}
|
|
91
|
-
/** Drop
|
|
92
|
-
* table
|
|
113
|
+
/** Drop row `r`, the header included: the row left at index 0 is the header, which is
|
|
114
|
+
* how a table whose first row went still has one. A no-op at the last row, that being
|
|
115
|
+
* the removal of the table rather than of a row, and the island's own to answer. */
|
|
93
116
|
export function deleteRow(props, r) {
|
|
94
|
-
|
|
117
|
+
const rows = allRows(props);
|
|
118
|
+
if (rows.length <= 1 || r < 0 || r >= rows.length)
|
|
95
119
|
return normalizeTable(props);
|
|
96
|
-
return
|
|
120
|
+
return fromRows(rows.filter((_, i) => i !== r), props.aligns);
|
|
97
121
|
}
|
|
98
122
|
/** A new empty column after column `c`. */
|
|
99
123
|
export function insertColumn(props, c) {
|
|
@@ -124,16 +148,16 @@ function move(xs, from, to) {
|
|
|
124
148
|
next.splice(to, 0, moved);
|
|
125
149
|
return next;
|
|
126
150
|
}
|
|
127
|
-
/**
|
|
128
|
-
*
|
|
129
|
-
*
|
|
130
|
-
*
|
|
151
|
+
/** Row `r` moved by `by` places, clamped: a drag that leaves the rectangle is a no-op
|
|
152
|
+
* rather than an error, since the drop target is geometry and geometry runs past the
|
|
153
|
+
* last row. The header travels like any other row, and so does the row that displaces
|
|
154
|
+
* it: being the header is holding index 0, which a move is free to hand over. */
|
|
131
155
|
export function moveRow(props, r, by) {
|
|
132
|
-
const
|
|
133
|
-
const to = Math.max(0, Math.min(
|
|
134
|
-
if (r ===
|
|
156
|
+
const rows = allRows(props);
|
|
157
|
+
const to = Math.max(0, Math.min(r + by, rows.length - 1));
|
|
158
|
+
if (r === to || r < 0 || r >= rows.length)
|
|
135
159
|
return normalizeTable(props);
|
|
136
|
-
return
|
|
160
|
+
return fromRows(move(rows, r, to), props.aligns);
|
|
137
161
|
}
|
|
138
162
|
/** Column `c` moved by `by` places, clamped. `aligns` travels with the column: an
|
|
139
163
|
* alignment is the column's property, so a move that left it behind would retint the
|
|
@@ -149,17 +173,37 @@ export function moveColumn(props, c, by) {
|
|
|
149
173
|
aligns: shift(props.aligns)
|
|
150
174
|
});
|
|
151
175
|
}
|
|
152
|
-
/**
|
|
153
|
-
*
|
|
154
|
-
*
|
|
155
|
-
|
|
156
|
-
|
|
176
|
+
/**
|
|
177
|
+
* Every cell in the inclusive rectangle emptied, alignment kept: what a delete gesture
|
|
178
|
+
* means over a block of cells that covers no whole rank. A rectangle spanning one axis
|
|
179
|
+
* covers ranks and deletes them, and one spanning both is the table itself, so what
|
|
180
|
+
* reaches here is a proper sub-rectangle and the shape it leaves is the shape it found.
|
|
181
|
+
*
|
|
182
|
+
* Alignment is the column's rather than the cells', so it survives a clear that spans one.
|
|
183
|
+
*/
|
|
184
|
+
export function clearCells(props, r0, c0, r1, c1) {
|
|
185
|
+
const blank = (cells, r) => cells.map((cell, c) => (r >= r0 && r <= r1 && c >= c0 && c <= c1 ? emptyCell() : cell));
|
|
157
186
|
return normalizeTable({
|
|
158
|
-
header: blank(props.header),
|
|
159
|
-
rows: props.rows.map(blank),
|
|
187
|
+
header: blank(props.header, 0),
|
|
188
|
+
rows: props.rows.map((row, i) => blank(row, i + 1)),
|
|
160
189
|
aligns: props.aligns
|
|
161
190
|
});
|
|
162
191
|
}
|
|
192
|
+
/**
|
|
193
|
+
* A rectangle written in at `(r, c)`, the table growing to hold whatever runs past its
|
|
194
|
+
* edges: what a paste into a cell means (`clipboard.ts`). The alternative is clipping
|
|
195
|
+
* to the rectangle that is there, which silently drops the tail of what the author
|
|
196
|
+
* copied; growth drops nothing and every added rank is one the ops already remove.
|
|
197
|
+
*
|
|
198
|
+
* `aligns` is the table's own throughout: a column keeps its alignment under a paste,
|
|
199
|
+
* and a column the paste added arrives `none` like any other fresh one.
|
|
200
|
+
*/
|
|
201
|
+
export function pasteCells(props, r, c, block) {
|
|
202
|
+
const rows = allRows(props);
|
|
203
|
+
const height = Math.max(rows.length, r + block.length);
|
|
204
|
+
const width = Math.max(columnCount(props), ...block.map((row) => c + row.length));
|
|
205
|
+
return fromRows(Array.from({ length: height }, (_, i) => Array.from({ length: width }, (_, j) => block[i - r]?.[j - c] ?? rows[i]?.[j] ?? emptyCell())), props.aligns);
|
|
206
|
+
}
|
|
163
207
|
/** Set column `c`'s alignment: the one table capability the content round-trips
|
|
164
208
|
* today and nothing in the editor could reach. */
|
|
165
209
|
export function setAlign(props, c, align) {
|
|
@@ -171,7 +215,7 @@ export function setAlign(props, c, align) {
|
|
|
171
215
|
// ── The cell codec ──────────────────────────────────────────────────────────
|
|
172
216
|
/**
|
|
173
217
|
* A cell as a one-line `Content`: what `decode` takes under the inline schema. The
|
|
174
|
-
* cell's marks
|
|
218
|
+
* cell's marks are that content's marks, because both are offsets into the same
|
|
175
219
|
* text: the cell-local coordinate space is a `Content`'s coordinate space with
|
|
176
220
|
* one line in it.
|
|
177
221
|
*/
|
package/dist/core/errors.d.ts
CHANGED
|
@@ -11,7 +11,7 @@ export type EditorErrorCode =
|
|
|
11
11
|
* the whole projection instead, so the store is correct and this field's
|
|
12
12
|
* identity anchors were paid. */
|
|
13
13
|
| 'commit-fallback'
|
|
14
|
-
/** The overwrite fallback
|
|
14
|
+
/** The overwrite fallback also failed: the optimistic PM state stands and the
|
|
15
15
|
* store is stale for this field. The one code here that leaves damage. */
|
|
16
16
|
| 'commit-lost'
|
|
17
17
|
/** A card operation (add, move, remove, retype) that threw. The document is
|
|
@@ -26,12 +26,12 @@ export type EditorErrorCode =
|
|
|
26
26
|
/** A tip's markdown did not render: the tip shows as literal text. */
|
|
27
27
|
| 'tip-render-failed'
|
|
28
28
|
/**
|
|
29
|
-
* A prop a surface binds
|
|
29
|
+
* A prop a surface binds once was swapped in place, and the surface neither
|
|
30
30
|
* re-keyed on it nor observed it. The mounted surface still names the previous
|
|
31
31
|
* handle. `dev` throughout: the fix is a remount at the call site, so this is
|
|
32
32
|
* aimed at whoever wired it and never at a running app's telemetry.
|
|
33
33
|
*
|
|
34
|
-
* The one code that is also
|
|
34
|
+
* The one code that is also thrown, in a dev build, once reported: a swapped
|
|
35
35
|
* `onError` is itself a rebind, so the handler this arrives at may be the one the
|
|
36
36
|
* consumer just replaced (`rebind.svelte.ts`).
|
|
37
37
|
*/
|
|
@@ -39,12 +39,12 @@ export type EditorErrorCode =
|
|
|
39
39
|
/**
|
|
40
40
|
* A landing named a card or a field the surface does not hold: a `cardId` from a
|
|
41
41
|
* previous session or an already-removed card, or a `DocPath` naming no declared
|
|
42
|
-
* field — an array
|
|
42
|
+
* field — an array element path included, where the array itself is undeclared or
|
|
43
43
|
* unmounted. The call is a no-op and the document is untouched.
|
|
44
44
|
*
|
|
45
45
|
* `dev`, because the fix is at the call site: a host driving the instance verbs
|
|
46
46
|
* from outside, or a preview pick the editor has no field to route to. Every
|
|
47
|
-
*
|
|
47
|
+
* mounted field is a target, prose leaf and form control alike, and an array's
|
|
48
48
|
* elements are targets through it, so this is not how a scalar or an element
|
|
49
49
|
* reports. The preview never reports it at all: a field it places nothing for is
|
|
50
50
|
* `scrollToField` returning `false`.
|
package/dist/core/index.js
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
// The theme derivation: the public dials → the private `--_qm-*` scale, applied
|
|
2
2
|
// to every `data-qm-root` element (THEMING.md). Imported at every barrel a
|
|
3
3
|
// consumer can enter through — here, `/visual`, `/preview` — because a subpath is
|
|
4
|
-
// what a consumer gets, and a surface reaching a module
|
|
4
|
+
// what a consumer gets, and a surface reaching a module inside `core/` reaches
|
|
5
5
|
// nothing this file imports. One sheet however many barrels name it: the
|
|
6
6
|
// derivation is minted once rather than re-declared per detached root.
|
|
7
7
|
import './theme.css';
|
|
8
|
-
// `@quillmark/svelte/core`: what this package
|
|
8
|
+
// `@quillmark/svelte/core`: what this package owns at the substrate seam.
|
|
9
9
|
//
|
|
10
10
|
// The `@quillmark/wasm` API is not re-exported: import it straight from the peer
|
|
11
11
|
// dependency, the single source of truth (quiver states the same rule). The
|
package/dist/core/lifecycle.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// `@quillmark/wasm` ships wasm-bindgen's web target: the core build is
|
|
2
|
-
// instantiated by an explicit `await init()`, which
|
|
2
|
+
// instantiated by an explicit `await init()`, which resolves to the classes and
|
|
3
3
|
// free functions — the artifact exports none of them statically, so awaiting is
|
|
4
4
|
// the only way to hold one. Instantiation carries the panic hook on its start
|
|
5
5
|
// section, so a Rust panic reaches JS as a stack trace.
|
|
@@ -22,10 +22,10 @@ export declare function reportRebindIgnored(onError: EditorErrorHandler | undefi
|
|
|
22
22
|
* in place, and in a dev build throw it after. `remount` closes the message with the
|
|
23
23
|
* surface's own remount spelling (`Remount the preview ({#key session}) to rebind.`).
|
|
24
24
|
*
|
|
25
|
-
* Mounted identities are recorded on the effect's
|
|
25
|
+
* Mounted identities are recorded on the effect's first run, the flush the surface
|
|
26
26
|
* binds in; every later comparison reads them through the same `snapshot`.
|
|
27
27
|
*
|
|
28
|
-
* The report goes to the
|
|
28
|
+
* The report goes to the snapshot's `onError`: every other error these surfaces
|
|
29
29
|
* report reaches the handler they bound, and a swapped `onError` is itself one of
|
|
30
30
|
* the reports.
|
|
31
31
|
*/
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
// The remount contract, enforced. `Preview` binds its props
|
|
1
|
+
// The remount contract, enforced. `Preview` binds its props once, in `onMount`, and
|
|
2
2
|
// observes nothing after: the vanilla core below it owns scroll position, mounted
|
|
3
3
|
// slots and observer sets that a remount would discard on every apply. So a prop
|
|
4
4
|
// swapped in place is reported, not dropped in silence, and thrown in a dev build.
|
|
5
5
|
//
|
|
6
|
-
// A guard over
|
|
6
|
+
// A guard over one prop of a set is worse than none: a consumer who learns the
|
|
7
7
|
// surface complains when it ignores a prop reads silence on the rest as reactivity.
|
|
8
8
|
// The snapshot is every once-bound prop, and one report names whichever went stale.
|
|
9
9
|
import { reportError } from './errors.js';
|
|
@@ -34,10 +34,10 @@ export function reportRebindIgnored(onError, message) {
|
|
|
34
34
|
* in place, and in a dev build throw it after. `remount` closes the message with the
|
|
35
35
|
* surface's own remount spelling (`Remount the preview ({#key session}) to rebind.`).
|
|
36
36
|
*
|
|
37
|
-
* Mounted identities are recorded on the effect's
|
|
37
|
+
* Mounted identities are recorded on the effect's first run, the flush the surface
|
|
38
38
|
* binds in; every later comparison reads them through the same `snapshot`.
|
|
39
39
|
*
|
|
40
|
-
* The report goes to the
|
|
40
|
+
* The report goes to the snapshot's `onError`: every other error these surfaces
|
|
41
41
|
* report reaches the handler they bound, and a swapped `onError` is itself one of
|
|
42
42
|
* the reports.
|
|
43
43
|
*/
|
package/dist/core/teardown.d.ts
CHANGED
|
@@ -4,7 +4,7 @@ export interface Lifespan {
|
|
|
4
4
|
readonly alive: boolean;
|
|
5
5
|
/**
|
|
6
6
|
* Register work to undo at the end: a registry entry to drop, a timer or frame
|
|
7
|
-
* to cancel, a handle to free. Cancellers run in
|
|
7
|
+
* to cancel, a handle to free. Cancellers run in registration order, which is
|
|
8
8
|
* where the order lives. Registering on an ended span runs the canceller at
|
|
9
9
|
* once: there is no later run to hold it for.
|
|
10
10
|
*/
|
package/dist/core/teardown.js
CHANGED
|
@@ -26,7 +26,7 @@ export function createLifespan() {
|
|
|
26
26
|
end() {
|
|
27
27
|
if (!alive)
|
|
28
28
|
return;
|
|
29
|
-
// Dead
|
|
29
|
+
// Dead before the cancellers run: one of them may synchronously reach
|
|
30
30
|
// something that asks, and a span mid-teardown is not alive.
|
|
31
31
|
alive = false;
|
|
32
32
|
for (const cancel of cancels)
|