@umbraci/jsmind 0.10.14 → 0.10.17
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/LICENSE +24 -24
- package/README.md +116 -116
- package/dist/jsmind.copy-paste.js +9 -0
- package/dist/jsmind.copy-paste.js.map +1 -0
- package/dist/jsmind.draggable-node.js +1 -1
- package/dist/jsmind.draggable-node.js.map +1 -1
- package/dist/jsmind.history.js +1 -1
- package/dist/jsmind.history.js.map +1 -1
- package/dist/jsmind.js +1 -1
- package/dist/jsmind.js.map +1 -1
- package/dist/jsmind.multi-select.js +1 -1
- package/dist/jsmind.multi-select.js.map +1 -1
- package/dist/jsmind.multiline-text.js +1 -1
- package/dist/jsmind.multiline-text.js.map +1 -1
- package/dist/jsmind.screenshot.js +1 -1
- package/dist/jsmind.screenshot.js.map +1 -1
- package/es/jsmind.copy-paste.js +9 -0
- package/es/jsmind.copy-paste.js.map +1 -0
- package/es/jsmind.draggable-node.js +1 -1
- package/es/jsmind.draggable-node.js.map +1 -1
- package/es/jsmind.history.js +1 -1
- package/es/jsmind.history.js.map +1 -1
- package/es/jsmind.js +1 -1
- package/es/jsmind.js.map +1 -1
- package/es/jsmind.multi-select.js +1 -1
- package/es/jsmind.multi-select.js.map +1 -1
- package/es/jsmind.multiline-text.js +1 -1
- package/es/jsmind.multiline-text.js.map +1 -1
- package/es/jsmind.screenshot.js +1 -1
- package/es/jsmind.screenshot.js.map +1 -1
- package/lib/jsmind.copy-paste.js +9 -0
- package/lib/jsmind.copy-paste.js.map +1 -0
- package/lib/jsmind.draggable-node.js +1 -1
- package/lib/jsmind.draggable-node.js.map +1 -1
- package/lib/jsmind.history.js +1 -1
- package/lib/jsmind.history.js.map +1 -1
- package/lib/jsmind.js +1 -1
- package/lib/jsmind.js.map +1 -1
- package/lib/jsmind.multi-select.js +1 -1
- package/lib/jsmind.multi-select.js.map +1 -1
- package/lib/jsmind.multiline-text.js +1 -1
- package/lib/jsmind.multiline-text.js.map +1 -1
- package/lib/jsmind.screenshot.js +1 -1
- package/lib/jsmind.screenshot.js.map +1 -1
- package/package.json +115 -115
- package/style/jsmind.css +408 -408
- package/types/generated/index.d.ts +8 -0
- package/types/generated/jsmind.common.d.ts +68 -0
- package/types/generated/jsmind.d.ts +438 -0
- package/types/generated/jsmind.data_provider.d.ts +56 -0
- package/types/generated/jsmind.dom.d.ts +59 -0
- package/types/generated/jsmind.enhanced-plugin.d.ts +103 -0
- package/types/generated/jsmind.format.d.ts +113 -0
- package/types/generated/jsmind.graph.d.ts +180 -0
- package/types/generated/jsmind.layout_provider.d.ts +182 -0
- package/types/generated/jsmind.mind.d.ts +121 -0
- package/types/generated/jsmind.node.d.ts +69 -0
- package/types/generated/jsmind.option.d.ts +73 -0
- package/types/generated/jsmind.plugin.d.ts +21 -0
- package/types/generated/jsmind.shortcut_provider.d.ts +52 -0
- package/types/generated/jsmind.util.d.ts +26 -0
- package/types/generated/jsmind.view_provider.d.ts +347 -0
- package/types/generated/plugins/history/history-diff.d.ts +297 -0
- package/types/generated/plugins/history/jsmind.history.d.ts +87 -0
- package/types/generated/plugins/jsmind.draggable-node.d.ts +262 -0
- package/types/generated/plugins/jsmind.multi-select.d.ts +238 -0
- package/types/generated/plugins/jsmind.multiline-text-v2.d.ts +58 -0
- package/types/generated/plugins/jsmind.multiline-text.d.ts +43 -0
- package/types/generated/plugins/jsmind.screenshot.d.ts +83 -0
- package/types/tsconfig.declaration.json +19 -19
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
export default HistoryPlugin;
|
|
2
|
+
export type JsMind = import("../../jsmind.js").default;
|
|
3
|
+
export type DiffResult = import("./history-diff.js").DiffResult;
|
|
4
|
+
export type DiffOptions = import("./history-diff.js").DiffOptions;
|
|
5
|
+
/**
|
|
6
|
+
* HistoryPlugin skeleton (Task 1)
|
|
7
|
+
*/
|
|
8
|
+
export class HistoryPlugin extends EnhancedPlugin {
|
|
9
|
+
/**
|
|
10
|
+
* @param {{ jm: JsMind, pluginOpt?: any }} params
|
|
11
|
+
*/
|
|
12
|
+
constructor({ jm, pluginOpt }: {
|
|
13
|
+
jm: JsMind;
|
|
14
|
+
pluginOpt?: any;
|
|
15
|
+
});
|
|
16
|
+
options: any;
|
|
17
|
+
_mounted: boolean;
|
|
18
|
+
_core: HistoryCore;
|
|
19
|
+
/**
|
|
20
|
+
* Lifecycle hook: called when jsMind instance is destroyed
|
|
21
|
+
*/
|
|
22
|
+
beforePluginDestroy(): void;
|
|
23
|
+
/** Default: call beforePluginRemove on destroy */
|
|
24
|
+
beforePluginDestroy(): void;
|
|
25
|
+
/** Initialize HistoryCore and wire API methods */
|
|
26
|
+
_initCore(): void;
|
|
27
|
+
_listener: (type: any, payload: any) => void;
|
|
28
|
+
/**
|
|
29
|
+
* Inject shortcut options so provider can register mapping in its init phase
|
|
30
|
+
* @param {{ enable?: boolean, handles: Record<string,Function>, mapping: Record<string, number|number[]> }} sc
|
|
31
|
+
* @param {boolean} redoUsesY
|
|
32
|
+
*/
|
|
33
|
+
_injectShortcuts(sc: {
|
|
34
|
+
enable?: boolean;
|
|
35
|
+
handles: Record<string, Function>;
|
|
36
|
+
mapping: Record<string, number | number[]>;
|
|
37
|
+
}, redoUsesY: boolean): void;
|
|
38
|
+
/** Mount public API on jm.history (placeholder defaults) */
|
|
39
|
+
_mountAPI(): void;
|
|
40
|
+
}
|
|
41
|
+
import { EnhancedPlugin } from '../../jsmind.enhanced-plugin.js';
|
|
42
|
+
declare class HistoryCore {
|
|
43
|
+
/** @param {JsMind} jm @param {any} options */
|
|
44
|
+
constructor(jm: JsMind, options: any);
|
|
45
|
+
jm: import("../../jsmind.js").default;
|
|
46
|
+
options: any;
|
|
47
|
+
enabled: boolean;
|
|
48
|
+
maxHistory: number;
|
|
49
|
+
throttleMs: number;
|
|
50
|
+
storageMode: any;
|
|
51
|
+
autoSwitchThreshold: number;
|
|
52
|
+
_history: any[];
|
|
53
|
+
_idx: number;
|
|
54
|
+
_paused: boolean;
|
|
55
|
+
_lastAddAt: number;
|
|
56
|
+
_timer: number;
|
|
57
|
+
_pending: boolean;
|
|
58
|
+
_pendingMeta: any;
|
|
59
|
+
_lastSig: any;
|
|
60
|
+
_lastRootId: any;
|
|
61
|
+
add(reason: string, meta: any): void;
|
|
62
|
+
pause(): void;
|
|
63
|
+
resume(flush?: boolean): void;
|
|
64
|
+
clear(): void;
|
|
65
|
+
canBack(): boolean;
|
|
66
|
+
canForward(): boolean;
|
|
67
|
+
back(steps?: number): boolean;
|
|
68
|
+
forward(steps?: number): boolean;
|
|
69
|
+
length(): number;
|
|
70
|
+
index(): number;
|
|
71
|
+
setMax(count: any): void;
|
|
72
|
+
setThrottle(ms: any): void;
|
|
73
|
+
exportSnapshot(): any;
|
|
74
|
+
importSnapshot(data: any, applyOptions: any): boolean;
|
|
75
|
+
getStackMeta(): {
|
|
76
|
+
items: any[];
|
|
77
|
+
index: number;
|
|
78
|
+
};
|
|
79
|
+
_notifyChange(): void;
|
|
80
|
+
_addNow(_reason: any, _meta: any): void;
|
|
81
|
+
_applyIndex(): boolean;
|
|
82
|
+
_takeSnapshot(): any;
|
|
83
|
+
_applySnapshot(data: any, applyOptions: any): boolean;
|
|
84
|
+
_countNodes(snapshot: any): number;
|
|
85
|
+
_deepFreeze(obj: any): any;
|
|
86
|
+
_cloneSnapshot(obj: any): any;
|
|
87
|
+
}
|
|
@@ -0,0 +1,262 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Draggable node plugin for jsMind.
|
|
3
|
+
*/
|
|
4
|
+
export class DraggableNode {
|
|
5
|
+
/**
|
|
6
|
+
* Create draggable node plugin instance.
|
|
7
|
+
* @param {import('../jsmind.js').default} jm - jsMind instance
|
|
8
|
+
* @param {Partial<DraggableNodeOptions>} options - Plugin options
|
|
9
|
+
*/
|
|
10
|
+
constructor(jm: import("../jsmind.js").default, options: Partial<DraggableNodeOptions>);
|
|
11
|
+
version: string;
|
|
12
|
+
/** @type {import('../jsmind.js').default} */
|
|
13
|
+
jm: import("../jsmind.js").default;
|
|
14
|
+
/** @type {DraggableNodeOptions} */
|
|
15
|
+
options: DraggableNodeOptions;
|
|
16
|
+
/** @type {boolean} */
|
|
17
|
+
is_svg_engine: boolean;
|
|
18
|
+
/** @type {HTMLCanvasElement|SVGSVGElement|null} */
|
|
19
|
+
e_canvas: HTMLCanvasElement | SVGSVGElement | null;
|
|
20
|
+
/** @type {CanvasRenderingContext2D|null} */
|
|
21
|
+
canvas_ctx: CanvasRenderingContext2D | null;
|
|
22
|
+
/** @type {SVGPathElement|null} */
|
|
23
|
+
helper_line: SVGPathElement | null;
|
|
24
|
+
/** @type {HTMLElement|null} */
|
|
25
|
+
shadow: HTMLElement | null;
|
|
26
|
+
/** @type {number} */
|
|
27
|
+
shadow_p_x: number;
|
|
28
|
+
/** @type {number} */
|
|
29
|
+
shadow_p_y: number;
|
|
30
|
+
/** @type {number} */
|
|
31
|
+
shadow_w: number;
|
|
32
|
+
/** @type {number} */
|
|
33
|
+
shadow_h: number;
|
|
34
|
+
/** @type {import('../jsmind.node.js').Node|null} */
|
|
35
|
+
active_node: import("../jsmind.node.js").Node | null;
|
|
36
|
+
/** @type {import('../jsmind.node.js').Node|null} */
|
|
37
|
+
target_node: import("../jsmind.node.js").Node | null;
|
|
38
|
+
/** @type {number|null} */
|
|
39
|
+
target_direct: number | null;
|
|
40
|
+
/** @type {number} */
|
|
41
|
+
client_w: number;
|
|
42
|
+
/** @type {number} */
|
|
43
|
+
client_h: number;
|
|
44
|
+
/** @type {number} */
|
|
45
|
+
offset_x: number;
|
|
46
|
+
/** @type {number} */
|
|
47
|
+
offset_y: number;
|
|
48
|
+
/** @type {number} */
|
|
49
|
+
hlookup_delay: number;
|
|
50
|
+
/** @type {number} */
|
|
51
|
+
hlookup_timer: number;
|
|
52
|
+
/** @type {boolean} */
|
|
53
|
+
capture: boolean;
|
|
54
|
+
/** @type {boolean} */
|
|
55
|
+
moved: boolean;
|
|
56
|
+
/** @type {boolean} */
|
|
57
|
+
canvas_draggable: boolean;
|
|
58
|
+
/** @type {HTMLElement} */
|
|
59
|
+
view_panel: HTMLElement;
|
|
60
|
+
/** @type {DOMRect|null} */
|
|
61
|
+
view_panel_rect: DOMRect | null;
|
|
62
|
+
/** Initialize the draggable node plugin. */
|
|
63
|
+
init(): void;
|
|
64
|
+
/** Resize canvas/SVG and shadow elements. */
|
|
65
|
+
resize(): void;
|
|
66
|
+
/** Create canvas or SVG for drawing drag lines. */
|
|
67
|
+
create_canvas(): void;
|
|
68
|
+
/**
|
|
69
|
+
* Create SVG element with proper namespace.
|
|
70
|
+
* @param {string} tag - SVG tag name
|
|
71
|
+
* @returns {SVGElement}
|
|
72
|
+
* @private
|
|
73
|
+
*/
|
|
74
|
+
private _create_svg_element;
|
|
75
|
+
create_shadow(): void;
|
|
76
|
+
/**
|
|
77
|
+
* Reset shadow element style and cache its size.
|
|
78
|
+
* @param {HTMLElement} el - The node element to mirror as shadow
|
|
79
|
+
*/
|
|
80
|
+
reset_shadow(el: HTMLElement): void;
|
|
81
|
+
/** Show the shadow element. */
|
|
82
|
+
show_shadow(): void;
|
|
83
|
+
/** Hide the shadow element. */
|
|
84
|
+
hide_shadow(): void;
|
|
85
|
+
/**
|
|
86
|
+
* Draw a helper line between the shadow and target node.
|
|
87
|
+
* @param {{x:number,y:number}} shadow_p - Shadow anchor point
|
|
88
|
+
* @param {{x:number,y:number}} node_p - Target node anchor point
|
|
89
|
+
* @param {boolean} invalid - Whether current target is invalid
|
|
90
|
+
*/
|
|
91
|
+
magnet_shadow(shadow_p: {
|
|
92
|
+
x: number;
|
|
93
|
+
y: number;
|
|
94
|
+
}, node_p: {
|
|
95
|
+
x: number;
|
|
96
|
+
y: number;
|
|
97
|
+
}, invalid: boolean): void;
|
|
98
|
+
/** Clear helper lines from canvas or SVG. */
|
|
99
|
+
clear_lines(): void;
|
|
100
|
+
/**
|
|
101
|
+
* Draw a straight helper line on canvas.
|
|
102
|
+
* @param {number} x1
|
|
103
|
+
* @param {number} y1
|
|
104
|
+
* @param {number} x2
|
|
105
|
+
* @param {number} y2
|
|
106
|
+
*/
|
|
107
|
+
canvas_lineto(x1: number, y1: number, x2: number, y2: number): void;
|
|
108
|
+
/**
|
|
109
|
+
* Draw a helper line on SVG using bezier curve.
|
|
110
|
+
* Reuses the line drawing logic from SvgGraph.
|
|
111
|
+
* @param {number} x1 - Start x coordinate
|
|
112
|
+
* @param {number} y1 - Start y coordinate
|
|
113
|
+
* @param {number} x2 - End x coordinate
|
|
114
|
+
* @param {number} y2 - End y coordinate
|
|
115
|
+
* @param {string} color - Line color
|
|
116
|
+
*/
|
|
117
|
+
svg_draw_line(x1: number, y1: number, x2: number, y2: number, color: string): void;
|
|
118
|
+
/**
|
|
119
|
+
* Draw bezier curve to SVG path element.
|
|
120
|
+
* Reuses logic from SvgGraph._bezier_to.
|
|
121
|
+
* @param {SVGPathElement} path - SVG path element
|
|
122
|
+
* @param {number} x1 - Start x coordinate
|
|
123
|
+
* @param {number} y1 - Start y coordinate
|
|
124
|
+
* @param {number} x2 - End x coordinate
|
|
125
|
+
* @param {number} y2 - End y coordinate
|
|
126
|
+
* @private
|
|
127
|
+
*/
|
|
128
|
+
private _svg_bezier_to;
|
|
129
|
+
/** Bind mouse/touch events for dragging. */
|
|
130
|
+
event_bind(): void;
|
|
131
|
+
/**
|
|
132
|
+
* Begin dragging interaction.
|
|
133
|
+
* @param {MouseEvent|TouchEvent} e - Pointer down event
|
|
134
|
+
*/
|
|
135
|
+
dragstart(e: MouseEvent | TouchEvent): void;
|
|
136
|
+
view_draggable: boolean;
|
|
137
|
+
client_hw: number;
|
|
138
|
+
client_hh: number;
|
|
139
|
+
/**
|
|
140
|
+
* Drag handler to move shadow and auto-scroll container.
|
|
141
|
+
* @param {MouseEvent|TouchEvent} e - Pointer move event
|
|
142
|
+
*/
|
|
143
|
+
drag(e: MouseEvent | TouchEvent): void;
|
|
144
|
+
/**
|
|
145
|
+
* Finish dragging, move the node if applicable.
|
|
146
|
+
* @param {MouseEvent|TouchEvent} e - Pointer up event
|
|
147
|
+
*/
|
|
148
|
+
dragend(e: MouseEvent | TouchEvent): void;
|
|
149
|
+
/**
|
|
150
|
+
* Find the closest node element from an event target.
|
|
151
|
+
* @param {HTMLElement} el - Current DOM element
|
|
152
|
+
* @returns {HTMLElement|null} Matched node element or null
|
|
153
|
+
*/
|
|
154
|
+
find_node_element(el: HTMLElement): HTMLElement | null;
|
|
155
|
+
/** Recompute target node under the shadow and draw helper. */
|
|
156
|
+
lookup_target_node(): void;
|
|
157
|
+
/**
|
|
158
|
+
* Get X coordinate of root node center.
|
|
159
|
+
* @returns {number}
|
|
160
|
+
*/
|
|
161
|
+
get_root_x(): number;
|
|
162
|
+
/**
|
|
163
|
+
* Lookup overlapping node's parent near the shadow position.
|
|
164
|
+
* @param {number} direction - Direction constant
|
|
165
|
+
* @returns {import('../jsmind.node.js').Node|null}
|
|
166
|
+
*/
|
|
167
|
+
lookup_overlapping_node_parent(direction: number): import("../jsmind.node.js").Node | null;
|
|
168
|
+
/**
|
|
169
|
+
* Find node's parent by a screen location.
|
|
170
|
+
* @param {number} x - Client X
|
|
171
|
+
* @param {number} y - Client Y
|
|
172
|
+
* @returns {import('../jsmind.node.js').Node|null}
|
|
173
|
+
*/
|
|
174
|
+
lookup_node_parent_by_location(x: number, y: number): import("../jsmind.node.js").Node | null;
|
|
175
|
+
/**
|
|
176
|
+
* Lookup the closest node along a direction.
|
|
177
|
+
* @param {number} direction
|
|
178
|
+
* @returns {import('../jsmind.node.js').Node}
|
|
179
|
+
*/
|
|
180
|
+
lookup_close_node(direction: number): import("../jsmind.node.js").Node;
|
|
181
|
+
/**
|
|
182
|
+
* Check if shadow is on the target side of a node.
|
|
183
|
+
* @param {import('../jsmind.node.js').Node} node
|
|
184
|
+
* @param {number} dir
|
|
185
|
+
* @returns {boolean}
|
|
186
|
+
*/
|
|
187
|
+
shadow_on_target_side(node: import("../jsmind.node.js").Node, dir: number): boolean;
|
|
188
|
+
/**
|
|
189
|
+
* Distance from shadow to the right side of a node.
|
|
190
|
+
* @param {import('../jsmind.node.js').Node} node
|
|
191
|
+
* @returns {number}
|
|
192
|
+
*/
|
|
193
|
+
shadow_to_right_of_node(node: import("../jsmind.node.js").Node): number;
|
|
194
|
+
/**
|
|
195
|
+
* Distance from shadow to the left side of a node.
|
|
196
|
+
* @param {import('../jsmind.node.js').Node} node
|
|
197
|
+
* @returns {number}
|
|
198
|
+
*/
|
|
199
|
+
shadow_to_left_of_node(node: import("../jsmind.node.js").Node): number;
|
|
200
|
+
/**
|
|
201
|
+
* Vertical distance between shadow centerline and node centerline.
|
|
202
|
+
* @param {import('../jsmind.node.js').Node} node
|
|
203
|
+
* @returns {number}
|
|
204
|
+
*/
|
|
205
|
+
shadow_to_base_line_of_node(node: import("../jsmind.node.js").Node): number;
|
|
206
|
+
/**
|
|
207
|
+
* Manhattan distance to a node along a direction.
|
|
208
|
+
* @param {import('../jsmind.node.js').Node} node
|
|
209
|
+
* @param {number} dir
|
|
210
|
+
* @returns {number}
|
|
211
|
+
*/
|
|
212
|
+
shadow_to_node(node: import("../jsmind.node.js").Node, dir: number): number;
|
|
213
|
+
/**
|
|
214
|
+
* Calculate connection points of a node and the shadow.
|
|
215
|
+
* @param {import('../jsmind.node.js').Node} node
|
|
216
|
+
* @param {number} dir
|
|
217
|
+
* @returns {{sp:{x:number,y:number}, np:{x:number,y:number}}}
|
|
218
|
+
*/
|
|
219
|
+
calc_point_of_node(node: import("../jsmind.node.js").Node, dir: number): {
|
|
220
|
+
sp: {
|
|
221
|
+
x: number;
|
|
222
|
+
y: number;
|
|
223
|
+
};
|
|
224
|
+
np: {
|
|
225
|
+
x: number;
|
|
226
|
+
y: number;
|
|
227
|
+
};
|
|
228
|
+
};
|
|
229
|
+
/**
|
|
230
|
+
* Move a node to a new parent/position.
|
|
231
|
+
* @param {import('../jsmind.node.js').Node} src_node
|
|
232
|
+
* @param {import('../jsmind.node.js').Node|null} target_node
|
|
233
|
+
* @param {number|null} target_direct
|
|
234
|
+
*/
|
|
235
|
+
move_node(src_node: import("../jsmind.node.js").Node, target_node: import("../jsmind.node.js").Node | null, target_direct: number | null): void;
|
|
236
|
+
/**
|
|
237
|
+
* Handle jsMind events.
|
|
238
|
+
* @param {number|string} type - Event type
|
|
239
|
+
* @param {object} [data] - Event data
|
|
240
|
+
*/
|
|
241
|
+
jm_event_handle(type: number | string, data?: object): void;
|
|
242
|
+
}
|
|
243
|
+
/**
|
|
244
|
+
* Draggable node plugin registration.
|
|
245
|
+
* @type {import('../jsmind.plugin.js').Plugin<Partial<DraggableNodeOptions>>}
|
|
246
|
+
*/
|
|
247
|
+
export const draggable_plugin: import("../jsmind.plugin.js").Plugin<Partial<DraggableNodeOptions>>;
|
|
248
|
+
export default DraggableNode;
|
|
249
|
+
/**
|
|
250
|
+
* Default options for draggable node plugin.
|
|
251
|
+
*/
|
|
252
|
+
export type DraggableNodeOptions = {
|
|
253
|
+
line_width?: number;
|
|
254
|
+
line_color?: string;
|
|
255
|
+
line_color_invalid?: string;
|
|
256
|
+
lookup_delay?: number;
|
|
257
|
+
lookup_interval?: number;
|
|
258
|
+
scrolling_trigger_width?: number;
|
|
259
|
+
scrolling_step_length?: number;
|
|
260
|
+
shadow_node_class_name?: string;
|
|
261
|
+
validate_drag?: (draggedNode: import("../jsmind.node.js").Node, targetNode: import("../jsmind.node.js").Node | null) => boolean;
|
|
262
|
+
};
|
|
@@ -0,0 +1,238 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Multi-Select Plugin - Enhanced plugin for jsMind
|
|
3
|
+
*/
|
|
4
|
+
export class MultiSelectPlugin extends EnhancedPlugin {
|
|
5
|
+
/**
|
|
6
|
+
* @param {{ jm: import('../jsmind.js').default, pluginOpt: object }} params
|
|
7
|
+
*/
|
|
8
|
+
constructor({ jm, pluginOpt }: {
|
|
9
|
+
jm: import("../jsmind.js").default;
|
|
10
|
+
pluginOpt: object;
|
|
11
|
+
});
|
|
12
|
+
options: any;
|
|
13
|
+
_mounted: boolean;
|
|
14
|
+
_core: MultiSelectCore;
|
|
15
|
+
_listener: (type: any, data: any) => void;
|
|
16
|
+
_enabled: boolean;
|
|
17
|
+
/**
|
|
18
|
+
* Initialize core and mount API
|
|
19
|
+
*/
|
|
20
|
+
_initCore(): void;
|
|
21
|
+
_original_select_node: any;
|
|
22
|
+
_original_select_clear: any;
|
|
23
|
+
_domClickHandler: (e: any) => void;
|
|
24
|
+
/**
|
|
25
|
+
* Mount API to jsMind instance
|
|
26
|
+
*/
|
|
27
|
+
_mountAPI(): void;
|
|
28
|
+
setEnabled(flag: any): void;
|
|
29
|
+
setOptions(partial: any): void;
|
|
30
|
+
}
|
|
31
|
+
export default MultiSelectPlugin;
|
|
32
|
+
/**
|
|
33
|
+
* Default options for multi-select plugin.
|
|
34
|
+
*/
|
|
35
|
+
export type MultiSelectOptions = {
|
|
36
|
+
/**
|
|
37
|
+
* - Enable multi-select feature
|
|
38
|
+
*/
|
|
39
|
+
enable_multi_select?: boolean;
|
|
40
|
+
/**
|
|
41
|
+
* - Include descendants in subtree selection
|
|
42
|
+
*/
|
|
43
|
+
include_descendants?: boolean;
|
|
44
|
+
/**
|
|
45
|
+
* - Shift mode: false=simple subtree, true=advanced range
|
|
46
|
+
*/
|
|
47
|
+
shift_simple_mode?: boolean;
|
|
48
|
+
/**
|
|
49
|
+
* - Node filter function
|
|
50
|
+
*/
|
|
51
|
+
filter?: ((node: import("../jsmind.node.js").Node) => boolean) | null;
|
|
52
|
+
};
|
|
53
|
+
import { EnhancedPlugin } from '../jsmind.enhanced-plugin.js';
|
|
54
|
+
/**
|
|
55
|
+
* Multi-Select Core - Handles all multi-select logic
|
|
56
|
+
*/
|
|
57
|
+
export class MultiSelectCore {
|
|
58
|
+
/**
|
|
59
|
+
* @param {import('../jsmind.js').default} jm - jsMind instance
|
|
60
|
+
* @param {MultiSelectOptions} options - Plugin options
|
|
61
|
+
*/
|
|
62
|
+
constructor(jm: import("../jsmind.js").default, options: MultiSelectOptions);
|
|
63
|
+
jm: import("../jsmind.js").default;
|
|
64
|
+
options: MultiSelectOptions;
|
|
65
|
+
_selection_mode: string;
|
|
66
|
+
_last_selected_node: import("../jsmind.node.js").Node;
|
|
67
|
+
/**
|
|
68
|
+
* Ensure selection state is initialized
|
|
69
|
+
* @private
|
|
70
|
+
*/
|
|
71
|
+
private _ensure_selection_state;
|
|
72
|
+
/**
|
|
73
|
+
* Get all selected nodes
|
|
74
|
+
* @returns {string[]} Array of selected node IDs
|
|
75
|
+
*/
|
|
76
|
+
get_selected_nodes(): string[];
|
|
77
|
+
/**
|
|
78
|
+
* Check if a node is selected
|
|
79
|
+
* @param {string|import('../jsmind.node.js').Node} node - Node ID or Node instance
|
|
80
|
+
* @returns {boolean}
|
|
81
|
+
*/
|
|
82
|
+
is_node_selected(node: string | import("../jsmind.node.js").Node): boolean;
|
|
83
|
+
/**
|
|
84
|
+
* Select a single node (clears other selections)
|
|
85
|
+
* @param {string|import('../jsmind.node.js').Node} node - Node ID or Node instance
|
|
86
|
+
*/
|
|
87
|
+
select_node(node: string | import("../jsmind.node.js").Node): void;
|
|
88
|
+
/**
|
|
89
|
+
* Clear all selections
|
|
90
|
+
*/
|
|
91
|
+
select_clear(): void;
|
|
92
|
+
/**
|
|
93
|
+
* Toggle node selection (equivalent to Ctrl/Cmd+Click)
|
|
94
|
+
* @param {string|import('../jsmind.node.js').Node} node - Node ID or Node instance
|
|
95
|
+
*/
|
|
96
|
+
toggle_node_selection(node: string | import("../jsmind.node.js").Node): void;
|
|
97
|
+
/**
|
|
98
|
+
* Toggle subtree selection
|
|
99
|
+
* @param {string|import('../jsmind.node.js').Node} node - Node ID or Node instance
|
|
100
|
+
*/
|
|
101
|
+
toggle_subtree_selection(node: string | import("../jsmind.node.js").Node, opts: any): void;
|
|
102
|
+
/**
|
|
103
|
+
* Get current selection mode
|
|
104
|
+
* @returns {'single'|'multi'|null}
|
|
105
|
+
*/
|
|
106
|
+
get_selection_mode(): "single" | "multi" | null;
|
|
107
|
+
/**
|
|
108
|
+
* Handle node click event
|
|
109
|
+
* @param {Object} payload - Click event payload
|
|
110
|
+
* @param {MouseEvent} payload.e - Mouse event
|
|
111
|
+
* @param {string} payload.node - Node ID
|
|
112
|
+
* @param {HTMLElement} payload.element - Node element
|
|
113
|
+
* @param {string} payload.evt - Event type
|
|
114
|
+
*/
|
|
115
|
+
_handle_node_click(payload: {
|
|
116
|
+
e: MouseEvent;
|
|
117
|
+
node: string;
|
|
118
|
+
element: HTMLElement;
|
|
119
|
+
evt: string;
|
|
120
|
+
}): void;
|
|
121
|
+
/**
|
|
122
|
+
* Handle node removed event
|
|
123
|
+
* @param {import('../jsmind.node.js').Node} node - Removed node
|
|
124
|
+
*/
|
|
125
|
+
_handle_node_removed(node: import("../jsmind.node.js").Node): void;
|
|
126
|
+
/**
|
|
127
|
+
* Get multi-select mode from event
|
|
128
|
+
* @param {MouseEvent} e - Mouse event
|
|
129
|
+
* @returns {'ctrl'|'shift'|null}
|
|
130
|
+
*/
|
|
131
|
+
_get_multi_select_mode(e: MouseEvent): "ctrl" | "shift" | null;
|
|
132
|
+
/**
|
|
133
|
+
* Append nodes to selection
|
|
134
|
+
* @param {import('../jsmind.node.js').Node[]} nodes - Nodes to select
|
|
135
|
+
* @param {Object} [options] - Options
|
|
136
|
+
* @param {import('../jsmind.node.js').Node} [options.focusNode] - Focus node
|
|
137
|
+
* @returns {import('../jsmind.node.js').Node[]} Actually added nodes
|
|
138
|
+
*/
|
|
139
|
+
_append_selection(nodes: import("../jsmind.node.js").Node[], options?: {
|
|
140
|
+
focusNode?: import("../jsmind.node.js").Node;
|
|
141
|
+
}): import("../jsmind.node.js").Node[];
|
|
142
|
+
/**
|
|
143
|
+
* Remove nodes from selection
|
|
144
|
+
* @param {import('../jsmind.node.js').Node[]} nodes - Nodes to deselect
|
|
145
|
+
* @returns {import('../jsmind.node.js').Node[]} Actually removed nodes
|
|
146
|
+
*/
|
|
147
|
+
_remove_selection(nodes: import("../jsmind.node.js").Node[]): import("../jsmind.node.js").Node[];
|
|
148
|
+
/**
|
|
149
|
+
* Deselect subtree
|
|
150
|
+
* @param {import('../jsmind.node.js').Node} node - Root node of subtree
|
|
151
|
+
*/
|
|
152
|
+
_deselect_subtree(node: import("../jsmind.node.js").Node): void;
|
|
153
|
+
/**
|
|
154
|
+
* Clear selection state
|
|
155
|
+
* @returns {import('../jsmind.node.js').Node[]} Removed nodes
|
|
156
|
+
*/
|
|
157
|
+
_clear_selection_state(): import("../jsmind.node.js").Node[];
|
|
158
|
+
/**
|
|
159
|
+
* Collect subtree nodes
|
|
160
|
+
* @param {import('../jsmind.node.js').Node} node - Root node
|
|
161
|
+
* @param {Object} options - Options
|
|
162
|
+
* @param {boolean} [options.includeChildren=true] - Include children
|
|
163
|
+
* @param {boolean} [options.respectFilter=false] - Respect filter
|
|
164
|
+
* @param {boolean} [options.skipRootFilter=false] - Skip root filter
|
|
165
|
+
* @returns {import('../jsmind.node.js').Node[]}
|
|
166
|
+
*/
|
|
167
|
+
_collect_subtree_nodes(node: import("../jsmind.node.js").Node, options: {
|
|
168
|
+
includeChildren?: boolean;
|
|
169
|
+
respectFilter?: boolean;
|
|
170
|
+
skipRootFilter?: boolean;
|
|
171
|
+
}): import("../jsmind.node.js").Node[];
|
|
172
|
+
/**
|
|
173
|
+
* Ensure ancestor selection
|
|
174
|
+
* @param {import('../jsmind.node.js').Node[]} nodes - Nodes
|
|
175
|
+
* @param {import('../jsmind.node.js').Node} focusNode - Focus node
|
|
176
|
+
* @param {Object} options - Options
|
|
177
|
+
* @returns {import('../jsmind.node.js').Node[]}
|
|
178
|
+
*/
|
|
179
|
+
_ensure_ancestor_selection(nodes: import("../jsmind.node.js").Node[], focusNode: import("../jsmind.node.js").Node, options: any): import("../jsmind.node.js").Node[];
|
|
180
|
+
/**
|
|
181
|
+
* Get selection filter
|
|
182
|
+
* @returns {Function|null}
|
|
183
|
+
*/
|
|
184
|
+
_get_selection_filter(): Function | null;
|
|
185
|
+
/**
|
|
186
|
+
* Range select nodes (advanced mode)
|
|
187
|
+
* @param {string} nodeId - Target node ID
|
|
188
|
+
*/
|
|
189
|
+
_range_select_nodes(nodeId: string): void;
|
|
190
|
+
/**
|
|
191
|
+
* Find nodes between two nodes
|
|
192
|
+
* @param {import('../jsmind.node.js').Node} from - Start node
|
|
193
|
+
* @param {import('../jsmind.node.js').Node} to - End node
|
|
194
|
+
* @returns {import('../jsmind.node.js').Node[]}
|
|
195
|
+
*/
|
|
196
|
+
_find_nodes_between(from: import("../jsmind.node.js").Node, to: import("../jsmind.node.js").Node): import("../jsmind.node.js").Node[];
|
|
197
|
+
/**
|
|
198
|
+
* Derive selection mode from current state
|
|
199
|
+
* @returns {'single'|'multi'|null}
|
|
200
|
+
*/
|
|
201
|
+
_derive_selection_mode(): "single" | "multi" | null;
|
|
202
|
+
/**
|
|
203
|
+
* Mark nodes as selected in view
|
|
204
|
+
* @param {import('../jsmind.node.js').Node[]} nodes - Nodes to mark
|
|
205
|
+
* @param {import('../jsmind.node.js').Node} focusNode - Focus node
|
|
206
|
+
*/
|
|
207
|
+
_mark_nodes_selected(nodes: import("../jsmind.node.js").Node[], focusNode: import("../jsmind.node.js").Node): void;
|
|
208
|
+
/**
|
|
209
|
+
* Mark a node as selected in view
|
|
210
|
+
* @param {import('../jsmind.node.js').Node} node - Node to mark
|
|
211
|
+
*/
|
|
212
|
+
_mark_node_selected(node: import("../jsmind.node.js").Node): void;
|
|
213
|
+
/**
|
|
214
|
+
* Unmark nodes as selected in view
|
|
215
|
+
* @param {import('../jsmind.node.js').Node[]} nodes - Nodes to unmark
|
|
216
|
+
*/
|
|
217
|
+
_unmark_nodes_selected(nodes: import("../jsmind.node.js").Node[]): void;
|
|
218
|
+
/**
|
|
219
|
+
* Unmark a node as selected in view
|
|
220
|
+
* @param {import('../jsmind.node.js').Node} node - Node to unmark
|
|
221
|
+
*/
|
|
222
|
+
_unmark_node_selected(node: import("../jsmind.node.js").Node): void;
|
|
223
|
+
/**
|
|
224
|
+
* Clear all selected nodes view
|
|
225
|
+
*/
|
|
226
|
+
_clear_all_selected_nodes_view(): void;
|
|
227
|
+
/**
|
|
228
|
+
* Invoke select event
|
|
229
|
+
* @param {Object} data - Event data
|
|
230
|
+
*/
|
|
231
|
+
_invoke_select_event(data: any): void;
|
|
232
|
+
/**
|
|
233
|
+
* Resolve node from ID or Node instance
|
|
234
|
+
* @param {string|import('../jsmind.node.js').Node} node - Node ID or Node instance
|
|
235
|
+
* @returns {import('../jsmind.node.js').Node|null}
|
|
236
|
+
*/
|
|
237
|
+
_resolve_node(node: string | import("../jsmind.node.js").Node): import("../jsmind.node.js").Node | null;
|
|
238
|
+
}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
export default MultilineTextV2;
|
|
2
|
+
/**
|
|
3
|
+
* MultilineTextV2 Plugin
|
|
4
|
+
* Enhanced multiline text plugin using the new plugin system
|
|
5
|
+
*/
|
|
6
|
+
declare class MultilineTextV2 extends EnhancedPlugin {
|
|
7
|
+
/**
|
|
8
|
+
* @param {{ jm: import('../jsmind.js').default, pluginOpt: object }} params
|
|
9
|
+
*/
|
|
10
|
+
constructor({ jm, pluginOpt }: {
|
|
11
|
+
jm: import("../jsmind.js").default;
|
|
12
|
+
pluginOpt: object;
|
|
13
|
+
});
|
|
14
|
+
options: any;
|
|
15
|
+
editing_node: import("../jsmind.node.js").Node;
|
|
16
|
+
multiline_editor: HTMLElement;
|
|
17
|
+
_original_custom_render: Function | ((jm: import("../jsmind.js").default, ele: HTMLElement, node: import("../jsmind.node.js").Node) => void);
|
|
18
|
+
_original_edit_node_begin: any;
|
|
19
|
+
_original_edit_node_end: any;
|
|
20
|
+
/**
|
|
21
|
+
* Setup custom rendering in options (for preload plugins)
|
|
22
|
+
*/
|
|
23
|
+
setupCustomRenderInOptions(): void;
|
|
24
|
+
/**
|
|
25
|
+
* Setup custom rendering for multiline text (for normal plugins)
|
|
26
|
+
*/
|
|
27
|
+
setupCustomRender(): void;
|
|
28
|
+
/**
|
|
29
|
+
* Setup edit handlers (common for both preload and normal plugins)
|
|
30
|
+
*/
|
|
31
|
+
setupEditHandlers(): void;
|
|
32
|
+
/**
|
|
33
|
+
* Re-render all nodes to apply multiline styles and recalculate sizes.
|
|
34
|
+
* This is necessary because node sizes are calculated before custom styles are applied.
|
|
35
|
+
* @private
|
|
36
|
+
*/
|
|
37
|
+
private _rerender_all_nodes;
|
|
38
|
+
/**
|
|
39
|
+
* Begin editing a node
|
|
40
|
+
* @param {import('../jsmind.node.js').Node} node
|
|
41
|
+
*/
|
|
42
|
+
edit_node_begin(node: import("../jsmind.node.js").Node): void;
|
|
43
|
+
/**
|
|
44
|
+
* End editing and save changes.
|
|
45
|
+
*/
|
|
46
|
+
edit_node_end(): void;
|
|
47
|
+
/**
|
|
48
|
+
* Cancel editing without saving changes.
|
|
49
|
+
*/
|
|
50
|
+
cancel_editing(): void;
|
|
51
|
+
/**
|
|
52
|
+
* Clean up editor and reset state.
|
|
53
|
+
* @private
|
|
54
|
+
*/
|
|
55
|
+
private _cleanup_editor;
|
|
56
|
+
}
|
|
57
|
+
import { EnhancedPlugin } from '../jsmind.enhanced-plugin.js';
|
|
58
|
+
import jsMind from '../jsmind.js';
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Create a custom node render function for multiline text
|
|
3
|
+
* @param {MultilineTextOptions} [options={}] - Plugin options
|
|
4
|
+
* @param {number} [options.text_width=200] - Maximum width for multiline text nodes
|
|
5
|
+
* @param {string} [options.line_height='1.5'] - Line height for text
|
|
6
|
+
* @returns {function(jsMind, HTMLElement, Node): boolean} Custom render function
|
|
7
|
+
* @example
|
|
8
|
+
* const options = {
|
|
9
|
+
* view: {
|
|
10
|
+
* custom_node_render: createMultilineRender({
|
|
11
|
+
* text_width: 250,
|
|
12
|
+
* line_height: '1.6',
|
|
13
|
+
* })
|
|
14
|
+
* }
|
|
15
|
+
* };
|
|
16
|
+
*/
|
|
17
|
+
export function createMultilineRender(options?: MultilineTextOptions): (arg0: jsMind, arg1: HTMLElement, arg2: Node) => boolean;
|
|
18
|
+
declare namespace _default {
|
|
19
|
+
export let name: string;
|
|
20
|
+
export { init };
|
|
21
|
+
export { createMultilineRender };
|
|
22
|
+
}
|
|
23
|
+
export default _default;
|
|
24
|
+
/**
|
|
25
|
+
* Default plugin options
|
|
26
|
+
*/
|
|
27
|
+
export type MultilineTextOptions = {
|
|
28
|
+
/**
|
|
29
|
+
* - Maximum width for multiline text nodes (default: 200)
|
|
30
|
+
*/
|
|
31
|
+
text_width: number;
|
|
32
|
+
/**
|
|
33
|
+
* - Line height for text (default: '1.5')
|
|
34
|
+
*/
|
|
35
|
+
line_height: string;
|
|
36
|
+
};
|
|
37
|
+
/**
|
|
38
|
+
* Plugin initialization function
|
|
39
|
+
* @param {import('../jsmind.js').default} jm - jsMind instance
|
|
40
|
+
* @param {MultilineTextOptions} options - Plugin options
|
|
41
|
+
* @private
|
|
42
|
+
*/
|
|
43
|
+
declare function init(jm: import("../jsmind.js").default, options: MultilineTextOptions): void;
|