@umbraci/jsmind 0.9.9 → 0.9.11

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@umbraci/jsmind",
3
- "version": "0.9.9",
3
+ "version": "0.9.11",
4
4
  "description": "jsMind is a pure javascript library for mindmap, it base on html5 canvas. jsMind was released under BSD license, you can embed it in any project, if only you observe the license.",
5
5
  "main": "lib/jsmind.js",
6
6
  "module": "es/jsmind.js",
@@ -28,6 +28,11 @@
28
28
  "require": "./lib/jsmind.multiline-text.js",
29
29
  "types": "./types/generated/plugins/jsmind.multiline-text.d.ts"
30
30
  },
31
+ "./history": {
32
+ "import": "./es/jsmind.history.js",
33
+ "require": "./lib/jsmind.history.js",
34
+ "types": "./types/generated/plugins/jsmind.history.d.ts"
35
+ },
31
36
  "./style/jsmind.css": "./style/jsmind.css"
32
37
  },
33
38
  "directories": {
@@ -77,6 +82,8 @@
77
82
  }
78
83
  ],
79
84
  "devDependencies": {
85
+ "@rollup/plugin-commonjs": "^28.0.8",
86
+ "@rollup/plugin-node-resolve": "^16.0.3",
80
87
  "@rollup/plugin-terser": "^0.4.4",
81
88
  "http-server": "^14.1.1",
82
89
  "jest": "^28.1.0",
@@ -93,5 +100,8 @@
93
100
  },
94
101
  "sideEffects": [
95
102
  "./es6/*"
96
- ]
103
+ ],
104
+ "dependencies": {
105
+ "fast-equals": "^5.3.2"
106
+ }
97
107
  }
@@ -27,6 +27,8 @@ export namespace EventType {
27
27
  let resize: number;
28
28
  let edit: number;
29
29
  let select: number;
30
+ let reset: number;
31
+ let history_change: number;
30
32
  }
31
33
  export type Key = number;
