@aionbuilders/nabu 0.1.0-alpha.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 +131 -0
- package/dist/behaviors/index.d.ts +1 -0
- package/dist/behaviors/index.js +1 -0
- package/dist/behaviors/text/RichText.svelte +33 -0
- package/dist/behaviors/text/RichText.svelte.d.ts +11 -0
- package/dist/behaviors/text/index.d.ts +3 -0
- package/dist/behaviors/text/index.js +3 -0
- package/dist/behaviors/text/rich-text.extension.d.ts +2 -0
- package/dist/behaviors/text/rich-text.extension.js +75 -0
- package/dist/behaviors/text/text.behavior.svelte.d.ts +103 -0
- package/dist/behaviors/text/text.behavior.svelte.js +346 -0
- package/dist/blocks/Block.svelte +18 -0
- package/dist/blocks/Block.svelte.d.ts +11 -0
- package/dist/blocks/Nabu.svelte +31 -0
- package/dist/blocks/Nabu.svelte.d.ts +12 -0
- package/dist/blocks/block.svelte.d.ts +143 -0
- package/dist/blocks/block.svelte.js +364 -0
- package/dist/blocks/container.utils.d.ts +28 -0
- package/dist/blocks/container.utils.js +114 -0
- package/dist/blocks/heading/Heading.svelte +42 -0
- package/dist/blocks/heading/Heading.svelte.d.ts +11 -0
- package/dist/blocks/heading/heading.svelte.d.ts +45 -0
- package/dist/blocks/heading/heading.svelte.js +94 -0
- package/dist/blocks/heading/hooks/onBeforeInput.hook.d.ts +3 -0
- package/dist/blocks/heading/hooks/onBeforeInput.hook.js +58 -0
- package/dist/blocks/heading/index.d.ts +7 -0
- package/dist/blocks/heading/index.js +41 -0
- package/dist/blocks/index.d.ts +10 -0
- package/dist/blocks/index.js +12 -0
- package/dist/blocks/list/List.svelte +25 -0
- package/dist/blocks/list/List.svelte.d.ts +11 -0
- package/dist/blocks/list/ListItem.svelte +45 -0
- package/dist/blocks/list/ListItem.svelte.d.ts +11 -0
- package/dist/blocks/list/index.d.ts +10 -0
- package/dist/blocks/list/index.js +41 -0
- package/dist/blocks/list/list-item.svelte.d.ts +50 -0
- package/dist/blocks/list/list-item.svelte.js +213 -0
- package/dist/blocks/list/list.behavior.svelte.d.ts +23 -0
- package/dist/blocks/list/list.behavior.svelte.js +61 -0
- package/dist/blocks/list/list.svelte.d.ts +39 -0
- package/dist/blocks/list/list.svelte.js +139 -0
- package/dist/blocks/megablock.svelte.d.ts +13 -0
- package/dist/blocks/megablock.svelte.js +64 -0
- package/dist/blocks/nabu.svelte.d.ts +121 -0
- package/dist/blocks/nabu.svelte.js +395 -0
- package/dist/blocks/paragraph/Paragraph.svelte +38 -0
- package/dist/blocks/paragraph/Paragraph.svelte.d.ts +11 -0
- package/dist/blocks/paragraph/index.d.ts +7 -0
- package/dist/blocks/paragraph/index.js +44 -0
- package/dist/blocks/paragraph/paragraph.svelte.d.ts +41 -0
- package/dist/blocks/paragraph/paragraph.svelte.js +86 -0
- package/dist/blocks/selection.svelte.d.ts +38 -0
- package/dist/blocks/selection.svelte.js +143 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.js +5 -0
- package/dist/utils/extensions.d.ts +69 -0
- package/dist/utils/extensions.js +43 -0
- package/dist/utils/index.d.ts +2 -0
- package/dist/utils/index.js +2 -0
- package/dist/utils/selection.svelte.d.ts +219 -0
- package/dist/utils/selection.svelte.js +611 -0
- package/package.json +74 -0
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
|
|
2
|
+
import { SvelteSelection } from "../utils/selection.svelte";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* @import { Nabu } from "./nabu.svelte";
|
|
6
|
+
* @import { Block } from "./block.svelte";
|
|
7
|
+
* @import { LoroTree, LoroTreeNode } from "loro-crdt";
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
export class NabuSelection extends SvelteSelection {
|
|
11
|
+
/** @param {Nabu} nabu */
|
|
12
|
+
constructor(nabu) {
|
|
13
|
+
super();
|
|
14
|
+
this.nabu = nabu;
|
|
15
|
+
|
|
16
|
+
$effect(() => {
|
|
17
|
+
if (this.blocks) {
|
|
18
|
+
this.previous.forEach(block => block.clearSelection());
|
|
19
|
+
let i = 0;
|
|
20
|
+
const lastIndex = this.blocks.size - 1;
|
|
21
|
+
this.blocks.forEach((block) => {
|
|
22
|
+
block.selected = true;
|
|
23
|
+
block.isSelectionStart = (i === 0);
|
|
24
|
+
block.isSelectionEnd = i === lastIndex;
|
|
25
|
+
i++;
|
|
26
|
+
});
|
|
27
|
+
this.previous = new Set(this.blocks);
|
|
28
|
+
}
|
|
29
|
+
})
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
anchorBlock = $derived.by(() => {
|
|
33
|
+
this.anchorNode;
|
|
34
|
+
const id = this.anchorNode?.parentElement?.closest("[data-block-id]")?.getAttribute("data-block-id");
|
|
35
|
+
return id ? this.nabu.blocks.get(id) : null;
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
focusBlock = $derived.by(() => {
|
|
39
|
+
this.focusNode;
|
|
40
|
+
const id = this.focusNode?.parentElement?.closest("[data-block-id]")?.getAttribute("data-block-id");
|
|
41
|
+
return id ? this.nabu.blocks.get(id) : null;
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
startBlock = $derived.by(() => {
|
|
45
|
+
this.range;
|
|
46
|
+
const id = this.range?.startContainer?.parentElement?.closest("[data-block-id]")?.getAttribute("data-block-id");
|
|
47
|
+
return id ? this.nabu.blocks.get(id) : null;
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
endBlock = $derived.by(() => {
|
|
51
|
+
this.range;
|
|
52
|
+
const id = this.range?.endContainer?.parentElement?.closest("[data-block-id]")?.getAttribute("data-block-id");
|
|
53
|
+
return id ? this.nabu.blocks.get(id) : null;
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
start = $derived(this.startBlock?.selection && {
|
|
57
|
+
block: this.startBlock,
|
|
58
|
+
...this.startBlock.selection
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
end = $derived(this.endBlock?.selection && {
|
|
62
|
+
block: this.endBlock,
|
|
63
|
+
...this.endBlock.selection
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* Définit le curseur à un endroit précis du document (Modèle -> DOM)
|
|
68
|
+
* @param {Block} block
|
|
69
|
+
* @param {number} offset
|
|
70
|
+
*/
|
|
71
|
+
setCursor(block, offset) {
|
|
72
|
+
if (!block.element) return;
|
|
73
|
+
|
|
74
|
+
// On délègue au bloc le soin de trouver le bon point DOM
|
|
75
|
+
// (Chaque type de bloc sait comment il affiche son texte)
|
|
76
|
+
//@ts-ignore
|
|
77
|
+
const point = block.getDOMPoint?.(offset);
|
|
78
|
+
if (!point) return;
|
|
79
|
+
|
|
80
|
+
this.setBaseAndExtent(point.node, point.offset, point.node, point.offset);
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
/** @type {Set<Block>} */
|
|
84
|
+
previous = new Set();
|
|
85
|
+
blocks = $derived(new Set(getNodesBetween(this.nabu.tree, this.startBlock?.node.id.toString() || "", this.endBlock?.node.id.toString() || "").map(node => {
|
|
86
|
+
return this.nabu.blocks.get(node.id.toString());
|
|
87
|
+
}).filter(b => !!b)));
|
|
88
|
+
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* Récupère tous les nœuds situés entre deux nœuds dans un arbre Loro (version aplatie).
|
|
95
|
+
* L'ordre dans lequel on passe A et B n'a pas d'importance.
|
|
96
|
+
* @param {LoroTree} tree - L'arbre Loro à parcourir
|
|
97
|
+
* @param {string} nodeIdA - ID du premier nœud de la sélection
|
|
98
|
+
* @param {string} nodeIdB - ID du second nœud de la sélection
|
|
99
|
+
*/
|
|
100
|
+
function getNodesBetween(tree, nodeIdA, nodeIdB) {
|
|
101
|
+
const roots = tree.roots();
|
|
102
|
+
|
|
103
|
+
let isRecording = false;
|
|
104
|
+
/** @type {LoroTreeNode[]} */
|
|
105
|
+
const nodesInRange = [];
|
|
106
|
+
|
|
107
|
+
|
|
108
|
+
// if (nodeIdA && nodeIdA === nodeIdB) {
|
|
109
|
+
//
|
|
110
|
+
// }
|
|
111
|
+
|
|
112
|
+
/** @param {LoroTreeNode[]} nodes */
|
|
113
|
+
function traverse(nodes) {
|
|
114
|
+
for (const node of nodes) {
|
|
115
|
+
const currentId = node.id.toString();
|
|
116
|
+
|
|
117
|
+
if (currentId === nodeIdA) {
|
|
118
|
+
isRecording = true;
|
|
119
|
+
nodesInRange.push(node);
|
|
120
|
+
|
|
121
|
+
if (currentId === nodeIdB) {
|
|
122
|
+
return true;
|
|
123
|
+
}
|
|
124
|
+
} else if (isRecording) {
|
|
125
|
+
nodesInRange.push(node);
|
|
126
|
+
if (currentId === nodeIdB) {
|
|
127
|
+
return true;
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
const children = node.children();
|
|
132
|
+
if (children && children.length > 0) {
|
|
133
|
+
if (traverse(children)) {
|
|
134
|
+
return true;
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
return false; // La fin n'a pas été trouvée dans cette branche
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
traverse(roots);
|
|
142
|
+
return nodesInRange;
|
|
143
|
+
}
|
package/dist/index.d.ts
ADDED
package/dist/index.js
ADDED
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @import { Nabu, Block } from '../blocks'
|
|
3
|
+
*/
|
|
4
|
+
/**
|
|
5
|
+
* @typedef {{
|
|
6
|
+
* onInit: function(Nabu): void,
|
|
7
|
+
* onBlockCreate: function(Nabu, Block): void,
|
|
8
|
+
* onBlockDelete: function(Nabu, Block): void,
|
|
9
|
+
* onBlockUpdate: function(Nabu, Block): void,
|
|
10
|
+
* onBeforeTransaction: function(Nabu, Array<{type: string, block: Block}>): void,
|
|
11
|
+
* onAfterTransaction: function(Nabu, Array<{type: string, block: Block}>): void,
|
|
12
|
+
* onSplit: function(Nabu, Block, Event, {offset: number, delta: import('loro-crdt').Delta<string>}): {block: Block},
|
|
13
|
+
* onBeforeInput: function(Nabu, InputEvent, Block): void,
|
|
14
|
+
* onInput: function(Nabu, InputEvent, Block): void,
|
|
15
|
+
* } & Object<string, function>} ExtensionHooks
|
|
16
|
+
*/
|
|
17
|
+
/**
|
|
18
|
+
* @typedef {Object} ExtensionInit
|
|
19
|
+
* @property {string} [name]
|
|
20
|
+
* @property {import('svelte').Component} [component]
|
|
21
|
+
* @property {typeof Block} [block]
|
|
22
|
+
* @property {Partial<ExtensionHooks>} [hooks]
|
|
23
|
+
* @property {Record<string, (nabu: Nabu) => any>} [serializers]
|
|
24
|
+
*/
|
|
25
|
+
export class Extension {
|
|
26
|
+
/** @param {string} name @param {ExtensionInit} init */
|
|
27
|
+
constructor(name: string, init?: ExtensionInit);
|
|
28
|
+
name: string;
|
|
29
|
+
component: import("svelte").Component<any, any, string> | undefined;
|
|
30
|
+
block: typeof Block | undefined;
|
|
31
|
+
/** @type {Partial<ExtensionHooks>} */
|
|
32
|
+
hooks: Partial<ExtensionHooks>;
|
|
33
|
+
/** @type {Record<string, (nabu: Nabu) => any>} */
|
|
34
|
+
serializers: Record<string, (nabu: Nabu) => any>;
|
|
35
|
+
}
|
|
36
|
+
export function extension(name: string, init: ExtensionInit): Extension;
|
|
37
|
+
export type ExtensionHooks = {
|
|
38
|
+
onInit: (arg0: Nabu) => void;
|
|
39
|
+
onBlockCreate: (arg0: Nabu, arg1: Block) => void;
|
|
40
|
+
onBlockDelete: (arg0: Nabu, arg1: Block) => void;
|
|
41
|
+
onBlockUpdate: (arg0: Nabu, arg1: Block) => void;
|
|
42
|
+
onBeforeTransaction: (arg0: Nabu, arg1: Array<{
|
|
43
|
+
type: string;
|
|
44
|
+
block: Block;
|
|
45
|
+
}>) => void;
|
|
46
|
+
onAfterTransaction: (arg0: Nabu, arg1: Array<{
|
|
47
|
+
type: string;
|
|
48
|
+
block: Block;
|
|
49
|
+
}>) => void;
|
|
50
|
+
onSplit: (arg0: Nabu, arg1: Block, arg2: Event, arg3: {
|
|
51
|
+
offset: number;
|
|
52
|
+
delta: import("loro-crdt").Delta<string>;
|
|
53
|
+
}) => {
|
|
54
|
+
block: Block;
|
|
55
|
+
};
|
|
56
|
+
onBeforeInput: (arg0: Nabu, arg1: InputEvent, arg2: Block) => void;
|
|
57
|
+
onInput: (arg0: Nabu, arg1: InputEvent, arg2: Block) => void;
|
|
58
|
+
} & {
|
|
59
|
+
[x: string]: Function;
|
|
60
|
+
};
|
|
61
|
+
export type ExtensionInit = {
|
|
62
|
+
name?: string | undefined;
|
|
63
|
+
component?: import("svelte").Component<any, any, string> | undefined;
|
|
64
|
+
block?: typeof Block | undefined;
|
|
65
|
+
hooks?: Partial<ExtensionHooks> | undefined;
|
|
66
|
+
serializers?: Record<string, (nabu: Nabu) => any> | undefined;
|
|
67
|
+
};
|
|
68
|
+
import type { Block } from '../blocks';
|
|
69
|
+
import type { Nabu } from '../blocks';
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @import { Nabu, Block } from '../blocks'
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* @typedef {{
|
|
7
|
+
* onInit: function(Nabu): void,
|
|
8
|
+
* onBlockCreate: function(Nabu, Block): void,
|
|
9
|
+
* onBlockDelete: function(Nabu, Block): void,
|
|
10
|
+
* onBlockUpdate: function(Nabu, Block): void,
|
|
11
|
+
* onBeforeTransaction: function(Nabu, Array<{type: string, block: Block}>): void,
|
|
12
|
+
* onAfterTransaction: function(Nabu, Array<{type: string, block: Block}>): void,
|
|
13
|
+
* onSplit: function(Nabu, Block, Event, {offset: number, delta: import('loro-crdt').Delta<string>}): {block: Block},
|
|
14
|
+
* onBeforeInput: function(Nabu, InputEvent, Block): void,
|
|
15
|
+
* onInput: function(Nabu, InputEvent, Block): void,
|
|
16
|
+
* } & Object<string, function>} ExtensionHooks
|
|
17
|
+
*/
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* @typedef {Object} ExtensionInit
|
|
21
|
+
* @property {string} [name]
|
|
22
|
+
* @property {import('svelte').Component} [component]
|
|
23
|
+
* @property {typeof Block} [block]
|
|
24
|
+
* @property {Partial<ExtensionHooks>} [hooks]
|
|
25
|
+
* @property {Record<string, (nabu: Nabu) => any>} [serializers]
|
|
26
|
+
*/
|
|
27
|
+
|
|
28
|
+
export class Extension {
|
|
29
|
+
/** @param {string} name @param {ExtensionInit} init */
|
|
30
|
+
constructor(name, init = {}) {
|
|
31
|
+
this.name = name;
|
|
32
|
+
this.component = init.component;
|
|
33
|
+
this.block = init.block;
|
|
34
|
+
/** @type {Partial<ExtensionHooks>} */
|
|
35
|
+
this.hooks = init.hooks || {};
|
|
36
|
+
/** @type {Record<string, (nabu: Nabu) => any>} */
|
|
37
|
+
this.serializers = init.serializers || {};
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
/** @param {string} name @param {ExtensionInit} init */
|
|
43
|
+
export const extension = (name, init) => new Extension(name, init);
|
|
@@ -0,0 +1,219 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @typedef {{
|
|
3
|
+
* anchorNode: Node | null,
|
|
4
|
+
* anchorOffset: number,
|
|
5
|
+
* focusNode: Node | null,
|
|
6
|
+
* focusOffset: number,
|
|
7
|
+
* startNode: Node | null,
|
|
8
|
+
* startOffset: number,
|
|
9
|
+
* endNode: Node | null,
|
|
10
|
+
* endOffset: number,
|
|
11
|
+
* isCollapsed: boolean,
|
|
12
|
+
* rangeCount: number,
|
|
13
|
+
* type: string,
|
|
14
|
+
* direction: "forward" | "backward" | "none",
|
|
15
|
+
* text: string,
|
|
16
|
+
* html: string
|
|
17
|
+
* }} SelectionObject
|
|
18
|
+
*/
|
|
19
|
+
/**
|
|
20
|
+
* Utilitaire réactif pour gérer la sélection de texte avec Svelte 5 runes
|
|
21
|
+
* @example
|
|
22
|
+
* const selection = new SvelteSelection();
|
|
23
|
+
* // Utiliser selection.text, selection.isCollapsed, etc. dans vos composants
|
|
24
|
+
*/
|
|
25
|
+
export class SvelteSelection {
|
|
26
|
+
/** @type {Selection?} */
|
|
27
|
+
raw: Selection | null;
|
|
28
|
+
is: boolean;
|
|
29
|
+
anchorNode: Node | null;
|
|
30
|
+
anchorOffset: number;
|
|
31
|
+
focusNode: Node | null;
|
|
32
|
+
focusOffset: number;
|
|
33
|
+
isCollapsed: boolean;
|
|
34
|
+
rangeCount: number;
|
|
35
|
+
type: string;
|
|
36
|
+
direction: "forward" | "backward" | "none";
|
|
37
|
+
startNode: Node | null;
|
|
38
|
+
endNode: Node | null;
|
|
39
|
+
startOffset: number;
|
|
40
|
+
endOffset: number;
|
|
41
|
+
ranges: Range[];
|
|
42
|
+
firstRange: Range;
|
|
43
|
+
get range(): Range;
|
|
44
|
+
lastRange: Range;
|
|
45
|
+
text: string;
|
|
46
|
+
html: string;
|
|
47
|
+
hasSelection: boolean;
|
|
48
|
+
isEmpty: boolean;
|
|
49
|
+
hasMultipleRanges: boolean;
|
|
50
|
+
commonAncestor: Node | null;
|
|
51
|
+
allText: string;
|
|
52
|
+
allHtml: string;
|
|
53
|
+
boundingRects: DOMRect[];
|
|
54
|
+
refresh: () => void;
|
|
55
|
+
/**
|
|
56
|
+
* Ajoute une range à la sélection.
|
|
57
|
+
* @param {Range} range - La range à ajouter.
|
|
58
|
+
* @returns {boolean} True si l'opération a réussi
|
|
59
|
+
*/
|
|
60
|
+
addRange: (range: Range) => boolean;
|
|
61
|
+
/**
|
|
62
|
+
* Supprime toutes les ranges de la sélection.
|
|
63
|
+
* @returns {boolean} True si l'opération a réussi
|
|
64
|
+
*/
|
|
65
|
+
removeAllRanges: () => boolean;
|
|
66
|
+
/**
|
|
67
|
+
* Supprime une range spécifique de la sélection.
|
|
68
|
+
* @param {Range} range - La range à supprimer.
|
|
69
|
+
* @returns {boolean} True si l'opération a réussi
|
|
70
|
+
*/
|
|
71
|
+
removeRange: (range: Range) => boolean;
|
|
72
|
+
/**
|
|
73
|
+
* Récupère la range à l'index spécifié.
|
|
74
|
+
* @param {number} index - L'index de la range à récupérer.
|
|
75
|
+
* @returns {Range|null} La range à l'index spécifié, ou null si elle n'existe pas.
|
|
76
|
+
*/
|
|
77
|
+
getRangeAt: (index: number) => Range | null;
|
|
78
|
+
/**
|
|
79
|
+
* Réduit la sélection à un nœud et offset spécifiques.
|
|
80
|
+
* @param {Node} node - Le nœud vers lequel réduire la sélection.
|
|
81
|
+
* @param {number} offset - L'offset dans le nœud.
|
|
82
|
+
* @returns {boolean} True si l'opération a réussi
|
|
83
|
+
*/
|
|
84
|
+
collapse: (node: Node, offset?: number) => boolean;
|
|
85
|
+
/**
|
|
86
|
+
* Réduit la sélection au début de la range courante.
|
|
87
|
+
* @returns {boolean} True si l'opération a réussi
|
|
88
|
+
*/
|
|
89
|
+
collapseToStart: () => boolean;
|
|
90
|
+
/**
|
|
91
|
+
* Réduit la sélection à la fin de la range courante.
|
|
92
|
+
* @returns {boolean} True si l'opération a réussi
|
|
93
|
+
*/
|
|
94
|
+
collapseToEnd: () => boolean;
|
|
95
|
+
/**
|
|
96
|
+
* Sélectionne le contenu d'un nœud.
|
|
97
|
+
* @param {Node} node - Le nœud dont le contenu doit être sélectionné.
|
|
98
|
+
* @returns {boolean} True si l'opération a réussi
|
|
99
|
+
*/
|
|
100
|
+
selectAllChildren: (node: Node) => boolean;
|
|
101
|
+
/**
|
|
102
|
+
* Étend la sélection vers un nœud et offset spécifiques.
|
|
103
|
+
* @param {Node} node - Le nœud vers lequel étendre.
|
|
104
|
+
* @param {number} offset - L'offset dans le nœud.
|
|
105
|
+
* @returns {boolean} True si l'opération a réussi
|
|
106
|
+
*/
|
|
107
|
+
extend: (node: Node, offset?: number) => boolean;
|
|
108
|
+
/**
|
|
109
|
+
* Définit la base et l'extension de la sélection.
|
|
110
|
+
* @param {Node} anchorNode - Le nœud d'ancrage.
|
|
111
|
+
* @param {number} anchorOffset - L'offset d'ancrage.
|
|
112
|
+
* @param {Node} focusNode - Le nœud de focus.
|
|
113
|
+
* @param {number} focusOffset - L'offset de focus.
|
|
114
|
+
* @returns {boolean} True si l'opération a réussi
|
|
115
|
+
|
|
116
|
+
*/
|
|
117
|
+
setBaseAndExtent: (anchorNode: Node, anchorOffset: number, focusNode: Node, focusOffset: number) => boolean;
|
|
118
|
+
/**
|
|
119
|
+
* Vérifie si la sélection contient un nœud donné.
|
|
120
|
+
* @param {Node} node - Le nœud à vérifier.
|
|
121
|
+
* @param {boolean} allowPartialContainment - Permet la contenance partielle.
|
|
122
|
+
* @returns {boolean} True si le nœud est contenu dans la sélection.
|
|
123
|
+
*/
|
|
124
|
+
containsNode: (node: Node, allowPartialContainment?: boolean) => boolean;
|
|
125
|
+
/**
|
|
126
|
+
* Crée une nouvelle range basée sur la sélection courante.
|
|
127
|
+
* @returns {Range|null} Une nouvelle range ou null.
|
|
128
|
+
*/
|
|
129
|
+
createRange: () => Range | null;
|
|
130
|
+
/**
|
|
131
|
+
* Crée des copies de toutes les ranges courantes.
|
|
132
|
+
* @returns {Range[]} Un array de toutes les ranges clonées.
|
|
133
|
+
*/
|
|
134
|
+
createAllRanges: () => Range[];
|
|
135
|
+
/**
|
|
136
|
+
* Récupère les coordonnées de toutes les ranges.
|
|
137
|
+
* @returns {DOMRect[]} Un array des rectangles de toutes les ranges.
|
|
138
|
+
*/
|
|
139
|
+
getAllBoundingRects: () => DOMRect[];
|
|
140
|
+
/**
|
|
141
|
+
* Vérifie si toutes les ranges sont dans un élément donné.
|
|
142
|
+
* @param {Element} element - L'élément à vérifier.
|
|
143
|
+
* @returns {boolean} True si toutes les ranges sont contenues.
|
|
144
|
+
*/
|
|
145
|
+
allRangesInElement: (element: Element) => boolean;
|
|
146
|
+
/**
|
|
147
|
+
* Filtre les ranges selon un prédicat.
|
|
148
|
+
* @param {function(Range): boolean} predicate - Fonction de filtre.
|
|
149
|
+
* @returns {Range[]} Les ranges qui passent le filtre.
|
|
150
|
+
*/
|
|
151
|
+
filterRanges: (predicate: (arg0: Range) => boolean) => Range[];
|
|
152
|
+
/**
|
|
153
|
+
* Sélectionne tout le contenu du document.
|
|
154
|
+
* @returns {boolean} True si l'opération a réussi
|
|
155
|
+
*/
|
|
156
|
+
selectAll: () => boolean;
|
|
157
|
+
/**
|
|
158
|
+
* Efface la sélection courante.
|
|
159
|
+
* @returns {boolean} True si l'opération a réussi
|
|
160
|
+
*/
|
|
161
|
+
clear: () => boolean;
|
|
162
|
+
/**
|
|
163
|
+
* Observe un élément contenteditable pour les mutations DOM qui peuvent
|
|
164
|
+
* affecter la position du caret sans déclencher selectionchange
|
|
165
|
+
*
|
|
166
|
+
* @param {Element} element - L'élément contenteditable à observer
|
|
167
|
+
* @param {Object} options - Options d'observation
|
|
168
|
+
* @param {number} options.debounceMs - Délai de debounce en ms (défaut: 16ms = ~1 frame)
|
|
169
|
+
* @param {boolean} options.observeAttributes - Observer les changements d'attributs (défaut: false)
|
|
170
|
+
* @returns {boolean} True si l'observation a été configurée avec succès
|
|
171
|
+
*/
|
|
172
|
+
observe: (element: Element, options?: {
|
|
173
|
+
debounceMs: number;
|
|
174
|
+
observeAttributes: boolean;
|
|
175
|
+
}) => boolean;
|
|
176
|
+
/**
|
|
177
|
+
* Arrête l'observation d'un élément spécifique
|
|
178
|
+
* @param {Element} element - L'élément à ne plus observer
|
|
179
|
+
* @returns {boolean} True si l'élément était observé et a été retiré
|
|
180
|
+
*/
|
|
181
|
+
unobserve: (element: Element) => boolean;
|
|
182
|
+
/**
|
|
183
|
+
* Arrête l'observation de tous les éléments
|
|
184
|
+
*/
|
|
185
|
+
unobserveAll: () => void;
|
|
186
|
+
/**
|
|
187
|
+
* Getter pour savoir quels éléments sont observés
|
|
188
|
+
* @returns {Element[]} Liste des éléments actuellement observés
|
|
189
|
+
*/
|
|
190
|
+
get observedElements(): Element[];
|
|
191
|
+
/**
|
|
192
|
+
* Vérifie si un élément est actuellement observé
|
|
193
|
+
* @param {Element} element - L'élément à vérifier
|
|
194
|
+
* @returns {boolean} True si l'élément est observé
|
|
195
|
+
*/
|
|
196
|
+
isObserving: (element: Element) => boolean;
|
|
197
|
+
/**
|
|
198
|
+
* Nettoie les ressources utilisées par l'instance.
|
|
199
|
+
* À appeler lors de la destruction du composant.
|
|
200
|
+
*/
|
|
201
|
+
destroy: () => void;
|
|
202
|
+
#private;
|
|
203
|
+
}
|
|
204
|
+
export type SelectionObject = {
|
|
205
|
+
anchorNode: Node | null;
|
|
206
|
+
anchorOffset: number;
|
|
207
|
+
focusNode: Node | null;
|
|
208
|
+
focusOffset: number;
|
|
209
|
+
startNode: Node | null;
|
|
210
|
+
startOffset: number;
|
|
211
|
+
endNode: Node | null;
|
|
212
|
+
endOffset: number;
|
|
213
|
+
isCollapsed: boolean;
|
|
214
|
+
rangeCount: number;
|
|
215
|
+
type: string;
|
|
216
|
+
direction: "forward" | "backward" | "none";
|
|
217
|
+
text: string;
|
|
218
|
+
html: string;
|
|
219
|
+
};
|