svedit 0.15.0 → 0.15.1
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 -0
- package/dist/Transaction.svelte.d.ts.map +1 -1
- package/dist/Transaction.svelte.js +8 -1
- package/dist/transforms.svelte.d.ts.map +1 -1
- package/dist/transforms.svelte.js +12 -0
- package/package.json +1 -1
- package/src/lib/Transaction.svelte.ts +8 -1
- package/src/lib/transforms.svelte.ts +14 -0
package/README.md
CHANGED
|
@@ -75,6 +75,8 @@ Each node has a `kind` that determines its behavior:
|
|
|
75
75
|
- Pressing Enter splits the node into two nodes of the same type
|
|
76
76
|
- Pressing Backspace at position 0 joins it with the previous node
|
|
77
77
|
|
|
78
|
+
When `break_text_node` splits through a mark or annotation, the right-hand occurrence receives an independent attachment node with the same properties. Editing one link or annotation therefore does not change the other. Ranges moved wholly to one side retain their ids. Subtree copying and pasting through `Transaction.build` also detach repeated attachment references in the copied data. These operations do not rewrite attachment references in existing stored documents.
|
|
79
|
+
|
|
78
80
|
If **any** of those assumptions don't hold, use `kind: 'block'`. Blocks can still have `text` properties with full editing support (typing, formatting, selection) — they just don't participate in split/join.
|
|
79
81
|
|
|
80
82
|
> **Common mistake:** A quote node with `content` + `author` properties might seem like `kind: 'text'` because both fields are editable text. But splitting a quote into two half-quotes doesn't make sense, and `join_text_node` hard-codes `node.content` — so Backspace in the `author` field would join the wrong property with the previous block and drop the author text. The correct kind is `'block'`.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Transaction.svelte.d.ts","sourceRoot":"","sources":["../src/lib/Transaction.svelte.ts"],"names":[],"mappings":"AA8BA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AACzD,OAAO,KAAK,EACX,MAAM,EACN,QAAQ,EACR,SAAS,EACT,QAAQ,EACR,cAAc,EACd,YAAY,EACZ,YAAY,EAEZ,IAAI,EACJ,UAAU,EACV,iBAAiB,EACjB,aAAa,EACb,UAAU,EACV,aAAa,EACb,MAAM,YAAY,CAAC;AAepB;;;;;;;;;;;;;;GAcG;AACH,MAAM,CAAC,OAAO,OAAO,WAAW;IAC/B,MAAM,EAAE,cAAc,CAAC;IACvB,GAAG,EAAE,QAAQ,CAAC;IAId,SAAS,EAAE,SAAS,CAAC;IACrB,MAAM,EAAE,aAAa,CAAC;IACtB,GAAG,EAAE,iBAAiB,EAAE,CAAC;IACzB,WAAW,EAAE,iBAAiB,EAAE,CAAC;IACjC,gBAAgB,EAAE,SAAS,GAAG,IAAI,CAAC;IACnC,gBAAgB,EAAE,MAAM,EAAE,CAAC;IAC3B,iBAAiB,EAAE,MAAM,EAAE,CAAC;IAC5B,gBAAgB,EAAE,MAAM,EAAE,CAAC;IAC3B,kBAAkB,EAAE,OAAO,CAAC;IAE5B;;;;;;;OAOG;gBAEF,MAAM,EAAE,cAAc,EACtB,GAAG,EAAE,QAAQ,EACb,SAAS,EAAE,SAAS,GAAG,IAAI,EAC3B,MAAM,EAAE,aAAa;IAyBtB;;;;;OAKG;IAEH,GAAG,CAAC,IAAI,EAAE,YAAY,GAAG,MAAM,GAAG,GAAG;IAIrC;;OAEG;IACH,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM;IAIrD;;OAEG;IACH,IAAI,CAAC,IAAI,EAAE,YAAY,GAAG,QAAQ;IAIlC;;OAEG;IACH,OAAO,CAAC,IAAI,EAAE,YAAY,GAAG,UAAU;IAIvC;;OAEG;IACH,WAAW,IAAI,MAAM;IAUrB;;;;OAIG;IACH,aAAa,CAAC,IAAI,EAAE,YAAY,GAAG,IAAI;IAIvC;;OAEG;IACH,oBAAoB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,EAAE;IAI/C;;OAEG;IACH,IAAI,oBAAoB,IAAI,MAAM,EAAE,CAInC;IAED;;OAEG;IACH,IAAI,0BAA0B,IAAI,MAAM,EAAE,CAIzC;IAED;;OAEG;IACH,IAAI,cAAc,IAAI,kBAAkB,EAAE,CAEzC;IAED,IAAI,WAAW,IAAI,kBAAkB,GAAG,IAAI,CAE3C;IAED;;OAEG;IACH,IAAI,oBAAoB,IAAI,kBAAkB,EAAE,CAE/C;IAED,IAAI,iBAAiB,IAAI,kBAAkB,GAAG,IAAI,CAEjD;IAED;;OAEG;IACH,OAAO,CAAC,SAAS;IAIjB,OAAO,CAAC,cAAc;IAItB;;;;;;;;;;;;;;;OAeG;IAEH,GAAG,CAAC,IAAI,EAAE,YAAY,EAAE,KAAK,EAAE,GAAG,GAAG,IAAI;IA2DzC,KAAK,CACJ,OAAO,EAAE,MAAM,EACf,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,YAAY,CAAC,EACnC,EAAE,YAAoB,EAAE,GAAE;QAAE,YAAY,CAAC,EAAE,OAAO,CAAA;KAAO,GACvD,MAAM;
|
|
1
|
+
{"version":3,"file":"Transaction.svelte.d.ts","sourceRoot":"","sources":["../src/lib/Transaction.svelte.ts"],"names":[],"mappings":"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"}
|
|
@@ -240,6 +240,8 @@ export default class Transaction {
|
|
|
240
240
|
const keep_ids = preserve_ids && depth_first_nodes.every((node) => !this.doc.nodes[node.id]);
|
|
241
241
|
// This maps original ids to newly generated ids
|
|
242
242
|
const id_map = {};
|
|
243
|
+
// eslint-disable-next-line svelte/prefer-svelte-reactivity -- Transaction-local ownership lookup.
|
|
244
|
+
const used_attachment_ids = new Set();
|
|
243
245
|
for (const node of depth_first_nodes) {
|
|
244
246
|
const new_id = keep_ids ? node.id : this.generate_id();
|
|
245
247
|
id_map[node.id] = new_id;
|
|
@@ -250,7 +252,12 @@ export default class Transaction {
|
|
|
250
252
|
const prop_type = property_definition.type;
|
|
251
253
|
const value = new_node[property_name];
|
|
252
254
|
const remap_ranges = (ranges) => (ranges ?? []).map(({ start_offset, end_offset, node_id }) => {
|
|
253
|
-
|
|
255
|
+
// Clipboard subtrees may contain legacy shared attachments; detach each occurrence.
|
|
256
|
+
const next_id = used_attachment_ids.has(node_id)
|
|
257
|
+
? this.build(node_id, nodes)
|
|
258
|
+
: id_map[node_id] || node_id;
|
|
259
|
+
used_attachment_ids.add(node_id);
|
|
260
|
+
return { start_offset, end_offset, node_id: next_id };
|
|
254
261
|
});
|
|
255
262
|
if (prop_type === 'node_array' && value && typeof value === 'object') {
|
|
256
263
|
new_node[property_name] = {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"transforms.svelte.d.ts","sourceRoot":"","sources":["../src/lib/transforms.svelte.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,WAAW,MAAM,yBAAyB,CAAC;AACvD,OAAO,KAAK,EAEX,YAAY,EAKZ,MAAM,YAAY,CAAC;AAEpB;;;;;;GAMG;AACH,wBAAgB,cAAc,CAC7B,EAAE,EAAE,WAAW,EACf,IAAI,EAAE,YAAY,EAClB,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GACjC,IAAI,CAIN;AAED,wBAAgB,eAAe,CAAC,EAAE,EAAE,WAAW,GAAG,OAAO,
|
|
1
|
+
{"version":3,"file":"transforms.svelte.d.ts","sourceRoot":"","sources":["../src/lib/transforms.svelte.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,WAAW,MAAM,yBAAyB,CAAC;AACvD,OAAO,KAAK,EAEX,YAAY,EAKZ,MAAM,YAAY,CAAC;AAEpB;;;;;;GAMG;AACH,wBAAgB,cAAc,CAC7B,EAAE,EAAE,WAAW,EACf,IAAI,EAAE,YAAY,EAClB,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GACjC,IAAI,CAIN;AAED,wBAAgB,eAAe,CAAC,EAAE,EAAE,WAAW,GAAG,OAAO,CAqExD;AAED,wBAAgB,cAAc,CAAC,EAAE,EAAE,WAAW,GAAG,OAAO,CAoEvD;AAED,wBAAgB,mBAAmB,CAAC,EAAE,EAAE,WAAW,GAAG,OAAO,CAyB5D"}
|
|
@@ -38,6 +38,18 @@ export function break_text_node(tr) {
|
|
|
38
38
|
const split_at_position = tr.selection.anchor_offset;
|
|
39
39
|
const content = tr.get(selection.path);
|
|
40
40
|
const [left_text, right_text] = split_text(content, split_at_position);
|
|
41
|
+
// Each attachment occurrence belongs to one range after the paragraph split.
|
|
42
|
+
// eslint-disable-next-line svelte/prefer-svelte-reactivity -- Transaction-local ownership lookup.
|
|
43
|
+
const used_attachment_ids = new Set([...left_text.marks, ...left_text.annotations].map((range) => range.node_id));
|
|
44
|
+
for (const range of [...right_text.marks, ...right_text.annotations]) {
|
|
45
|
+
const original_id = range.node_id;
|
|
46
|
+
if (used_attachment_ids.has(original_id)) {
|
|
47
|
+
range.node_id = tr.build(original_id, tr.doc.nodes);
|
|
48
|
+
}
|
|
49
|
+
else {
|
|
50
|
+
used_attachment_ids.add(original_id);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
41
53
|
tr.set([node.id, 'content'], left_text);
|
|
42
54
|
const node_insert_position = {
|
|
43
55
|
type: 'node',
|
package/package.json
CHANGED
|
@@ -324,6 +324,8 @@ export default class Transaction {
|
|
|
324
324
|
const keep_ids = preserve_ids && depth_first_nodes.every((node) => !this.doc.nodes[node.id]);
|
|
325
325
|
// This maps original ids to newly generated ids
|
|
326
326
|
const id_map: Record<string, string> = {};
|
|
327
|
+
// eslint-disable-next-line svelte/prefer-svelte-reactivity -- Transaction-local ownership lookup.
|
|
328
|
+
const used_attachment_ids = new Set<NodeId>();
|
|
327
329
|
|
|
328
330
|
for (const node of depth_first_nodes) {
|
|
329
331
|
const new_id = keep_ids ? node.id : this.generate_id();
|
|
@@ -338,7 +340,12 @@ export default class Transaction {
|
|
|
338
340
|
|
|
339
341
|
const remap_ranges = (ranges: Attachment[] | undefined) =>
|
|
340
342
|
(ranges ?? []).map(({ start_offset, end_offset, node_id }) => {
|
|
341
|
-
|
|
343
|
+
// Clipboard subtrees may contain legacy shared attachments; detach each occurrence.
|
|
344
|
+
const next_id = used_attachment_ids.has(node_id)
|
|
345
|
+
? this.build(node_id, nodes)
|
|
346
|
+
: id_map[node_id] || node_id;
|
|
347
|
+
used_attachment_ids.add(node_id);
|
|
348
|
+
return { start_offset, end_offset, node_id: next_id };
|
|
342
349
|
});
|
|
343
350
|
|
|
344
351
|
if (prop_type === 'node_array' && value && typeof value === 'object') {
|
|
@@ -55,6 +55,20 @@ export function break_text_node(tr: Transaction): boolean {
|
|
|
55
55
|
const content = tr.get(selection.path);
|
|
56
56
|
const [left_text, right_text] = split_text(content, split_at_position);
|
|
57
57
|
|
|
58
|
+
// Each attachment occurrence belongs to one range after the paragraph split.
|
|
59
|
+
// eslint-disable-next-line svelte/prefer-svelte-reactivity -- Transaction-local ownership lookup.
|
|
60
|
+
const used_attachment_ids = new Set(
|
|
61
|
+
[...left_text.marks, ...left_text.annotations].map((range) => range.node_id)
|
|
62
|
+
);
|
|
63
|
+
for (const range of [...right_text.marks, ...right_text.annotations]) {
|
|
64
|
+
const original_id = range.node_id;
|
|
65
|
+
if (used_attachment_ids.has(original_id)) {
|
|
66
|
+
range.node_id = tr.build(original_id, tr.doc.nodes);
|
|
67
|
+
} else {
|
|
68
|
+
used_attachment_ids.add(original_id);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
58
72
|
tr.set([node.id, 'content'], left_text);
|
|
59
73
|
|
|
60
74
|
const node_insert_position: Selection = {
|