svedit 0.12.0 → 0.13.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 +33 -21
- package/dist/Command.svelte.d.ts +38 -30
- package/dist/Command.svelte.d.ts.map +1 -1
- package/dist/Command.svelte.js +271 -326
- package/dist/CustomProperty.svelte +3 -5
- package/dist/CustomProperty.svelte.d.ts +3 -6
- package/dist/CustomProperty.svelte.d.ts.map +1 -1
- package/dist/KeyMapper.svelte.d.ts +19 -6
- package/dist/KeyMapper.svelte.d.ts.map +1 -1
- package/dist/KeyMapper.svelte.js +95 -112
- package/dist/Node.svelte +16 -13
- package/dist/Node.svelte.d.ts +3 -5
- package/dist/Node.svelte.d.ts.map +1 -1
- package/dist/NodeArrayProperty.svelte +39 -22
- package/dist/NodeArrayProperty.svelte.d.ts +3 -5
- package/dist/NodeArrayProperty.svelte.d.ts.map +1 -1
- package/dist/NodeCaret.svelte +1 -1
- package/dist/NodeCaret.svelte.d.ts +6 -14
- package/dist/NodeCaret.svelte.d.ts.map +1 -1
- package/dist/NodeGap.svelte +12 -6
- package/dist/NodeGap.svelte.d.ts +7 -14
- package/dist/NodeGap.svelte.d.ts.map +1 -1
- package/dist/NodeGapMarkers.svelte +19 -10
- package/dist/NodeGapMarkers.svelte.d.ts +6 -11
- package/dist/NodeGapMarkers.svelte.d.ts.map +1 -1
- package/dist/NodeSelectionMarkers.svelte +20 -6
- package/dist/NodeSelectionMarkers.svelte.d.ts +2 -5
- package/dist/NodeSelectionMarkers.svelte.d.ts.map +1 -1
- package/dist/Session.svelte.d.ts +81 -129
- package/dist/Session.svelte.d.ts.map +1 -1
- package/dist/Session.svelte.js +542 -648
- package/dist/Svedit.svelte +144 -138
- package/dist/Svedit.svelte.d.ts +30 -10
- package/dist/Svedit.svelte.d.ts.map +1 -1
- package/dist/TextProperty.svelte +32 -18
- package/dist/TextProperty.svelte.d.ts +3 -5
- package/dist/TextProperty.svelte.d.ts.map +1 -1
- package/dist/Transaction.svelte.d.ts +64 -127
- package/dist/Transaction.svelte.d.ts.map +1 -1
- package/dist/Transaction.svelte.js +839 -1001
- package/dist/UnknownNode.svelte +4 -3
- package/dist/UnknownNode.svelte.d.ts +5 -9
- package/dist/UnknownNode.svelte.d.ts.map +1 -1
- package/dist/doc_utils.d.ts +67 -155
- package/dist/doc_utils.d.ts.map +1 -1
- package/dist/doc_utils.js +619 -863
- package/dist/index.d.ts +20 -17
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -17
- package/dist/node_visibility.svelte.d.ts +110 -9
- package/dist/node_visibility.svelte.d.ts.map +1 -1
- package/dist/node_visibility.svelte.js +473 -544
- package/dist/paste_utils.d.ts +11 -44
- package/dist/paste_utils.d.ts.map +1 -1
- package/dist/paste_utils.js +111 -152
- package/dist/transforms.svelte.d.ts +9 -7
- package/dist/transforms.svelte.d.ts.map +1 -1
- package/dist/transforms.svelte.js +125 -150
- package/dist/types.d.ts +277 -309
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +1 -0
- package/dist/utils.d.ts +40 -119
- package/dist/utils.d.ts.map +1 -1
- package/dist/utils.js +346 -473
- package/package.json +69 -70
- package/src/lib/{Command.svelte.js → Command.svelte.ts} +29 -17
- package/src/lib/CustomProperty.svelte +3 -5
- package/src/lib/{KeyMapper.svelte.js → KeyMapper.svelte.ts} +28 -11
- package/src/lib/Node.svelte +16 -13
- package/src/lib/NodeArrayProperty.svelte +39 -22
- package/src/lib/NodeCaret.svelte +1 -1
- package/src/lib/NodeGap.svelte +12 -6
- package/src/lib/NodeGapMarkers.svelte +19 -10
- package/src/lib/NodeSelectionMarkers.svelte +20 -6
- package/src/lib/{Session.svelte.js → Session.svelte.ts} +130 -127
- package/src/lib/Svedit.svelte +144 -138
- package/src/lib/TextProperty.svelte +32 -18
- package/src/lib/{Transaction.svelte.js → Transaction.svelte.ts} +139 -143
- package/src/lib/UnknownNode.svelte +4 -3
- package/src/lib/{doc_utils.js → doc_utils.ts} +247 -206
- package/src/lib/{index.js → index.ts} +47 -0
- package/src/lib/{node_visibility.svelte.js → node_visibility.svelte.ts} +68 -92
- package/src/lib/{paste_utils.js → paste_utils.ts} +47 -58
- package/src/lib/{transforms.svelte.js → transforms.svelte.ts} +39 -21
- package/src/lib/{types.d.ts → types.ts} +143 -66
- package/src/lib/{utils.js → utils.ts} +110 -129
|
@@ -1,20 +1,33 @@
|
|
|
1
1
|
import { split_text, join_text, get_char_length } from './utils.js';
|
|
2
2
|
import { get_default_node_type } from './doc_utils.js';
|
|
3
|
+
import type Transaction from './Transaction.svelte.js';
|
|
4
|
+
import type {
|
|
5
|
+
DocumentNode,
|
|
6
|
+
DocumentPath,
|
|
7
|
+
NodeArrayProperty,
|
|
8
|
+
NodeProperty,
|
|
9
|
+
Selection,
|
|
10
|
+
TextSelection
|
|
11
|
+
} from './types.js';
|
|
3
12
|
|
|
4
13
|
/**
|
|
5
14
|
* Set multiple properties on a node via a transaction.
|
|
6
15
|
*
|
|
7
|
-
* @param
|
|
8
|
-
* @param
|
|
9
|
-
* @param
|
|
16
|
+
* @param tr - The transaction
|
|
17
|
+
* @param path - Path to the node
|
|
18
|
+
* @param properties - Key/value pairs to set
|
|
10
19
|
*/
|
|
11
|
-
export function set_properties(
|
|
20
|
+
export function set_properties(
|
|
21
|
+
tr: Transaction,
|
|
22
|
+
path: DocumentPath,
|
|
23
|
+
properties: Record<string, unknown>
|
|
24
|
+
): void {
|
|
12
25
|
for (const [key, value] of Object.entries(properties)) {
|
|
13
26
|
tr.set([...path, key], value);
|
|
14
27
|
}
|
|
15
28
|
}
|
|
16
29
|
|
|
17
|
-
export function break_text_node(tr) {
|
|
30
|
+
export function break_text_node(tr: Transaction): boolean {
|
|
18
31
|
// Keep a reference of the original selection (before any transforms are applied)
|
|
19
32
|
const selection = tr.selection;
|
|
20
33
|
// First we need to ensure we have a text selection
|
|
@@ -28,7 +41,7 @@ export function break_text_node(tr) {
|
|
|
28
41
|
if (tr.kind(node) !== 'text') return false;
|
|
29
42
|
const is_inside_node_array = tr.inspect(selection.path.slice(0, -2))?.type === 'node_array';
|
|
30
43
|
if (!is_inside_node_array) return false; // Do nothing if we're not inside a node_array
|
|
31
|
-
const node_array_prop = selection.path.at(-3);
|
|
44
|
+
const node_array_prop = String(selection.path.at(-3));
|
|
32
45
|
// Get the node that owns the node_array property (e.g. a page.body)
|
|
33
46
|
const node_array_node = tr.get(selection.path.slice(0, -3));
|
|
34
47
|
|
|
@@ -37,23 +50,26 @@ export function break_text_node(tr) {
|
|
|
37
50
|
tr.delete_selection();
|
|
38
51
|
}
|
|
39
52
|
|
|
40
|
-
|
|
53
|
+
// After delete_selection the selection is still a (collapsed) text selection
|
|
54
|
+
const split_at_position = (tr.selection as TextSelection).anchor_offset;
|
|
41
55
|
const content = tr.get(selection.path);
|
|
42
56
|
const [left_text, right_text] = split_text(content, split_at_position);
|
|
43
57
|
|
|
44
58
|
tr.set([node.id, 'content'], left_text);
|
|
45
59
|
|
|
46
|
-
const node_insert_position = {
|
|
60
|
+
const node_insert_position: Selection = {
|
|
47
61
|
type: 'node',
|
|
48
62
|
path: tr.selection.path.slice(0, -2),
|
|
49
|
-
anchor_offset:
|
|
50
|
-
focus_offset:
|
|
63
|
+
anchor_offset: (tr.selection.path.at(-2) as number) + 1,
|
|
64
|
+
focus_offset: (tr.selection.path.at(-2) as number) + 1
|
|
51
65
|
};
|
|
52
66
|
|
|
53
67
|
// TODO: Only use default_node_type when caret is at the end of
|
|
54
68
|
const node_array_property_definition =
|
|
55
69
|
tr.schema[node_array_node.type].properties[node_array_prop];
|
|
56
|
-
const target_node_type = get_default_node_type(
|
|
70
|
+
const target_node_type = get_default_node_type(
|
|
71
|
+
node_array_property_definition as NodeProperty | NodeArrayProperty
|
|
72
|
+
);
|
|
57
73
|
|
|
58
74
|
if (!target_node_type) {
|
|
59
75
|
console.warn(
|
|
@@ -68,7 +84,7 @@ export function break_text_node(tr) {
|
|
|
68
84
|
return true;
|
|
69
85
|
}
|
|
70
86
|
|
|
71
|
-
export function join_text_node(tr) {
|
|
87
|
+
export function join_text_node(tr: Transaction): boolean {
|
|
72
88
|
// Keep a reference of the original selection (before any transforms are applied)
|
|
73
89
|
const selection = tr.selection;
|
|
74
90
|
// First we need to ensure we have a text selection
|
|
@@ -79,16 +95,16 @@ export function join_text_node(tr) {
|
|
|
79
95
|
const is_inside_node_array = tr.inspect(selection.path.slice(0, -2))?.type === 'node_array';
|
|
80
96
|
if (!is_inside_node_array) return false; // Do nothing if we're not inside a node_array
|
|
81
97
|
|
|
82
|
-
const node_index =
|
|
98
|
+
const node_index = tr.selection.path.at(-2) as number;
|
|
83
99
|
|
|
84
100
|
// Determine if we can join with the previous node
|
|
85
101
|
let can_join = false;
|
|
86
|
-
let predecessor_node = null;
|
|
102
|
+
let predecessor_node: DocumentNode | null = null;
|
|
87
103
|
|
|
88
104
|
if (node_index > 0) {
|
|
89
105
|
const previous_text_path = [...tr.selection.path.slice(0, -2), node_index - 1];
|
|
90
106
|
predecessor_node = tr.get(previous_text_path);
|
|
91
|
-
can_join = tr.kind(predecessor_node) === 'text';
|
|
107
|
+
can_join = predecessor_node !== null && tr.kind(predecessor_node) === 'text';
|
|
92
108
|
}
|
|
93
109
|
|
|
94
110
|
// Special behavior: if we can't join and current node is empty, delete it
|
|
@@ -104,7 +120,7 @@ export function join_text_node(tr) {
|
|
|
104
120
|
}
|
|
105
121
|
|
|
106
122
|
// If we can't join for any reason, return false
|
|
107
|
-
if (!can_join) {
|
|
123
|
+
if (!can_join || !predecessor_node) {
|
|
108
124
|
return false;
|
|
109
125
|
}
|
|
110
126
|
|
|
@@ -138,7 +154,7 @@ export function join_text_node(tr) {
|
|
|
138
154
|
return true;
|
|
139
155
|
}
|
|
140
156
|
|
|
141
|
-
export function insert_default_node(tr) {
|
|
157
|
+
export function insert_default_node(tr: Transaction): boolean {
|
|
142
158
|
const selection = tr.selection;
|
|
143
159
|
|
|
144
160
|
// Only work with collapsed node selections
|
|
@@ -148,15 +164,17 @@ export function insert_default_node(tr) {
|
|
|
148
164
|
|
|
149
165
|
const path = selection.path;
|
|
150
166
|
const node_array_node = tr.get(path.slice(0, -1));
|
|
151
|
-
const property_name = path.at(-1);
|
|
167
|
+
const property_name = String(path.at(-1));
|
|
152
168
|
|
|
153
169
|
// Get the definition for this property
|
|
154
170
|
const property_definition = tr.schema[node_array_node.type].properties[property_name];
|
|
155
|
-
const default_type = get_default_node_type(
|
|
171
|
+
const default_type = get_default_node_type(
|
|
172
|
+
property_definition as NodeProperty | NodeArrayProperty
|
|
173
|
+
);
|
|
156
174
|
|
|
157
175
|
// Use the inserter function if available
|
|
158
|
-
if (tr.config?.inserters?.[default_type]) {
|
|
159
|
-
tr.config.inserters[default_type](tr);
|
|
176
|
+
if (tr.config?.inserters?.[default_type as string]) {
|
|
177
|
+
tr.config.inserters[default_type as string](tr);
|
|
160
178
|
return true;
|
|
161
179
|
} else {
|
|
162
180
|
throw new Error(`No inserter function available for default node type '${default_type}'`);
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import type Session from './Session.svelte.js';
|
|
2
|
-
import type
|
|
2
|
+
import type { VisibilityRegistryApi } from './node_visibility.svelte.js';
|
|
3
3
|
|
|
4
4
|
// ===== SVELTE TYPE IMPORTS =====
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
7
|
* Import Svelte's Snippet type for properly typing children in components
|
|
8
8
|
*/
|
|
9
|
-
import type {
|
|
9
|
+
import type { Snippet } from 'svelte';
|
|
10
10
|
|
|
11
11
|
// ===== SELECTION TYPE DEFINITIONS =====
|
|
12
12
|
|
|
@@ -19,6 +19,13 @@ import type { Component, Snippet } from 'svelte';
|
|
|
19
19
|
*/
|
|
20
20
|
export type NodeId = string;
|
|
21
21
|
|
|
22
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
23
|
+
export type DynamicRecord = Record<string, any>;
|
|
24
|
+
export type SessionConfig = DynamicRecord;
|
|
25
|
+
export type CommandRegistry = DynamicRecord;
|
|
26
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
27
|
+
export type DocumentOperation = [string, ...any[]];
|
|
28
|
+
|
|
22
29
|
/**
|
|
23
30
|
* Array of IDs, property names (strings), or indexes (integers) that identify a node or property in the document.
|
|
24
31
|
* String segments must follow the same path segment rules as NodeId.
|
|
@@ -98,54 +105,82 @@ export type PrimitiveType = ScalarType | ArrayType | RichType;
|
|
|
98
105
|
*/
|
|
99
106
|
export type PropertyType = PrimitiveType | ReferenceType;
|
|
100
107
|
|
|
101
|
-
//
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
108
|
+
// ===== SCHEMA-DERIVED NODE TYPES =====
|
|
109
|
+
|
|
110
|
+
/**
|
|
111
|
+
* Maps a schema property definition to the runtime value type it stores.
|
|
112
|
+
*/
|
|
113
|
+
export type PropertyValue<P extends PropertyDefinition> = P extends {
|
|
114
|
+
type: 'string';
|
|
115
|
+
values: readonly (infer Value extends string)[];
|
|
116
|
+
}
|
|
117
|
+
? Value
|
|
118
|
+
: P extends { type: 'string' }
|
|
119
|
+
? string
|
|
120
|
+
: P extends { type: 'number' }
|
|
121
|
+
? number
|
|
122
|
+
: P extends { type: 'integer' }
|
|
123
|
+
? number
|
|
124
|
+
: P extends { type: 'boolean' }
|
|
125
|
+
? boolean
|
|
126
|
+
: P extends { type: 'datetime' }
|
|
127
|
+
? string
|
|
128
|
+
: P extends { type: 'string_array' }
|
|
129
|
+
? string[]
|
|
130
|
+
: P extends { type: 'number_array' }
|
|
131
|
+
? number[]
|
|
132
|
+
: P extends { type: 'integer_array' }
|
|
133
|
+
? number[]
|
|
134
|
+
: P extends { type: 'boolean_array' }
|
|
135
|
+
? boolean[]
|
|
136
|
+
: P extends { type: 'text' }
|
|
137
|
+
? Text
|
|
138
|
+
: P extends { type: 'node' }
|
|
139
|
+
? NodeId
|
|
140
|
+
: P extends { type: 'node_array' }
|
|
141
|
+
? NodeArray
|
|
142
|
+
: never;
|
|
143
|
+
|
|
144
|
+
/**
|
|
145
|
+
* The runtime shape of a node of a specific type, derived from the schema.
|
|
146
|
+
*
|
|
147
|
+
* Falls back to the untyped DocumentNode when the schema is not a concrete
|
|
148
|
+
* schema literal (e.g. the DocumentSchema default of Session).
|
|
149
|
+
*/
|
|
150
|
+
export type NodeOfType<S extends DocumentSchema, T extends keyof S> = string extends keyof S
|
|
151
|
+
? DocumentNode
|
|
152
|
+
: {
|
|
153
|
+
id: NodeId;
|
|
154
|
+
type: T;
|
|
155
|
+
} & {
|
|
156
|
+
[K in keyof S[T]['properties']]: PropertyValue<S[T]['properties'][K]>;
|
|
157
|
+
};
|
|
158
|
+
|
|
159
|
+
/**
|
|
160
|
+
* Discriminated union of all node types in a schema. Narrow with
|
|
161
|
+
* `node.type === '...'` to get exact property types.
|
|
162
|
+
*
|
|
163
|
+
* Falls back to the untyped DocumentNode when the schema is not a concrete
|
|
164
|
+
* schema literal (e.g. the DocumentSchema default of Session).
|
|
165
|
+
*/
|
|
166
|
+
export type AnyNode<S extends DocumentSchema> = string extends keyof S
|
|
167
|
+
? DocumentNode
|
|
168
|
+
: {
|
|
169
|
+
[T in keyof S]: NodeOfType<S, T>;
|
|
170
|
+
}[keyof S];
|
|
148
171
|
|
|
172
|
+
/**
|
|
173
|
+
* Convenience map from node type name to its runtime node shape,
|
|
174
|
+
* e.g. `NodeMap<typeof document_schema>['story']`.
|
|
175
|
+
*/
|
|
176
|
+
export type NodeMap<S extends DocumentSchema> = {
|
|
177
|
+
[T in keyof S]: NodeOfType<S, T>;
|
|
178
|
+
};
|
|
179
|
+
|
|
180
|
+
/**
|
|
181
|
+
* Assert that a node is of the given type. Narrows the static type and
|
|
182
|
+
* checks at runtime — for call sites that know what they expect.
|
|
183
|
+
*/
|
|
149
184
|
/**
|
|
150
185
|
* A property that stores text with optional marks and annotations and required allow_newlines setting.
|
|
151
186
|
*/
|
|
@@ -162,6 +197,7 @@ export type TextProperty = {
|
|
|
162
197
|
export type StringProperty = {
|
|
163
198
|
type: 'string';
|
|
164
199
|
default?: string;
|
|
200
|
+
values?: readonly string[];
|
|
165
201
|
};
|
|
166
202
|
|
|
167
203
|
/**
|
|
@@ -186,6 +222,8 @@ export type BooleanProperty = {
|
|
|
186
222
|
export type IntegerProperty = {
|
|
187
223
|
type: 'integer';
|
|
188
224
|
default?: number;
|
|
225
|
+
min?: number;
|
|
226
|
+
max?: number;
|
|
189
227
|
};
|
|
190
228
|
|
|
191
229
|
/**
|
|
@@ -346,6 +384,13 @@ export type DocumentSchema = Record<string, NodeSchema>;
|
|
|
346
384
|
export type DocumentNode = {
|
|
347
385
|
id: string;
|
|
348
386
|
type: string;
|
|
387
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
388
|
+
[key: string]: any;
|
|
389
|
+
};
|
|
390
|
+
|
|
391
|
+
export type Inspection = {
|
|
392
|
+
kind: 'property' | 'node';
|
|
393
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
349
394
|
[key: string]: any;
|
|
350
395
|
};
|
|
351
396
|
|
|
@@ -360,6 +405,13 @@ export type Document = {
|
|
|
360
405
|
};
|
|
361
406
|
};
|
|
362
407
|
|
|
408
|
+
/** Converts a document node to HTML, with access to recursive exporters. */
|
|
409
|
+
export type NodeHtmlExporter<S extends DocumentSchema = DocumentSchema> = (
|
|
410
|
+
node: DocumentNode,
|
|
411
|
+
session: Session<S>,
|
|
412
|
+
html_exporters: Record<string, NodeHtmlExporter<S>>
|
|
413
|
+
) => string;
|
|
414
|
+
|
|
363
415
|
/**
|
|
364
416
|
* Props for the TextProperty component
|
|
365
417
|
*/
|
|
@@ -373,7 +425,7 @@ export type TextPropertyProps = {
|
|
|
373
425
|
/** A placeholder to be rendered for empty content */
|
|
374
426
|
placeholder?: string;
|
|
375
427
|
/** Rest props to spread onto the rendered element (e.g. href, target, etc.) */
|
|
376
|
-
[key: string]:
|
|
428
|
+
[key: string]: unknown;
|
|
377
429
|
};
|
|
378
430
|
|
|
379
431
|
/**
|
|
@@ -389,7 +441,7 @@ export type CustomPropertyProps = {
|
|
|
389
441
|
/** The content of the custom property (e.g. an image) */
|
|
390
442
|
children: Snippet;
|
|
391
443
|
/** Rest props to spread onto the rendered element */
|
|
392
|
-
[key: string]:
|
|
444
|
+
[key: string]: unknown;
|
|
393
445
|
};
|
|
394
446
|
|
|
395
447
|
/**
|
|
@@ -403,7 +455,7 @@ export type NodeArrayPropertyProps = {
|
|
|
403
455
|
/** The `class` attribute on the container element */
|
|
404
456
|
class?: string;
|
|
405
457
|
/** Rest props to spread onto the rendered element (e.g. href, target, etc.) */
|
|
406
|
-
[key: string]:
|
|
458
|
+
[key: string]: unknown;
|
|
407
459
|
};
|
|
408
460
|
|
|
409
461
|
/**
|
|
@@ -423,15 +475,15 @@ export type NodeProps = {
|
|
|
423
475
|
/** The type-specific content of the node */
|
|
424
476
|
children: Snippet;
|
|
425
477
|
/** Rest props to spread onto the rendered element (e.g. href, target, etc.) */
|
|
426
|
-
[key: string]:
|
|
478
|
+
[key: string]: unknown;
|
|
427
479
|
};
|
|
428
480
|
|
|
429
481
|
/**
|
|
430
482
|
* Props for the Svedit component
|
|
431
483
|
*/
|
|
432
|
-
export type SveditProps = {
|
|
433
|
-
/** The session instance */
|
|
434
|
-
session: Session
|
|
484
|
+
export type SveditProps<S extends DocumentSchema = DocumentSchema> = {
|
|
485
|
+
/** The schema-typed session instance */
|
|
486
|
+
session: Session<S>;
|
|
435
487
|
/** Determines wether the document should be editable or read-only. */
|
|
436
488
|
editable?: boolean;
|
|
437
489
|
/** The path to the root element (e.g. ['page_1']) */
|
|
@@ -444,6 +496,24 @@ export type SveditProps = {
|
|
|
444
496
|
spellcheck?: 'true' | 'false';
|
|
445
497
|
};
|
|
446
498
|
|
|
499
|
+
/**
|
|
500
|
+
* Context provided by the Svedit component to commands and descendant components.
|
|
501
|
+
*/
|
|
502
|
+
export type SveditContext<S extends DocumentSchema = DocumentSchema> = {
|
|
503
|
+
session: Session<S>;
|
|
504
|
+
editable: boolean;
|
|
505
|
+
is_composing: boolean;
|
|
506
|
+
canvas_el: HTMLElement | undefined;
|
|
507
|
+
canvas_focused: boolean;
|
|
508
|
+
focus_canvas: () => void;
|
|
509
|
+
visibility_registry?: VisibilityRegistryApi;
|
|
510
|
+
};
|
|
511
|
+
|
|
512
|
+
/** Internal descendant context after Svedit's visibility registry is installed. */
|
|
513
|
+
export type SveditRenderContext<S extends DocumentSchema = DocumentSchema> = SveditContext<S> & {
|
|
514
|
+
visibility_registry: VisibilityRegistryApi;
|
|
515
|
+
};
|
|
516
|
+
|
|
447
517
|
/**
|
|
448
518
|
* A range with an attached payload node, used for both marks and annotations.
|
|
449
519
|
*/
|
|
@@ -468,23 +538,23 @@ export type Annotation = Attachment;
|
|
|
468
538
|
/**
|
|
469
539
|
* Represents text content with marks and annotations.
|
|
470
540
|
*/
|
|
471
|
-
export type
|
|
541
|
+
export type Text = {
|
|
472
542
|
content: string;
|
|
473
543
|
marks: Array<Mark>;
|
|
474
544
|
annotations: Array<Annotation>;
|
|
475
545
|
};
|
|
476
546
|
|
|
477
547
|
/**
|
|
478
|
-
* Represents
|
|
548
|
+
* Represents a node array with nodes, marks and annotations.
|
|
479
549
|
*/
|
|
480
|
-
export type
|
|
550
|
+
export type NodeArray = {
|
|
481
551
|
nodes: Array<NodeId>;
|
|
482
552
|
marks: Array<Mark>;
|
|
483
553
|
annotations: Array<Annotation>;
|
|
484
554
|
};
|
|
485
555
|
|
|
486
556
|
/**
|
|
487
|
-
* Attachment context passed to a node rendered inside
|
|
557
|
+
* Attachment context passed to a node rendered inside a node array.
|
|
488
558
|
* It is the flattened mark or annotation attachment, enriched with the resolved
|
|
489
559
|
* payload node, its index in the parent attachment array, and this child node's
|
|
490
560
|
* position in the attachment range.
|
|
@@ -500,8 +570,15 @@ export type NodeArrayAttachmentContext = {
|
|
|
500
570
|
is_end: boolean;
|
|
501
571
|
};
|
|
502
572
|
|
|
573
|
+
/** Internal context shared by a node array and its rendered child nodes. */
|
|
574
|
+
export type NodeArrayRenderContext = {
|
|
575
|
+
length: number;
|
|
576
|
+
mark_for: (node_index: number) => NodeArrayAttachmentContext | null;
|
|
577
|
+
annotations_for: (node_index: number) => NodeArrayAttachmentContext[];
|
|
578
|
+
};
|
|
579
|
+
|
|
503
580
|
/**
|
|
504
|
-
* Represents a selection highlight fragment for
|
|
581
|
+
* Represents a selection highlight fragment for unmarked text selections
|
|
505
582
|
*/
|
|
506
583
|
export type SelectionHighlightFragment = {
|
|
507
584
|
type: 'selection_highlight';
|
|
@@ -509,12 +586,12 @@ export type SelectionHighlightFragment = {
|
|
|
509
586
|
};
|
|
510
587
|
|
|
511
588
|
/**
|
|
512
|
-
* Represents a mark fragment in
|
|
589
|
+
* Represents a mark fragment in text content
|
|
513
590
|
*/
|
|
514
591
|
export type MarkFragment = {
|
|
515
592
|
type: 'mark';
|
|
516
593
|
/** NodeId that has mark type and details */
|
|
517
|
-
node:
|
|
594
|
+
node: DocumentNode;
|
|
518
595
|
/** The text content of the mark */
|
|
519
596
|
content: string;
|
|
520
597
|
/** Index of the mark in the original array */
|
|
@@ -522,7 +599,7 @@ export type MarkFragment = {
|
|
|
522
599
|
};
|
|
523
600
|
|
|
524
601
|
/**
|
|
525
|
-
* Represents a fragment of
|
|
602
|
+
* Represents a fragment of text content
|
|
526
603
|
*/
|
|
527
604
|
export type Fragment = string | MarkFragment | SelectionHighlightFragment;
|
|
528
605
|
|
|
@@ -541,7 +618,7 @@ export type NodeArrayPlainFragment = {
|
|
|
541
618
|
export type NodeArrayMarkFragment = {
|
|
542
619
|
type: 'mark';
|
|
543
620
|
/** NodeId that has mark type and details */
|
|
544
|
-
node:
|
|
621
|
+
node: DocumentNode;
|
|
545
622
|
/** The nodes wrapped by the mark */
|
|
546
623
|
nodes: Array<NodeId>;
|
|
547
624
|
/** Start index in the original nodes array */
|
|
@@ -551,6 +628,6 @@ export type NodeArrayMarkFragment = {
|
|
|
551
628
|
};
|
|
552
629
|
|
|
553
630
|
/**
|
|
554
|
-
* Represents a fragment of
|
|
631
|
+
* Represents a fragment of node array content
|
|
555
632
|
*/
|
|
556
633
|
export type NodeArrayFragment = NodeArrayPlainFragment | NodeArrayMarkFragment;
|