/* * Released under BSD License * Copyright (c) 2019-2020 Allen_sun_js@hotmail.com * * Project Home: * https://github.com/allensunjian */ (function ($w, temp) { var obj = null var Jm = $w[temp], name = 'menu', $d = $w['document'], menuEvent = 'oncontextmenu', clickEvent = 'onclick', $c = function (tag) { return $d.createElement(tag); }, _noop = function () { }, logger = (typeof console === 'undefined') ? { log: _noop, debug: _noop, error: _noop, warn: _noop, info: _noop } : console; var $t = function (n, t) { if (n.hasChildNodes()) { n.firstChild.nodeValue = t; } else { n.appendChild($d.createTextNode(t)); } }; var $h = function (n, t) { if (t instanceof HTMLElement) { t.innerHTML = ""; n.appendChild(t) } else { n.innerHTML = t; } }; if (!Jm || Jm[name]) return; Jm.menu = function (_jm) { obj = this this._get_menu_options(_jm, function () { this.init(_jm); this._mount_events() }) } Jm.menu.prototype = { defaultDataMap: { funcMap: { edit: { isDepNode: true, // defaultFn不受到中台变量的控制,始终会先于fn去执行 defaultFn: function (node) { var f = this._menu_default_mind_methods._menu_begin_edit.call(this.jm); f && this._menu_default_mind_methods._menu_edit_node_begin(this.jm.view, node); }, fn: _noop, text: 'edit node' }, addChild: { isDepNode: true, fn: function (nodeid,text) { var selected_node = this.get_selected_node(); if (selected_node) { var node = this.add_node(selected_node, nodeid, text); if (node) { this.select_node(nodeid); this.begin_edit(nodeid); obj._mount_events(); } } }, text: 'append child' }, addBrother: { isDepNode: true, fn: function (nodeid,text) { var selected_node = this.get_selected_node(); if (selected_node && !selected_node.isroot) { var node = this.insert_node_after(selected_node, nodeid, text); if (node) { this.select_node(nodeid); this.begin_edit(nodeid); obj._mount_events(); } } }, text: 'append brother' }, delete: { isDepNode: true, fn: function () { this.shortcut.handle_delnode.call(this.shortcut, this); }, text: 'delete node' }, showAll: { sDepNode: false, fn: function () { this.expand_all(this) }, text: 'show all' }, hideAll: { isDepNode: false, fn: function () { this.collapse_all(this) }, text: 'hide all' }, screenshot: { isDepNode: false, fn: function () { if (!this.screenshot) { logger.error('[jsmind] screenshot dependent on jsmind.screenshot.js !'); return; } this.screenshot.shootDownload(); }, text: 'load mind picture' }, showNode: { isDepNode: true, fn: function (node) { this.expand_node(node); }, text: 'show target node' }, hideNode: { isDepNode: true, fn: function (node) { this.collapse_node(node); }, text: 'hide target node' }, }, menuStl: { 'width': '150px', 'padding': '12px 0', 'position': 'fixed', 'z-index': '10', 'background': '#fff', 'box-shadow': '0 2px 12px 0 rgba(0,0,0,0.1)', 'border-radius': '5px', 'font-size': '12px', 'display': 'none' }, menuItemStl:{ padding: '5px 15px', cursor: 'pointer', display: 'block', 'text-align': 'center', 'transition':'all .2s' }, injectionList:['edit','addChild','delete'] }, init: function (_jm) { this._create_menu(_jm); this._get_injectionList(_jm); this.menuOpts.switchMidStage && Jm.util.dom.add_event(_jm.view.e_editor , 'blur', function () { this._menu_default_mind_methods._menu_edit_node_end.call(_jm.view); if(typeof this.menuOpts.editCaller == 'function') { this.menuOpts.editCaller($w.menu._update_node_info, this._menu_default_mind_methods._menu_update_edit_node) return } this._menu_default_mind_methods._menu_update_edit_node(); }.bind(this)); }, _event_contextMenu (e) { e.preventDefault(); this.menu.style.left = e.clientX + 'px'; this.menu.style.top = e.clientY + 'px'; this.menu.style.display = 'block'; this.selected_node = this.jm.get_selected_node(); } , _event_hideMenu() { this.menu.style.display = 'none' }, _mount_events () { var items = document.getElementsByTagName('jmnode') for(let i = 0; i < items.length; i++) { items[i][menuEvent] = this._event_contextMenu.bind(this); } $w[clickEvent] = this._event_hideMenu.bind(this); }, _create_menu (_jm) { var d = $c('menu'); this._set_menu_wrap_syl(d); this.menu = d; this.e_panel = _jm.view.e_panel; this.e_panel.appendChild(d); }, _create_menu_item (j, text, fn, isDepNode,cb, defaultFn) { var d = $c('menu-item'),_this = this; this._set_menu_item_syl(d); d.innerText = text; d.addEventListener('click', function () { if (this.selected_node || !isDepNode) { defaultFn.call(_this, this.selected_node); if (!_this._get_mid_opts()) { cb(this.selected_node, _noop) fn.call(j,Jm.util.uuid.newid(), this.menuOpts.newNodeText || 'New Node'); return; } cb(this.selected_node,_this._mid_stage_next(function () { var retArgs = [this.selected_node], argus = Array.prototype.slice.call(arguments[0],0); argus[1] = this.menuOpts.newNodeText || 'New Node'; if (argus[0]) { retArgs = argus } fn.apply(j,retArgs); }.bind(this))) return } alert(this.menuOpts.tipContent || 'Continue with node selected!') }.bind(this)) d.addEventListener('mouseover', function () { d.style.background = 'rgb(179, 216, 255)' }.bind(this)) d.addEventListener('mouseleave', function () { d.style.background = '#fff' }.bind(this)) return d }, _set_menu_wrap_syl (d) { var os = this._get_option_sty('menu',this._get_mixin_sty); d.style.cssText = this._format_cssText(os); }, _set_menu_item_syl (d) { var os = this._get_option_sty('menuItem',this._get_mixin_sty); d.style.cssText = this._format_cssText(os) }, _format_cssText (o) { var text = ''; Object.keys(o).forEach(function (k) { text += k +':'+o[k] +';' }) return text; }, _empty_object (o) { return Object.keys(o).length == 0? true :false }, _get_option_sty (type, fn) { var sty = this.menuOpts.style, menu = this.defaultDataMap.menuStl, menuItem = this.defaultDataMap.menuItemStl, o = {menu,menuItem} if (!sty) return o[type]; if (!sty[type]) return o[type]; if (!sty[type] || this._empty_object(sty[type])) return o[type]; return fn( o[type],sty[type]) }, _get_mixin_sty (dSty, oSty) { var o = {}; Object.keys(oSty).forEach(function (k) { o[k] = oSty[k]; }) Object.keys(dSty).forEach(function (k) { if (!o[k]) o[k] = dSty[k]; }) return o }, _get_menu_options (j, fn) { var options = j.options; if (!options.menuOpts) return; if (!options.menuOpts.showMenu) return; this.menuOpts = j.options.menuOpts fn.call(this) }, _get_injectionDetail () { var iLs = this.menuOpts.injectionList, dLs = this.defaultDataMap.injectionList; if (!iLs) return dLs; if (!Array.isArray(iLs)) { logger.error('[jsmind] injectionList must be a Array'); return; } if (iLs.length == 0) return dLs; return iLs }, _get_injectionList (j) { var list = this._get_injectionDetail(), _this = this; list.forEach(function (k) { var o = null, text = "", callback = _noop, defaultFn = _noop; if (typeof k == 'object') { o = _this.defaultDataMap.funcMap[k.target]; text = k.text; k.callback && (callback = k.callback); } else { o = _this.defaultDataMap.funcMap[k]; text = o.text; } if (o.defaultFn) defaultFn = o.defaultFn; _this.menu.appendChild(_this._create_menu_item(j ,text, o.fn, o.isDepNode,callback, defaultFn)); }) }, _get_mid_opts () { var b = this.menuOpts.switchMidStage; if (!b) return false; if (typeof b !== 'boolean') { logger.error('[jsmind] switchMidStage must be Boolean'); return false; } return b }, _switch_view_db_event () { Jm.prototype.dblclick_handle = _noop; Jm.shortcut_provider.prototype.handler = _noop; Jm.view_provider.prototype.edit_node_end = _noop; }, _mid_stage_next (fn) { return function () { fn(arguments); } }, _reset_mind_event_edit () {}, _menu_default_mind_methods: { _menu_begin_edit: function () { var f = this.get_editable(); if (!f) { logger.error('fail, this mind map is not editable.'); } return f; }, _menu_edit_node_begin (scope, node) { if (!node.topic) { logger.warn("don't edit image nodes"); return; } if (scope.editing_node != null) { this._menu_default_mind_methods._menu_edit_node_end.call(scope); } scope.editing_node = node; var view_data = node._data.view; var element = view_data.element; var topic = node.topic; var ncs = getComputedStyle(element); scope.e_editor.value = topic; scope.e_editor.style.width = (element.clientWidth - parseInt(ncs.getPropertyValue('padding-left')) - parseInt(ncs.getPropertyValue('padding-right'))) + 'px'; element.innerHTML = ''; element.appendChild(scope.e_editor); element.style.zIndex = 5; scope.e_editor.focus(); scope.e_editor.select(); }, _menu_edit_node_end: function () { if (this.editing_node != null) { var node = this.editing_node; this.editing_node = null; var view_data = node._data.view; var element = view_data.element; var topic = this.e_editor.value; element.style.zIndex = 'auto'; element.removeChild(this.e_editor); $w.menu._update_node_info = {id: node.id, topic: topic}; if (Jm.util.text.is_empty(topic) || node.topic === topic) { if (this.opts.support_html) { $h(element, node.topic); } else { $t(element, node.topic); } } } }, _menu_update_edit_node: function () { var info = $w.menu._update_node_info; $w.menu.jm.update_node(info.id, info.topic); } } } var plugin = new Jm.plugin('menu',function (_jm) { $w.menu = new Jm.menu(_jm); $w.menu.jm = _jm; if($w.menu.menuOpts) _jm.menu = $w.menu; }) Jm.register_plugin(plugin) function preventMindEventDefault() { Jm.menu.prototype._switch_view_db_event(); } Jm.preventMindEventDefault = preventMindEventDefault // eslint-disable-next-line no-unused-vars function reBuild () { if (obj !== null) { obj._mount_events() } } // export reBuild if (typeof module !== 'undefined' && typeof exports === 'object') { module.exports = { reBuild, init: function (opt) { Jm = opt } }; } // exports = { // reBuild, // // init: function (opt) { // // console.log(opt) // // } // }; // $w['render'] = function () { // if (obj !== null) { // obj._mount_events() // } // } })(window, 'jsMind')