32
34
  export namespace Key {
@@ -14,6 +14,8 @@ declare class jsMind {
14
14
  resize: number;
15
15
  edit: number;
16
16
  select: number;
17
+ reset: number;
18
+ history_change: number;
17
19
  };
18
20
  static $: {
19
21
  w: Window;
@@ -0,0 +1,55 @@
1
+ /**
2
+ * Flatten a NodeTreeFormat/NodeTreeData by id
3
+ * @param {NodeTreeFormat|NodeTreeData} tree
4
+ * @param {{ fields?: string[], includeStructure?: boolean }=} opts
5
+ * @returns {Record<string, any>}
6
+ */
7
+ export function flatten(tree: NodeTreeFormat | NodeTreeData, opts?: {
8
+ fields?: string[];
9
+ includeStructure?: boolean;
10
+ } | undefined): Record<string, any>;
11
+ /**
12
+ * Compute diff between two snapshots
13
+ * @param {NodeTreeFormat|NodeTreeData} a
14
+ * @param {NodeTreeFormat|NodeTreeData} b
15
+ * @param {{ fields?: string[], includeStructure?: boolean, maxSize?: number }=} opts
16
+ * - fields: 可选。指定要参与 diff 的节点属性列表;默认比较所有属性(除 children)。与 includeStructure 组合使用时可同时比较 _parentid/_order。
17
+ * @returns {{
18
+ * created: any[],
19
+ * updated: { id:string, before:any, after:any, changes: { key:string, before:any, after:any }[] }[],
20
+ * deleted: any[],
21
+ * truncated: boolean
22
+ * }}
23
+ */
24
+ export function diff(a: NodeTreeFormat | NodeTreeData, b: NodeTreeFormat | NodeTreeData, opts?: {
25
+ fields?: string[];
26
+ includeStructure?: boolean;
27
+ maxSize?: number;
28
+ } | undefined): {
29
+ created: any[];
30
+ updated: {
31
+ id: string;
32
+ before: any;
33
+ after: any;
34
+ changes: {
35
+ key: string;
36
+ before: any;
37
+ after: any;
38
+ }[];
39
+ }[];
40
+ deleted: any[];
41
+ truncated: boolean;
42
+ };
43
+ export type NodeTreeFormat = {
44
+ meta?: any;
45
+ format?: "node_tree";
46
+ data: NodeTreeData;
47
+ };
48
+ export type NodeTreeData = {
49
+ id: string;
50
+ topic?: string;
51
+ expanded?: boolean;
52
+ direction?: "left" | "right";
53
+ data?: Record<string, any>;
54
+ children?: NodeTreeData[];
55
+ };
@@ -0,0 +1,84 @@
1
+ export default HistoryPlugin;
2
+ export type JsMind = import("../../jsmind.js").default;
3
+ /**
4
+ * HistoryPlugin skeleton (Task 1)
5
+ */
6
+ export class HistoryPlugin extends EnhancedPlugin {
7
+ /**
8
+ * @param {{ jm: JsMind, pluginOpt?: any }} params
9
+ */
10
+ constructor({ jm, pluginOpt }: {
11
+ jm: JsMind;
12
+ pluginOpt?: any;
13
+ });
14
+ options: any;
15
+ _mounted: boolean;
16
+ _core: HistoryCore;
17
+ /**
18
+ * Lifecycle hook: called when jsMind instance is destroyed
19
+ */
20
+ beforePluginDestroy(): void;
21
+ /** Default: call beforePluginRemove on destroy */
22
+ beforePluginDestroy(): void;
23
+ /** Initialize HistoryCore and wire API methods */
24
+ _initCore(): void;
25
+ _listener: (type: any, payload: any) => void;
26
+ /**
27
+ * Inject shortcut options so provider can register mapping in its init phase
28
+ * @param {{ enable?: boolean, handles: Record<string,Function>, mapping: Record<string, number|number[]> }} sc
29
+ * @param {boolean} redoUsesY
30
+ */
31
+ _injectShortcuts(sc: {
32
+ enable?: boolean;
33
+ handles: Record<string, Function>;
34
+ mapping: Record<string, number | number[]>;
35
+ }, redoUsesY: boolean): void;
36
+ /** Mount public API on jm.history (placeholder defaults) */
37
+ _mountAPI(): void;
38
+ }
39
+ import { EnhancedPlugin } from '../../jsmind.enhanced-plugin.js';
40
+ declare class HistoryCore {
41
+ /** @param {JsMind} jm @param {any} options */
42
+ constructor(jm: JsMind, options: any);
43
+ jm: import("../../jsmind.js").default;
44
+ options: any;
45
+ enabled: boolean;
46
+ maxHistory: number;
47
+ throttleMs: number;
48
+ storageMode: any;
49
+ autoSwitchThreshold: number;
50
+ _history: any[];
51
+ _idx: number;
52
+ _paused: boolean;
53
+ _lastAddAt: number;
54
+ _timer: number;
55
+ _pending: boolean;
56
+ _pendingMeta: any;
57
+ _lastSig: any;
58
+ add(reason: string, meta: any): void;
59
+ pause(): void;
60
+ resume(flush?: boolean): void;
61
+ clear(): void;
62
+ canBack(): boolean;
63
+ canForward(): boolean;
64
+ back(steps?: number): boolean;
65
+ forward(steps?: number): boolean;
66
+ length(): number;
67
+ index(): number;
68
+ setMax(count: any): void;
69
+ setThrottle(ms: any): void;
70
+ exportSnapshot(): any;
71
+ importSnapshot(data: any, applyOptions: any): boolean;
72
+ getStackMeta(): {
73
+ items: any[];
74
+ index: number;
75
+ };
76
+ _notifyChange(): void;
77
+ _addNow(_reason: any, _meta: any): void;
78
+ _applyIndex(): boolean;
79
+ _takeSnapshot(): any;
80
+ _applySnapshot(data: any, applyOptions: any): boolean;
81
+ _countNodes(snapshot: any): number;
82
+ _deepFreeze(obj: any): any;
83
+ _cloneSnapshot(obj: any): any;
84
+ }
@@ -13,10 +13,14 @@ export class DraggableNode {
13
13
  jm: import("../jsmind.js").default;
14
14
  /** @type {DraggableNodeOptions} */
15
15
  options: DraggableNodeOptions;
16
- /** @type {HTMLCanvasElement|null} */
17
- e_canvas: HTMLCanvasElement | null;
16
+ /** @type {boolean} */
17
+ is_svg_engine: boolean;
18
+ /** @type {HTMLCanvasElement|SVGSVGElement|null} */
19
+ e_canvas: HTMLCanvasElement | SVGSVGElement | null;
18
20
  /** @type {CanvasRenderingContext2D|null} */
19
21
  canvas_ctx: CanvasRenderingContext2D | null;
22
+ /** @type {SVGPathElement|null} */
23
+ helper_line: SVGPathElement | null;
20
24
  /** @type {HTMLElement|null} */
21
25
  shadow: HTMLElement | null;
22
26
  /** @type {number} */
@@ -57,10 +61,17 @@ export class DraggableNode {
57
61
  view_panel_rect: DOMRect | null;
58
62
  /** Initialize the draggable node plugin. */
59
63
  init(): void;
60
- /** Resize canvas and shadow elements. */
64
+ /** Resize canvas/SVG and shadow elements. */
61
65
  resize(): void;
62
- /** Create canvas for drawing drag lines. */
66
+ /** Create canvas or SVG for drawing drag lines. */
63
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;
64
75
  create_shadow(): void;
65
76
  /**
66
77
  * Reset shadow element style and cache its size.
@@ -84,16 +95,37 @@ export class DraggableNode {
84
95
  x: number;
85
96
  y: number;
86
97
  }, invalid: boolean): void;
87
- /** Clear helper lines from canvas. */
98
+ /** Clear helper lines from canvas or SVG. */
88
99
  clear_lines(): void;
89
100
  /**
90
- * Draw a straight helper line.
101
+ * Draw a straight helper line on canvas.
91
102
  * @param {number} x1
92
103
  * @param {number} y1
93
104
  * @param {number} x2
94
105
  * @param {number} y2
95
106
  */
96
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;
97
129
  /** Bind mouse/touch events for dragging. */
98
130
  event_bind(): void;
99
131
  /**