@umbraci/jsmind 0.10.2 → 0.10.4

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.
@@ -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 */\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 // 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","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/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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"}
@@ -5,5 +5,5 @@
5
5
  * Project Home:
6
6
  * https://github.com/hizzgdev/jsmind/
7
7
  */
8
- "function"!=typeof String.prototype.startsWith&&(String.prototype.startsWith=function(t){return this.slice(0,t.length)===t});const t=1,e=3,r=6,i=1,n=2,o=3,a=4;var s=function(){};let h="undefined"==typeof console?{level:s,log:s,debug:s,info:s,warn:s,error:s}:{level:function(t){h.debug=t>i?s:console.debug;h.info=t>n?s:console.info;h.warn=t>o?s:console.warn;h.error=t>a?s: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 c=Object.getOwnPropertyNames,l=Object.getOwnPropertySymbols,d=Object.prototype.hasOwnProperty;function f(t,e){return function(r,i,n){return t(r,i,n)&&e(r,i,n)}}function p(t){return function(e,r,i){if(!e||!r||"object"!=typeof e||"object"!=typeof r)return t(e,r,i);var n=i.cache,o=n.get(e),a=n.get(r);if(o&&a)return o===r&&a===e;n.set(e,r),n.set(r,e);var s=t(e,r,i);return n.delete(e),n.delete(r),s}}function y(t){return c(t).concat(l(t))}var g=Object.hasOwn||function(t,e){return d.call(t,e)};function m(t,e){return t===e||!t&&!e&&t!=t&&e!=e}var _=Object.getOwnPropertyDescriptor,b=Object.keys;function v(t,e,r){var i=t.length;if(e.length!==i)return!1;for(;i-- >0;)if(!r.equals(t[i],e[i],i,i,t,e,r))return!1;return!0}function j(t,e){return m(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 x(t,e){return t===e}function w(t,e,r){var i=t.size;if(i!==e.size)return!1;if(!i)return!0;for(var n,o,a=new Array(i),s=t.entries(),h=0;(n=s.next())&&!n.done;){for(var u=e.entries(),c=!1,l=0;(o=u.next())&&!o.done;)if(a[l])l++;else{var d=n.value,f=o.value;if(r.equals(d[0],f[0],h,l,t,e,r)&&r.equals(d[1],f[1],d[0],f[0],t,e,r)){c=a[l]=!0;break}l++}if(!c)return!1;h++}return!0}var k=m;function M(t,e,r){var i=b(t),n=i.length;if(b(e).length!==n)return!1;for(;n-- >0;)if(!N(t,e,r,i[n]))return!1;return!0}function O(t,e,r){var i,n,o,a=y(t),s=a.length;if(y(e).length!==s)return!1;for(;s-- >0;){if(!N(t,e,r,i=a[s]))return!1;if(n=_(t,i),o=_(e,i),(n||o)&&(!n||!o||n.configurable!==o.configurable||n.enumerable!==o.enumerable||n.writable!==o.writable))return!1}return!0}function q(t,e){return m(t.valueOf(),e.valueOf())}function A(t,e){return t.source===e.source&&t.flags===e.flags}function E(t,e,r){var i=t.size;if(i!==e.size)return!1;if(!i)return!0;for(var n,o,a=new Array(i),s=t.values();(n=s.next())&&!n.done;){for(var h=e.values(),u=!1,c=0;(o=h.next())&&!o.done;){if(!a[c]&&r.equals(n.value,o.value,n.value,o.value,t,e,r)){u=a[c]=!0;break}c++}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 C(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 N(t,e,r,i){return!("_owner"!==i&&"__o"!==i&&"__v"!==i||!t.$$typeof&&!e.$$typeof)||g(e,i)&&r.equals(t[i],e[i],i,i,t,e,r)}var T=Array.isArray,D="function"==typeof ArrayBuffer&&ArrayBuffer.isView?ArrayBuffer.isView:null,I=Object.assign,z=Object.prototype.toString.call.bind(Object.prototype.toString);function F(t){var e=t.areArraysEqual,r=t.areDatesEqual,i=t.areErrorsEqual,n=t.areFunctionsEqual,o=t.areMapsEqual,a=t.areNumbersEqual,s=t.areObjectsEqual,h=t.arePrimitiveWrappersEqual,u=t.areRegExpsEqual,c=t.areSetsEqual,l=t.areTypedArraysEqual,d=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?a(t,p,y):"function"===g&&n(t,p,y);var m=t.constructor;if(m!==p.constructor)return!1;if(m===Object)return s(t,p,y);if(T(t))return e(t,p,y);if(null!=D&&D(t))return l(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 c(t,p,y);var _,b=z(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 c(t,p,y);if("[object Object]"===b)return"function"!=typeof t.then&&"function"!=typeof p.then&&s(t,p,y);if("[object URL]"===b)return d(t,p,y);if("[object Error]"===b)return i(t,p,y);if("[object Arguments]"===b)return s(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 j=null!=(_=t)?_[Symbol.toStringTag]:void 0;j&&(v=f[j])}if(v)return v(t,p,y)}return!1}}var K=R();function R(t){void 0===t&&(t={});var e,r=t.circular,i=void 0!==r&&r,n=t.createInternalComparator,o=t.createState,a=t.strict,s=void 0!==a&&a,h=function(t){var e=t.circular,r=t.createCustomConfig,i=t.strict,n={areArraysEqual:i?O:v,areDatesEqual:j,areErrorsEqual:S,areFunctionsEqual:x,areMapsEqual:i?f(w,O):w,areNumbersEqual:k,areObjectsEqual:i?O:M,arePrimitiveWrappersEqual:q,areRegExpsEqual:A,areSetsEqual:i?f(E,O):E,areTypedArraysEqual:i?O:P,areUrlsEqual:C,unknownTagComparators:void 0};if(r&&(n=I({},n,r(n))),e){var o=p(n.areArraysEqual),a=p(n.areMapsEqual),s=p(n.areObjectsEqual),h=p(n.areSetsEqual);n=I({},n,{areArraysEqual:o,areMapsEqual:a,areObjectsEqual:s,areSetsEqual:h})}return n}(t),u=F(h);return function(t){var e=t.circular,r=t.comparator,i=t.createState,n=t.equals,o=t.strict;if(i)return function(t,a){var s=i(),h=s.cache,u=void 0===h?e?new WeakMap:void 0:h,c=s.meta;return r(t,a,{cache:u,equals:n,meta:c,strict:o})};if(e)return function(t,e){return r(t,e,{cache:new WeakMap,equals:n,meta:void 0,strict:o})};var a={cache:void 0,equals:n,meta:void 0,strict:o};return function(t,e){return r(t,e,a)}}({circular:i,comparator:u,createState:o,equals:n?n(u):(e=u,function(t,r,i,n,o,a,s){return e(t,r,s)}),strict:s})}function B(t,e){const r=function(t){return(e=t)&&"object"==typeof e&&"data"in e?t.data:t;var e}(t),i=e&&Array.isArray(e.fields)?e.fields:["topic","data","id"],n=e&&e.idKey?e.idKey:"id",o=e&&e.childrenKey?e.childrenKey:"children",a=!e||!1!==e.includeStructure,s=new Map;return r&&r[n]&&function t(e,r,h){const u=function(t){const e={};n in t&&(e[n]=t[n]);for(const r of i)r in t&&r!==n&&(e[r]=t[r]);return e}(e),c=e[n];a&&(u._parentid=r||null,u._order="number"==typeof h?h:0),s.set(c,u);const l=e[o];l&&Array.isArray(l)&&l.forEach((e,r)=>t(e,c,r))}(r,null,0),s}function U(t,e){if(t===e)return!0;if(!t||!e)return!1;const r=Object.keys(t),i=Object.keys(e);if(r.length!==i.length)return!1;for(const i of r){const r=t[i],n=e[i];if(r===n)continue;if(r&&n&&"object"==typeof r&&"object"==typeof n){if(!K(r,n))return!1}else if(r!==n)return!1}return!0}function W(t,e){const r=[];if(!t||!e)return r;const i=new Set([...Object.keys(t),...Object.keys(e)]);i.delete("id");for(const n of i){const i=t[n],o=e[n];if(i===o)continue;(i&&o&&"object"==typeof i&&"object"==typeof o?!K(i,o):i!==o)&&r.push({key:n,before:i,after:o})}return r}function $(t){let e=!1,r=!1;for(const i of t)"_parentid"===i.key&&(e=!0),"_order"===i.key&&(r=!0);return{moved:e||r,parentChanged:e,orderChanged:r}}function H(t,e,r){const i=r&&r.fields,n=r&&r.idKey,o=r&&r.childrenKey,a=!r||!1!==r.includeStructure,s=r&&"number"==typeof r.maxSize?r.maxSize:5e3,h=r&&!0===r.categorize,u=B(t,{fields:i,idKey:n,childrenKey:o,includeStructure:a}),c=B(e,{fields:i,idKey:n,childrenKey:o,includeStructure:a}),l=[],d=[],f=[];for(const[t,e]of c){if(!u.has(t)){l.push(e);continue}const r=u.get(t);if(!U(r,e)){const i=W(r,e);d.push({id:t,before:r,after:e,changes:i})}}for(const[t,e]of u)c.has(t)||f.push(e);let p=!1;const y=l.length+d.length+f.length;if(y>s){p=!0;const t=Math.max(0,s),e=Math.min(l.length,Math.floor(t*(l.length/y))),r=Math.min(d.length,Math.floor(t*(d.length/y))),i=Math.min(f.length,Math.max(0,t-e-r));l.length=e,d.length=r,f.length=i}if(h&&a){const t=function(t){const e=[],r=[],i=[];for(const n of t){const{id:t,before:o,after:a,changes:s}=n,h=$(s);if(h.moved){const r={parentChanged:h.parentChanged,orderChanged:h.orderChanged,fromParent:o._parentid,toParent:a._parentid,fromOrder:o._order,toOrder:a._order},n=s.filter(t=>"_parentid"!==t.key&&"_order"!==t.key);n.length>0?i.push({id:t,before:o,after:a,changes:n,moveInfo:r}):e.push({id:t,before:o,after:a,moveInfo:r})}else r.push({id:t,before:o,after:a,changes:s})}return{moved:e,modified:r,movedAndModified:i}}(d);return{created:l,updated:d,deleted:f,truncated:p,moved:t.moved,modified:t.modified,movedAndModified:t.movedAndModified}}return{created:l,updated:d,deleted:f,truncated:p}}R({strict:!0}),R({circular:!0}),R({circular:!0,strict:!0}),R({createInternalComparator:function(){return m}}),R({strict:!0,createInternalComparator:function(){return m}}),R({circular:!0,createInternalComparator:function(){return m}}),R({circular:!0,createInternalComparator:function(){return m},strict:!0});const J={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 Y 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({},J,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(){h.debug("[history] beforePluginDestroy: clearing history stack"),this._core&&this._core.clear()}_initCore(){const r=this.jm,i=this.options;i.keymap&&i.keymap.enabled&&r.options&&r.options.shortcut&&this._injectShortcuts(r.options.shortcut,!!i.keymap.redoUsesY);const n=new V(r,i);this._core=n,r.history&&(r.history.add=(t,e)=>n.add(t,e),r.history.pause=()=>n.pause(),r.history.resume=t=>n.resume(!!t),r.history.clear=()=>n.clear(),r.history.canBack=()=>n.canBack(),r.history.canForward=()=>n.canForward(),r.history.back=t=>n.back("number"==typeof t?t:1),r.history.forward=t=>n.forward("number"==typeof t?t:1),r.history.length=()=>n.length(),r.history.index=()=>n.index(),r.history.setMax=t=>n.setMax(t),r.history.setThrottle=t=>n.setThrottle(t),r.history.exportSnapshot=()=>n.exportSnapshot(),r.history.importSnapshot=(t,e)=>n.importSnapshot(t,e),r.history.getStack=()=>n.getStackMeta(),r.history.diff=(t,e,r)=>{const i=this.jm.options.fieldNames,n=i?.id||"id";return H(t,e,{fields:[i?.topic||"topic","data",n],idKey:n,childrenKey:i?.children||"children",...r})},this._listener=(r,i)=>{try{if(r===t&&i&&"data"in i){let t=null;const e=i.data&&i.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!==n._lastRootId&&(h.debug("[history] root id changed, clearing stack and pausing"),n.clear(),n._lastRootId=t,setTimeout(()=>{try{h.debug("[history] adding bootstrap snapshot after show"),n._addNow&&n._addNow("bootstrap"),h.debug("[history] resuming history recording")}catch(t){h.warn("[history] failed to add bootstrap snapshot",t)}},100)))}r===e&&i&&i.evt&&n.add(i.evt,i)}catch(t){h.warn("[history] listener error",t)}},r.add_event_listener(this._listener))}_injectShortcuts(t,e){const r=[4186,8282],i=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=i}_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 i=this.jm.options.fieldNames,n=i?.id||"id";return H(t,e,{fields:[i?.topic||"topic","data",n],idKey:n,childrenKey:i?.children||"children",...r})},getOptions:()=>Object.assign({},this.options)};Object.defineProperty(t,"history",{value:e,configurable:!0,enumerable:!1,writable:!1}),this._mounted=!0,h.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){h.error("[history] remove failed:",t)}}beforePluginDestroy(){h.error("beforePluginDestroy"),this.beforePluginRemove()}}class V{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 i=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},i)}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(r,{index:this._idx,length:this._history.length,canBack:this.canBack(),canForward:this.canForward()})}catch(t){h.warn("[history] failed to notify change",t)}}_addNow(t,e){const r=this._takeSnapshot();let i=this.storageMode;if(this.autoSwitchThreshold>0&&"object"===i){const t=this._countNodes(r);t>this.autoSwitchThreshold&&(i="string",h.debug(`[history] auto-switched to string mode (${t} nodes > ${this.autoSwitchThreshold})`))}let n=null;try{n=JSON.stringify(r)}catch{}if(!n||!this._lastSig||n!==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"===i)this._history.push(n);else{const t=this._deepFreeze(r);this._history.push(t)}this._idx=this._history.length-1,this._lastSig=n,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 h.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}}}export{Y as HistoryPlugin,Y as default};
8
+ "function"!=typeof String.prototype.startsWith&&(String.prototype.startsWith=function(t){return this.slice(0,t.length)===t});const t=1,e=3,r=6,i=1,n=2,o=3,a=4;var s=function(){};let h="undefined"==typeof console?{level:s,log:s,debug:s,info:s,warn:s,error:s}:{level:function(t){h.debug=t>i?s:console.debug;h.info=t>n?s:console.info;h.warn=t>o?s:console.warn;h.error=t>a?s: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 c=Object.getOwnPropertyNames,l=Object.getOwnPropertySymbols,d=Object.prototype.hasOwnProperty;function f(t,e){return function(r,i,n){return t(r,i,n)&&e(r,i,n)}}function p(t){return function(e,r,i){if(!e||!r||"object"!=typeof e||"object"!=typeof r)return t(e,r,i);var n=i.cache,o=n.get(e),a=n.get(r);if(o&&a)return o===r&&a===e;n.set(e,r),n.set(r,e);var s=t(e,r,i);return n.delete(e),n.delete(r),s}}function y(t){return c(t).concat(l(t))}var g=Object.hasOwn||function(t,e){return d.call(t,e)};function m(t,e){return t===e||!t&&!e&&t!=t&&e!=e}var _=Object.getOwnPropertyDescriptor,b=Object.keys;function v(t,e,r){var i=t.length;if(e.length!==i)return!1;for(;i-- >0;)if(!r.equals(t[i],e[i],i,i,t,e,r))return!1;return!0}function j(t,e){return m(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 x(t,e){return t===e}function w(t,e,r){var i=t.size;if(i!==e.size)return!1;if(!i)return!0;for(var n,o,a=new Array(i),s=t.entries(),h=0;(n=s.next())&&!n.done;){for(var u=e.entries(),c=!1,l=0;(o=u.next())&&!o.done;)if(a[l])l++;else{var d=n.value,f=o.value;if(r.equals(d[0],f[0],h,l,t,e,r)&&r.equals(d[1],f[1],d[0],f[0],t,e,r)){c=a[l]=!0;break}l++}if(!c)return!1;h++}return!0}var k=m;function M(t,e,r){var i=b(t),n=i.length;if(b(e).length!==n)return!1;for(;n-- >0;)if(!N(t,e,r,i[n]))return!1;return!0}function O(t,e,r){var i,n,o,a=y(t),s=a.length;if(y(e).length!==s)return!1;for(;s-- >0;){if(!N(t,e,r,i=a[s]))return!1;if(n=_(t,i),o=_(e,i),(n||o)&&(!n||!o||n.configurable!==o.configurable||n.enumerable!==o.enumerable||n.writable!==o.writable))return!1}return!0}function q(t,e){return m(t.valueOf(),e.valueOf())}function A(t,e){return t.source===e.source&&t.flags===e.flags}function E(t,e,r){var i=t.size;if(i!==e.size)return!1;if(!i)return!0;for(var n,o,a=new Array(i),s=t.values();(n=s.next())&&!n.done;){for(var h=e.values(),u=!1,c=0;(o=h.next())&&!o.done;){if(!a[c]&&r.equals(n.value,o.value,n.value,o.value,t,e,r)){u=a[c]=!0;break}c++}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 C(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 N(t,e,r,i){return!("_owner"!==i&&"__o"!==i&&"__v"!==i||!t.$$typeof&&!e.$$typeof)||g(e,i)&&r.equals(t[i],e[i],i,i,t,e,r)}var T=Array.isArray,D="function"==typeof ArrayBuffer&&ArrayBuffer.isView?ArrayBuffer.isView:null,I=Object.assign,z=Object.prototype.toString.call.bind(Object.prototype.toString);function F(t){var e=t.areArraysEqual,r=t.areDatesEqual,i=t.areErrorsEqual,n=t.areFunctionsEqual,o=t.areMapsEqual,a=t.areNumbersEqual,s=t.areObjectsEqual,h=t.arePrimitiveWrappersEqual,u=t.areRegExpsEqual,c=t.areSetsEqual,l=t.areTypedArraysEqual,d=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?a(t,p,y):"function"===g&&n(t,p,y);var m=t.constructor;if(m!==p.constructor)return!1;if(m===Object)return s(t,p,y);if(T(t))return e(t,p,y);if(null!=D&&D(t))return l(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 c(t,p,y);var _,b=z(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 c(t,p,y);if("[object Object]"===b)return"function"!=typeof t.then&&"function"!=typeof p.then&&s(t,p,y);if("[object URL]"===b)return d(t,p,y);if("[object Error]"===b)return i(t,p,y);if("[object Arguments]"===b)return s(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 j=null!=(_=t)?_[Symbol.toStringTag]:void 0;j&&(v=f[j])}if(v)return v(t,p,y)}return!1}}var K=R();function R(t){void 0===t&&(t={});var e,r=t.circular,i=void 0!==r&&r,n=t.createInternalComparator,o=t.createState,a=t.strict,s=void 0!==a&&a,h=function(t){var e=t.circular,r=t.createCustomConfig,i=t.strict,n={areArraysEqual:i?O:v,areDatesEqual:j,areErrorsEqual:S,areFunctionsEqual:x,areMapsEqual:i?f(w,O):w,areNumbersEqual:k,areObjectsEqual:i?O:M,arePrimitiveWrappersEqual:q,areRegExpsEqual:A,areSetsEqual:i?f(E,O):E,areTypedArraysEqual:i?O:P,areUrlsEqual:C,unknownTagComparators:void 0};if(r&&(n=I({},n,r(n))),e){var o=p(n.areArraysEqual),a=p(n.areMapsEqual),s=p(n.areObjectsEqual),h=p(n.areSetsEqual);n=I({},n,{areArraysEqual:o,areMapsEqual:a,areObjectsEqual:s,areSetsEqual:h})}return n}(t),u=F(h);return function(t){var e=t.circular,r=t.comparator,i=t.createState,n=t.equals,o=t.strict;if(i)return function(t,a){var s=i(),h=s.cache,u=void 0===h?e?new WeakMap:void 0:h,c=s.meta;return r(t,a,{cache:u,equals:n,meta:c,strict:o})};if(e)return function(t,e){return r(t,e,{cache:new WeakMap,equals:n,meta:void 0,strict:o})};var a={cache:void 0,equals:n,meta:void 0,strict:o};return function(t,e){return r(t,e,a)}}({circular:i,comparator:u,createState:o,equals:n?n(u):(e=u,function(t,r,i,n,o,a,s){return e(t,r,s)}),strict:s})}function B(t,e){const r=function(t){return(e=t)&&"object"==typeof e&&"data"in e?t.data:t;var e}(t),i=e&&Array.isArray(e.fields)?e.fields:["topic","data","id"],n=e&&e.idKey?e.idKey:"id",o=e&&e.childrenKey?e.childrenKey:"children",a=!e||!1!==e.includeStructure,s=new Map;return r&&r[n]&&function t(e,r,h){const u=function(t){const e={};n in t&&(e[n]=t[n]);const r=new Set([n,o,"direction","expanded"]),a={};let s=!1;for(const o of i)if("data"===o){for(const e in t)r.has(e)||i.includes(e)||(a[e]=t[e],s=!0);s&&(e.data=a)}else o in t&&o!==n&&(e[o]=t[o]);return e}(e),c=e[n];a&&(u._parentid=r||null,u._order="number"==typeof h?h:0),s.set(c,u);const l=e[o];l&&Array.isArray(l)&&l.forEach((e,r)=>t(e,c,r))}(r,null,0),s}function U(t,e){if(t===e)return!0;if(!t||!e)return!1;const r=Object.keys(t),i=Object.keys(e);if(r.length!==i.length)return!1;for(const i of r){const r=t[i],n=e[i];if(r===n)continue;if(r&&n&&"object"==typeof r&&"object"==typeof n){if(!K(r,n))return!1}else if(r!==n)return!1}return!0}function W(t,e){const r=[];if(!t||!e)return r;const i=new Set([...Object.keys(t),...Object.keys(e)]);i.delete("id");for(const n of i){const i=t[n],o=e[n];if(i===o)continue;(i&&o&&"object"==typeof i&&"object"==typeof o?!K(i,o):i!==o)&&r.push({key:n,before:i,after:o})}return r}function $(t){let e=!1,r=!1;for(const i of t)"_parentid"===i.key&&(e=!0),"_order"===i.key&&(r=!0);return{moved:e||r,parentChanged:e,orderChanged:r}}function H(t,e,r){const i=r&&r.fields,n=r&&r.idKey,o=r&&r.childrenKey,a=!r||!1!==r.includeStructure,s=r&&"number"==typeof r.maxSize?r.maxSize:5e3,h=r&&!0===r.categorize,u=B(t,{fields:i,idKey:n,childrenKey:o,includeStructure:a}),c=B(e,{fields:i,idKey:n,childrenKey:o,includeStructure:a}),l=[],d=[],f=[];for(const[t,e]of c){if(!u.has(t)){l.push(e);continue}const r=u.get(t);if(!U(r,e)){const i=W(r,e);d.push({id:t,before:r,after:e,changes:i})}}for(const[t,e]of u)c.has(t)||f.push(e);let p=!1;const y=l.length+d.length+f.length;if(y>s){p=!0;const t=Math.max(0,s),e=Math.min(l.length,Math.floor(t*(l.length/y))),r=Math.min(d.length,Math.floor(t*(d.length/y))),i=Math.min(f.length,Math.max(0,t-e-r));l.length=e,d.length=r,f.length=i}if(h&&a){const t=function(t){const e=[],r=[],i=[];for(const n of t){const{id:t,before:o,after:a,changes:s}=n,h=$(s);if(h.moved){const r={parentChanged:h.parentChanged,orderChanged:h.orderChanged,fromParent:o._parentid,toParent:a._parentid,fromOrder:o._order,toOrder:a._order},n=s.filter(t=>"_parentid"!==t.key&&"_order"!==t.key);n.length>0?i.push({id:t,before:o,after:a,changes:n,moveInfo:r}):e.push({id:t,before:o,after:a,moveInfo:r})}else r.push({id:t,before:o,after:a,changes:s})}return{moved:e,modified:r,movedAndModified:i}}(d);return{created:l,updated:d,deleted:f,truncated:p,moved:t.moved,modified:t.modified,movedAndModified:t.movedAndModified}}return{created:l,updated:d,deleted:f,truncated:p}}R({strict:!0}),R({circular:!0}),R({circular:!0,strict:!0}),R({createInternalComparator:function(){return m}}),R({strict:!0,createInternalComparator:function(){return m}}),R({circular:!0,createInternalComparator:function(){return m}}),R({circular:!0,createInternalComparator:function(){return m},strict:!0});const J={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 Y 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({},J,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(){h.debug("[history] beforePluginDestroy: clearing history stack"),this._core&&this._core.clear()}_initCore(){const r=this.jm,i=this.options;i.keymap&&i.keymap.enabled&&r.options&&r.options.shortcut&&this._injectShortcuts(r.options.shortcut,!!i.keymap.redoUsesY);const n=new V(r,i);this._core=n,r.history&&(r.history.add=(t,e)=>n.add(t,e),r.history.pause=()=>n.pause(),r.history.resume=t=>n.resume(!!t),r.history.clear=()=>n.clear(),r.history.canBack=()=>n.canBack(),r.history.canForward=()=>n.canForward(),r.history.back=t=>n.back("number"==typeof t?t:1),r.history.forward=t=>n.forward("number"==typeof t?t:1),r.history.length=()=>n.length(),r.history.index=()=>n.index(),r.history.setMax=t=>n.setMax(t),r.history.setThrottle=t=>n.setThrottle(t),r.history.exportSnapshot=()=>n.exportSnapshot(),r.history.importSnapshot=(t,e)=>n.importSnapshot(t,e),r.history.getStack=()=>n.getStackMeta(),r.history.diff=(t,e,r)=>{const i=this.jm.options.fieldNames,n=i?.id||"id";return H(t,e,{fields:[i?.topic||"topic","data",n],idKey:n,childrenKey:i?.children||"children",...r})},this._listener=(r,i)=>{try{if(r===t&&i&&"data"in i){let t=null;const e=i.data&&i.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!==n._lastRootId&&(h.debug("[history] root id changed, clearing stack and pausing"),n.clear(),n._lastRootId=t,setTimeout(()=>{try{h.debug("[history] adding bootstrap snapshot after show"),n._addNow&&n._addNow("bootstrap"),h.debug("[history] resuming history recording")}catch(t){h.warn("[history] failed to add bootstrap snapshot",t)}},100)))}r===e&&i&&i.evt&&n.add(i.evt,i)}catch(t){h.warn("[history] listener error",t)}},r.add_event_listener(this._listener))}_injectShortcuts(t,e){const r=[4186,8282],i=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=i}_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 i=this.jm.options.fieldNames,n=i?.id||"id";return H(t,e,{fields:[i?.topic||"topic","data",n],idKey:n,childrenKey:i?.children||"children",...r})},getOptions:()=>Object.assign({},this.options)};Object.defineProperty(t,"history",{value:e,configurable:!0,enumerable:!1,writable:!1}),this._mounted=!0,h.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){h.error("[history] remove failed:",t)}}beforePluginDestroy(){h.error("beforePluginDestroy"),this.beforePluginRemove()}}class V{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 i=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},i)}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(r,{index:this._idx,length:this._history.length,canBack:this.canBack(),canForward:this.canForward()})}catch(t){h.warn("[history] failed to notify change",t)}}_addNow(t,e){const r=this._takeSnapshot();let i=this.storageMode;if(this.autoSwitchThreshold>0&&"object"===i){const t=this._countNodes(r);t>this.autoSwitchThreshold&&(i="string",h.debug(`[history] auto-switched to string mode (${t} nodes > ${this.autoSwitchThreshold})`))}let n=null;try{n=JSON.stringify(r)}catch{}if(!n||!this._lastSig||n!==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"===i)this._history.push(n);else{const t=this._deepFreeze(r);this._history.push(t)}this._idx=this._history.length-1,this._lastSig=n,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 h.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}}}export{Y as HistoryPlugin,Y as default};
9
9
  //# sourceMappingURL=jsmind.history.js.map