@umbraci/jsmind 0.10.17 → 1.0.0-beta
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 +7 -7
- 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.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.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.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 +262 -7
- 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.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 +26 -25
- package/types/generated/jsmind.d.ts +21 -24
- package/types/generated/jsmind.mind.d.ts +7 -0
- package/types/generated/{jsmind.enhanced-plugin.d.ts → jsmind.plugin-system.d.ts} +10 -10
- package/types/generated/jsmind.plugin.d.ts +93 -13
- package/types/generated/jsmind.view_provider.d.ts +1 -1
- package/types/generated/plugins/history/history-diff.d.ts +10 -0
- package/types/generated/plugins/history/jsmind.history.d.ts +2 -2
- package/types/generated/plugins/jsmind.draggable-node.d.ts +13 -3
- package/types/generated/plugins/jsmind.multi-select.d.ts +3 -3
- package/types/generated/plugins/jsmind.multiline-text.d.ts +67 -21
- package/types/generated/plugins/jsmind.screenshot.d.ts +12 -3
- package/types/tsconfig.declaration.json +6 -1
- package/dist/jsmind.copy-paste.js +0 -9
- package/dist/jsmind.copy-paste.js.map +0 -1
- package/es/jsmind.copy-paste.js +0 -9
- package/es/jsmind.copy-paste.js.map +0 -1
- package/types/generated/plugins/jsmind.multiline-text-v2.d.ts +0 -58
package/README.md
CHANGED
|
@@ -7,9 +7,9 @@ jsMind 是一个显示/编辑思维导图的纯 javascript 类库,其基于 ht
|
|
|
7
7
|
|
|
8
8
|
jsMind is mind map library built by javascript, it base on html5 canvas and svg. jsMind is released under [the BSD license](LICENSE), you can embed it in any project as long as you abide by the license.
|
|
9
9
|
|
|
10
|
-
## ✨ New Feature:
|
|
10
|
+
## ✨ New Feature: Plugin System
|
|
11
11
|
|
|
12
|
-
jsMind now supports a new
|
|
12
|
+
jsMind now supports a new plugin system with:
|
|
13
13
|
|
|
14
14
|
- **Synchronous Initialization**: Plugins initialize before rendering, allowing them to affect the initial render
|
|
15
15
|
- **Preload Support**: Control plugin initialization order (before or after core modules)
|
|
@@ -17,16 +17,16 @@ jsMind now supports a new enhanced plugin system with:
|
|
|
17
17
|
- **Dynamic Plugin Management**: Add or remove plugins at runtime
|
|
18
18
|
- **Backward Compatibility**: Works alongside the existing plugin system
|
|
19
19
|
|
|
20
|
-
See [
|
|
20
|
+
See [Plugin System Documentation](docs/plugin-system.md) for more information.
|
|
21
21
|
|
|
22
22
|
### Quick Example
|
|
23
23
|
|
|
24
24
|
```javascript
|
|
25
25
|
import jsMind from './jsmind.js';
|
|
26
|
-
import
|
|
26
|
+
import { MultilineTextPlugin } from './plugins/jsmind.multiline-text.js';
|
|
27
27
|
|
|
28
28
|
// Register plugin (before creating instance)
|
|
29
|
-
jsMind.usePlugin(
|
|
29
|
+
jsMind.usePlugin(MultilineTextPlugin, {
|
|
30
30
|
text_width: 250,
|
|
31
31
|
min_height: 40,
|
|
32
32
|
});
|
|
@@ -62,11 +62,11 @@ jm.show({
|
|
|
62
62
|
<link
|
|
63
63
|
type="text/css"
|
|
64
64
|
rel="stylesheet"
|
|
65
|
-
href="//cdn.jsdelivr.net/npm/jsmind@0.9.
|
|
65
|
+
href="//cdn.jsdelivr.net/npm/jsmind@0.9.1/style/jsmind.css"
|
|
66
66
|
/>
|
|
67
67
|
<script
|
|
68
68
|
type="text/javascript"
|
|
69
|
-
src="//cdn.jsdelivr.net/npm/jsmind@0.9.
|
|
69
|
+
src="//cdn.jsdelivr.net/npm/jsmind@0.9.1/es6/jsmind.js"
|
|
70
70
|
></script>
|
|
71
71
|
</head>
|
|
72
72
|
<body>
|
|
@@ -5,5 +5,5 @@
|
|
|
5
5
|
* Project Home:
|
|
6
6
|
* https://github.com/hizzgdev/jsmind/
|
|
7
7
|
*/
|
|
8
|
-
!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?e(exports,require("@umbraci/jsmind")):"function"==typeof define&&define.amd?define(["exports","@umbraci/jsmind"],e):e((t="undefined"!=typeof globalThis?globalThis:t||self).jsMindDraggableNode={},t.jsMind)}(this,function(t,e){"use strict";function i(t){return t&&"object"==typeof t&&"default"in t?t:{default:t}}var s=i(e);if(!s.default)throw new Error("jsMind is not defined");const o=s.default.$,n="getSelection"in o.w?function(){o.w.getSelection().removeAllRanges()}:function(){o.d.selection.empty()},h={line_width:5,line_color:"rgba(0,0,0,0.3)",line_color_invalid:"rgba(255,51,51,0.6)",lookup_delay:200,lookup_interval:100,scrolling_trigger_width:20,scrolling_step_length:10,shadow_node_class_name:"jsmind-draggable-shadow-node"};class l{constructor(t,e){var i={};s.default.util.json.merge(i,h),s.default.util.json.merge(i,e),this.version="0.4.0",this.jm=t,this.options=i,this.is_svg_engine="svg"===t.view.opts.engine,this.e_canvas=null,this.canvas_ctx=null,this.helper_line=null,this.shadow=null,this.shadow_p_x=0,this.shadow_p_y=0,this.shadow_w=0,this.shadow_h=0,this.active_node=null,this.target_node=null,this.target_direct=null,this.client_w=0,this.client_h=0,this.offset_x=0,this.offset_y=0,this.hlookup_delay=0,this.hlookup_timer=0,this.capture=!1,this.moved=!1,this.canvas_draggable=t.get_view_draggable(),this.view_panel=t.view.e_panel,this.view_panel_rect=null}init(){this.create_canvas(),this.create_shadow(),this.event_bind()}resize(){this.jm.view.e_nodes.appendChild(this.shadow),this.is_svg_engine?(this.e_canvas.setAttribute("width",this.jm.view.size.w),this.e_canvas.setAttribute("height",this.jm.view.size.h)):(this.e_canvas.width=this.jm.view.size.w,this.e_canvas.height=this.jm.view.size.h)}create_canvas(){if(this.is_svg_engine){var t=this._create_svg_element("svg");t.setAttribute("class","jsmind-draggable-helper"),t.setAttribute("style","position: absolute; top: 0; left: 0; pointer-events: none;"),this.jm.view.e_panel.appendChild(t),this.e_canvas=t}else{var e=o.c("canvas");this.jm.view.e_panel.appendChild(e);var i=e.getContext("2d");this.e_canvas=e,this.canvas_ctx=i}}_create_svg_element(t){return o.d.createElementNS("http://www.w3.org/2000/svg",t)}create_shadow(){var t=o.c("jmnode");t.style.visibility="hidden",t.style.zIndex="3",t.style.cursor="move",t.style.opacity="0.7",t.className=this.options.shadow_node_class_name,this.shadow=t}reset_shadow(t){var e=this.shadow.style;this.shadow.innerHTML=t.innerHTML,e.left=t.style.left,e.top=t.style.top,e.width=t.style.width,e.height=t.style.height,e.backgroundImage=t.style.backgroundImage,e.backgroundSize=t.style.backgroundSize,e.transform=t.style.transform,this.shadow_w=this.shadow.clientWidth,this.shadow_h=this.shadow.clientHeight}show_shadow(){this.moved||(this.shadow.style.visibility="visible")}hide_shadow(){this.shadow.style.visibility="hidden"}magnet_shadow(t,e,i){this.clear_lines();var s=i?this.options.line_color_invalid:this.options.line_color;this.is_svg_engine?this.svg_draw_line(t.x,t.y,e.x,e.y,s):(this.canvas_ctx.lineWidth=this.options.line_width,this.canvas_ctx.strokeStyle=s,this.canvas_ctx.lineCap="round",this.canvas_lineto(t.x,t.y,e.x,e.y))}clear_lines(){this.is_svg_engine?this.helper_line&&this.helper_line.parentNode&&(this.e_canvas.removeChild(this.helper_line),this.helper_line=null):this.canvas_ctx.clearRect(0,0,this.jm.view.size.w,this.jm.view.size.h)}canvas_lineto(t,e,i,s){this.canvas_ctx.beginPath(),this.canvas_ctx.moveTo(t,e),this.canvas_ctx.lineTo(i,s),this.canvas_ctx.stroke()}svg_draw_line(t,e,i,s,o){this.helper_line=this._create_svg_element("path"),this.helper_line.setAttribute("stroke",o),this.helper_line.setAttribute("stroke-width",this.options.line_width),this.helper_line.setAttribute("fill","transparent"),this.helper_line.setAttribute("stroke-linecap","round"),this._svg_bezier_to(this.helper_line,t,e,i,s),this.e_canvas.appendChild(this.helper_line)}_svg_bezier_to(t,e,i,s,o){t.setAttribute("d","M "+e+" "+i+" C "+(e+2*(s-e)/3)+" "+i+", "+e+" "+o+", "+s+" "+o)}event_bind(){var t=this,e=this.jm.view.container;o.on(e,"mousedown",function(e){0===e.button&&t.dragstart.call(t,e)}),o.on(e,"mousemove",function(e){0===e.movementX&&0===e.movementY||t.drag.call(t,e)}),o.on(e,"mouseup",function(e){t.dragend.call(t,e)}),o.on(e,"touchstart",function(e){t.dragstart.call(t,e)}),o.on(e,"touchmove",function(e){t.drag.call(t,e)}),o.on(e,"touchend",function(e){t.dragend.call(t,e)})}dragstart(t){if(this.jm.get_editable()&&!this.capture){var e=this.jm.view;if(!e.is_editing()){this.active_node=null,this.view_draggable=this.jm.get_view_draggable();var i=this.find_node_element(t.target);if(i){this.view_draggable&&this.jm.disable_view_draggable();var s=e.get_binded_nodeid(i);if(s){var n=this.jm.get_node(s);if(!n.isroot){if(n.data&&!1===n.data.draggable)return;this.reset_shadow(i),this.view_panel_rect=this.view_panel.getBoundingClientRect(),this.active_node=n,this.offset_x=(t.clientX||t.touches[0].clientX)/e.zoom_current-i.offsetLeft,this.offset_y=(t.clientY||t.touches[0].clientY)/e.zoom_current-i.offsetTop,this.client_hw=Math.floor(i.clientWidth/2),this.client_hh=Math.floor(i.clientHeight/2),0!=this.hlookup_delay&&o.w.clearTimeout(this.hlookup_delay),0!=this.hlookup_timer&&o.w.clearInterval(this.hlookup_timer);var h=this;this.hlookup_delay=o.w.setTimeout(function(){h.hlookup_delay=0,h.hlookup_timer=o.w.setInterval(function(){h.lookup_target_node.call(h)},h.options.lookup_interval)},this.options.lookup_delay),h.capture=!0}}}}}}drag(t){if(this.jm.get_editable()&&this.capture){t.preventDefault(),this.show_shadow(),this.moved=!0,n();var e=this.jm.view,i=(t.clientX||t.touches[0].clientX)/e.zoom_current-this.offset_x,s=(t.clientY||t.touches[0].clientY)/e.zoom_current-this.offset_y;t.clientY-this.view_panel_rect.top<this.options.scrolling_trigger_width&&this.view_panel.scrollTop>this.options.scrolling_step_length?(this.view_panel.scrollBy(0,-this.options.scrolling_step_length),this.offset_y+=this.options.scrolling_step_length/e.zoom_current):this.view_panel_rect.bottom-t.clientY<this.options.scrolling_trigger_width&&this.view_panel.scrollTop<this.view_panel.scrollHeight-this.view_panel_rect.height-this.options.scrolling_step_length&&(this.view_panel.scrollBy(0,this.options.scrolling_step_length),this.offset_y-=this.options.scrolling_step_length/e.zoom_current),t.clientX-this.view_panel_rect.left<this.options.scrolling_trigger_width&&this.view_panel.scrollLeft>this.options.scrolling_step_length?(this.view_panel.scrollBy(-this.options.scrolling_step_length,0),this.offset_x+=this.options.scrolling_step_length/e.zoom_current):this.view_panel_rect.right-t.clientX<this.options.scrolling_trigger_width&&this.view_panel.scrollLeft<this.view_panel.scrollWidth-this.view_panel_rect.width-this.options.scrolling_step_length&&(this.view_panel.scrollBy(this.options.scrolling_step_length,0),this.offset_x-=this.options.scrolling_step_length/e.zoom_current),this.shadow.style.left=i+"px",this.shadow.style.top=s+"px",n()}}dragend(t){if(this.jm.get_editable()){if(this.view_draggable&&this.jm.enable_view_draggable(),this.capture){if(0!=this.hlookup_delay&&(o.w.clearTimeout(this.hlookup_delay),this.hlookup_delay=0,this.clear_lines()),0!=this.hlookup_timer&&(o.w.clearInterval(this.hlookup_timer),this.hlookup_timer=0,this.clear_lines()),this.moved){var e=this.active_node,i=this.target_node,s=this.target_direct;this.move_node(e,i,s)}this.hide_shadow()}this.view_panel_rect=null,this.moved=!1,this.capture=!1}}find_node_element(t){return t===this.jm.view.e_nodes||t===this.jm.view.e_panel||t===this.jm.view.container?null:"jmnode"===t.tagName.toLowerCase()?t:this.find_node_element(t.parentNode)}lookup_target_node(){let t=this.shadow.offsetLeft,e=this.shadow.offsetTop;if(t===this.shadow_p_x&&e===this.shadow_p_y)return;this.shadow_p_x=t,this.shadow_p_y=e;let i=this.shadow_p_x+this.shadow_w/2>=this.get_root_x()?s.default.direction.right:s.default.direction.left,o=this.lookup_overlapping_node_parent(i)||this.lookup_close_node(i);if(o){let t=this.calc_point_of_node(o,i),e=s.default.node.inherited(this.active_node,o);this.magnet_shadow(t.sp,t.np,e),this.target_node=o,this.target_direct=i}}get_root_x(){let t=this.jm.get_root(),e=t.get_location(),i=t.get_size();return e.x+i.w/2}lookup_overlapping_node_parent(t){let e=this.shadow.getBoundingClientRect(),i=e.x+e.width*(1-t)/2,s=(this.jm.options.layout.hspace+this.jm.options.layout.pspace)*t,o=e.height,n=[[i,e.y],[i,e.y+o/2],[i,e.y+o],[i+s/2,e.y],[i+s/2,e.y+o/2],[i+s/2,e.y+o],[i+s,e.y],[i+s,e.y+o/2],[i+s,e.y+o]];for(const t of n){let e=this.lookup_node_parent_by_location(t[0],t[1]);if(e)return e}}lookup_node_parent_by_location(t,e){return o.d.elementsFromPoint(t,e).filter(t=>"JMNODE"===t.tagName&&t.className!==this.options.shadow_node_class_name).map(t=>this.jm.view.get_binded_nodeid(t)).map(t=>t&&this.jm.mind.nodes[t]).map(t=>t&&t.parent).find(t=>t)}lookup_close_node(t){return Object.values(this.jm.mind.nodes).filter(e=>e.direction==t||e.isroot).filter(t=>this.jm.layout.is_visible(t)).filter(e=>this.shadow_on_target_side(e,t)).map(e=>({node:e,distance:this.shadow_to_node(e,t)})).reduce((t,e)=>t.distance<e.distance?t:e,{node:this.jm.get_root(),distance:Number.MAX_VALUE}).node}shadow_on_target_side(t,e){return e==s.default.direction.right&&this.shadow_to_right_of_node(t)>0||e==s.default.direction.left&&this.shadow_to_left_of_node(t)>0}shadow_to_right_of_node(t){return this.shadow_p_x-t.get_location().x-t.get_size().w}shadow_to_left_of_node(t){return t.get_location().x-this.shadow_p_x-this.shadow_w}shadow_to_base_line_of_node(t){return this.shadow_p_y+this.shadow_h/2-t.get_location().y-t.get_size().h/2}shadow_to_node(t,e){return(e===s.default.direction.right?Math.abs(this.shadow_to_right_of_node(t)):Math.abs(this.shadow_to_left_of_node(t)))+Math.abs(this.shadow_to_base_line_of_node(t))}calc_point_of_node(t,e){let i=t.get_size(),s=t.get_location(),o=t.isroot?s.x+i.w/2:s.x+i.w*(1+e)/2+this.options.line_width*e,n=s.y+i.h/2;return{sp:{x:this.shadow_p_x+this.shadow_w*(1-e)/2-this.options.line_width*e,y:this.shadow_p_y+this.shadow_h/2},np:{x:o,y:n}}}move_node(t,e,i){var o=this.shadow.offsetTop;if(e&&t&&!s.default.node.inherited(t,e)){if(this.options.validate_drag&&"function"==typeof this.options.validate_drag){if(!this.options.validate_drag(t,e))return this.active_node=null,this.target_node=null,void(this.target_direct=null)}for(var n=e.children,h=n.length,l=null,a=Number.MAX_VALUE,_=null,r="_last_";h--;)if((l=n[h]).direction==i&&l.id!=t.id){var d=l.get_location().y-o;d>0&&d<a&&(a=d,_=l,r="_first_")}_&&(r=_.id),this.jm.move_node(t.id,r,e.id,i)}this.active_node=null,this.target_node=null,this.target_direct=null}jm_event_handle(t,e){t===s.default.event_type.resize&&this.resize()}}const a=new s.default.plugin("draggable_node",function(t,e){var i=new l(t,e);i.init(),t.add_event_listener(function(t,e){i.jm_event_handle.call(i,t,e)})});s.default.register_plugin(a),t.DraggableNode=l,t.default=l,t.draggable_plugin=a,Object.defineProperty(t,"__esModule",{value:!0})});
|
|
8
|
+
!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?e(exports,require("@umbraci/jsmind")):"function"==typeof define&&define.amd?define(["exports","@umbraci/jsmind"],e):e((t="undefined"!=typeof globalThis?globalThis:t||self).jsMindDraggableNode={},t.jsMind)}(this,function(t,e){"use strict";function i(t){return t&&"object"==typeof t&&"default"in t?t:{default:t}}var s=i(e);"function"!=typeof String.prototype.startsWith&&(String.prototype.startsWith=function(t){return this.slice(0,t.length)===t});class o{static instanceName="";static preload=!1;constructor({jm:t,pluginOpt:e}){this.jm=t,this.options=e||{}}beforePluginRemove(){}beforePluginDestroy(){this.beforePluginRemove()}}if(!s.default)throw new Error("jsMind is not defined");const n=s.default.$,h="getSelection"in n.w?function(){n.w.getSelection().removeAllRanges()}:function(){n.d.selection.empty()},l={line_width:5,line_color:"rgba(0,0,0,0.3)",line_color_invalid:"rgba(255,51,51,0.6)",lookup_delay:200,lookup_interval:100,scrolling_trigger_width:20,scrolling_step_length:10,shadow_node_class_name:"jsmind-draggable-shadow-node"};class a{constructor(t,e){var i={};s.default.util.json.merge(i,l),s.default.util.json.merge(i,e),this.version="0.4.0",this.jm=t,this.options=i,this.is_svg_engine="svg"===t.view.opts.engine,this.e_canvas=null,this.canvas_ctx=null,this.helper_line=null,this.shadow=null,this.shadow_p_x=0,this.shadow_p_y=0,this.shadow_w=0,this.shadow_h=0,this.active_node=null,this.target_node=null,this.target_direct=null,this.client_w=0,this.client_h=0,this.offset_x=0,this.offset_y=0,this.hlookup_delay=0,this.hlookup_timer=0,this.capture=!1,this.moved=!1,this.canvas_draggable=t.get_view_draggable(),this.view_panel=t.view.e_panel,this.view_panel_rect=null}init(){this.create_canvas(),this.create_shadow(),this.event_bind()}resize(){this.jm.view.e_nodes.appendChild(this.shadow),this.is_svg_engine?(this.e_canvas.setAttribute("width",this.jm.view.size.w),this.e_canvas.setAttribute("height",this.jm.view.size.h)):(this.e_canvas.width=this.jm.view.size.w,this.e_canvas.height=this.jm.view.size.h)}create_canvas(){if(this.is_svg_engine){var t=this._create_svg_element("svg");t.setAttribute("class","jsmind-draggable-helper"),t.setAttribute("style","position: absolute; top: 0; left: 0; pointer-events: none;"),this.jm.view.e_panel.appendChild(t),this.e_canvas=t}else{var e=n.c("canvas");this.jm.view.e_panel.appendChild(e);var i=e.getContext("2d");this.e_canvas=e,this.canvas_ctx=i}}_create_svg_element(t){return n.d.createElementNS("http://www.w3.org/2000/svg",t)}create_shadow(){var t=n.c("jmnode");t.style.visibility="hidden",t.style.zIndex="3",t.style.cursor="move",t.style.opacity="0.7",t.className=this.options.shadow_node_class_name,this.shadow=t}reset_shadow(t){var e=this.shadow.style,i=t.style,s=n.w.getComputedStyle(t);this.shadow.innerHTML=t.innerHTML;["left","top","width","height","backgroundImage","backgroundSize","transform"].forEach(t=>{e[t]=i[t]});["whiteSpace","wordBreak","overflowWrap","maxWidth"].forEach(t=>{e[t]=i[t]||s[t]}),this.shadow_w=this.shadow.clientWidth,this.shadow_h=this.shadow.clientHeight}show_shadow(){this.moved||(this.shadow.style.visibility="visible")}hide_shadow(){this.shadow.style.visibility="hidden"}magnet_shadow(t,e,i){this.clear_lines();var s=i?this.options.line_color_invalid:this.options.line_color;this.is_svg_engine?this.svg_draw_line(t.x,t.y,e.x,e.y,s):(this.canvas_ctx.lineWidth=this.options.line_width,this.canvas_ctx.strokeStyle=s,this.canvas_ctx.lineCap="round",this.canvas_lineto(t.x,t.y,e.x,e.y))}clear_lines(){this.is_svg_engine?this.helper_line&&this.helper_line.parentNode&&(this.e_canvas.removeChild(this.helper_line),this.helper_line=null):this.canvas_ctx.clearRect(0,0,this.jm.view.size.w,this.jm.view.size.h)}canvas_lineto(t,e,i,s){this.canvas_ctx.beginPath(),this.canvas_ctx.moveTo(t,e),this.canvas_ctx.lineTo(i,s),this.canvas_ctx.stroke()}svg_draw_line(t,e,i,s,o){this.helper_line=this._create_svg_element("path"),this.helper_line.setAttribute("stroke",o),this.helper_line.setAttribute("stroke-width",this.options.line_width),this.helper_line.setAttribute("fill","transparent"),this.helper_line.setAttribute("stroke-linecap","round"),this._svg_bezier_to(this.helper_line,t,e,i,s),this.e_canvas.appendChild(this.helper_line)}_svg_bezier_to(t,e,i,s,o){t.setAttribute("d","M "+e+" "+i+" C "+(e+2*(s-e)/3)+" "+i+", "+e+" "+o+", "+s+" "+o)}event_bind(){var t=this,e=this.jm.view.container;n.on(e,"mousedown",function(e){0===e.button&&t.dragstart.call(t,e)}),n.on(e,"mousemove",function(e){0===e.movementX&&0===e.movementY||t.drag.call(t,e)}),n.on(e,"mouseup",function(e){t.dragend.call(t,e)}),n.on(e,"touchstart",function(e){t.dragstart.call(t,e)}),n.on(e,"touchmove",function(e){t.drag.call(t,e)}),n.on(e,"touchend",function(e){t.dragend.call(t,e)})}dragstart(t){if(this.jm.get_editable()&&!this.capture){var e=this.jm.view;if(!e.is_editing()){this.active_node=null,this.view_draggable=this.jm.get_view_draggable();var i=this.find_node_element(t.target);if(i){this.view_draggable&&this.jm.disable_view_draggable();var s=e.get_binded_nodeid(i);if(s){var o=this.jm.get_node(s);if(!o.isroot){if(o.data&&!1===o.data.draggable)return;this.reset_shadow(i),this.view_panel_rect=this.view_panel.getBoundingClientRect(),this.active_node=o,this.offset_x=(t.clientX||t.touches[0].clientX)/e.zoom_current-i.offsetLeft,this.offset_y=(t.clientY||t.touches[0].clientY)/e.zoom_current-i.offsetTop,this.client_hw=Math.floor(i.clientWidth/2),this.client_hh=Math.floor(i.clientHeight/2),0!=this.hlookup_delay&&n.w.clearTimeout(this.hlookup_delay),0!=this.hlookup_timer&&n.w.clearInterval(this.hlookup_timer);var h=this;this.hlookup_delay=n.w.setTimeout(function(){h.hlookup_delay=0,h.hlookup_timer=n.w.setInterval(function(){h.lookup_target_node.call(h)},h.options.lookup_interval)},this.options.lookup_delay),h.capture=!0}}}}}}drag(t){if(this.jm.get_editable()&&this.capture){t.preventDefault(),this.show_shadow(),this.moved=!0,h();var e=this.jm.view,i=(t.clientX||t.touches[0].clientX)/e.zoom_current-this.offset_x,s=(t.clientY||t.touches[0].clientY)/e.zoom_current-this.offset_y;t.clientY-this.view_panel_rect.top<this.options.scrolling_trigger_width&&this.view_panel.scrollTop>this.options.scrolling_step_length?(this.view_panel.scrollBy(0,-this.options.scrolling_step_length),this.offset_y+=this.options.scrolling_step_length/e.zoom_current):this.view_panel_rect.bottom-t.clientY<this.options.scrolling_trigger_width&&this.view_panel.scrollTop<this.view_panel.scrollHeight-this.view_panel_rect.height-this.options.scrolling_step_length&&(this.view_panel.scrollBy(0,this.options.scrolling_step_length),this.offset_y-=this.options.scrolling_step_length/e.zoom_current),t.clientX-this.view_panel_rect.left<this.options.scrolling_trigger_width&&this.view_panel.scrollLeft>this.options.scrolling_step_length?(this.view_panel.scrollBy(-this.options.scrolling_step_length,0),this.offset_x+=this.options.scrolling_step_length/e.zoom_current):this.view_panel_rect.right-t.clientX<this.options.scrolling_trigger_width&&this.view_panel.scrollLeft<this.view_panel.scrollWidth-this.view_panel_rect.width-this.options.scrolling_step_length&&(this.view_panel.scrollBy(this.options.scrolling_step_length,0),this.offset_x-=this.options.scrolling_step_length/e.zoom_current),this.shadow.style.left=i+"px",this.shadow.style.top=s+"px",h()}}dragend(t){if(this.jm.get_editable()){if(this.view_draggable&&this.jm.enable_view_draggable(),this.capture){if(0!=this.hlookup_delay&&(n.w.clearTimeout(this.hlookup_delay),this.hlookup_delay=0,this.clear_lines()),0!=this.hlookup_timer&&(n.w.clearInterval(this.hlookup_timer),this.hlookup_timer=0,this.clear_lines()),this.moved){var e=this.active_node,i=this.target_node,s=this.target_direct;this.move_node(e,i,s)}this.hide_shadow()}this.view_panel_rect=null,this.moved=!1,this.capture=!1}}find_node_element(t){return t===this.jm.view.e_nodes||t===this.jm.view.e_panel||t===this.jm.view.container?null:"jmnode"===t.tagName.toLowerCase()?t:this.find_node_element(t.parentNode)}lookup_target_node(){let t=this.shadow.offsetLeft,e=this.shadow.offsetTop;if(t===this.shadow_p_x&&e===this.shadow_p_y)return;this.shadow_p_x=t,this.shadow_p_y=e;let i=this.shadow_p_x+this.shadow_w/2>=this.get_root_x()?s.default.direction.right:s.default.direction.left,o=this.lookup_overlapping_node_parent(i)||this.lookup_close_node(i);if(o){let t=this.calc_point_of_node(o,i),e=s.default.node.inherited(this.active_node,o);this.magnet_shadow(t.sp,t.np,e),this.target_node=o,this.target_direct=i}}get_root_x(){let t=this.jm.get_root(),e=t.get_location(),i=t.get_size();return e.x+i.w/2}lookup_overlapping_node_parent(t){let e=this.shadow.getBoundingClientRect(),i=e.x+e.width*(1-t)/2,s=(this.jm.options.layout.hspace+this.jm.options.layout.pspace)*t,o=e.height,n=[[i,e.y],[i,e.y+o/2],[i,e.y+o],[i+s/2,e.y],[i+s/2,e.y+o/2],[i+s/2,e.y+o],[i+s,e.y],[i+s,e.y+o/2],[i+s,e.y+o]];for(const t of n){let e=this.lookup_node_parent_by_location(t[0],t[1]);if(e)return e}}lookup_node_parent_by_location(t,e){return n.d.elementsFromPoint(t,e).filter(t=>"JMNODE"===t.tagName&&t.className!==this.options.shadow_node_class_name).map(t=>this.jm.view.get_binded_nodeid(t)).map(t=>t&&this.jm.mind.nodes[t]).map(t=>t&&t.parent).find(t=>t)}lookup_close_node(t){return Object.values(this.jm.mind.nodes).filter(e=>e.direction==t||e.isroot).filter(t=>this.jm.layout.is_visible(t)).filter(e=>this.shadow_on_target_side(e,t)).map(e=>({node:e,distance:this.shadow_to_node(e,t)})).reduce((t,e)=>t.distance<e.distance?t:e,{node:this.jm.get_root(),distance:Number.MAX_VALUE}).node}shadow_on_target_side(t,e){return e==s.default.direction.right&&this.shadow_to_right_of_node(t)>0||e==s.default.direction.left&&this.shadow_to_left_of_node(t)>0}shadow_to_right_of_node(t){return this.shadow_p_x-t.get_location().x-t.get_size().w}shadow_to_left_of_node(t){return t.get_location().x-this.shadow_p_x-this.shadow_w}shadow_to_base_line_of_node(t){return this.shadow_p_y+this.shadow_h/2-t.get_location().y-t.get_size().h/2}shadow_to_node(t,e){return(e===s.default.direction.right?Math.abs(this.shadow_to_right_of_node(t)):Math.abs(this.shadow_to_left_of_node(t)))+Math.abs(this.shadow_to_base_line_of_node(t))}calc_point_of_node(t,e){let i=t.get_size(),s=t.get_location(),o=t.isroot?s.x+i.w/2:s.x+i.w*(1+e)/2+this.options.line_width*e,n=s.y+i.h/2;return{sp:{x:this.shadow_p_x+this.shadow_w*(1-e)/2-this.options.line_width*e,y:this.shadow_p_y+this.shadow_h/2},np:{x:o,y:n}}}move_node(t,e,i){var o=this.shadow.offsetTop;if(e&&t&&!s.default.node.inherited(t,e)){if(this.options.validate_drag&&"function"==typeof this.options.validate_drag){if(!this.options.validate_drag(t,e))return this.active_node=null,this.target_node=null,void(this.target_direct=null)}for(var n=e.children,h=n.length,l=null,a=Number.MAX_VALUE,_=null,r="_last_";h--;)if((l=n[h]).direction==i&&l.id!=t.id){var d=l.get_location().y-o;d>0&&d<a&&(a=d,_=l,r="_first_")}_&&(r=_.id),this.jm.move_node(t.id,r,e.id,i)}this.active_node=null,this.target_node=null,this.target_direct=null}jm_event_handle(t,e){t===s.default.event_type.resize&&this.resize()}}class _ extends o{static instanceName="draggable";static preload=!1;constructor({jm:t,pluginOpt:e}){super({jm:t,pluginOpt:e}),this.draggable=new a(t,e),this.draggable.init(),this._eventHandle=(t,e)=>{this.draggable.jm_event_handle(t,e)},t.add_event_listener(this._eventHandle),t.draggable=this.draggable}beforePluginRemove(){delete this.jm.draggable}}s.default.usePlugin(_),t.DraggableNode=a,t.DraggableNodePlugin=_,t.default=a,Object.defineProperty(t,"__esModule",{value:!0})});
|
|
9
9
|
//# sourceMappingURL=jsmind.draggable-node.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"jsmind.draggable-node.js","sources":["../src/plugins/jsmind.draggable-node.js"],"sourcesContent":["/**\n * @license BSD\n * @copyright 2014-2025 UmbraCi\n *\n * Project Home:\n * https://github.com/UmbraCi/jsmind/\n */\n\nimport jsMind from '@umbraci/jsmind';\n\nif (!jsMind) {\n throw new Error('jsMind is not defined');\n}\n\nconst $ = jsMind.$;\n\nconst clear_selection =\n 'getSelection' in $.w\n ? function () {\n $.w.getSelection().removeAllRanges();\n }\n : function () {\n $.d.selection.empty();\n };\n\n/**\n * Default options for draggable node plugin.\n * @typedef {Object} DraggableNodeOptions\n * @property {number} [line_width]\n * @property {string} [line_color]\n * @property {string} [line_color_invalid]\n * @property {number} [lookup_delay]\n * @property {number} [lookup_interval]\n * @property {number} [scrolling_trigger_width]\n * @property {number} [scrolling_step_length]\n * @property {string} [shadow_node_class_name]\n * @property {(draggedNode:import('../jsmind.node.js').Node, targetNode:import('../jsmind.node.js').Node|null)=>boolean} [validate_drag]\n */\nconst DEFAULT_OPTIONS = {\n line_width: 5,\n line_color: 'rgba(0,0,0,0.3)',\n line_color_invalid: 'rgba(255,51,51,0.6)',\n lookup_delay: 200,\n lookup_interval: 100,\n scrolling_trigger_width: 20,\n scrolling_step_length: 10,\n shadow_node_class_name: 'jsmind-draggable-shadow-node',\n};\n\n/**\n * Draggable node plugin for jsMind.\n */\nexport class DraggableNode {\n /**\n * Create draggable node plugin instance.\n * @param {import('../jsmind.js').default} jm - jsMind instance\n * @param {Partial<DraggableNodeOptions>} options - Plugin options\n */\n constructor(jm, options) {\n var opts = {};\n jsMind.util.json.merge(opts, DEFAULT_OPTIONS);\n jsMind.util.json.merge(opts, options);\n\n this.version = '0.4.0';\n /** @type {import('../jsmind.js').default} */\n this.jm = jm;\n /** @type {DraggableNodeOptions} */\n this.options = opts;\n /** @type {boolean} */\n this.is_svg_engine = jm.view.opts.engine === 'svg';\n /** @type {HTMLCanvasElement|SVGSVGElement|null} */\n this.e_canvas = null;\n /** @type {CanvasRenderingContext2D|null} */\n this.canvas_ctx = null;\n /** @type {SVGPathElement|null} */\n this.helper_line = null;\n /** @type {HTMLElement|null} */\n this.shadow = null;\n /** @type {number} */\n this.shadow_p_x = 0;\n /** @type {number} */\n this.shadow_p_y = 0;\n /** @type {number} */\n this.shadow_w = 0;\n /** @type {number} */\n this.shadow_h = 0;\n /** @type {import('../jsmind.node.js').Node|null} */\n this.active_node = null;\n /** @type {import('../jsmind.node.js').Node|null} */\n this.target_node = null;\n /** @type {number|null} */\n this.target_direct = null;\n /** @type {number} */\n this.client_w = 0;\n /** @type {number} */\n this.client_h = 0;\n /** @type {number} */\n this.offset_x = 0;\n /** @type {number} */\n this.offset_y = 0;\n /** @type {number} */\n this.hlookup_delay = 0;\n /** @type {number} */\n this.hlookup_timer = 0;\n /** @type {boolean} */\n this.capture = false;\n /** @type {boolean} */\n this.moved = false;\n /** @type {boolean} */\n this.canvas_draggable = jm.get_view_draggable();\n /** @type {HTMLElement} */\n this.view_panel = jm.view.e_panel;\n /** @type {DOMRect|null} */\n this.view_panel_rect = null;\n }\n /** Initialize the draggable node plugin. */\n init() {\n this.create_canvas();\n this.create_shadow();\n this.event_bind();\n }\n /** Resize canvas/SVG and shadow elements. */\n resize() {\n this.jm.view.e_nodes.appendChild(this.shadow);\n if (this.is_svg_engine) {\n this.e_canvas.setAttribute('width', this.jm.view.size.w);\n this.e_canvas.setAttribute('height', this.jm.view.size.h);\n } else {\n this.e_canvas.width = this.jm.view.size.w;\n this.e_canvas.height = this.jm.view.size.h;\n }\n }\n /** Create canvas or SVG for drawing drag lines. */\n create_canvas() {\n if (this.is_svg_engine) {\n // Create SVG element for helper lines\n var svg = this._create_svg_element('svg');\n svg.setAttribute('class', 'jsmind-draggable-helper');\n svg.setAttribute('style', 'position: absolute; top: 0; left: 0; pointer-events: none;');\n this.jm.view.e_panel.appendChild(svg);\n this.e_canvas = svg;\n } else {\n // Create Canvas element for helper lines\n var c = $.c('canvas');\n this.jm.view.e_panel.appendChild(c);\n var ctx = c.getContext('2d');\n this.e_canvas = c;\n this.canvas_ctx = ctx;\n }\n }\n /**\n * Create SVG element with proper namespace.\n * @param {string} tag - SVG tag name\n * @returns {SVGElement}\n * @private\n */\n _create_svg_element(tag) {\n return $.d.createElementNS('http://www.w3.org/2000/svg', tag);\n }\n create_shadow() {\n var s = $.c('jmnode');\n s.style.visibility = 'hidden';\n s.style.zIndex = '3';\n s.style.cursor = 'move';\n s.style.opacity = '0.7';\n s.className = this.options.shadow_node_class_name;\n this.shadow = s;\n }\n /**\n * Reset shadow element style and cache its size.\n * @param {HTMLElement} el - The node element to mirror as shadow\n */\n reset_shadow(el) {\n var s = this.shadow.style;\n this.shadow.innerHTML = el.innerHTML;\n s.left = el.style.left;\n s.top = el.style.top;\n s.width = el.style.width;\n s.height = el.style.height;\n s.backgroundImage = el.style.backgroundImage;\n s.backgroundSize = el.style.backgroundSize;\n s.transform = el.style.transform;\n this.shadow_w = this.shadow.clientWidth;\n this.shadow_h = this.shadow.clientHeight;\n }\n /** Show the shadow element. */\n show_shadow() {\n if (!this.moved) {\n this.shadow.style.visibility = 'visible';\n }\n }\n /** Hide the shadow element. */\n hide_shadow() {\n this.shadow.style.visibility = 'hidden';\n }\n /**\n * Draw a helper line between the shadow and target node.\n * @param {{x:number,y:number}} shadow_p - Shadow anchor point\n * @param {{x:number,y:number}} node_p - Target node anchor point\n * @param {boolean} invalid - Whether current target is invalid\n */\n magnet_shadow(shadow_p, node_p, invalid) {\n this.clear_lines();\n var color = invalid ? this.options.line_color_invalid : this.options.line_color;\n\n if (this.is_svg_engine) {\n this.svg_draw_line(shadow_p.x, shadow_p.y, node_p.x, node_p.y, color);\n } else {\n this.canvas_ctx.lineWidth = this.options.line_width;\n this.canvas_ctx.strokeStyle = color;\n this.canvas_ctx.lineCap = 'round';\n this.canvas_lineto(shadow_p.x, shadow_p.y, node_p.x, node_p.y);\n }\n }\n /** Clear helper lines from canvas or SVG. */\n clear_lines() {\n if (this.is_svg_engine) {\n if (this.helper_line && this.helper_line.parentNode) {\n this.e_canvas.removeChild(this.helper_line);\n this.helper_line = null;\n }\n } else {\n this.canvas_ctx.clearRect(0, 0, this.jm.view.size.w, this.jm.view.size.h);\n }\n }\n /**\n * Draw a straight helper line on canvas.\n * @param {number} x1\n * @param {number} y1\n * @param {number} x2\n * @param {number} y2\n */\n canvas_lineto(x1, y1, x2, y2) {\n this.canvas_ctx.beginPath();\n this.canvas_ctx.moveTo(x1, y1);\n this.canvas_ctx.lineTo(x2, y2);\n this.canvas_ctx.stroke();\n }\n /**\n * Draw a helper line on SVG using bezier curve.\n * Reuses the line drawing logic from SvgGraph.\n * @param {number} x1 - Start x coordinate\n * @param {number} y1 - Start y coordinate\n * @param {number} x2 - End x coordinate\n * @param {number} y2 - End y coordinate\n * @param {string} color - Line color\n */\n svg_draw_line(x1, y1, x2, y2, color) {\n // Create SVG path element for helper line\n this.helper_line = this._create_svg_element('path');\n this.helper_line.setAttribute('stroke', color);\n this.helper_line.setAttribute('stroke-width', this.options.line_width);\n this.helper_line.setAttribute('fill', 'transparent');\n this.helper_line.setAttribute('stroke-linecap', 'round');\n\n // Draw bezier curve (same as SvgGraph._bezier_to)\n this._svg_bezier_to(this.helper_line, x1, y1, x2, y2);\n\n // Add to SVG container\n this.e_canvas.appendChild(this.helper_line);\n }\n /**\n * Draw bezier curve to SVG path element.\n * Reuses logic from SvgGraph._bezier_to.\n * @param {SVGPathElement} path - SVG path element\n * @param {number} x1 - Start x coordinate\n * @param {number} y1 - Start y coordinate\n * @param {number} x2 - End x coordinate\n * @param {number} y2 - End y coordinate\n * @private\n */\n _svg_bezier_to(path, x1, y1, x2, y2) {\n path.setAttribute(\n 'd',\n 'M ' +\n x1 +\n ' ' +\n y1 +\n ' C ' +\n (x1 + ((x2 - x1) * 2) / 3) +\n ' ' +\n y1 +\n ', ' +\n x1 +\n ' ' +\n y2 +\n ', ' +\n x2 +\n ' ' +\n y2\n );\n }\n /** Bind mouse/touch events for dragging. */\n event_bind() {\n var jd = this;\n var container = this.jm.view.container;\n $.on(container, 'mousedown', function (e) {\n if (e.button === 0) {\n jd.dragstart.call(jd, e);\n }\n });\n $.on(container, 'mousemove', function (e) {\n if (e.movementX !== 0 || e.movementY !== 0) {\n jd.drag.call(jd, e);\n }\n });\n $.on(container, 'mouseup', function (e) {\n jd.dragend.call(jd, e);\n });\n $.on(container, 'touchstart', function (e) {\n jd.dragstart.call(jd, e);\n });\n $.on(container, 'touchmove', function (e) {\n jd.drag.call(jd, e);\n });\n $.on(container, 'touchend', function (e) {\n jd.dragend.call(jd, e);\n });\n }\n /**\n * Begin dragging interaction.\n * @param {MouseEvent|TouchEvent} e - Pointer down event\n */\n dragstart(e) {\n if (!this.jm.get_editable()) {\n return;\n }\n if (this.capture) {\n return;\n }\n var jview = this.jm.view;\n if (jview.is_editing()) {\n return;\n }\n this.active_node = null;\n this.view_draggable = this.jm.get_view_draggable();\n\n var el = this.find_node_element(e.target);\n if (!el) {\n return;\n }\n if (this.view_draggable) {\n this.jm.disable_view_draggable();\n }\n var nodeid = jview.get_binded_nodeid(el);\n if (!!nodeid) {\n var node = this.jm.get_node(nodeid);\n if (!node.isroot) {\n // 检查节点是否允许拖拽\n if (node.data && node.data.draggable === false) {\n return;\n }\n this.reset_shadow(el);\n this.view_panel_rect = this.view_panel.getBoundingClientRect();\n this.active_node = node;\n this.offset_x =\n (e.clientX || e.touches[0].clientX) / jview.zoom_current - el.offsetLeft;\n this.offset_y =\n (e.clientY || e.touches[0].clientY) / jview.zoom_current - el.offsetTop;\n this.client_hw = Math.floor(el.clientWidth / 2);\n this.client_hh = Math.floor(el.clientHeight / 2);\n if (this.hlookup_delay != 0) {\n $.w.clearTimeout(this.hlookup_delay);\n }\n if (this.hlookup_timer != 0) {\n $.w.clearInterval(this.hlookup_timer);\n }\n var jd = this;\n this.hlookup_delay = $.w.setTimeout(function () {\n jd.hlookup_delay = 0;\n jd.hlookup_timer = $.w.setInterval(function () {\n jd.lookup_target_node.call(jd);\n }, jd.options.lookup_interval);\n }, this.options.lookup_delay);\n jd.capture = true;\n }\n }\n }\n /**\n * Drag handler to move shadow and auto-scroll container.\n * @param {MouseEvent|TouchEvent} e - Pointer move event\n */\n drag(e) {\n if (!this.jm.get_editable()) {\n return;\n }\n if (this.capture) {\n e.preventDefault();\n this.show_shadow();\n this.moved = true;\n clear_selection();\n var jview = this.jm.view;\n var px = (e.clientX || e.touches[0].clientX) / jview.zoom_current - this.offset_x;\n var py = (e.clientY || e.touches[0].clientY) / jview.zoom_current - this.offset_y;\n // scrolling container axisY if drag nodes exceeding container\n if (\n e.clientY - this.view_panel_rect.top < this.options.scrolling_trigger_width &&\n this.view_panel.scrollTop > this.options.scrolling_step_length\n ) {\n this.view_panel.scrollBy(0, -this.options.scrolling_step_length);\n this.offset_y += this.options.scrolling_step_length / jview.zoom_current;\n } else if (\n this.view_panel_rect.bottom - e.clientY < this.options.scrolling_trigger_width &&\n this.view_panel.scrollTop <\n this.view_panel.scrollHeight -\n this.view_panel_rect.height -\n this.options.scrolling_step_length\n ) {\n this.view_panel.scrollBy(0, this.options.scrolling_step_length);\n this.offset_y -= this.options.scrolling_step_length / jview.zoom_current;\n }\n // scrolling container axisX if drag nodes exceeding container\n if (\n e.clientX - this.view_panel_rect.left < this.options.scrolling_trigger_width &&\n this.view_panel.scrollLeft > this.options.scrolling_step_length\n ) {\n this.view_panel.scrollBy(-this.options.scrolling_step_length, 0);\n this.offset_x += this.options.scrolling_step_length / jview.zoom_current;\n } else if (\n this.view_panel_rect.right - e.clientX < this.options.scrolling_trigger_width &&\n this.view_panel.scrollLeft <\n this.view_panel.scrollWidth -\n this.view_panel_rect.width -\n this.options.scrolling_step_length\n ) {\n this.view_panel.scrollBy(this.options.scrolling_step_length, 0);\n this.offset_x -= this.options.scrolling_step_length / jview.zoom_current;\n }\n this.shadow.style.left = px + 'px';\n this.shadow.style.top = py + 'px';\n clear_selection();\n }\n }\n /**\n * Finish dragging, move the node if applicable.\n * @param {MouseEvent|TouchEvent} e - Pointer up event\n */\n dragend(e) {\n if (!this.jm.get_editable()) {\n return;\n }\n if (this.view_draggable) {\n this.jm.enable_view_draggable();\n }\n if (this.capture) {\n if (this.hlookup_delay != 0) {\n $.w.clearTimeout(this.hlookup_delay);\n this.hlookup_delay = 0;\n this.clear_lines();\n }\n if (this.hlookup_timer != 0) {\n $.w.clearInterval(this.hlookup_timer);\n this.hlookup_timer = 0;\n this.clear_lines();\n }\n if (this.moved) {\n var src_node = this.active_node;\n var target_node = this.target_node;\n var target_direct = this.target_direct;\n this.move_node(src_node, target_node, target_direct);\n }\n this.hide_shadow();\n }\n this.view_panel_rect = null;\n this.moved = false;\n this.capture = false;\n }\n /**\n * Find the closest node element from an event target.\n * @param {HTMLElement} el - Current DOM element\n * @returns {HTMLElement|null} Matched node element or null\n */\n find_node_element(el) {\n if (\n el === this.jm.view.e_nodes ||\n el === this.jm.view.e_panel ||\n el === this.jm.view.container\n ) {\n return null;\n }\n if (el.tagName.toLowerCase() === 'jmnode') {\n return el;\n }\n return this.find_node_element(el.parentNode);\n }\n /** Recompute target node under the shadow and draw helper. */\n lookup_target_node() {\n let sx = this.shadow.offsetLeft;\n let sy = this.shadow.offsetTop;\n if (sx === this.shadow_p_x && sy === this.shadow_p_y) {\n return;\n }\n this.shadow_p_x = sx;\n this.shadow_p_y = sy;\n\n let target_direction =\n this.shadow_p_x + this.shadow_w / 2 >= this.get_root_x()\n ? jsMind.direction.right\n : jsMind.direction.left;\n let overlapping_node = this.lookup_overlapping_node_parent(target_direction);\n let target_node = overlapping_node || this.lookup_close_node(target_direction);\n if (!!target_node) {\n let points = this.calc_point_of_node(target_node, target_direction);\n let invalid = jsMind.node.inherited(this.active_node, target_node);\n this.magnet_shadow(points.sp, points.np, invalid);\n this.target_node = target_node;\n this.target_direct = target_direction;\n }\n }\n /**\n * Get X coordinate of root node center.\n * @returns {number}\n */\n get_root_x() {\n let root = this.jm.get_root();\n let root_location = root.get_location();\n let root_size = root.get_size();\n return root_location.x + root_size.w / 2;\n }\n\n /**\n * Lookup overlapping node's parent near the shadow position.\n * @param {number} direction - Direction constant\n * @returns {import('../jsmind.node.js').Node|null}\n */\n lookup_overlapping_node_parent(direction) {\n let shadowRect = this.shadow.getBoundingClientRect();\n let x = shadowRect.x + (shadowRect.width * (1 - direction)) / 2;\n let deltaX = (this.jm.options.layout.hspace + this.jm.options.layout.pspace) * direction;\n let deltaY = shadowRect.height;\n let points = [\n [x, shadowRect.y],\n [x, shadowRect.y + deltaY / 2],\n [x, shadowRect.y + deltaY],\n [x + deltaX / 2, shadowRect.y],\n [x + deltaX / 2, shadowRect.y + deltaY / 2],\n [x + deltaX / 2, shadowRect.y + deltaY],\n [x + deltaX, shadowRect.y],\n [x + deltaX, shadowRect.y + deltaY / 2],\n [x + deltaX, shadowRect.y + deltaY],\n ];\n for (const p of points) {\n let n = this.lookup_node_parent_by_location(p[0], p[1]);\n if (!!n) {\n return n;\n }\n }\n }\n\n /**\n * Find node's parent by a screen location.\n * @param {number} x - Client X\n * @param {number} y - Client Y\n * @returns {import('../jsmind.node.js').Node|null}\n */\n lookup_node_parent_by_location(x, y) {\n return $.d\n .elementsFromPoint(x, y)\n .filter(\n x => x.tagName === 'JMNODE' && x.className !== this.options.shadow_node_class_name\n )\n .map(el => this.jm.view.get_binded_nodeid(el))\n .map(id => id && this.jm.mind.nodes[id])\n .map(n => n && n.parent)\n .find(n => n);\n }\n\n /**\n * Lookup the closest node along a direction.\n * @param {number} direction\n * @returns {import('../jsmind.node.js').Node}\n */\n lookup_close_node(direction) {\n return Object.values(this.jm.mind.nodes)\n .filter(n => n.direction == direction || n.isroot)\n .filter(n => this.jm.layout.is_visible(n))\n .filter(n => this.shadow_on_target_side(n, direction))\n .map(n => ({ node: n, distance: this.shadow_to_node(n, direction) }))\n .reduce(\n (prev, curr) => {\n return prev.distance < curr.distance ? prev : curr;\n },\n { node: this.jm.get_root(), distance: Number.MAX_VALUE }\n ).node;\n }\n\n /**\n * Check if shadow is on the target side of a node.\n * @param {import('../jsmind.node.js').Node} node\n * @param {number} dir\n * @returns {boolean}\n */\n shadow_on_target_side(node, dir) {\n return (\n (dir == jsMind.direction.right && this.shadow_to_right_of_node(node) > 0) ||\n (dir == jsMind.direction.left && this.shadow_to_left_of_node(node) > 0)\n );\n }\n\n /**\n * Distance from shadow to the right side of a node.\n * @param {import('../jsmind.node.js').Node} node\n * @returns {number}\n */\n shadow_to_right_of_node(node) {\n return this.shadow_p_x - node.get_location().x - node.get_size().w;\n }\n\n /**\n * Distance from shadow to the left side of a node.\n * @param {import('../jsmind.node.js').Node} node\n * @returns {number}\n */\n shadow_to_left_of_node(node) {\n return node.get_location().x - this.shadow_p_x - this.shadow_w;\n }\n\n /**\n * Vertical distance between shadow centerline and node centerline.\n * @param {import('../jsmind.node.js').Node} node\n * @returns {number}\n */\n shadow_to_base_line_of_node(node) {\n return this.shadow_p_y + this.shadow_h / 2 - node.get_location().y - node.get_size().h / 2;\n }\n\n /**\n * Manhattan distance to a node along a direction.\n * @param {import('../jsmind.node.js').Node} node\n * @param {number} dir\n * @returns {number}\n */\n shadow_to_node(node, dir) {\n let distance_x =\n dir === jsMind.direction.right\n ? Math.abs(this.shadow_to_right_of_node(node))\n : Math.abs(this.shadow_to_left_of_node(node));\n let distance_y = Math.abs(this.shadow_to_base_line_of_node(node));\n return distance_x + distance_y;\n }\n\n /**\n * Calculate connection points of a node and the shadow.\n * @param {import('../jsmind.node.js').Node} node\n * @param {number} dir\n * @returns {{sp:{x:number,y:number}, np:{x:number,y:number}}}\n */\n calc_point_of_node(node, dir) {\n let ns = node.get_size();\n let nl = node.get_location();\n let node_x = node.isroot\n ? nl.x + ns.w / 2\n : nl.x + (ns.w * (1 + dir)) / 2 + this.options.line_width * dir;\n let node_y = nl.y + ns.h / 2;\n let shadow_x =\n this.shadow_p_x + (this.shadow_w * (1 - dir)) / 2 - this.options.line_width * dir;\n let shadow_y = this.shadow_p_y + this.shadow_h / 2;\n return {\n sp: { x: shadow_x, y: shadow_y },\n np: { x: node_x, y: node_y },\n };\n }\n\n /**\n * Move a node to a new parent/position.\n * @param {import('../jsmind.node.js').Node} src_node\n * @param {import('../jsmind.node.js').Node|null} target_node\n * @param {number|null} target_direct\n */\n move_node(src_node, target_node, target_direct) {\n var shadow_h = this.shadow.offsetTop;\n if (!!target_node && !!src_node && !jsMind.node.inherited(src_node, target_node)) {\n // Call validate_drag function if provided, to validate the drag operation\n if (this.options.validate_drag && typeof this.options.validate_drag === 'function') {\n const isValid = this.options.validate_drag(src_node, target_node);\n if (!isValid) {\n // Drag operation is not allowed, cleanup and return\n this.active_node = null;\n this.target_node = null;\n this.target_direct = null;\n return;\n }\n }\n\n // lookup before_node\n var sibling_nodes = target_node.children;\n var sc = sibling_nodes.length;\n var node = null;\n var delta_y = Number.MAX_VALUE;\n var node_before = null;\n var beforeid = '_last_';\n while (sc--) {\n node = sibling_nodes[sc];\n if (node.direction == target_direct && node.id != src_node.id) {\n var dy = node.get_location().y - shadow_h;\n if (dy > 0 && dy < delta_y) {\n delta_y = dy;\n node_before = node;\n beforeid = '_first_';\n }\n }\n }\n if (!!node_before) {\n beforeid = node_before.id;\n }\n this.jm.move_node(src_node.id, beforeid, target_node.id, target_direct);\n }\n this.active_node = null;\n this.target_node = null;\n this.target_direct = null;\n }\n /**\n * Handle jsMind events.\n * @param {number|string} type - Event type\n * @param {object} [data] - Event data\n */\n jm_event_handle(type, data) {\n if (type === jsMind.event_type.resize) {\n this.resize();\n }\n }\n}\n\n/**\n * Draggable node plugin registration.\n * @type {import('../jsmind.plugin.js').Plugin<Partial<DraggableNodeOptions>>}\n */\nexport const draggable_plugin = new jsMind.plugin('draggable_node', function (jm, options) {\n var jd = new DraggableNode(jm, options);\n jd.init();\n jm.add_event_listener(function (type, data) {\n jd.jm_event_handle.call(jd, type, data);\n });\n});\n\njsMind.register_plugin(draggable_plugin);\n\nexport default DraggableNode;\n"],"names":["jsMind","Error","$","clear_selection","w","getSelection","removeAllRanges","d","selection","empty","DEFAULT_OPTIONS","line_width","line_color","line_color_invalid","lookup_delay","lookup_interval","scrolling_trigger_width","scrolling_step_length","shadow_node_class_name","DraggableNode","constructor","jm","options","opts","util","json","merge","this","version","is_svg_engine","view","engine","e_canvas","canvas_ctx","helper_line","shadow","shadow_p_x","shadow_p_y","shadow_w","shadow_h","active_node","target_node","target_direct","client_w","client_h","offset_x","offset_y","hlookup_delay","hlookup_timer","capture","moved","canvas_draggable","get_view_draggable","view_panel","e_panel","view_panel_rect","init","create_canvas","create_shadow","event_bind","resize","e_nodes","appendChild","setAttribute","size","h","width","height","svg","_create_svg_element","c","ctx","getContext","tag","createElementNS","s","style","visibility","zIndex","cursor","opacity","className","reset_shadow","el","innerHTML","left","top","backgroundImage","backgroundSize","transform","clientWidth","clientHeight","show_shadow","hide_shadow","magnet_shadow","shadow_p","node_p","invalid","clear_lines","color","svg_draw_line","x","y","lineWidth","strokeStyle","lineCap","canvas_lineto","parentNode","removeChild","clearRect","x1","y1","x2","y2","beginPath","moveTo","lineTo","stroke","_svg_bezier_to","path","jd","container","on","e","button","dragstart","call","movementX","movementY","drag","dragend","get_editable","jview","is_editing","view_draggable","find_node_element","target","disable_view_draggable","nodeid","get_binded_nodeid","node","get_node","isroot","data","draggable","getBoundingClientRect","clientX","touches","zoom_current","offsetLeft","clientY","offsetTop","client_hw","Math","floor","client_hh","clearTimeout","clearInterval","setTimeout","setInterval","lookup_target_node","preventDefault","px","py","scrollTop","scrollBy","bottom","scrollHeight","scrollLeft","right","scrollWidth","enable_view_draggable","src_node","move_node","tagName","toLowerCase","sx","sy","target_direction","get_root_x","direction","lookup_overlapping_node_parent","lookup_close_node","points","calc_point_of_node","inherited","sp","np","root","get_root","root_location","get_location","root_size","get_size","shadowRect","deltaX","layout","hspace","pspace","deltaY","p","n","lookup_node_parent_by_location","elementsFromPoint","filter","map","id","mind","nodes","parent","find","Object","values","is_visible","shadow_on_target_side","distance","shadow_to_node","reduce","prev","curr","Number","MAX_VALUE","dir","shadow_to_right_of_node","shadow_to_left_of_node","shadow_to_base_line_of_node","abs","ns","nl","node_x","node_y","validate_drag","sibling_nodes","children","sc","length","delta_y","node_before","beforeid","dy","jm_event_handle","type","event_type","draggable_plugin","plugin","add_event_listener","register_plugin"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"jsmind.draggable-node.js","sources":["../src/jsmind.common.js","../src/jsmind.plugin.js","../src/plugins/jsmind.draggable-node.js"],"sourcesContent":["/**\n * @license BSD\n * @copyright 2014-2025 UmbraCi\n *\n * Project Home:\n * https://github.com/UmbraCi/jsmind/\n */\n\n/**\n * Library version string.\n * @type {string}\n */\nexport const __version__ = '0.9.1';\n/**\n * Library author.\n * @type {string}\n */\nexport const __author__ = 'UmbraCi';\n\nif (typeof String.prototype.startsWith != 'function') {\n String.prototype.startsWith = function (p) {\n return this.slice(0, p.length) === p;\n };\n}\n\n/**\n * Direction constants and parser.\n * @typedef {{left:number,center:number,right:number,of:(dir:(string|number))=>number|undefined}} DirectionType\n */\n/** @type {DirectionType} */\nexport const Direction = {\n left: -1,\n center: 0,\n right: 1,\n of: function (dir) {\n if (!dir || dir === -1 || dir === 0 || dir === 1) {\n return dir;\n }\n if (dir === '-1' || dir === '0' || dir === '1') {\n return parseInt(dir);\n }\n if (dir.toLowerCase() === 'left') {\n return this.left;\n }\n if (dir.toLowerCase() === 'right') {\n return this.right;\n }\n if (dir.toLowerCase() === 'center') {\n return this.center;\n }\n },\n};\n/** @enum {number} */\nexport const EventType = { show: 1, resize: 2, edit: 3, select: 4, reset: 5, history_change: 6 };\n/** @enum {number} */\nexport const Key = { meta: 1 << 13, ctrl: 1 << 12, alt: 1 << 11, shift: 1 << 10 };\n/** @enum {number} */\nexport const LogLevel = { debug: 1, info: 2, warn: 3, error: 4, disable: 9 };\n\n// an noop function define\nvar _noop = function () {};\n/**\n * Logger facade with dynamic level.\n * @type {{level:(lvl:number)=>void,log:Function,debug:Function,info:Function,warn:Function,error:Function}}\n */\nexport let logger =\n typeof console === 'undefined'\n ? {\n level: _noop,\n log: _noop,\n debug: _noop,\n info: _noop,\n warn: _noop,\n error: _noop,\n }\n : {\n level: setup_logger_level,\n log: console.log,\n debug: console.debug,\n info: console.info,\n warn: console.warn,\n error: console.error,\n };\n\n/**\n * Set logger level.\n * @param {number} log_level\n */\nfunction setup_logger_level(log_level) {\n if (log_level > LogLevel.debug) {\n logger.debug = _noop;\n } else {\n logger.debug = console.debug;\n }\n if (log_level > LogLevel.info) {\n logger.info = _noop;\n } else {\n logger.info = console.info;\n }\n if (log_level > LogLevel.warn) {\n logger.warn = _noop;\n } else {\n logger.warn = console.warn;\n }\n if (log_level > LogLevel.error) {\n logger.error = _noop;\n } else {\n logger.error = console.error;\n }\n}\n","/**\n * @license BSD\n * @copyright 2014-2025 UmbraCi\n *\n * Project Home:\n * https://github.com/UmbraCi/jsmind/\n */\n\nimport { logger } from './jsmind.common.js';\n\n/**\n * Plugin Manager\n * Manages plugin lifecycle with synchronous initialization,\n * preload support, and lifecycle hooks.\n */\nexport class PluginManager {\n /**\n * @param {import('./jsmind.js').default} jm - jsMind instance\n */\n constructor(jm) {\n this.jm = jm;\n /** @type {Map<string, Plugin>} */\n this.plugins = new Map();\n }\n\n /**\n * Initialize preload plugins (before core modules)\n */\n initPreloadPlugins() {\n const preloadPlugins = this.jm.constructor.pluginList.filter(d => d.preload);\n logger.info('Initializing ' + preloadPlugins.length + ' preload plugins');\n preloadPlugins.forEach(descriptor => {\n this._initPlugin(descriptor);\n });\n }\n\n /**\n * Initialize normal plugins (after core modules)\n */\n initNormalPlugins() {\n const normalPlugins = this.jm.constructor.pluginList.filter(d => !d.preload);\n logger.info('Initializing ' + normalPlugins.length + ' normal plugins');\n normalPlugins.forEach(descriptor => {\n this._initPlugin(descriptor);\n });\n }\n\n /**\n * Internal method: Initialize a single plugin\n * @param {PluginDescriptor} descriptor\n * @private\n */\n _initPlugin(descriptor) {\n try {\n const { PluginClass, pluginOpt } = descriptor;\n\n if (!PluginClass.instanceName) {\n throw new Error('Plugin ' + PluginClass.name + ' must define static instanceName');\n }\n if (this.plugins.has(PluginClass.instanceName)) {\n logger.warn(\n 'Plugin ' + PluginClass.instanceName + ' already exists, will be replaced'\n );\n }\n\n const instance = new PluginClass({\n jm: this.jm,\n pluginOpt: pluginOpt || {},\n });\n\n this.plugins.set(PluginClass.instanceName, instance);\n this.jm[PluginClass.instanceName] = instance;\n descriptor.instance = instance;\n\n logger.info('Plugin ' + PluginClass.instanceName + ' initialized');\n } catch (error) {\n logger.error('Failed to initialize plugin ' + descriptor.PluginClass.name + ':', error);\n }\n }\n\n /**\n * Remove a plugin\n * @param {typeof Plugin} PluginClass\n */\n removePlugin(PluginClass) {\n const instanceName = PluginClass.instanceName;\n if (!instanceName) {\n return;\n }\n\n const instance = this.plugins.get(instanceName);\n if (!instance) {\n return;\n }\n\n try {\n if (typeof instance.beforePluginRemove === 'function') {\n instance.beforePluginRemove();\n }\n\n this.plugins.delete(instanceName);\n delete this.jm[instanceName];\n\n const list = this.jm.constructor.pluginList;\n const index = list.findIndex(d => d.PluginClass === PluginClass);\n if (index !== -1) {\n list.splice(index, 1);\n }\n\n logger.info('Plugin ' + instanceName + ' removed');\n } catch (error) {\n logger.error('Failed to remove plugin ' + instanceName + ':', error);\n }\n }\n\n /**\n * Destroy all plugins\n */\n destroyAllPlugins() {\n this.plugins.forEach((instance, instanceName) => {\n try {\n if (typeof instance.beforePluginDestroy === 'function') {\n instance.beforePluginDestroy();\n }\n } catch (error) {\n logger.error('Failed to destroy plugin ' + instanceName + ':', error);\n }\n });\n\n this.plugins.clear();\n }\n\n /**\n * Get plugin instance by name\n * @param {string} instanceName\n * @returns {Plugin | undefined}\n */\n getPlugin(instanceName) {\n return this.plugins.get(instanceName);\n }\n}\n\n/**\n * Plugin Base Class\n * Provides standard plugin interface.\n */\nexport class Plugin {\n /**\n * Plugin instance name (must be defined by subclass)\n * @type {string}\n */\n static instanceName = '';\n\n /**\n * Whether to initialize before core modules\n * @type {boolean}\n */\n static preload = false;\n\n /**\n * @param {{ jm: import('./jsmind.js').default, pluginOpt: object }} params\n */\n constructor({ jm, pluginOpt }) {\n this.jm = jm;\n this.options = pluginOpt || {};\n }\n\n /**\n * Called before plugin is removed\n */\n beforePluginRemove() {}\n\n /**\n * Called before jsMind instance is destroyed\n */\n beforePluginDestroy() {\n this.beforePluginRemove();\n }\n}\n\n/**\n * Plugin descriptor\n * @typedef {object} PluginDescriptor\n * @property {typeof Plugin} PluginClass - Plugin class\n * @property {string} instanceName - Plugin instance name\n * @property {boolean} preload - Whether to preload\n * @property {object} pluginOpt - Plugin options\n * @property {Plugin | null} instance - Plugin instance (after initialization)\n */\n","/**\n * @license BSD\n * @copyright 2014-2025 UmbraCi\n *\n * Project Home:\n * https://github.com/UmbraCi/jsmind/\n */\n\nimport jsMind from '@umbraci/jsmind';\nimport { Plugin } from '../jsmind.plugin.js';\n\nif (!jsMind) {\n throw new Error('jsMind is not defined');\n}\n\nconst $ = jsMind.$;\n\nconst clear_selection =\n 'getSelection' in $.w\n ? function () {\n $.w.getSelection().removeAllRanges();\n }\n : function () {\n $.d.selection.empty();\n };\n\n/**\n * Default options for draggable node plugin.\n * @typedef {Object} DraggableNodeOptions\n * @property {number} [line_width]\n * @property {string} [line_color]\n * @property {string} [line_color_invalid]\n * @property {number} [lookup_delay]\n * @property {number} [lookup_interval]\n * @property {number} [scrolling_trigger_width]\n * @property {number} [scrolling_step_length]\n * @property {string} [shadow_node_class_name]\n * @property {(draggedNode:import('../jsmind.node.js').Node, targetNode:import('../jsmind.node.js').Node|null)=>boolean} [validate_drag]\n */\nconst DEFAULT_OPTIONS = {\n line_width: 5,\n line_color: 'rgba(0,0,0,0.3)',\n line_color_invalid: 'rgba(255,51,51,0.6)',\n lookup_delay: 200,\n lookup_interval: 100,\n scrolling_trigger_width: 20,\n scrolling_step_length: 10,\n shadow_node_class_name: 'jsmind-draggable-shadow-node',\n};\n\n/**\n * Draggable node plugin for jsMind.\n */\nexport class DraggableNode {\n /**\n * Create draggable node plugin instance.\n * @param {import('../jsmind.js').default} jm - jsMind instance\n * @param {Partial<DraggableNodeOptions>} options - Plugin options\n */\n constructor(jm, options) {\n var opts = {};\n jsMind.util.json.merge(opts, DEFAULT_OPTIONS);\n jsMind.util.json.merge(opts, options);\n\n this.version = '0.4.0';\n /** @type {import('../jsmind.js').default} */\n this.jm = jm;\n /** @type {DraggableNodeOptions} */\n this.options = opts;\n /** @type {boolean} */\n this.is_svg_engine = jm.view.opts.engine === 'svg';\n /** @type {HTMLCanvasElement|SVGSVGElement|null} */\n this.e_canvas = null;\n /** @type {CanvasRenderingContext2D|null} */\n this.canvas_ctx = null;\n /** @type {SVGPathElement|null} */\n this.helper_line = null;\n /** @type {HTMLElement|null} */\n this.shadow = null;\n /** @type {number} */\n this.shadow_p_x = 0;\n /** @type {number} */\n this.shadow_p_y = 0;\n /** @type {number} */\n this.shadow_w = 0;\n /** @type {number} */\n this.shadow_h = 0;\n /** @type {import('../jsmind.node.js').Node|null} */\n this.active_node = null;\n /** @type {import('../jsmind.node.js').Node|null} */\n this.target_node = null;\n /** @type {number|null} */\n this.target_direct = null;\n /** @type {number} */\n this.client_w = 0;\n /** @type {number} */\n this.client_h = 0;\n /** @type {number} */\n this.offset_x = 0;\n /** @type {number} */\n this.offset_y = 0;\n /** @type {number} */\n this.hlookup_delay = 0;\n /** @type {number} */\n this.hlookup_timer = 0;\n /** @type {boolean} */\n this.capture = false;\n /** @type {boolean} */\n this.moved = false;\n /** @type {boolean} */\n this.canvas_draggable = jm.get_view_draggable();\n /** @type {HTMLElement} */\n this.view_panel = jm.view.e_panel;\n /** @type {DOMRect|null} */\n this.view_panel_rect = null;\n }\n /** Initialize the draggable node plugin. */\n init() {\n this.create_canvas();\n this.create_shadow();\n this.event_bind();\n }\n /** Resize canvas/SVG and shadow elements. */\n resize() {\n this.jm.view.e_nodes.appendChild(this.shadow);\n if (this.is_svg_engine) {\n this.e_canvas.setAttribute('width', this.jm.view.size.w);\n this.e_canvas.setAttribute('height', this.jm.view.size.h);\n } else {\n this.e_canvas.width = this.jm.view.size.w;\n this.e_canvas.height = this.jm.view.size.h;\n }\n }\n /** Create canvas or SVG for drawing drag lines. */\n create_canvas() {\n if (this.is_svg_engine) {\n // Create SVG element for helper lines\n var svg = this._create_svg_element('svg');\n svg.setAttribute('class', 'jsmind-draggable-helper');\n svg.setAttribute('style', 'position: absolute; top: 0; left: 0; pointer-events: none;');\n this.jm.view.e_panel.appendChild(svg);\n this.e_canvas = svg;\n } else {\n // Create Canvas element for helper lines\n var c = $.c('canvas');\n this.jm.view.e_panel.appendChild(c);\n var ctx = c.getContext('2d');\n this.e_canvas = c;\n this.canvas_ctx = ctx;\n }\n }\n /**\n * Create SVG element with proper namespace.\n * @param {string} tag - SVG tag name\n * @returns {SVGElement}\n * @private\n */\n _create_svg_element(tag) {\n return $.d.createElementNS('http://www.w3.org/2000/svg', tag);\n }\n create_shadow() {\n var s = $.c('jmnode');\n s.style.visibility = 'hidden';\n s.style.zIndex = '3';\n s.style.cursor = 'move';\n s.style.opacity = '0.7';\n s.className = this.options.shadow_node_class_name;\n this.shadow = s;\n }\n /**\n * Reset shadow element style and cache its size.\n * @param {HTMLElement} el - The node element to mirror as shadow\n */\n reset_shadow(el) {\n var shadowStyle = this.shadow.style;\n var inlineStyle = el.style;\n var computedStyle = $.w.getComputedStyle(el);\n\n this.shadow.innerHTML = el.innerHTML;\n\n var copiedInlineProps = [\n 'left',\n 'top',\n 'width',\n 'height',\n 'backgroundImage',\n 'backgroundSize',\n 'transform',\n ];\n copiedInlineProps.forEach(prop => {\n shadowStyle[prop] = inlineStyle[prop];\n });\n\n var textLayoutProps = ['whiteSpace', 'wordBreak', 'overflowWrap', 'maxWidth'];\n textLayoutProps.forEach(prop => {\n shadowStyle[prop] = inlineStyle[prop] || computedStyle[prop];\n });\n\n this.shadow_w = this.shadow.clientWidth;\n this.shadow_h = this.shadow.clientHeight;\n }\n /** Show the shadow element. */\n show_shadow() {\n if (!this.moved) {\n this.shadow.style.visibility = 'visible';\n }\n }\n /** Hide the shadow element. */\n hide_shadow() {\n this.shadow.style.visibility = 'hidden';\n }\n /**\n * Draw a helper line between the shadow and target node.\n * @param {{x:number,y:number}} shadow_p - Shadow anchor point\n * @param {{x:number,y:number}} node_p - Target node anchor point\n * @param {boolean} invalid - Whether current target is invalid\n */\n magnet_shadow(shadow_p, node_p, invalid) {\n this.clear_lines();\n var color = invalid ? this.options.line_color_invalid : this.options.line_color;\n\n if (this.is_svg_engine) {\n this.svg_draw_line(shadow_p.x, shadow_p.y, node_p.x, node_p.y, color);\n } else {\n this.canvas_ctx.lineWidth = this.options.line_width;\n this.canvas_ctx.strokeStyle = color;\n this.canvas_ctx.lineCap = 'round';\n this.canvas_lineto(shadow_p.x, shadow_p.y, node_p.x, node_p.y);\n }\n }\n /** Clear helper lines from canvas or SVG. */\n clear_lines() {\n if (this.is_svg_engine) {\n if (this.helper_line && this.helper_line.parentNode) {\n this.e_canvas.removeChild(this.helper_line);\n this.helper_line = null;\n }\n } else {\n this.canvas_ctx.clearRect(0, 0, this.jm.view.size.w, this.jm.view.size.h);\n }\n }\n /**\n * Draw a straight helper line on canvas.\n * @param {number} x1\n * @param {number} y1\n * @param {number} x2\n * @param {number} y2\n */\n canvas_lineto(x1, y1, x2, y2) {\n this.canvas_ctx.beginPath();\n this.canvas_ctx.moveTo(x1, y1);\n this.canvas_ctx.lineTo(x2, y2);\n this.canvas_ctx.stroke();\n }\n /**\n * Draw a helper line on SVG using bezier curve.\n * Reuses the line drawing logic from SvgGraph.\n * @param {number} x1 - Start x coordinate\n * @param {number} y1 - Start y coordinate\n * @param {number} x2 - End x coordinate\n * @param {number} y2 - End y coordinate\n * @param {string} color - Line color\n */\n svg_draw_line(x1, y1, x2, y2, color) {\n // Create SVG path element for helper line\n this.helper_line = this._create_svg_element('path');\n this.helper_line.setAttribute('stroke', color);\n this.helper_line.setAttribute('stroke-width', this.options.line_width);\n this.helper_line.setAttribute('fill', 'transparent');\n this.helper_line.setAttribute('stroke-linecap', 'round');\n\n // Draw bezier curve (same as SvgGraph._bezier_to)\n this._svg_bezier_to(this.helper_line, x1, y1, x2, y2);\n\n // Add to SVG container\n this.e_canvas.appendChild(this.helper_line);\n }\n /**\n * Draw bezier curve to SVG path element.\n * Reuses logic from SvgGraph._bezier_to.\n * @param {SVGPathElement} path - SVG path element\n * @param {number} x1 - Start x coordinate\n * @param {number} y1 - Start y coordinate\n * @param {number} x2 - End x coordinate\n * @param {number} y2 - End y coordinate\n * @private\n */\n _svg_bezier_to(path, x1, y1, x2, y2) {\n path.setAttribute(\n 'd',\n 'M ' +\n x1 +\n ' ' +\n y1 +\n ' C ' +\n (x1 + ((x2 - x1) * 2) / 3) +\n ' ' +\n y1 +\n ', ' +\n x1 +\n ' ' +\n y2 +\n ', ' +\n x2 +\n ' ' +\n y2\n );\n }\n /** Bind mouse/touch events for dragging. */\n event_bind() {\n var jd = this;\n var container = this.jm.view.container;\n $.on(container, 'mousedown', function (e) {\n if (e.button === 0) {\n jd.dragstart.call(jd, e);\n }\n });\n $.on(container, 'mousemove', function (e) {\n if (e.movementX !== 0 || e.movementY !== 0) {\n jd.drag.call(jd, e);\n }\n });\n $.on(container, 'mouseup', function (e) {\n jd.dragend.call(jd, e);\n });\n $.on(container, 'touchstart', function (e) {\n jd.dragstart.call(jd, e);\n });\n $.on(container, 'touchmove', function (e) {\n jd.drag.call(jd, e);\n });\n $.on(container, 'touchend', function (e) {\n jd.dragend.call(jd, e);\n });\n }\n /**\n * Begin dragging interaction.\n * @param {MouseEvent|TouchEvent} e - Pointer down event\n */\n dragstart(e) {\n if (!this.jm.get_editable()) {\n return;\n }\n if (this.capture) {\n return;\n }\n var jview = this.jm.view;\n if (jview.is_editing()) {\n return;\n }\n this.active_node = null;\n this.view_draggable = this.jm.get_view_draggable();\n\n var el = this.find_node_element(e.target);\n if (!el) {\n return;\n }\n if (this.view_draggable) {\n this.jm.disable_view_draggable();\n }\n var nodeid = jview.get_binded_nodeid(el);\n if (!!nodeid) {\n var node = this.jm.get_node(nodeid);\n if (!node.isroot) {\n // 检查节点是否允许拖拽\n if (node.data && node.data.draggable === false) {\n return;\n }\n this.reset_shadow(el);\n this.view_panel_rect = this.view_panel.getBoundingClientRect();\n this.active_node = node;\n this.offset_x =\n (e.clientX || e.touches[0].clientX) / jview.zoom_current - el.offsetLeft;\n this.offset_y =\n (e.clientY || e.touches[0].clientY) / jview.zoom_current - el.offsetTop;\n this.client_hw = Math.floor(el.clientWidth / 2);\n this.client_hh = Math.floor(el.clientHeight / 2);\n if (this.hlookup_delay != 0) {\n $.w.clearTimeout(this.hlookup_delay);\n }\n if (this.hlookup_timer != 0) {\n $.w.clearInterval(this.hlookup_timer);\n }\n var jd = this;\n this.hlookup_delay = $.w.setTimeout(function () {\n jd.hlookup_delay = 0;\n jd.hlookup_timer = $.w.setInterval(function () {\n jd.lookup_target_node.call(jd);\n }, jd.options.lookup_interval);\n }, this.options.lookup_delay);\n jd.capture = true;\n }\n }\n }\n /**\n * Drag handler to move shadow and auto-scroll container.\n * @param {MouseEvent|TouchEvent} e - Pointer move event\n */\n drag(e) {\n if (!this.jm.get_editable()) {\n return;\n }\n if (this.capture) {\n e.preventDefault();\n this.show_shadow();\n this.moved = true;\n clear_selection();\n var jview = this.jm.view;\n var px = (e.clientX || e.touches[0].clientX) / jview.zoom_current - this.offset_x;\n var py = (e.clientY || e.touches[0].clientY) / jview.zoom_current - this.offset_y;\n // scrolling container axisY if drag nodes exceeding container\n if (\n e.clientY - this.view_panel_rect.top < this.options.scrolling_trigger_width &&\n this.view_panel.scrollTop > this.options.scrolling_step_length\n ) {\n this.view_panel.scrollBy(0, -this.options.scrolling_step_length);\n this.offset_y += this.options.scrolling_step_length / jview.zoom_current;\n } else if (\n this.view_panel_rect.bottom - e.clientY < this.options.scrolling_trigger_width &&\n this.view_panel.scrollTop <\n this.view_panel.scrollHeight -\n this.view_panel_rect.height -\n this.options.scrolling_step_length\n ) {\n this.view_panel.scrollBy(0, this.options.scrolling_step_length);\n this.offset_y -= this.options.scrolling_step_length / jview.zoom_current;\n }\n // scrolling container axisX if drag nodes exceeding container\n if (\n e.clientX - this.view_panel_rect.left < this.options.scrolling_trigger_width &&\n this.view_panel.scrollLeft > this.options.scrolling_step_length\n ) {\n this.view_panel.scrollBy(-this.options.scrolling_step_length, 0);\n this.offset_x += this.options.scrolling_step_length / jview.zoom_current;\n } else if (\n this.view_panel_rect.right - e.clientX < this.options.scrolling_trigger_width &&\n this.view_panel.scrollLeft <\n this.view_panel.scrollWidth -\n this.view_panel_rect.width -\n this.options.scrolling_step_length\n ) {\n this.view_panel.scrollBy(this.options.scrolling_step_length, 0);\n this.offset_x -= this.options.scrolling_step_length / jview.zoom_current;\n }\n this.shadow.style.left = px + 'px';\n this.shadow.style.top = py + 'px';\n clear_selection();\n }\n }\n /**\n * Finish dragging, move the node if applicable.\n * @param {MouseEvent|TouchEvent} e - Pointer up event\n */\n dragend(e) {\n if (!this.jm.get_editable()) {\n return;\n }\n if (this.view_draggable) {\n this.jm.enable_view_draggable();\n }\n if (this.capture) {\n if (this.hlookup_delay != 0) {\n $.w.clearTimeout(this.hlookup_delay);\n this.hlookup_delay = 0;\n this.clear_lines();\n }\n if (this.hlookup_timer != 0) {\n $.w.clearInterval(this.hlookup_timer);\n this.hlookup_timer = 0;\n this.clear_lines();\n }\n if (this.moved) {\n var src_node = this.active_node;\n var target_node = this.target_node;\n var target_direct = this.target_direct;\n this.move_node(src_node, target_node, target_direct);\n }\n this.hide_shadow();\n }\n this.view_panel_rect = null;\n this.moved = false;\n this.capture = false;\n }\n /**\n * Find the closest node element from an event target.\n * @param {HTMLElement} el - Current DOM element\n * @returns {HTMLElement|null} Matched node element or null\n */\n find_node_element(el) {\n if (\n el === this.jm.view.e_nodes ||\n el === this.jm.view.e_panel ||\n el === this.jm.view.container\n ) {\n return null;\n }\n if (el.tagName.toLowerCase() === 'jmnode') {\n return el;\n }\n return this.find_node_element(el.parentNode);\n }\n /** Recompute target node under the shadow and draw helper. */\n lookup_target_node() {\n let sx = this.shadow.offsetLeft;\n let sy = this.shadow.offsetTop;\n if (sx === this.shadow_p_x && sy === this.shadow_p_y) {\n return;\n }\n this.shadow_p_x = sx;\n this.shadow_p_y = sy;\n\n let target_direction =\n this.shadow_p_x + this.shadow_w / 2 >= this.get_root_x()\n ? jsMind.direction.right\n : jsMind.direction.left;\n let overlapping_node = this.lookup_overlapping_node_parent(target_direction);\n let target_node = overlapping_node || this.lookup_close_node(target_direction);\n if (!!target_node) {\n let points = this.calc_point_of_node(target_node, target_direction);\n let invalid = jsMind.node.inherited(this.active_node, target_node);\n this.magnet_shadow(points.sp, points.np, invalid);\n this.target_node = target_node;\n this.target_direct = target_direction;\n }\n }\n /**\n * Get X coordinate of root node center.\n * @returns {number}\n */\n get_root_x() {\n let root = this.jm.get_root();\n let root_location = root.get_location();\n let root_size = root.get_size();\n return root_location.x + root_size.w / 2;\n }\n\n /**\n * Lookup overlapping node's parent near the shadow position.\n * @param {number} direction - Direction constant\n * @returns {import('../jsmind.node.js').Node|null}\n */\n lookup_overlapping_node_parent(direction) {\n let shadowRect = this.shadow.getBoundingClientRect();\n let x = shadowRect.x + (shadowRect.width * (1 - direction)) / 2;\n let deltaX = (this.jm.options.layout.hspace + this.jm.options.layout.pspace) * direction;\n let deltaY = shadowRect.height;\n let points = [\n [x, shadowRect.y],\n [x, shadowRect.y + deltaY / 2],\n [x, shadowRect.y + deltaY],\n [x + deltaX / 2, shadowRect.y],\n [x + deltaX / 2, shadowRect.y + deltaY / 2],\n [x + deltaX / 2, shadowRect.y + deltaY],\n [x + deltaX, shadowRect.y],\n [x + deltaX, shadowRect.y + deltaY / 2],\n [x + deltaX, shadowRect.y + deltaY],\n ];\n for (const p of points) {\n let n = this.lookup_node_parent_by_location(p[0], p[1]);\n if (!!n) {\n return n;\n }\n }\n }\n\n /**\n * Find node's parent by a screen location.\n * @param {number} x - Client X\n * @param {number} y - Client Y\n * @returns {import('../jsmind.node.js').Node|null}\n */\n lookup_node_parent_by_location(x, y) {\n return $.d\n .elementsFromPoint(x, y)\n .filter(\n x => x.tagName === 'JMNODE' && x.className !== this.options.shadow_node_class_name\n )\n .map(el => this.jm.view.get_binded_nodeid(el))\n .map(id => id && this.jm.mind.nodes[id])\n .map(n => n && n.parent)\n .find(n => n);\n }\n\n /**\n * Lookup the closest node along a direction.\n * @param {number} direction\n * @returns {import('../jsmind.node.js').Node}\n */\n lookup_close_node(direction) {\n return Object.values(this.jm.mind.nodes)\n .filter(n => n.direction == direction || n.isroot)\n .filter(n => this.jm.layout.is_visible(n))\n .filter(n => this.shadow_on_target_side(n, direction))\n .map(n => ({ node: n, distance: this.shadow_to_node(n, direction) }))\n .reduce(\n (prev, curr) => {\n return prev.distance < curr.distance ? prev : curr;\n },\n { node: this.jm.get_root(), distance: Number.MAX_VALUE }\n ).node;\n }\n\n /**\n * Check if shadow is on the target side of a node.\n * @param {import('../jsmind.node.js').Node} node\n * @param {number} dir\n * @returns {boolean}\n */\n shadow_on_target_side(node, dir) {\n return (\n (dir == jsMind.direction.right && this.shadow_to_right_of_node(node) > 0) ||\n (dir == jsMind.direction.left && this.shadow_to_left_of_node(node) > 0)\n );\n }\n\n /**\n * Distance from shadow to the right side of a node.\n * @param {import('../jsmind.node.js').Node} node\n * @returns {number}\n */\n shadow_to_right_of_node(node) {\n return this.shadow_p_x - node.get_location().x - node.get_size().w;\n }\n\n /**\n * Distance from shadow to the left side of a node.\n * @param {import('../jsmind.node.js').Node} node\n * @returns {number}\n */\n shadow_to_left_of_node(node) {\n return node.get_location().x - this.shadow_p_x - this.shadow_w;\n }\n\n /**\n * Vertical distance between shadow centerline and node centerline.\n * @param {import('../jsmind.node.js').Node} node\n * @returns {number}\n */\n shadow_to_base_line_of_node(node) {\n return this.shadow_p_y + this.shadow_h / 2 - node.get_location().y - node.get_size().h / 2;\n }\n\n /**\n * Manhattan distance to a node along a direction.\n * @param {import('../jsmind.node.js').Node} node\n * @param {number} dir\n * @returns {number}\n */\n shadow_to_node(node, dir) {\n let distance_x =\n dir === jsMind.direction.right\n ? Math.abs(this.shadow_to_right_of_node(node))\n : Math.abs(this.shadow_to_left_of_node(node));\n let distance_y = Math.abs(this.shadow_to_base_line_of_node(node));\n return distance_x + distance_y;\n }\n\n /**\n * Calculate connection points of a node and the shadow.\n * @param {import('../jsmind.node.js').Node} node\n * @param {number} dir\n * @returns {{sp:{x:number,y:number}, np:{x:number,y:number}}}\n */\n calc_point_of_node(node, dir) {\n let ns = node.get_size();\n let nl = node.get_location();\n let node_x = node.isroot\n ? nl.x + ns.w / 2\n : nl.x + (ns.w * (1 + dir)) / 2 + this.options.line_width * dir;\n let node_y = nl.y + ns.h / 2;\n let shadow_x =\n this.shadow_p_x + (this.shadow_w * (1 - dir)) / 2 - this.options.line_width * dir;\n let shadow_y = this.shadow_p_y + this.shadow_h / 2;\n return {\n sp: { x: shadow_x, y: shadow_y },\n np: { x: node_x, y: node_y },\n };\n }\n\n /**\n * Move a node to a new parent/position.\n * @param {import('../jsmind.node.js').Node} src_node\n * @param {import('../jsmind.node.js').Node|null} target_node\n * @param {number|null} target_direct\n */\n move_node(src_node, target_node, target_direct) {\n var shadow_h = this.shadow.offsetTop;\n if (!!target_node && !!src_node && !jsMind.node.inherited(src_node, target_node)) {\n // Call validate_drag function if provided, to validate the drag operation\n if (this.options.validate_drag && typeof this.options.validate_drag === 'function') {\n const isValid = this.options.validate_drag(src_node, target_node);\n if (!isValid) {\n // Drag operation is not allowed, cleanup and return\n this.active_node = null;\n this.target_node = null;\n this.target_direct = null;\n return;\n }\n }\n\n // lookup before_node\n var sibling_nodes = target_node.children;\n var sc = sibling_nodes.length;\n var node = null;\n var delta_y = Number.MAX_VALUE;\n var node_before = null;\n var beforeid = '_last_';\n while (sc--) {\n node = sibling_nodes[sc];\n if (node.direction == target_direct && node.id != src_node.id) {\n var dy = node.get_location().y - shadow_h;\n if (dy > 0 && dy < delta_y) {\n delta_y = dy;\n node_before = node;\n beforeid = '_first_';\n }\n }\n }\n if (!!node_before) {\n beforeid = node_before.id;\n }\n this.jm.move_node(src_node.id, beforeid, target_node.id, target_direct);\n }\n this.active_node = null;\n this.target_node = null;\n this.target_direct = null;\n }\n /**\n * Handle jsMind events.\n * @param {number|string} type - Event type\n * @param {object} [data] - Event data\n */\n jm_event_handle(type, data) {\n if (type === jsMind.event_type.resize) {\n this.resize();\n }\n }\n}\n\n/**\n * Draggable node plugin for unified plugin system.\n */\nexport class DraggableNodePlugin extends Plugin {\n static instanceName = 'draggable';\n static preload = false;\n\n /**\n * @param {{ jm: import('../jsmind.js').default, pluginOpt: Partial<DraggableNodeOptions> }} params\n */\n constructor({ jm, pluginOpt }) {\n super({ jm, pluginOpt });\n this.draggable = new DraggableNode(jm, pluginOpt);\n this.draggable.init();\n this._eventHandle = (type, data) => {\n this.draggable.jm_event_handle(type, data);\n };\n jm.add_event_listener(this._eventHandle);\n jm.draggable = this.draggable;\n }\n\n beforePluginRemove() {\n delete this.jm.draggable;\n }\n}\n\njsMind.usePlugin(DraggableNodePlugin);\n\nexport default DraggableNode;\n"],"names":["String","prototype","startsWith","p","this","slice","length","Plugin","static","constructor","jm","pluginOpt","options","beforePluginRemove","beforePluginDestroy","jsMind","Error","$","clear_selection","w","getSelection","removeAllRanges","d","selection","empty","DEFAULT_OPTIONS","line_width","line_color","line_color_invalid","lookup_delay","lookup_interval","scrolling_trigger_width","scrolling_step_length","shadow_node_class_name","DraggableNode","opts","util","json","merge","version","is_svg_engine","view","engine","e_canvas","canvas_ctx","helper_line","shadow","shadow_p_x","shadow_p_y","shadow_w","shadow_h","active_node","target_node","target_direct","client_w","client_h","offset_x","offset_y","hlookup_delay","hlookup_timer","capture","moved","canvas_draggable","get_view_draggable","view_panel","e_panel","view_panel_rect","init","create_canvas","create_shadow","event_bind","resize","e_nodes","appendChild","setAttribute","size","h","width","height","svg","_create_svg_element","c","ctx","getContext","tag","createElementNS","s","style","visibility","zIndex","cursor","opacity","className","reset_shadow","el","shadowStyle","inlineStyle","computedStyle","getComputedStyle","innerHTML","forEach","prop","clientWidth","clientHeight","show_shadow","hide_shadow","magnet_shadow","shadow_p","node_p","invalid","clear_lines","color","svg_draw_line","x","y","lineWidth","strokeStyle","lineCap","canvas_lineto","parentNode","removeChild","clearRect","x1","y1","x2","y2","beginPath","moveTo","lineTo","stroke","_svg_bezier_to","path","jd","container","on","e","button","dragstart","call","movementX","movementY","drag","dragend","get_editable","jview","is_editing","view_draggable","find_node_element","target","disable_view_draggable","nodeid","get_binded_nodeid","node","get_node","isroot","data","draggable","getBoundingClientRect","clientX","touches","zoom_current","offsetLeft","clientY","offsetTop","client_hw","Math","floor","client_hh","clearTimeout","clearInterval","setTimeout","setInterval","lookup_target_node","preventDefault","px","py","top","scrollTop","scrollBy","bottom","scrollHeight","left","scrollLeft","right","scrollWidth","enable_view_draggable","src_node","move_node","tagName","toLowerCase","sx","sy","target_direction","get_root_x","direction","lookup_overlapping_node_parent","lookup_close_node","points","calc_point_of_node","inherited","sp","np","root","get_root","root_location","get_location","root_size","get_size","shadowRect","deltaX","layout","hspace","pspace","deltaY","n","lookup_node_parent_by_location","elementsFromPoint","filter","map","id","mind","nodes","parent","find","Object","values","is_visible","shadow_on_target_side","distance","shadow_to_node","reduce","prev","curr","Number","MAX_VALUE","dir","shadow_to_right_of_node","shadow_to_left_of_node","shadow_to_base_line_of_node","abs","ns","nl","node_x","node_y","validate_drag","sibling_nodes","children","sc","delta_y","node_before","beforeid","dy","jm_event_handle","type","event_type","DraggableNodePlugin","super","_eventHandle","add_event_listener","usePlugin"],"mappings":"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"}
|
package/dist/jsmind.history.js
CHANGED
|
@@ -5,5 +5,5 @@
|
|
|
5
5
|
* Project Home:
|
|
6
6
|
* https://github.com/hizzgdev/jsmind/
|
|
7
7
|
*/
|
|
8
|
-
!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?e(exports):"function"==typeof define&&define.amd?define(["exports"],e):e((t="undefined"!=typeof globalThis?globalThis:t||self).jsMindHistory={})}(this,function(t){"use strict";"function"!=typeof String.prototype.startsWith&&(String.prototype.startsWith=function(t){return this.slice(0,t.length)===t});const e=1,r=3,n=6,i=1,o=2,s=3,a=4;var h=function(){};let c="undefined"==typeof console?{level:h,log:h,debug:h,info:h,warn:h,error:h}:{level:function(t){c.debug=t>i?h:console.debug;c.info=t>o?h:console.info;c.warn=t>s?h:console.warn;c.error=t>a?h:console.error},log:console.log,debug:console.debug,info:console.info,warn:console.warn,error:console.error};class u{static instanceName="";static preload=!1;constructor({jm:t,pluginOpt:e}){this.jm=t,this.options=e||{}}beforePluginRemove(){}beforePluginDestroy(){this.beforePluginRemove()}}var d=Object.getOwnPropertyNames,l=Object.getOwnPropertySymbols,f=Object.prototype.hasOwnProperty;function p(t,e){return function(r,n,i){return t(r,n,i)&&e(r,n,i)}}function y(t){return function(e,r,n){if(!e||!r||"object"!=typeof e||"object"!=typeof r)return t(e,r,n);var i=n.cache,o=i.get(e),s=i.get(r);if(o&&s)return o===r&&s===e;i.set(e,r),i.set(r,e);var a=t(e,r,n);return i.delete(e),i.delete(r),a}}function g(t){return d(t).concat(l(t))}var m=Object.hasOwn||function(t,e){return f.call(t,e)};function _(t,e){return t===e||!t&&!e&&t!=t&&e!=e}var b=Object.getOwnPropertyDescriptor,v=Object.keys;function x(t,e,r){var n=t.length;if(e.length!==n)return!1;for(;n-- >0;)if(!r.equals(t[n],e[n],n,n,t,e,r))return!1;return!0}function j(t,e){return _(t.getTime(),e.getTime())}function S(t,e){return t.name===e.name&&t.message===e.message&&t.cause===e.cause&&t.stack===e.stack}function w(t,e){return t===e}function M(t,e,r){var n=t.size;if(n!==e.size)return!1;if(!n)return!0;for(var i,o,s=new Array(n),a=t.entries(),h=0;(i=a.next())&&!i.done;){for(var c=e.entries(),u=!1,d=0;(o=c.next())&&!o.done;)if(s[d])d++;else{var l=i.value,f=o.value;if(r.equals(l[0],f[0],h,d,t,e,r)&&r.equals(l[1],f[1],l[0],f[0],t,e,r)){u=s[d]=!0;break}d++}if(!u)return!1;h++}return!0}var k=_;function O(t,e,r){var n=v(t),i=n.length;if(v(e).length!==i)return!1;for(;i-- >0;)if(!T(t,e,r,n[i]))return!1;return!0}function A(t,e,r){var n,i,o,s=g(t),a=s.length;if(g(e).length!==a)return!1;for(;a-- >0;){if(!T(t,e,r,n=s[a]))return!1;if(i=b(t,n),o=b(e,n),(i||o)&&(!i||!o||i.configurable!==o.configurable||i.enumerable!==o.enumerable||i.writable!==o.writable))return!1}return!0}function q(t,e){return _(t.valueOf(),e.valueOf())}function E(t,e){return t.source===e.source&&t.flags===e.flags}function C(t,e,r){var n=t.size;if(n!==e.size)return!1;if(!n)return!0;for(var i,o,s=new Array(n),a=t.values();(i=a.next())&&!i.done;){for(var h=e.values(),c=!1,u=0;(o=h.next())&&!o.done;){if(!s[u]&&r.equals(i.value,o.value,i.value,o.value,t,e,r)){c=s[u]=!0;break}u++}if(!c)return!1}return!0}function P(t,e){var r=t.length;if(e.length!==r)return!1;for(;r-- >0;)if(t[r]!==e[r])return!1;return!0}function N(t,e){return t.hostname===e.hostname&&t.pathname===e.pathname&&t.protocol===e.protocol&&t.port===e.port&&t.hash===e.hash&&t.username===e.username&&t.password===e.password}function T(t,e,r,n){return!("_owner"!==n&&"__o"!==n&&"__v"!==n||!t.$$typeof&&!e.$$typeof)||m(e,n)&&r.equals(t[n],e[n],n,n,t,e,r)}var D=Array.isArray,I="function"==typeof ArrayBuffer&&ArrayBuffer.isView?ArrayBuffer.isView:null,F=Object.assign,K=Object.prototype.toString.call.bind(Object.prototype.toString);function z(t){var e=t.areArraysEqual,r=t.areDatesEqual,n=t.areErrorsEqual,i=t.areFunctionsEqual,o=t.areMapsEqual,s=t.areNumbersEqual,a=t.areObjectsEqual,h=t.arePrimitiveWrappersEqual,c=t.areRegExpsEqual,u=t.areSetsEqual,d=t.areTypedArraysEqual,l=t.areUrlsEqual,f=t.unknownTagComparators;return function(t,p,y){if(t===p)return!0;if(null==t||null==p)return!1;var g=typeof t;if(g!==typeof p)return!1;if("object"!==g)return"number"===g?s(t,p,y):"function"===g&&i(t,p,y);var m=t.constructor;if(m!==p.constructor)return!1;if(m===Object)return a(t,p,y);if(D(t))return e(t,p,y);if(null!=I&&I(t))return d(t,p,y);if(m===Date)return r(t,p,y);if(m===RegExp)return c(t,p,y);if(m===Map)return o(t,p,y);if(m===Set)return u(t,p,y);var _,b=K(t);if("[object Date]"===b)return r(t,p,y);if("[object RegExp]"===b)return c(t,p,y);if("[object Map]"===b)return o(t,p,y);if("[object Set]"===b)return u(t,p,y);if("[object Object]"===b)return"function"!=typeof t.then&&"function"!=typeof p.then&&a(t,p,y);if("[object URL]"===b)return l(t,p,y);if("[object Error]"===b)return n(t,p,y);if("[object Arguments]"===b)return a(t,p,y);if("[object Boolean]"===b||"[object Number]"===b||"[object String]"===b)return h(t,p,y);if(f){var v=f[b];if(!v){var x=null!=(_=t)?_[Symbol.toStringTag]:void 0;x&&(v=f[x])}if(v)return v(t,p,y)}return!1}}var R=B();function B(t){void 0===t&&(t={});var e,r=t.circular,n=void 0!==r&&r,i=t.createInternalComparator,o=t.createState,s=t.strict,a=void 0!==s&&s,h=function(t){var e=t.circular,r=t.createCustomConfig,n=t.strict,i={areArraysEqual:n?A:x,areDatesEqual:j,areErrorsEqual:S,areFunctionsEqual:w,areMapsEqual:n?p(M,A):M,areNumbersEqual:k,areObjectsEqual:n?A:O,arePrimitiveWrappersEqual:q,areRegExpsEqual:E,areSetsEqual:n?p(C,A):C,areTypedArraysEqual:n?A:P,areUrlsEqual:N,unknownTagComparators:void 0};if(r&&(i=F({},i,r(i))),e){var o=y(i.areArraysEqual),s=y(i.areMapsEqual),a=y(i.areObjectsEqual),h=y(i.areSetsEqual);i=F({},i,{areArraysEqual:o,areMapsEqual:s,areObjectsEqual:a,areSetsEqual:h})}return i}(t),c=z(h);return function(t){var e=t.circular,r=t.comparator,n=t.createState,i=t.equals,o=t.strict;if(n)return function(t,s){var a=n(),h=a.cache,c=void 0===h?e?new WeakMap:void 0:h,u=a.meta;return r(t,s,{cache:c,equals:i,meta:u,strict:o})};if(e)return function(t,e){return r(t,e,{cache:new WeakMap,equals:i,meta:void 0,strict:o})};var s={cache:void 0,equals:i,meta:void 0,strict:o};return function(t,e){return r(t,e,s)}}({circular:n,comparator:c,createState:o,equals:i?i(c):(e=c,function(t,r,n,i,o,s,a){return e(t,r,a)}),strict:a})}function H(t,e){const r=function(t){return(e=t)&&"object"==typeof e&&"data"in e?t.data:t;var e}(t),n=e&&Array.isArray(e.fields)?e.fields:["topic","data","id"],i=e&&e.idKey?e.idKey:"id",o=e&&e.childrenKey?e.childrenKey:"children",s=!e||!1!==e.includeStructure,a=new Map;return r&&r[i]&&function t(e,r,h){const c=function(t){const e={};i in t&&(e[i]=t[i]);const r=new Set([i,o,"direction","expanded","parentid","index","isroot"]);n.includes("data");for(const o of n)if("data"===o){const i={};let o=!1;for(const e in t)r.has(e)||n.includes(e)||(i[e]=t[e],o=!0);o&&(e.data=i)}else o in t&&o!==i&&(e[o]=t[o]);return e}(e),u=e[i];s&&(c.parentid=r||null,c.index="number"==typeof h?h:0),a.set(u,c);const d=e[o];d&&Array.isArray(d)&&d.forEach((e,r)=>t(e,u,r))}(r,null,0),a}function U(t,e){if(t===e)return!0;if(!t||!e)return!1;const r=Object.keys(t),n=Object.keys(e);if(r.length!==n.length)return!1;for(const n of r){const r=t[n],i=e[n];if(r===i)continue;if(r&&i&&"object"==typeof r&&"object"==typeof i){if(!R(r,i))return!1}else if(r!==i)return!1}return!0}function W(t,e){const r=[];if(!t||!e)return r;const n=new Set([...Object.keys(t),...Object.keys(e)]);n.delete("id");for(const i of n){const n=t[i],o=e[i];if(n===o)continue;(n&&o&&"object"==typeof n&&"object"==typeof o?!R(n,o):n!==o)&&r.push({key:i,before:n,after:o})}return r}function $(t){let e=!1,r=!1;for(const n of t)"parentid"===n.key&&(e=!0),"index"===n.key&&(r=!0);return{moved:e||r,parentChanged:e,orderChanged:r}}function J(t){const e=new Map;for(const[r,n]of t){const t=n.parentid;e.has(t)||e.set(t,[]),e.get(t).push({id:r,index:n.index})}for(const t of e.values())t.sort((t,e)=>t.index-e.index);return e}function Y(t,e,r){const n=new Set,i=new Map;e.forEach((t,e)=>i.set(t.id,e));const o=[],s=[];for(const e of t)i.has(e.id)&&(o.push(e.id),s.push(i.get(e.id)));if(o.length<=1)return n;const a=function(t){const e=t.slice(),r=[0];let n,i,o,s,a;const h=t.length;for(n=0;n<h;n++){const h=t[n];if(0!==h||0===n){if(i=r[r.length-1],t[i]<h){e[n]=i,r.push(n);continue}for(o=0,s=r.length-1;o<s;)a=o+s>>1,t[r[a]]<h?o=a+1:s=a;h<t[r[o]]&&(o>0&&(e[n]=r[o-1]),r[o]=n)}}for(o=r.length,s=r[o-1];o-- >0;)r[o]=s,s=e[s];return r}(s),h=new Set(a);return o.forEach((t,e)=>{h.has(e)||n.add(t)}),n}function V(t,e,r={}){const{fields:n,idKey:i,childrenKey:o,includeStructure:s=!0,maxSize:a=5e3}=r,h=H(t,{fields:n,idKey:i,childrenKey:o,includeStructure:s}),c=H(e,{fields:n,idKey:i,childrenKey:o,includeStructure:s}),u=[],d=[],l=[];for(const[t,e]of c){if(!h.has(t)){u.push(e);continue}const r=h.get(t);if(!U(r,e)){const n=W(r,e);d.push({id:t,before:r,after:e,changes:n})}}for(const[t,e]of h)c.has(t)||l.push(e);let f=!1;const p=u.length+d.length+l.length;if(p>a){f=!0;const t=Math.max(0,a),e=Math.min(u.length,Math.floor(t*(u.length/p))),r=Math.min(d.length,Math.floor(t*(d.length/p))),n=Math.min(l.length,Math.max(0,t-e-r));u.length=e,d.length=r,l.length=n}if(s){const t=function(t,e,r){const n=[],i=[],o=[],s=new Set,a=J(e),h=J(r);for(const[t,e]of h){const r=Y(a.get(t)||[],e);for(const t of r)s.add(t)}for(const e of t){const{id:t,before:r,after:a,changes:h}=e,c=$(h),u=c.parentChanged,d=!u&&c.orderChanged&&s.has(t);if(u||d){const e={moveType:u?"cross-parent":"reorder",parentChanged:c.parentChanged,orderChanged:c.orderChanged,fromParent:r.parentid,toParent:a.parentid,fromOrder:r.index,toOrder:a.index},i=h.filter(t=>"parentid"!==t.key&&"index"!==t.key);i.length>0?o.push({id:t,before:r,after:a,changes:i,moveInfo:e}):n.push({id:t,before:r,after:a,moveInfo:e})}else if(c.orderChanged){const e=h.filter(t=>"parentid"!==t.key&&"index"!==t.key);e.length>0&&i.push({id:t,before:r,after:a,changes:e})}else i.push({id:t,before:r,after:a,changes:h})}return{moved:n,modified:i,movedAndModified:o}}(d,h,c);return{created:u,deleted:l,truncated:f,moved:t.moved,modified:t.modified,movedAndModified:t.movedAndModified}}return{created:u,deleted:l,moved:[],modified:d,movedAndModified:[],truncated:f}}B({strict:!0}),B({circular:!0}),B({circular:!0,strict:!0}),B({createInternalComparator:function(){return _}}),B({strict:!0,createInternalComparator:function(){return _}}),B({circular:!0,createInternalComparator:function(){return _}}),B({circular:!0,createInternalComparator:function(){return _},strict:!0});const L={enabled:!0,throttleMs:100,maxHistory:500,storageMode:"object",autoSwitchThreshold:0,keymap:{enabled:!1,redoUsesY:!1},detail:{enabled:!1},diff:{flat:!0,fields:void 0,maxSize:5e3}};class G extends u{static instanceName="historyPlugin";static preload=!0;constructor({jm:t,pluginOpt:e}){super({jm:t,pluginOpt:e}),this.options=function(t){const e=Object.assign({},L,t||{});return e.keymap||(e.keymap={enabled:!1,redoUsesY:!1}),e.detail||(e.detail={enabled:!1}),e.diff||(e.diff={flat:!0,fields:void 0,maxSize:5e3}),e}(e),this._mounted=!1,this._core=null,this._mountAPI(),this._initCore()}beforePluginDestroy(){c.debug("[history] beforePluginDestroy: clearing history stack"),this._core&&this._core.clear()}_initCore(){const t=this.jm,n=this.options;n.keymap&&n.keymap.enabled&&t.options&&t.options.shortcut&&this._injectShortcuts(t.options.shortcut,!!n.keymap.redoUsesY);const i=new Q(t,n);this._core=i,t.history&&(t.history.add=(t,e)=>i.add(t,e),t.history.pause=()=>i.pause(),t.history.resume=t=>i.resume(!!t),t.history.clear=()=>i.clear(),t.history.canBack=()=>i.canBack(),t.history.canForward=()=>i.canForward(),t.history.back=t=>i.back("number"==typeof t?t:1),t.history.forward=t=>i.forward("number"==typeof t?t:1),t.history.length=()=>i.length(),t.history.index=()=>i.index(),t.history.setMax=t=>i.setMax(t),t.history.setThrottle=t=>i.setThrottle(t),t.history.exportSnapshot=()=>i.exportSnapshot(),t.history.importSnapshot=(t,e)=>i.importSnapshot(t,e),t.history.getStack=()=>i.getStackMeta(),t.history.diff=(t,e,r)=>{const n=this.jm.options.fieldNames,i=n?.id||"id";return V(t,e,{fields:[n?.topic||"topic","data",i],idKey:i,childrenKey:n?.children||"children",...r})},this._listener=(t,n)=>{try{if(t===e&&n&&"data"in n){let t=null;const e=n.data&&n.data[0];if(e)if(e.data)if(Array.isArray(e.data)){const r=e.data.find(t=>t.isroot);t=r&&r.id}else t=e.data.id;else e.id&&(t=e.id);return void(t&&t!==i._lastRootId&&(c.debug("[history] root id changed, clearing stack and pausing"),i.clear(),i._lastRootId=t,setTimeout(()=>{try{c.debug("[history] adding bootstrap snapshot after show"),i._addNow&&i._addNow("bootstrap"),c.debug("[history] resuming history recording")}catch(t){c.warn("[history] failed to add bootstrap snapshot",t)}},100)))}t===r&&n&&n.evt&&i.add(n.evt,n)}catch(t){c.warn("[history] listener error",t)}},t.add_event_listener(this._listener))}_injectShortcuts(t,e){const r=[4186,8282],n=e?[4185,8281]:[5210,9306];t.handles.history_back=(t,e)=>{t.history&&t.history.back()&&(e.preventDefault(),e.stopPropagation&&e.stopPropagation())},t.handles.history_forward=(t,e)=>{t.history&&t.history.forward()&&(e.preventDefault(),e.stopPropagation&&e.stopPropagation())},t.mapping.history_back=r,t.mapping.history_forward=n}_mountAPI(){if(this._mounted)return;const t=this.jm,e={add:()=>{},pause:()=>{},resume:t=>{},clear:()=>{},canBack:()=>!1,canForward:()=>!1,back:t=>!1,forward:t=>!1,length:()=>0,index:()=>-1,setMax:t=>{},setThrottle:t=>{},exportSnapshot:()=>null,importSnapshot:(t,e)=>{},getStack:()=>({items:[],index:-1}),diff:(t,e,r)=>{const n=this.jm.options.fieldNames,i=n?.id||"id";return V(t,e,{fields:[n?.topic||"topic","data",i],idKey:i,childrenKey:n?.children||"children",...r})},getOptions:()=>Object.assign({},this.options)};Object.defineProperty(t,"history",{value:e,configurable:!0,enumerable:!1,writable:!1}),this._mounted=!0,c.info("[history] API mounted (preload).")}beforePluginRemove(){try{if(this._listener&&this.jm&&Array.isArray(this.jm.event_handles)){const t=this.jm.event_handles.indexOf(this._listener);t>=0&&this.jm.event_handles.splice(t,1)}this.jm&&Object.prototype.hasOwnProperty.call(this.jm,"history")&&delete this.jm.history,this._mounted=!1}catch(t){c.error("[history] remove failed:",t)}}beforePluginDestroy(){c.error("beforePluginDestroy"),this.beforePluginRemove()}}class Q{constructor(t,e){this.jm=t,this.options=e,this.enabled=!!e.enabled,this.maxHistory=Math.max(1,0|e.maxHistory),this.throttleMs=Math.max(0,0|e.throttleMs),this.storageMode=e.storageMode||"object",this.autoSwitchThreshold=Math.max(0,0|e.autoSwitchThreshold),this._history=[],this._idx=-1,this._paused=!1,this._lastAddAt=0,this._timer=0,this._pending=!1,this._pendingMeta=void 0,this._lastSig=null,this._lastRootId=null}add(t="manual",e){if(!this.enabled||this._paused)return;const r=Date.now()-this._lastAddAt;if(r>=this.throttleMs)return this._addNow(t,e),void(this._lastAddAt=Date.now());if(this._pending=!0,this._pendingMeta=e,this._timer)return;const n=Math.max(0,this.throttleMs-r);this._timer=setTimeout(()=>{this._timer=0,!this._paused&&this.enabled&&(this._addNow(t,this._pendingMeta),this._lastAddAt=Date.now()),this._pending=!1,this._pendingMeta=void 0},n)}pause(){this._paused=!0}resume(t=!1){this._paused=!1,t&&this._pending&&(clearTimeout(this._timer),this._timer=0,this._addNow("resume-flush",this._pendingMeta),this._lastAddAt=Date.now(),this._pending=!1,this._pendingMeta=void 0)}clear(){this._history=[],this._idx=-1,this._lastSig=null,this._notifyChange()}canBack(){return this._idx>0}canForward(){return this._idx>=0&&this._idx<this._history.length-1}back(t=1){if((!Number.isFinite(t)||t<=0)&&(t=1),this._idx-t<0)return!1;this._idx-=t;const e=this._applyIndex();return e&&this._notifyChange(),e}forward(t=1){if((!Number.isFinite(t)||t<=0)&&(t=1),this._idx+t>=this._history.length)return!1;this._idx+=t;const e=this._applyIndex();return e&&this._notifyChange(),e}length(){return this._history.length}index(){return this._idx}setMax(t){this.maxHistory=Math.max(1,0|t)}setThrottle(t){this.throttleMs=Math.max(0,0|t)}exportSnapshot(){return this._takeSnapshot()}importSnapshot(t,e){return this._applySnapshot(t,e)}getStackMeta(){return{items:this._history.slice(),index:this._idx}}_notifyChange(){try{this.jm.invoke_event_handle(n,{index:this._idx,length:this._history.length,canBack:this.canBack(),canForward:this.canForward()})}catch(t){c.warn("[history] failed to notify change",t)}}_addNow(t,e){const r=this._takeSnapshot();let n=this.storageMode;if(this.autoSwitchThreshold>0&&"object"===n){const t=this._countNodes(r);t>this.autoSwitchThreshold&&(n="string",c.debug(`[history] auto-switched to string mode (${t} nodes > ${this.autoSwitchThreshold})`))}let i=null;try{i=JSON.stringify(r)}catch{}if(!i||!this._lastSig||i!==this._lastSig){if(this._idx<this._history.length-1&&(this._history=this._history.slice(0,this._idx+1)),this._history.length>=this.maxHistory&&(this._history.shift(),this._idx=Math.max(-1,this._idx-1)),"string"===n)this._history.push(i);else{const t=this._deepFreeze(r);this._history.push(t)}this._idx=this._history.length-1,this._lastSig=i,this._notifyChange()}}_applyIndex(){const t=this._history[this._idx];if(!t)return!1;try{let e;if("string"==typeof t)e=JSON.parse(t),this._lastSig=t;else{e=this._cloneSnapshot(t);try{this._lastSig=JSON.stringify(t)}catch{this._lastSig=null}}return this._applySnapshot(e,{skipCentering:!0}),!0}catch(t){return c.error("[history] apply snapshot failed",t),!1}}_takeSnapshot(){return this.jm.get_data("node_tree")}_applySnapshot(t,e){const r=!(!e||!e.skipCentering);return this.jm.show(t,r),!0}_countNodes(t){let e=0;return function t(r){if(r&&(e++,r.children&&Array.isArray(r.children)))for(const e of r.children)t(e)}(t&&t.data?t.data:t),e}_deepFreeze(t){if(!t||"object"!=typeof t)return t;if(Object.isFrozen(t))return t;if(Object.freeze(t),Array.isArray(t))for(const e of t)this._deepFreeze(e);else for(const e of Object.keys(t))this._deepFreeze(t[e]);return t}_cloneSnapshot(t){if("function"==typeof structuredClone)try{return structuredClone(t)}catch{}try{return JSON.parse(JSON.stringify(t))}catch{return t}}}t.HistoryPlugin=G,t.default=G,Object.defineProperty(t,"__esModule",{value:!0})});
|
|
8
|
+
!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?e(exports):"function"==typeof define&&define.amd?define(["exports"],e):e((t="undefined"!=typeof globalThis?globalThis:t||self).jsMindHistory={})}(this,function(t){"use strict";"function"!=typeof String.prototype.startsWith&&(String.prototype.startsWith=function(t){return this.slice(0,t.length)===t});const e=1,r=3,n=6,i=1,o=2,s=3,a=4;var c=function(){};let u="undefined"==typeof console?{level:c,log:c,debug:c,info:c,warn:c,error:c}:{level:function(t){u.debug=t>i?c:console.debug;u.info=t>o?c:console.info;u.warn=t>s?c:console.warn;u.error=t>a?c:console.error},log:console.log,debug:console.debug,info:console.info,warn:console.warn,error:console.error};class h{static instanceName="";static preload=!1;constructor({jm:t,pluginOpt:e}){this.jm=t,this.options=e||{}}beforePluginRemove(){}beforePluginDestroy(){this.beforePluginRemove()}}var d=Object.getOwnPropertyNames,l=Object.getOwnPropertySymbols,f=Object.prototype.hasOwnProperty;function p(t,e){return function(r,n,i){return t(r,n,i)&&e(r,n,i)}}function y(t){return function(e,r,n){if(!e||!r||"object"!=typeof e||"object"!=typeof r)return t(e,r,n);var i=n.cache,o=i.get(e),s=i.get(r);if(o&&s)return o===r&&s===e;i.set(e,r),i.set(r,e);var a=t(e,r,n);return i.delete(e),i.delete(r),a}}function g(t){return d(t).concat(l(t))}var m=Object.hasOwn||function(t,e){return f.call(t,e)};function _(t,e){return t===e||!t&&!e&&t!=t&&e!=e}var b=Object.getOwnPropertyDescriptor,v=Object.keys;function x(t,e,r){var n=t.length;if(e.length!==n)return!1;for(;n-- >0;)if(!r.equals(t[n],e[n],n,n,t,e,r))return!1;return!0}function j(t,e){return _(t.getTime(),e.getTime())}function S(t,e){return t.name===e.name&&t.message===e.message&&t.cause===e.cause&&t.stack===e.stack}function w(t,e){return t===e}function M(t,e,r){var n=t.size;if(n!==e.size)return!1;if(!n)return!0;for(var i,o,s=new Array(n),a=t.entries(),c=0;(i=a.next())&&!i.done;){for(var u=e.entries(),h=!1,d=0;(o=u.next())&&!o.done;)if(s[d])d++;else{var l=i.value,f=o.value;if(r.equals(l[0],f[0],c,d,t,e,r)&&r.equals(l[1],f[1],l[0],f[0],t,e,r)){h=s[d]=!0;break}d++}if(!h)return!1;c++}return!0}var k=_;function O(t,e,r){var n=v(t),i=n.length;if(v(e).length!==i)return!1;for(;i-- >0;)if(!T(t,e,r,n[i]))return!1;return!0}function A(t,e,r){var n,i,o,s=g(t),a=s.length;if(g(e).length!==a)return!1;for(;a-- >0;){if(!T(t,e,r,n=s[a]))return!1;if(i=b(t,n),o=b(e,n),(i||o)&&(!i||!o||i.configurable!==o.configurable||i.enumerable!==o.enumerable||i.writable!==o.writable))return!1}return!0}function q(t,e){return _(t.valueOf(),e.valueOf())}function E(t,e){return t.source===e.source&&t.flags===e.flags}function C(t,e,r){var n=t.size;if(n!==e.size)return!1;if(!n)return!0;for(var i,o,s=new Array(n),a=t.values();(i=a.next())&&!i.done;){for(var c=e.values(),u=!1,h=0;(o=c.next())&&!o.done;){if(!s[h]&&r.equals(i.value,o.value,i.value,o.value,t,e,r)){u=s[h]=!0;break}h++}if(!u)return!1}return!0}function P(t,e){var r=t.length;if(e.length!==r)return!1;for(;r-- >0;)if(t[r]!==e[r])return!1;return!0}function N(t,e){return t.hostname===e.hostname&&t.pathname===e.pathname&&t.protocol===e.protocol&&t.port===e.port&&t.hash===e.hash&&t.username===e.username&&t.password===e.password}function T(t,e,r,n){return!("_owner"!==n&&"__o"!==n&&"__v"!==n||!t.$$typeof&&!e.$$typeof)||m(e,n)&&r.equals(t[n],e[n],n,n,t,e,r)}var F=Array.isArray,D="function"==typeof ArrayBuffer&&ArrayBuffer.isView?ArrayBuffer.isView:null,I=Object.assign,K=Object.prototype.toString.call.bind(Object.prototype.toString);function z(t){var e=t.areArraysEqual,r=t.areDatesEqual,n=t.areErrorsEqual,i=t.areFunctionsEqual,o=t.areMapsEqual,s=t.areNumbersEqual,a=t.areObjectsEqual,c=t.arePrimitiveWrappersEqual,u=t.areRegExpsEqual,h=t.areSetsEqual,d=t.areTypedArraysEqual,l=t.areUrlsEqual,f=t.unknownTagComparators;return function(t,p,y){if(t===p)return!0;if(null==t||null==p)return!1;var g=typeof t;if(g!==typeof p)return!1;if("object"!==g)return"number"===g?s(t,p,y):"function"===g&&i(t,p,y);var m=t.constructor;if(m!==p.constructor)return!1;if(m===Object)return a(t,p,y);if(F(t))return e(t,p,y);if(null!=D&&D(t))return d(t,p,y);if(m===Date)return r(t,p,y);if(m===RegExp)return u(t,p,y);if(m===Map)return o(t,p,y);if(m===Set)return h(t,p,y);var _,b=K(t);if("[object Date]"===b)return r(t,p,y);if("[object RegExp]"===b)return u(t,p,y);if("[object Map]"===b)return o(t,p,y);if("[object Set]"===b)return h(t,p,y);if("[object Object]"===b)return"function"!=typeof t.then&&"function"!=typeof p.then&&a(t,p,y);if("[object URL]"===b)return l(t,p,y);if("[object Error]"===b)return n(t,p,y);if("[object Arguments]"===b)return a(t,p,y);if("[object Boolean]"===b||"[object Number]"===b||"[object String]"===b)return c(t,p,y);if(f){var v=f[b];if(!v){var x=null!=(_=t)?_[Symbol.toStringTag]:void 0;x&&(v=f[x])}if(v)return v(t,p,y)}return!1}}var R=B();function B(t){void 0===t&&(t={});var e,r=t.circular,n=void 0!==r&&r,i=t.createInternalComparator,o=t.createState,s=t.strict,a=void 0!==s&&s,c=function(t){var e=t.circular,r=t.createCustomConfig,n=t.strict,i={areArraysEqual:n?A:x,areDatesEqual:j,areErrorsEqual:S,areFunctionsEqual:w,areMapsEqual:n?p(M,A):M,areNumbersEqual:k,areObjectsEqual:n?A:O,arePrimitiveWrappersEqual:q,areRegExpsEqual:E,areSetsEqual:n?p(C,A):C,areTypedArraysEqual:n?A:P,areUrlsEqual:N,unknownTagComparators:void 0};if(r&&(i=I({},i,r(i))),e){var o=y(i.areArraysEqual),s=y(i.areMapsEqual),a=y(i.areObjectsEqual),c=y(i.areSetsEqual);i=I({},i,{areArraysEqual:o,areMapsEqual:s,areObjectsEqual:a,areSetsEqual:c})}return i}(t),u=z(c);return function(t){var e=t.circular,r=t.comparator,n=t.createState,i=t.equals,o=t.strict;if(n)return function(t,s){var a=n(),c=a.cache,u=void 0===c?e?new WeakMap:void 0:c,h=a.meta;return r(t,s,{cache:u,equals:i,meta:h,strict:o})};if(e)return function(t,e){return r(t,e,{cache:new WeakMap,equals:i,meta:void 0,strict:o})};var s={cache:void 0,equals:i,meta:void 0,strict:o};return function(t,e){return r(t,e,s)}}({circular:n,comparator:u,createState:o,equals:i?i(u):(e=u,function(t,r,n,i,o,s,a){return e(t,r,a)}),strict:a})}function H(t,e){const r=function(t){return(e=t)&&"object"==typeof e&&"data"in e?t.data:t;var e}(t),n=e&&Array.isArray(e.fields)?e.fields:["topic","data","id"],i=e&&Array.isArray(e.excludeFields)?e.excludeFields:[],o=e&&e.idKey?e.idKey:"id",s=e&&e.childrenKey?e.childrenKey:"children",a=!e||!1!==e.includeStructure,c=new Map;return r&&r[o]&&function t(e,r,u){const h=function(t){const e={};o in t&&(e[o]=t[o]);const r=new Set([o,s,"direction","expanded","parentid","index","isroot"]),a=new Set(i);n.includes("data");for(const i of n)if("data"===i){const i={};let o=!1;for(const e in t)r.has(e)||n.includes(e)||a.has(e)||(i[e]=t[e],o=!0);o&&(e.data=i)}else i in t&&i!==o&&!a.has(i)&&(e[i]=t[i]);return e}(e),d=e[o];a&&(h.parentid=r||null,h.index="number"==typeof u?u:0),c.set(d,h);const l=e[s];l&&Array.isArray(l)&&l.forEach((e,r)=>t(e,d,r))}(r,null,0),c}function U(t,e){if(t===e)return!0;if(!t||!e)return!1;const r=Object.keys(t),n=Object.keys(e);if(r.length!==n.length)return!1;for(const n of r){const r=t[n],i=e[n];if(r===i)continue;if(r&&i&&"object"==typeof r&&"object"==typeof i){if(!R(r,i))return!1}else if(r!==i)return!1}return!0}function W(t,e){const r=[];if(!t||!e)return r;const n=new Set([...Object.keys(t),...Object.keys(e)]);n.delete("id");for(const i of n){const n=t[i],o=e[i];if(n===o)continue;(n&&o&&"object"==typeof n&&"object"==typeof o?!R(n,o):n!==o)&&r.push({key:i,before:n,after:o})}return r}function $(t){let e=!1,r=!1;for(const n of t)"parentid"===n.key&&(e=!0),"index"===n.key&&(r=!0);return{moved:e||r,parentChanged:e,orderChanged:r}}function J(t){const e=new Map;for(const[r,n]of t){const t=n.parentid;e.has(t)||e.set(t,[]),e.get(t).push({id:r,index:n.index})}for(const t of e.values())t.sort((t,e)=>t.index-e.index);return e}function Y(t,e,r){const n=new Set,i=new Map;e.forEach((t,e)=>i.set(t.id,e));const o=[],s=[];for(const e of t)i.has(e.id)&&(o.push(e.id),s.push(i.get(e.id)));if(o.length<=1)return n;const a=function(t){const e=t.slice(),r=[0];let n,i,o,s,a;const c=t.length;for(n=0;n<c;n++){const c=t[n];if(0!==c||0===n){if(i=r[r.length-1],t[i]<c){e[n]=i,r.push(n);continue}for(o=0,s=r.length-1;o<s;)a=o+s>>1,t[r[a]]<c?o=a+1:s=a;c<t[r[o]]&&(o>0&&(e[n]=r[o-1]),r[o]=n)}}for(o=r.length,s=r[o-1];o-- >0;)r[o]=s,s=e[s];return r}(s),c=new Set(a);return o.forEach((t,e)=>{c.has(e)||n.add(t)}),n}function V(t,e,r={}){const{fields:n,excludeFields:i,idKey:o,childrenKey:s,includeStructure:a=!0,maxSize:c=5e3}=r,u=H(t,{fields:n,excludeFields:i,idKey:o,childrenKey:s,includeStructure:a}),h=H(e,{fields:n,excludeFields:i,idKey:o,childrenKey:s,includeStructure:a}),d=[],l=[],f=[];for(const[t,e]of h){if(!u.has(t)){d.push(e);continue}const r=u.get(t);if(!U(r,e)){const n=W(r,e);l.push({id:t,before:r,after:e,changes:n})}}for(const[t,e]of u)h.has(t)||f.push(e);let p=!1;const y=d.length+l.length+f.length;if(y>c){p=!0;const t=Math.max(0,c),e=Math.min(d.length,Math.floor(t*(d.length/y))),r=Math.min(l.length,Math.floor(t*(l.length/y))),n=Math.min(f.length,Math.max(0,t-e-r));d.length=e,l.length=r,f.length=n}if(a){const t=function(t,e,r){const n=[],i=[],o=[],s=new Set,a=J(e),c=J(r);for(const[t,e]of c){const r=Y(a.get(t)||[],e);for(const t of r)s.add(t)}for(const e of t){const{id:t,before:r,after:a,changes:c}=e,u=$(c),h=u.parentChanged,d=!h&&u.orderChanged&&s.has(t);if(h||d){const e={moveType:h?"cross-parent":"reorder",parentChanged:u.parentChanged,orderChanged:u.orderChanged,fromParent:r.parentid,toParent:a.parentid,fromOrder:r.index,toOrder:a.index},i=c.filter(t=>"parentid"!==t.key&&"index"!==t.key);i.length>0?o.push({id:t,before:r,after:a,changes:i,moveInfo:e}):n.push({id:t,before:r,after:a,moveInfo:e})}else if(u.orderChanged){const e=c.filter(t=>"parentid"!==t.key&&"index"!==t.key);e.length>0&&i.push({id:t,before:r,after:a,changes:e})}else i.push({id:t,before:r,after:a,changes:c})}return{moved:n,modified:i,movedAndModified:o}}(l,u,h);return{created:d,deleted:f,truncated:p,moved:t.moved,modified:t.modified,movedAndModified:t.movedAndModified}}return{created:d,deleted:f,moved:[],modified:l,movedAndModified:[],truncated:p}}B({strict:!0}),B({circular:!0}),B({circular:!0,strict:!0}),B({createInternalComparator:function(){return _}}),B({strict:!0,createInternalComparator:function(){return _}}),B({circular:!0,createInternalComparator:function(){return _}}),B({circular:!0,createInternalComparator:function(){return _},strict:!0});const L={enabled:!0,throttleMs:100,maxHistory:500,storageMode:"object",autoSwitchThreshold:0,keymap:{enabled:!1,redoUsesY:!1},detail:{enabled:!1},diff:{flat:!0,fields:void 0,maxSize:5e3}};class G extends h{static instanceName="historyPlugin";static preload=!0;constructor({jm:t,pluginOpt:e}){super({jm:t,pluginOpt:e}),this.options=function(t){const e=Object.assign({},L,t||{});return e.keymap||(e.keymap={enabled:!1,redoUsesY:!1}),e.detail||(e.detail={enabled:!1}),e.diff||(e.diff={flat:!0,fields:void 0,maxSize:5e3}),e}(e),this._mounted=!1,this._core=null,this._mountAPI(),this._initCore()}beforePluginDestroy(){u.debug("[history] beforePluginDestroy: clearing history stack"),this._core&&this._core.clear()}_initCore(){const t=this.jm,n=this.options;n.keymap&&n.keymap.enabled&&t.options&&t.options.shortcut&&this._injectShortcuts(t.options.shortcut,!!n.keymap.redoUsesY);const i=new Q(t,n);this._core=i,t.history&&(t.history.add=(t,e)=>i.add(t,e),t.history.pause=()=>i.pause(),t.history.resume=t=>i.resume(!!t),t.history.clear=()=>i.clear(),t.history.canBack=()=>i.canBack(),t.history.canForward=()=>i.canForward(),t.history.back=t=>i.back("number"==typeof t?t:1),t.history.forward=t=>i.forward("number"==typeof t?t:1),t.history.length=()=>i.length(),t.history.index=()=>i.index(),t.history.setMax=t=>i.setMax(t),t.history.setThrottle=t=>i.setThrottle(t),t.history.exportSnapshot=()=>i.exportSnapshot(),t.history.importSnapshot=(t,e)=>i.importSnapshot(t,e),t.history.getStack=()=>i.getStackMeta(),t.history.diff=(t,e,r)=>{const n=this.jm.options.fieldNames,i=n?.id||"id";return V(t,e,{fields:[n?.topic||"topic","data",i],idKey:i,childrenKey:n?.children||"children",...r})},this._listener=(t,n)=>{try{if(t===e&&n&&"data"in n){let t=null;const e=n.data&&n.data[0];if(e)if(e.data)if(Array.isArray(e.data)){const r=e.data.find(t=>t.isroot);t=r&&r.id}else t=e.data.id;else e.id&&(t=e.id);return void(t&&t!==i._lastRootId&&(u.debug("[history] root id changed, clearing stack and pausing"),i.clear(),i._lastRootId=t,setTimeout(()=>{try{u.debug("[history] adding bootstrap snapshot after show"),i._addNow&&i._addNow("bootstrap"),u.debug("[history] resuming history recording")}catch(t){u.warn("[history] failed to add bootstrap snapshot",t)}},100)))}t===r&&n&&n.evt&&i.add(n.evt,n)}catch(t){u.warn("[history] listener error",t)}},t.add_event_listener(this._listener))}_injectShortcuts(t,e){const r=[4186,8282],n=e?[4185,8281]:[5210,9306];t.handles.history_back=(t,e)=>{t.history&&t.history.back()&&(e.preventDefault(),e.stopPropagation&&e.stopPropagation())},t.handles.history_forward=(t,e)=>{t.history&&t.history.forward()&&(e.preventDefault(),e.stopPropagation&&e.stopPropagation())},t.mapping.history_back=r,t.mapping.history_forward=n}_mountAPI(){if(this._mounted)return;const t=this.jm,e={add:()=>{},pause:()=>{},resume:t=>{},clear:()=>{},canBack:()=>!1,canForward:()=>!1,back:t=>!1,forward:t=>!1,length:()=>0,index:()=>-1,setMax:t=>{},setThrottle:t=>{},exportSnapshot:()=>null,importSnapshot:(t,e)=>{},getStack:()=>({items:[],index:-1}),diff:(t,e,r)=>{const n=this.jm.options.fieldNames,i=n?.id||"id";return V(t,e,{fields:[n?.topic||"topic","data",i],idKey:i,childrenKey:n?.children||"children",...r})},getOptions:()=>Object.assign({},this.options)};Object.defineProperty(t,"history",{value:e,configurable:!0,enumerable:!1,writable:!1}),this._mounted=!0,u.info("[history] API mounted (preload).")}beforePluginRemove(){try{if(this._listener&&this.jm&&Array.isArray(this.jm.event_handles)){const t=this.jm.event_handles.indexOf(this._listener);t>=0&&this.jm.event_handles.splice(t,1)}this.jm&&Object.prototype.hasOwnProperty.call(this.jm,"history")&&delete this.jm.history,this._mounted=!1}catch(t){u.error("[history] remove failed:",t)}}beforePluginDestroy(){u.error("beforePluginDestroy"),this.beforePluginRemove()}}class Q{constructor(t,e){this.jm=t,this.options=e,this.enabled=!!e.enabled,this.maxHistory=Math.max(1,0|e.maxHistory),this.throttleMs=Math.max(0,0|e.throttleMs),this.storageMode=e.storageMode||"object",this.autoSwitchThreshold=Math.max(0,0|e.autoSwitchThreshold),this._history=[],this._idx=-1,this._paused=!1,this._lastAddAt=0,this._timer=0,this._pending=!1,this._pendingMeta=void 0,this._lastSig=null,this._lastRootId=null}add(t="manual",e){if(!this.enabled||this._paused)return;const r=Date.now()-this._lastAddAt;if(r>=this.throttleMs)return this._addNow(t,e),void(this._lastAddAt=Date.now());if(this._pending=!0,this._pendingMeta=e,this._timer)return;const n=Math.max(0,this.throttleMs-r);this._timer=setTimeout(()=>{this._timer=0,!this._paused&&this.enabled&&(this._addNow(t,this._pendingMeta),this._lastAddAt=Date.now()),this._pending=!1,this._pendingMeta=void 0},n)}pause(){this._paused=!0}resume(t=!1){this._paused=!1,t&&this._pending&&(clearTimeout(this._timer),this._timer=0,this._addNow("resume-flush",this._pendingMeta),this._lastAddAt=Date.now(),this._pending=!1,this._pendingMeta=void 0)}clear(){this._history=[],this._idx=-1,this._lastSig=null,this._notifyChange()}canBack(){return this._idx>0}canForward(){return this._idx>=0&&this._idx<this._history.length-1}back(t=1){if((!Number.isFinite(t)||t<=0)&&(t=1),this._idx-t<0)return!1;this._idx-=t;const e=this._applyIndex();return e&&this._notifyChange(),e}forward(t=1){if((!Number.isFinite(t)||t<=0)&&(t=1),this._idx+t>=this._history.length)return!1;this._idx+=t;const e=this._applyIndex();return e&&this._notifyChange(),e}length(){return this._history.length}index(){return this._idx}setMax(t){this.maxHistory=Math.max(1,0|t)}setThrottle(t){this.throttleMs=Math.max(0,0|t)}exportSnapshot(){return this._takeSnapshot()}importSnapshot(t,e){return this._applySnapshot(t,e)}getStackMeta(){return{items:this._history.slice(),index:this._idx}}_notifyChange(){try{this.jm.invoke_event_handle(n,{index:this._idx,length:this._history.length,canBack:this.canBack(),canForward:this.canForward()})}catch(t){u.warn("[history] failed to notify change",t)}}_addNow(t,e){const r=this._takeSnapshot();let n=this.storageMode;if(this.autoSwitchThreshold>0&&"object"===n){const t=this._countNodes(r);t>this.autoSwitchThreshold&&(n="string",u.debug(`[history] auto-switched to string mode (${t} nodes > ${this.autoSwitchThreshold})`))}let i=null;try{i=JSON.stringify(r)}catch{}if(!i||!this._lastSig||i!==this._lastSig){if(this._idx<this._history.length-1&&(this._history=this._history.slice(0,this._idx+1)),this._history.length>=this.maxHistory&&(this._history.shift(),this._idx=Math.max(-1,this._idx-1)),"string"===n)this._history.push(i);else{const t=this._deepFreeze(r);this._history.push(t)}this._idx=this._history.length-1,this._lastSig=i,this._notifyChange()}}_applyIndex(){const t=this._history[this._idx];if(!t)return!1;try{let e;if("string"==typeof t)e=JSON.parse(t),this._lastSig=t;else{e=this._cloneSnapshot(t);try{this._lastSig=JSON.stringify(t)}catch{this._lastSig=null}}return this._applySnapshot(e,{skipCentering:!0}),!0}catch(t){return u.error("[history] apply snapshot failed",t),!1}}_takeSnapshot(){return this.jm.get_data("node_tree")}_applySnapshot(t,e){const r=!(!e||!e.skipCentering);return this.jm.show(t,r),!0}_countNodes(t){let e=0;return function t(r){if(r&&(e++,r.children&&Array.isArray(r.children)))for(const e of r.children)t(e)}(t&&t.data?t.data:t),e}_deepFreeze(t){if(!t||"object"!=typeof t)return t;if(Object.isFrozen(t))return t;if(Object.freeze(t),Array.isArray(t))for(const e of t)this._deepFreeze(e);else for(const e of Object.keys(t))this._deepFreeze(t[e]);return t}_cloneSnapshot(t){if("function"==typeof structuredClone)try{return structuredClone(t)}catch{}try{return JSON.parse(JSON.stringify(t))}catch{return t}}}t.HistoryPlugin=G,t.default=G,Object.defineProperty(t,"__esModule",{value:!0})});
|
|
9
9
|
//# sourceMappingURL=jsmind.history.js.map
|