svedit 0.8.0 → 0.9.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 +24 -0
- package/dist/Svedit.svelte +26 -4
- package/dist/Svedit.svelte.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/lib/Svedit.svelte +26 -4
package/README.md
CHANGED
|
@@ -259,6 +259,16 @@ const doc = {
|
|
|
259
259
|
|
|
260
260
|
Documents need a config object that tells Svedit how to render and manipulate your content. See the full example in [`src/routes/create_demo_session.js`](src/routes/create_demo_session.js).
|
|
261
261
|
|
|
262
|
+
Two optional hooks are especially useful when integrating custom media workflows:
|
|
263
|
+
|
|
264
|
+
- `handle_media_paste(session, pasted_media)`
|
|
265
|
+
Called when media is pasted. You can upload/process files, replace an existing media property, or return a node payload to insert new content.
|
|
266
|
+
See example implementation in [`src/routes/create_demo_session.js`](src/routes/create_demo_session.js).
|
|
267
|
+
|
|
268
|
+
- `handle_property_deletion(session, path)`
|
|
269
|
+
Called when deleting/cutting a property selection. Use it to define app-specific reset behavior (for example clearing an image property or resetting a referenced media node).
|
|
270
|
+
See example implementation in [`src/routes/create_demo_session.js`](src/routes/create_demo_session.js).
|
|
271
|
+
|
|
262
272
|
```js
|
|
263
273
|
const session_config = {
|
|
264
274
|
// ID generator for creating new nodes
|
|
@@ -345,6 +355,20 @@ tr.insert_nodes(['new_node_id']);
|
|
|
345
355
|
session.apply(tr); // Apply the transaction
|
|
346
356
|
```
|
|
347
357
|
|
|
358
|
+
#### Batching history entries
|
|
359
|
+
|
|
360
|
+
By default, every `session.apply(tr)` creates a new undo/redo entry. Pass `{ batch: true }` to merge the transaction into the previous history entry instead — useful for continuous interactions like dragging, where you want the entire gesture to undo as one step.
|
|
361
|
+
|
|
362
|
+
```js
|
|
363
|
+
session.apply(tr, { batch: true });
|
|
364
|
+
```
|
|
365
|
+
|
|
366
|
+
Batched transactions merge into the current history entry as long as they arrive within a 2-second window of the batch start. After 2 seconds of inactivity, the next `apply` starts a fresh entry. To force a new entry immediately (e.g. on pointer up), reset the batch timer:
|
|
367
|
+
|
|
368
|
+
```js
|
|
369
|
+
session.last_batch_started = undefined;
|
|
370
|
+
```
|
|
371
|
+
|
|
348
372
|
### History
|
|
349
373
|
|
|
350
374
|
```js
|
package/dist/Svedit.svelte
CHANGED
|
@@ -145,14 +145,14 @@
|
|
|
145
145
|
if (
|
|
146
146
|
['deleteContentBackward', 'deleteWordBackward', 'deleteContent'].includes(event.inputType)
|
|
147
147
|
) {
|
|
148
|
-
|
|
148
|
+
delete_at_selection('backward');
|
|
149
149
|
event.preventDefault();
|
|
150
150
|
event.stopPropagation();
|
|
151
151
|
return;
|
|
152
152
|
}
|
|
153
153
|
|
|
154
154
|
if (['deleteContentForward', 'deleteWordForward'].includes(event.inputType)) {
|
|
155
|
-
|
|
155
|
+
delete_at_selection('forward');
|
|
156
156
|
event.preventDefault();
|
|
157
157
|
event.stopPropagation();
|
|
158
158
|
return;
|
|
@@ -494,7 +494,24 @@ ${fallback_html}`;
|
|
|
494
494
|
}
|
|
495
495
|
|
|
496
496
|
if (delete_selection) {
|
|
497
|
-
|
|
497
|
+
delete_at_selection();
|
|
498
|
+
}
|
|
499
|
+
}
|
|
500
|
+
|
|
501
|
+
/**
|
|
502
|
+
* Shared delete logic for cut, backspace, and forward-delete.
|
|
503
|
+
* For property selections, delegates to the config's handle_property_deletion hook.
|
|
504
|
+
* For text/node selections, uses the standard transaction delete_selection.
|
|
505
|
+
*
|
|
506
|
+
* @param {'backward' | 'forward'} [direction]
|
|
507
|
+
*/
|
|
508
|
+
function delete_at_selection(direction = 'backward') {
|
|
509
|
+
if (session.selection?.type === 'property') {
|
|
510
|
+
if (session.config.handle_property_deletion) {
|
|
511
|
+
session.config.handle_property_deletion(session, session.selection.path);
|
|
512
|
+
}
|
|
513
|
+
} else {
|
|
514
|
+
session.apply(session.tr.delete_selection(direction));
|
|
498
515
|
}
|
|
499
516
|
}
|
|
500
517
|
|
|
@@ -871,6 +888,11 @@ ${fallback_html}`;
|
|
|
871
888
|
// (e.g. selecting between nav and page body). The resulting path would be empty.
|
|
872
889
|
if (anchor_root_path.length <= 1) return null;
|
|
873
890
|
|
|
891
|
+
const parent_array_path = anchor_root_path.slice(0, -1);
|
|
892
|
+
// A node selection is only valid inside a node_array property.
|
|
893
|
+
const parent_property = session.inspect(parent_array_path);
|
|
894
|
+
if (!parent_property || parent_property.type !== 'node_array') return null;
|
|
895
|
+
|
|
874
896
|
let anchor_offset = parseInt(anchor_root_path.at(-1));
|
|
875
897
|
let focus_offset = parseInt(focus_root_path.at(-1));
|
|
876
898
|
|
|
@@ -910,7 +932,7 @@ ${fallback_html}`;
|
|
|
910
932
|
|
|
911
933
|
return {
|
|
912
934
|
type: 'node',
|
|
913
|
-
path:
|
|
935
|
+
path: parent_array_path,
|
|
914
936
|
anchor_offset: anchor_offset,
|
|
915
937
|
focus_offset: focus_offset
|
|
916
938
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Svedit.svelte.d.ts","sourceRoot":"","sources":["../src/lib/Svedit.svelte.js"],"names":[],"mappings":";;;;;;;
|
|
1
|
+
{"version":3,"file":"Svedit.svelte.d.ts","sourceRoot":"","sources":["../src/lib/Svedit.svelte.js"],"names":[],"mappings":";;;;;;;AAm2CA;;eAAqD;iCAt0C1C,cAAc"}
|
package/package.json
CHANGED
package/src/lib/Svedit.svelte
CHANGED
|
@@ -145,14 +145,14 @@
|
|
|
145
145
|
if (
|
|
146
146
|
['deleteContentBackward', 'deleteWordBackward', 'deleteContent'].includes(event.inputType)
|
|
147
147
|
) {
|
|
148
|
-
|
|
148
|
+
delete_at_selection('backward');
|
|
149
149
|
event.preventDefault();
|
|
150
150
|
event.stopPropagation();
|
|
151
151
|
return;
|
|
152
152
|
}
|
|
153
153
|
|
|
154
154
|
if (['deleteContentForward', 'deleteWordForward'].includes(event.inputType)) {
|
|
155
|
-
|
|
155
|
+
delete_at_selection('forward');
|
|
156
156
|
event.preventDefault();
|
|
157
157
|
event.stopPropagation();
|
|
158
158
|
return;
|
|
@@ -494,7 +494,24 @@ ${fallback_html}`;
|
|
|
494
494
|
}
|
|
495
495
|
|
|
496
496
|
if (delete_selection) {
|
|
497
|
-
|
|
497
|
+
delete_at_selection();
|
|
498
|
+
}
|
|
499
|
+
}
|
|
500
|
+
|
|
501
|
+
/**
|
|
502
|
+
* Shared delete logic for cut, backspace, and forward-delete.
|
|
503
|
+
* For property selections, delegates to the config's handle_property_deletion hook.
|
|
504
|
+
* For text/node selections, uses the standard transaction delete_selection.
|
|
505
|
+
*
|
|
506
|
+
* @param {'backward' | 'forward'} [direction]
|
|
507
|
+
*/
|
|
508
|
+
function delete_at_selection(direction = 'backward') {
|
|
509
|
+
if (session.selection?.type === 'property') {
|
|
510
|
+
if (session.config.handle_property_deletion) {
|
|
511
|
+
session.config.handle_property_deletion(session, session.selection.path);
|
|
512
|
+
}
|
|
513
|
+
} else {
|
|
514
|
+
session.apply(session.tr.delete_selection(direction));
|
|
498
515
|
}
|
|
499
516
|
}
|
|
500
517
|
|
|
@@ -871,6 +888,11 @@ ${fallback_html}`;
|
|
|
871
888
|
// (e.g. selecting between nav and page body). The resulting path would be empty.
|
|
872
889
|
if (anchor_root_path.length <= 1) return null;
|
|
873
890
|
|
|
891
|
+
const parent_array_path = anchor_root_path.slice(0, -1);
|
|
892
|
+
// A node selection is only valid inside a node_array property.
|
|
893
|
+
const parent_property = session.inspect(parent_array_path);
|
|
894
|
+
if (!parent_property || parent_property.type !== 'node_array') return null;
|
|
895
|
+
|
|
874
896
|
let anchor_offset = parseInt(anchor_root_path.at(-1));
|
|
875
897
|
let focus_offset = parseInt(focus_root_path.at(-1));
|
|
876
898
|
|
|
@@ -910,7 +932,7 @@ ${fallback_html}`;
|
|
|
910
932
|
|
|
911
933
|
return {
|
|
912
934
|
type: 'node',
|
|
913
|
-
path:
|
|
935
|
+
path: parent_array_path,
|
|
914
936
|
anchor_offset: anchor_offset,
|
|
915
937
|
focus_offset: focus_offset
|
|
916
938
|
};
|