diff options
Diffstat (limited to 'plugins/55/indexmenu/scripts')
143 files changed, 70782 insertions, 0 deletions
diff --git a/plugins/55/indexmenu/scripts/contextmenu.js b/plugins/55/indexmenu/scripts/contextmenu.js new file mode 100644 index 0000000..051401e --- /dev/null +++ b/plugins/55/indexmenu/scripts/contextmenu.js @@ -0,0 +1,429 @@ +/** + * Right Context Menu configuration + * + * Some usefull variables: + * node.hns = headpage id; + * node.isdir = node is namespace; + * node.dokuid = the DW id (namespace parent in case of headpage); + * id = the DW id of the selected node (headpage id in case of headpage); + * index.config.urlbase = Url Base; + * index.config.sepchar = Url separator; + * + * HOWTO EDIT: + * + * To override menu entries or add a menu entry: + * - PLEASE EDIT ONLY the scripts/contextmenu.local.js file + * - DON'T EDIT this file, it is overwritten at plugin update + * + * Base structure of the context menu is displayed below. + * The entries with 'pg' are shown for page noded, these with 'ns' only for namespaces. + * + * Current available for everybody: + * indexmenu_contextmenu['all']['pg']['view'] = [...array with menu description here... ]; + * indexmenu_contextmenu['all']['pg']['edit'] = [ ... ]; + * indexmenu_contextmenu['all']['ns']['view'] = [ ... ]; + * + * Current available for admins: + * indexmenu_contextmenu['pg']['view'] = [ ... ]; + * indexmenu_contextmenu['ns']['view'] = [ ... ]; + * + * Current available for authenticated users: + * indexmenu_contextmenu['pg']['view'] = [ ... ]; + * indexmenu_contextmenu['ns']['view'] = [ ... ]; + * + * A menu description may contain four kind of entries: + * - section title: array with one entry e.g.: + * ['Section title (html allowed)'] + * - menu action: array with two entries e.g.: + * ['Title of action 1 (html allowed)', 'javascript here ... see for examples scripts/contextmenu.js'] + * - menu action with custom tooltip: array with three entries e.g.: + * ['Title of action 1 (html allowed)', 'javascript here ... see for examples scripts/contextmenu.js', 'Customized title'] + * - submenu: array with two entries where second entry is an array that describes again a menu e.g.: + * ['title of submenu (html allowed)', [ ...array with menu actions... ]] + * + * + * Examples: + * A menu description array: + * ... = [ + * ['section title'], + * ['title of action 1', 'javascript here'], + * ['title of submenu', [['title of subaction 1', 'javascript here'], ['title of subaction 1', 'javascript here', 'Click here for action']] ] + * ]; + * + * To Override the common menu title: + * indexmenu_contextmenu['all']['pg']['view'][0] = ['customtitle']; + * + * To override a menu entry, for example the menu title: + * indexmenu_contextmenu['all']['pg']['view'][0] = ['Custom Title']; + * + * To add option to page menu: + * Array.splice(index, howManyToRemove, description1) + * index = position to start (start counting at zero) + * howManyToRemove = number of elements that are removed (set to 1 to replace a element) + * description1 = array with menu entry description + * -> optional: description2 = optional you can add more elements at once by splice(index, howManyToRemove, description1, description2, etc) + * + * indexmenu_contextmenu['all']['pg']['view'].splice(1, 0, ['Input new page', '"javascript: IndexmenuContextmenu.reqpage(\'"+index.config.urlbase+"\',\'"+index.config.sepchar+"\',\'"+node.dokuid+"\');"']); + */ + +/* global LANG */ +/* global DOKU_BASE */ +/* global JSINFO */ + + +// IMPORTANT: DON'T MODIFY THIS FILE, BUT EDIT contextmenu.local.js PLEASE! +// THIS FILE IS OVERWRITTEN WHEN PLUGIN IS UPDATED + +/** + * Right Context Menu configuration for all users: + */ +indexmenu_contextmenu['all']['pg'] = { + 'view': [ + ['<span class="indexmenu_titlemenu"><b>'+LANG.plugins.indexmenu.page+'</b></span>'], + [LANG.plugins.indexmenu.revs, 'IndexmenuContextmenu.getid(index.config.urlbase,id)+"do=revisions"'], + [LANG.plugins.indexmenu.tocpreview, '"javascript: IndexmenuContextmenu.createTocMenu(\'call=indexmenu&req=toc&id="+id+"\',\'picker_"+index.treeName+"\',\'s"+index.treeName+node.id+"\');"'] + ], + //Menu items in edit mode, when previewing + 'edit': [ + ['<span class="indexmenu_titlemenu"><b>'+LANG.plugins.indexmenu.editmode+'</b></span>'], + [LANG.plugins.indexmenu.insertdwlink, '"javascript: IndexmenuContextmenu.insertTags(\'"+id+"\',\'"+index.config.sepchar+"\');"+index.treeName+".divdisplay(\'r\',0);"', LANG.plugins.indexmenu.insertdwlinktooltip] + ] +}; + +indexmenu_contextmenu['all']['ns'] = { + 'view': [ + ['<span class="indexmenu_titlemenu"><b>'+LANG.plugins.indexmenu.ns+'</b></span>'], + [LANG.plugins.indexmenu.search, '"javascript: IndexmenuContextmenu.srchpage(\'"+index.config.urlbase+"\',\'"+index.config.sepchar+"\',\'"+node.isdir+"\',\'"+node.dokuid+"\');"', LANG.plugins.indexmenu.searchtooltip] + ] +}; + + +if (JSINFO && JSINFO.isadmin) { + /** + * Right Context Menu configuration for admin users: + */ + indexmenu_contextmenu['pg'] = { + 'view': [ + [LANG.plugins.indexmenu.edit, 'IndexmenuContextmenu.getid(index.config.urlbase,id)+"do=edit"'], + ['<em>'+LANG.plugins.indexmenu.create+'--></em>', [ + [LANG.plugins.indexmenu.headpage, '"javascript: IndexmenuContextmenu.reqpage(\'"+index.config.urlbase+"\',\'"+index.config.sepchar+"\',\'"+node.dokuid+"\',\'"+node.name+"\');"', LANG.plugins.indexmenu.headpagetooltip], + [LANG.plugins.indexmenu.startpage, 'IndexmenuContextmenu.getid(index.config.urlbase,id+index.config.sepchar+"start")+"do=edit"', LANG.plugins.indexmenu.startpagetooltip], + [LANG.plugins.indexmenu.custompage, '"javascript: IndexmenuContextmenu.reqpage(\'"+index.config.urlbase+"\',\'"+index.config.sepchar+"\',\'"+node.dokuid+"\');"', LANG.plugins.indexmenu.custompagetooltip] + ]], + ['<em>'+LANG.plugins.indexmenu.more+'--></em>', [ + [LANG.plugins.indexmenu.acls, 'IndexmenuContextmenu.getid(index.config.urlbase,id)+"do=admin&page=acl"'], + [LANG.plugins.indexmenu.purgecache, 'IndexmenuContextmenu.getid(index.config.urlbase,id)+"purge=true"'], + [LANG.plugins.indexmenu.exporthtml, 'IndexmenuContextmenu.getid(index.config.urlbase,id)+"do=export_xhtml"'], + [LANG.plugins.indexmenu.exporttext, 'IndexmenuContextmenu.getid(index.config.urlbase,id)+"do=export_raw"'] + ]] + ] + }; + + indexmenu_contextmenu['ns'] = { + 'view': [ + [LANG.plugins.indexmenu.newpage, '"javascript: IndexmenuContextmenu.reqpage(\'"+index.config.urlbase+"\',\'"+index.config.sepchar+"\',\'"+node.dokuid+"\');"', LANG.plugins.indexmenu.newpagetooltip], + ['<em>'+LANG.plugins.indexmenu.more+'--></em>', [ + [LANG.plugins.indexmenu.headpagehere, '"javascript: IndexmenuContextmenu.reqpage(\'"+index.config.urlbase+"\',\'"+index.config.sepchar+"\',\'"+node.dokuid+"\',\'"+node.name+"\');"', LANG.plugins.indexmenu.headpageheretooltip], + [LANG.plugins.indexmenu.acls, 'IndexmenuContextmenu.getid(index.config.urlbase,node.dokuid)+"do=admin&page=acl"'] + ]] + ] + }; + +} else if (JSINFO && JSINFO.isauth) { + /** + * Right Context Menu configuration for authenticated users: + */ + indexmenu_contextmenu['pg'] = { + 'view': [ + [LANG.plugins.indexmenu.newpagehere, '"javascript: IndexmenuContextmenu.reqpage(\'"+index.config.urlbase+"\',\'"+index.config.sepchar+"\',\'"+node.dokuid+"\');"'], + ['Edit', 'IndexmenuContextmenu.getid(index.config.urlbase,id)+"do=edit"', 1, 0 ], + ['<em>'+LANG.plugins.indexmenu.more+'--></em>', [ + [LANG.plugins.indexmenu.headpagehere, '"javascript: IndexmenuContextmenu.reqpage(\'"+index.config.urlbase+"\',\'"+index.config.sepchar+"\',\'"+node.dokuid+"\',\'"+node.name+"\');"'], + [LANG.plugins.indexmenu.purgecache, 'IndexmenuContextmenu.getid(index.config.urlbase,id)+"purge=true"'], + [LANG.plugins.indexmenu.exporthtml, 'IndexmenuContextmenu.getid(index.config.urlbase,id)+"do=export_xhtml"'] + ]] + ] + }; + +} + +var IndexmenuContextmenu = { + + /** + * Common functions + * Insert your custom functions (available for all users) here. + */ + + /** + * Navigate to the search page + * + * @param {string} urlbase index.config.urlbase + * @param {string} sepchar index.config.sepchar + * @param {boolean} isdir whether a directory (probably boolean, might be string) + * @param {string} nid page id of node (dokuid mentioned in indexmenu.js) + */ + + srchpage: function (urlbase, sepchar, isdir, nid) { + const enteredText = prompt(LANG.plugins.indexmenu.insertkeywords, ""); + if (enteredText) { + let fnid = nid; + if (isdir == "0") { + fnid = fnid.substring(0, nid.lastIndexOf(sepchar)); + } + let b = urlbase, re = new RegExp(sepchar, 'g'); + fnid = fnid.replace(re, ":"); + b += (urlbase.indexOf("?id=") < 0) ? '?id=' : ''; + window.location.href = IndexmenuContextmenu.getid(b, enteredText + " @" + fnid) + "do=search"; + } + }, + + /** + * Build a url to a wiki page + * + * @param {string} urlbase + * @param {string} id + * @returns {string} + */ + getid: function (urlbase, id) { + let url = (urlbase || '') + encodeURIComponent(id || ''); + url += (urlbase.indexOf("?") < 0) ? '?' : '&'; + return url; + }, + + /** + * Navigate to the editor window + * + * @param {string} urlbase + * @param {string} sepchar + * @param {string} id + * @param {string} pagename + */ + reqpage: function (urlbase, sepchar, id, pagename) { + let newpageid; + if (pagename) { + newpageid = id + sepchar + pagename; + } else { + newpageid = prompt(LANG.plugins.indexmenu.insertpagename, ""); + if (!newpageid) { + return; + } + newpageid = id + sepchar + newpageid; + } + if (newpageid) { + window.location.href = IndexmenuContextmenu.getid(urlbase, newpageid) + "do=edit"; + } + }, + + /** + * Insert link syntax with given id in current editor window + * + * @param {string} lnk page id + * @param {string} sepchar + */ + insertTags: function (lnk, sepchar) { + let r, l = lnk; + if (sepchar) { + r = new RegExp(sepchar, "g"); + l = lnk.replace(r, ':'); + } + insertTags('wiki__text', '[[', ']]', l); + }, + + /** + * Create or catch the picker and hide it, next call the ajax content loading to get the ToC + * + * @param {string} get query string + * @param {string} picker id of picker + * @param {string} btn id of button + */ + createTocMenu: function (get, picker, btn) { + var $toc_picker = jQuery('#' + picker); + if (!$toc_picker.length) { + $toc_picker = IndexmenuUtils.createPicker(picker, 'indexmenu_toc'); + $toc_picker + .html('<a href="#"><img src="' + DOKU_BASE + 'lib/plugins/indexmenu/images/close.gif" class="indexmenu_close" /></a><div />') + .children().first().click(function (event) { + event.stopPropagation(); + return IndexmenuContextmenu.togglePicker($toc_picker, jQuery('#' + btn)); + }); + } else { + $toc_picker.hide(); + } + IndexmenuContextmenu.ajaxmenu(get, $toc_picker, jQuery('#' + btn), $toc_picker.children().last(), null); + }, + + /** + * Shows the picker and adds to it or to an internal containter the ajax content + * + * @param {string} get query string + * @param {jQuery} $picker + * @param {jQuery} $btn + * @param {jQuery} $container if defined ajax result is added to it, otherwise to $picker + * @param {function} oncomplete called when defined to handle ajax result + */ + ajaxmenu: function (get, $picker, $btn, $container, oncomplete) { + var $indx_list; + $indx_list = $container || $picker; + + if (!IndexmenuContextmenu.togglePicker($picker, $btn)) return; + + var onComplete = function (data) { + $indx_list.html(''); + if (typeof oncomplete == 'function') { + oncomplete(data, $indx_list); + } else { + $indx_list.html(data); + } + }; + + //get content for picker/container + jQuery.ajax({ + type: "POST", + url: DOKU_BASE + 'lib/exe/ajax.php', + data: get, + beforeSend: function () { + $indx_list.html('<div class="tocheader">'+LANG.plugins.indexmenu.loading+'</div>'); + }, + success: onComplete, + dataType: 'html' + }); + }, + + + /** + * Hide/show picker, will be shown beside btn + * + * @param {string|jQuery} $picker + * @param {jQuery} $btn + * @return {Boolean} true if open, false closed + */ + togglePicker: function ($picker, $btn) { + var x = 8, y = 0; + + if (!$picker.is(':visible')) { + var pos = $btn.offset(); + //position + width of button + x += pos.left + $btn[0].offsetWidth; + y += pos.top; + + $picker + .show() + .offset({ + left: x, + top: y + }); + + return true; + } else { + $picker.hide(); + return false; + } + }, + + /** + * Fills the contextmenu by creating entries from the given configuration arrays and concatenating these + * to the #r<id> picker + * + * @param {any[]} amenu (part of) the configuration array + * @param {dTree} index the indexmenu object + * @param {int} n node id + */ + arrconcat: function (amenu, index, n) { + var html, id, item, a, li; + if (typeof amenu == 'undefined' || typeof amenu['view'] == 'undefined') { + return; + } + var cmenu = amenu['view']; + if (jQuery('#tool__bar')[0] && amenu['edit'] instanceof Array) { + cmenu = amenu['edit'].concat(cmenu); + } + var node = index.aNodes[n]; + id = node.hns || node.dokuid; + + var createCMenuEntry = function (entry) { + return '<a title="' + ((entry[2]) ? entry[2] : entry[0]) + '" href="' + eval(entry[1]) + '">' + entry[0] + '</a>'; + }; + + jQuery.each(cmenu, function (i, cmenuentry) { + if (cmenuentry == '') { + return true; + } + item = document.createElement('li'); + var $cmenu = jQuery('#r' + index.treeName); + if (cmenuentry[1]) { + if (cmenuentry[1] instanceof Array) { + html = document.createElement('ul'); + jQuery.each(cmenuentry[1], function (a, subcmenuentry) { + li = document.createElement('li'); + li.innerHTML = createCMenuEntry(subcmenuentry); + html.appendChild(li); + }); + + //} + item.innerHTML = '<span class="indexmenu_submenu">' + cmenuentry[0] + '</span>'; + html.left = $cmenu[0].width; + item.appendChild(html); + } else { + item.innerHTML = createCMenuEntry(cmenuentry); + } + } else { + item.innerHTML = cmenuentry; + } + $cmenu.children().last().append(item); + }); + }, + + /** + * Absolute positioning of the div at place of mouseclick + * + * @param obj div element + * @param e + */ + mouseposition: function (obj, e) { + //http://www.quirksmode.org/js/events_properties.html + var X = 0, Y = 0; + if (!e) e = window.event; + if (e.pageX || e.pageY) { + X = e.pageX; + Y = e.pageY; + } + else if (e.clientX || e.clientY) { + X = e.clientX + document.body.scrollLeft + document.documentElement.scrollLeft; + Y = e.clientY + document.body.scrollTop + document.documentElement.scrollTop; + } + obj.style.left = X - 5 + 'px'; + obj.style.top = Y - 5 + 'px'; + }, + + /** + * Check mouse button onmousedown event, only for middle and right mouse button contextmenu is shown + * + * @param {int} n node id + * @param {string|dTree} obj the unique name of a dTree object + * @param {event} e + */ + checkcontextm: function (n, obj, e) { + e = e || event; + // mouse clicks: which 3 === right, button 2 === right button + if ((e.which === 3 || e.button === 2) || (window.opera && e.which === 1 && e.ctrlKey)) { + obj.contextmenu(n, e); + IndexmenuContextmenu.stopevt(e); + } + }, + + /** + * Prevent default oncontextmenu event + * + * @param {event} e + * @returns {boolean} + */ + stopevt: function (e) { + if (!window.indexmenu_contextmenu) { + return true; + } + e = e || event; + e.preventDefault ? e.preventDefault() : e.returnValue = false; + return false; + } +}; + diff --git a/plugins/55/indexmenu/scripts/contextmenu.local.js.example b/plugins/55/indexmenu/scripts/contextmenu.local.js.example new file mode 100644 index 0000000..73ab81b --- /dev/null +++ b/plugins/55/indexmenu/scripts/contextmenu.local.js.example @@ -0,0 +1,70 @@ +/** + * Right Context Menu local configuration -- RENAME THIS FILE TO contextmenu.local.js -- + * How to change: + * - Rename this file to contextmenu.local.js + * - Make in this file your modifications + * - and go to the Configuration Manager and save the config again (this clears the cached javascript) + * + * See for information about available variables, menu structure, override and adding menu entries in the scripts/contextmenu.js + */ + +/** + * Right Context Menu configuration for all users: + */ +if (!indexmenu_contextmenu['all']['pg']) indexmenu_contextmenu['all']['pg'] = {'view': [] }; +if (!indexmenu_contextmenu['all']['ns']) indexmenu_contextmenu['all']['ns'] = {'view': [] }; + + +// Override title of page menu +//indexmenu_contextmenu['all']['pg']['view'][0] = ['Custom Title']; + +// add option to page menu +//indexmenu_contextmenu['all']['pg']['view'].splice(1, 0, ['Input new page', '"javascript: IndexmenuContextmenu.reqpage(\'"+index.config.urlbase+"\',\'"+index.config.sepchar+"\',\'"+node.dokuid+"\');"']); + + +if (JSINFO && JSINFO.isadmin) { + if (!indexmenu_contextmenu['pg']) indexmenu_contextmenu['pg'] = {'view': []}; + if (!indexmenu_contextmenu['ns']) indexmenu_contextmenu['ns'] = {'view': []}; + /** + * Right Context Menu configuration for admin users: + */ + + //override or add here the menu entries for admin, see for examples above + + +} else if (JSINFO && JSINFO.isauth) { + if (!indexmenu_contextmenu['pg']) indexmenu_contextmenu['pg'] = {'view': []}; + if (!indexmenu_contextmenu['ns']) indexmenu_contextmenu['ns'] = {'view': []}; + /** + * Right Context Menu configuration for authenticated users: + */ + + //override or add here the menu entries for authenticated users, see for examples above + +} + +/** + * Common available functions: + * + * Some common functions are added by [indexmenu plugin folder]/scripts/contextmenu.js + * - IndexmenuContextmenu.srchpage(urlbase, sepchar, isdir, dokuid) + * - IndexmenuContextmenu.getid(urlbase, dokuid) + * - IndexmenuContextmenu.reqpage(urlbase, sepchar, dokuid, pagename) + * - IndexmenuContextmenu.insertTags(dokuid, sepchar) + * + * Insert your custom functions (available for all users) at the bottom of this file. + */ + +/** + * Random Example function do something + * + * @param {string} id + * @param {Boolean} isdir + * @return {*} ... + */ +/* +function indexmenu_custom_dosomething(a, isdir) { + //do something + return false; +} +*/ diff --git a/plugins/55/indexmenu/scripts/contextmenu/jquery.ui-contextmenu.js b/plugins/55/indexmenu/scripts/contextmenu/jquery.ui-contextmenu.js new file mode 100644 index 0000000..a8fcf73 --- /dev/null +++ b/plugins/55/indexmenu/scripts/contextmenu/jquery.ui-contextmenu.js @@ -0,0 +1,634 @@ +/******************************************************************************* + * jquery.ui-contextmenu.js plugin. + * + * jQuery plugin that provides a context menu (based on the jQueryUI menu widget). + * + * @see https://github.com/mar10/jquery-ui-contextmenu + * + * Copyright (c) 2013-2018, Martin Wendt (http://wwWendt.de). Licensed MIT. + */ + +(function( factory ) { + "use strict"; + if ( typeof define === "function" && define.amd ) { + // AMD. Register as an anonymous module. + define([ "jquery", "jquery-ui/ui/widgets/menu" ], factory ); + } else { + // Browser globals + factory( jQuery ); + } +}(function( $ ) { + +"use strict"; + +var supportSelectstart = "onselectstart" in document.createElement("div"), + match = $.ui.menu.version.match(/^(\d)\.(\d+)/), + uiVersion = { + major: parseInt(match[1], 10), + minor: parseInt(match[2], 10) + }, + isLTE110 = ( uiVersion.major < 2 && uiVersion.minor <= 10 ), + isLTE111 = ( uiVersion.major < 2 && uiVersion.minor <= 11 ); + +$.widget("moogle.contextmenu", { + version: "@VERSION", + options: { + addClass: "ui-contextmenu", // Add this class to the outer <ul> + closeOnWindowBlur: true, // Close menu when window loses focus + appendTo: "body", // Set keyboard focus to first entry on open + autoFocus: false, // Set keyboard focus to first entry on open + autoTrigger: true, // open menu on browser's `contextmenu` event + delegate: null, // selector + hide: { effect: "fadeOut", duration: "fast" }, + ignoreParentSelect: true, // Don't trigger 'select' for sub-menu parents + menu: null, // selector or jQuery pointing to <UL>, or a definition hash + position: null, // popup positon + preventContextMenuForPopup: false, // prevent opening the browser's system + // context menu on menu entries + preventSelect: false, // disable text selection of target + show: { effect: "slideDown", duration: "fast" }, + taphold: false, // open menu on taphold events (requires external plugins) + uiMenuOptions: {}, // Additional options, used when UI Menu is created + // Events: + beforeOpen: $.noop, // menu about to open; return `false` to prevent opening + blur: $.noop, // menu option lost focus + close: $.noop, // menu was closed + create: $.noop, // menu was initialized + createMenu: $.noop, // menu was initialized (original UI Menu) + focus: $.noop, // menu option got focus + open: $.noop, // menu was opened + select: $.noop // menu option was selected; return `false` to prevent closing + }, + /** Constructor */ + _create: function() { + var cssText, eventNames, targetId, + opts = this.options; + + this.$headStyle = null; + this.$menu = null; + this.menuIsTemp = false; + this.currentTarget = null; + this.extraData = {}; + this.previousFocus = null; + + if (opts.delegate == null) { + $.error("ui-contextmenu: Missing required option `delegate`."); + } + if (opts.preventSelect) { + // Create a global style for all potential menu targets + // If the contextmenu was bound to `document`, we apply the + // selector relative to the <body> tag instead + targetId = ($(this.element).is(document) ? $("body") + : this.element).uniqueId().attr("id"); + cssText = "#" + targetId + " " + opts.delegate + " { " + + "-webkit-user-select: none; " + + "-khtml-user-select: none; " + + "-moz-user-select: none; " + + "-ms-user-select: none; " + + "user-select: none; " + + "}"; + this.$headStyle = $("<style class='moogle-contextmenu-style' />") + .prop("type", "text/css") + .appendTo("head"); + + try { + this.$headStyle.html(cssText); + } catch ( e ) { + // issue #47: fix for IE 6-8 + this.$headStyle[0].styleSheet.cssText = cssText; + } + // TODO: the selectstart is not supported by FF? + if (supportSelectstart) { + this.element.on("selectstart" + this.eventNamespace, opts.delegate, + function(event) { + event.preventDefault(); + }); + } + } + this._createUiMenu(opts.menu); + + eventNames = "contextmenu" + this.eventNamespace; + if (opts.taphold) { + eventNames += " taphold" + this.eventNamespace; + } + this.element.on(eventNames, opts.delegate, $.proxy(this._openMenu, this)); + }, + /** Destructor, called on $().contextmenu("destroy"). */ + _destroy: function() { + this.element.off(this.eventNamespace); + + this._createUiMenu(null); + + if (this.$headStyle) { + this.$headStyle.remove(); + this.$headStyle = null; + } + }, + /** (Re)Create jQuery UI Menu. */ + _createUiMenu: function(menuDef) { + var ct, ed, + opts = this.options; + + // Remove temporary <ul> if any + if (this.isOpen()) { + // #58: 'replaceMenu' in beforeOpen causing select: to lose ui.target + ct = this.currentTarget; + ed = this.extraData; + // close without animation, to force async mode + this._closeMenu(true); + this.currentTarget = ct; + this.extraData = ed; + } + if (this.menuIsTemp) { + this.$menu.remove(); // this will also destroy ui.menu + } else if (this.$menu) { + this.$menu + .menu("destroy") + .removeClass(opts.addClass) + .hide(); + } + this.$menu = null; + this.menuIsTemp = false; + // If a menu definition array was passed, create a hidden <ul> + // and generate the structure now + if ( !menuDef ) { + return; + } else if ($.isArray(menuDef)) { + this.$menu = $.moogle.contextmenu.createMenuMarkup(menuDef, null, opts); + this.menuIsTemp = true; + }else if ( typeof menuDef === "string" ) { + this.$menu = $(menuDef); + } else { + this.$menu = menuDef; + } + // Create - but hide - the jQuery UI Menu widget + this.$menu + .hide() + .addClass(opts.addClass) + // Create a menu instance that delegates events to our widget + .menu($.extend(true, {}, opts.uiMenuOptions, { + items: "> :not(.ui-widget-header)", + blur: $.proxy(opts.blur, this), + create: $.proxy(opts.createMenu, this), + focus: $.proxy(opts.focus, this), + select: $.proxy(function(event, ui) { + // User selected a menu entry + var retval, + isParent = $.moogle.contextmenu.isMenu(ui.item), + actionHandler = ui.item.data("actionHandler"); + + ui.cmd = ui.item.attr("data-command"); + ui.target = $(this.currentTarget); + ui.extraData = this.extraData; + // ignore clicks, if they only open a sub-menu + if ( !isParent || !opts.ignoreParentSelect) { + retval = this._trigger.call(this, "select", event, ui); + if ( actionHandler ) { + retval = actionHandler.call(this, event, ui); + } + if ( retval !== false ) { + this._closeMenu.call(this); + } + event.preventDefault(); + } + }, this) + })); + }, + /** Open popup (called on 'contextmenu' event). */ + _openMenu: function(event, recursive) { + var res, promise, ui, + opts = this.options, + posOption = opts.position, + self = this, + manualTrigger = !!event.isTrigger; + + if ( !opts.autoTrigger && !manualTrigger ) { + // ignore browser's `contextmenu` events + return; + } + // Prevent browser from opening the system context menu + event.preventDefault(); + + this.currentTarget = event.target; + this.extraData = event._extraData || {}; + + ui = { menu: this.$menu, target: $(this.currentTarget), extraData: this.extraData, + originalEvent: event, result: null }; + + if ( !recursive ) { + res = this._trigger("beforeOpen", event, ui); + promise = (ui.result && $.isFunction(ui.result.promise)) ? ui.result : null; + ui.result = null; + if ( res === false ) { + this.currentTarget = null; + return false; + } else if ( promise ) { + // Handler returned a Deferred or Promise. Delay menu open until + // the promise is resolved + promise.done(function() { + self._openMenu(event, true); + }); + this.currentTarget = null; + return false; + } + ui.menu = this.$menu; // Might have changed in beforeOpen + } + + // Register global event handlers that close the dropdown-menu + $(document).on("keydown" + this.eventNamespace, function(event) { + if ( event.which === $.ui.keyCode.ESCAPE ) { + self._closeMenu(); + } + }).on("mousedown" + this.eventNamespace + " touchstart" + this.eventNamespace, + function(event) { + // Close menu when clicked outside menu + if ( !$(event.target).closest(".ui-menu-item").length ) { + self._closeMenu(); + } + }); + $(window).on("blur" + this.eventNamespace, function(event) { + if ( opts.closeOnWindowBlur ) { + self._closeMenu(); + } + }); + + // required for custom positioning (issue #18 and #13). + if ($.isFunction(posOption)) { + posOption = posOption(event, ui); + } + posOption = $.extend({ + my: "left top", + at: "left bottom", + // if called by 'open' method, event does not have pageX/Y + of: (event.pageX === undefined) ? event.target : event, + collision: "fit" + }, posOption); + + // Update entry statuses from callbacks + this._updateEntries(this.$menu); + + // Finally display the popup + this.$menu + .show() // required to fix positioning error + .css({ + position: "absolute", + left: 0, + top: 0 + }).position(posOption) + .hide(); // hide again, so we can apply nice effects + + if ( opts.preventContextMenuForPopup ) { + this.$menu.on("contextmenu" + this.eventNamespace, function(event) { + event.preventDefault(); + }); + } + this._show(this.$menu, opts.show, function() { + var $first; + + // Set focus to first active menu entry + if ( opts.autoFocus ) { + self.previousFocus = $(event.target); + // self.$menu.focus(); + $first = self.$menu + .children("li.ui-menu-item") + .not(".ui-state-disabled") + .first(); + self.$menu.menu("focus", null, $first).focus(); + } + self._trigger.call(self, "open", event, ui); + }); + }, + /** Close popup. */ + _closeMenu: function(immediately) { + var self = this, + hideOpts = immediately ? false : this.options.hide, + ui = { menu: this.$menu, target: $(this.currentTarget), extraData: this.extraData }; + + // Note: we don't want to unbind the 'contextmenu' event + $(document) + .off("mousedown" + this.eventNamespace) + .off("touchstart" + this.eventNamespace) + .off("keydown" + this.eventNamespace); + $(window) + .off("blur" + this.eventNamespace); + + self.currentTarget = null; // issue #44 after hide animation is too late + self.extraData = {}; + if ( this.$menu ) { // #88: widget might have been destroyed already + this.$menu + .off("contextmenu" + this.eventNamespace); + this._hide(this.$menu, hideOpts, function() { + if ( self.previousFocus ) { + self.previousFocus.focus(); + self.previousFocus = null; + } + self._trigger("close", null, ui); + }); + } else { + self._trigger("close", null, ui); + } + }, + /** Handle $().contextmenu("option", key, value) calls. */ + _setOption: function(key, value) { + switch (key) { + case "menu": + this.replaceMenu(value); + break; + } + $.Widget.prototype._setOption.apply(this, arguments); + }, + /** Return ui-menu entry (<LI> tag). */ + _getMenuEntry: function(cmd) { + return this.$menu.find("li[data-command=" + cmd + "]"); + }, + /** Close context menu. */ + close: function() { + if (this.isOpen()) { + this._closeMenu(); + } + }, + /* Apply status callbacks when menu is opened. */ + _updateEntries: function() { + var self = this, + ui = { + menu: this.$menu, target: $(this.currentTarget), extraData: this.extraData }; + + $.each(this.$menu.find(".ui-menu-item"), function(i, o) { + var $entry = $(o), + fn = $entry.data("disabledHandler"), + res = fn ? fn({ type: "disabled" }, ui) : null; + + ui.item = $entry; + ui.cmd = $entry.attr("data-command"); + // Evaluate `disabled()` callback + if ( res != null ) { + self.enableEntry(ui.cmd, !res); + self.showEntry(ui.cmd, res !== "hide"); + } + // Evaluate `title()` callback + fn = $entry.data("titleHandler"), + res = fn ? fn({ type: "title" }, ui) : null; + if ( res != null ) { + self.setTitle(ui.cmd, "" + res); + } + // Evaluate `tooltip()` callback + fn = $entry.data("tooltipHandler"), + res = fn ? fn({ type: "tooltip" }, ui) : null; + if ( res != null ) { + $entry.attr("title", "" + res); + } + }); + }, + /** Enable or disable the menu command. */ + enableEntry: function(cmd, flag) { + this._getMenuEntry(cmd).toggleClass("ui-state-disabled", (flag === false)); + }, + /** Return ui-menu entry (LI tag) as jQuery object. */ + getEntry: function(cmd) { + return this._getMenuEntry(cmd); + }, + /** Return ui-menu entry wrapper as jQuery object. + UI 1.10: this is the <a> tag inside the LI + UI 1.11: this is the LI istself + UI 1.12: this is the <div> tag inside the LI + */ + getEntryWrapper: function(cmd) { + return this._getMenuEntry(cmd).find(">[role=menuitem]").addBack("[role=menuitem]"); + }, + /** Return Menu element (UL). */ + getMenu: function() { + return this.$menu; + }, + /** Return true if menu is open. */ + isOpen: function() { +// return this.$menu && this.$menu.is(":visible"); + return !!this.$menu && !!this.currentTarget; + }, + /** Open context menu on a specific target (must match options.delegate) + * Optional `extraData` is passed to event handlers as `ui.extraData`. + */ + open: function(targetOrEvent, extraData) { + // Fake a 'contextmenu' event + extraData = extraData || {}; + + var isEvent = (targetOrEvent && targetOrEvent.type && targetOrEvent.target), + event = isEvent ? targetOrEvent : {}, + target = isEvent ? targetOrEvent.target : targetOrEvent, + e = jQuery.Event("contextmenu", { + target: $(target).get(0), + pageX: event.pageX, + pageY: event.pageY, + originalEvent: isEvent ? targetOrEvent : undefined, + _extraData: extraData + }); + return this.element.trigger(e); + }, + /** Replace the menu altogether. */ + replaceMenu: function(data) { + this._createUiMenu(data); + }, + /** Redefine a whole menu entry. */ + setEntry: function(cmd, entry) { + var $ul, + $entryLi = this._getMenuEntry(cmd); + + if (typeof entry === "string") { + window.console && window.console.warn( + "setEntry(cmd, t) with a plain string title is deprecated since v1.18." + + "Use setTitle(cmd, '" + entry + "') instead."); + return this.setTitle(cmd, entry); + } + $entryLi.empty(); + entry.cmd = entry.cmd || cmd; + $.moogle.contextmenu.createEntryMarkup(entry, $entryLi); + if ($.isArray(entry.children)) { + $ul = $("<ul/>").appendTo($entryLi); + $.moogle.contextmenu.createMenuMarkup(entry.children, $ul); + } + // #110: jQuery UI 1.12: refresh only works when this class is not set: + $entryLi.removeClass("ui-menu-item"); + this.getMenu().menu("refresh"); + }, + /** Set icon (pass null to remove). */ + setIcon: function(cmd, icon) { + return this.updateEntry(cmd, { uiIcon: icon }); + }, + /** Set title. */ + setTitle: function(cmd, title) { + return this.updateEntry(cmd, { title: title }); + }, + // /** Set tooltip (pass null to remove). */ + // setTooltip: function(cmd, tooltip) { + // this._getMenuEntry(cmd).attr("title", tooltip); + // }, + /** Show or hide the menu command. */ + showEntry: function(cmd, flag) { + this._getMenuEntry(cmd).toggle(flag !== false); + }, + /** Redefine selective attributes of a menu entry. */ + updateEntry: function(cmd, entry) { + var $icon, $wrapper, + $entryLi = this._getMenuEntry(cmd); + + if ( entry.title !== undefined ) { + $.moogle.contextmenu.updateTitle($entryLi, "" + entry.title); + } + if ( entry.tooltip !== undefined ) { + if ( entry.tooltip === null ) { + $entryLi.removeAttr("title"); + } else { + $entryLi.attr("title", entry.tooltip); + } + } + if ( entry.uiIcon !== undefined ) { + $wrapper = this.getEntryWrapper(cmd), + $icon = $wrapper.find("span.ui-icon").not(".ui-menu-icon"); + $icon.remove(); + if ( entry.uiIcon ) { + $wrapper.append($("<span class='ui-icon' />").addClass(entry.uiIcon)); + } + } + if ( entry.hide !== undefined ) { + $entryLi.toggle(!entry.hide); + } else if ( entry.show !== undefined ) { + // Note: `show` is an undocumented variant. `hide: false` is preferred + $entryLi.toggle(!!entry.show); + } + // if ( entry.isHeader !== undefined ) { + // $entryLi.toggleClass("ui-widget-header", !!entry.isHeader); + // } + if ( entry.data !== undefined ) { + $entryLi.data(entry.data); + } + + // Set/clear class names, but handle ui-state-disabled separately + if ( entry.disabled === undefined ) { + entry.disabled = $entryLi.hasClass("ui-state-disabled"); + } + if ( entry.setClass ) { + if ( $entryLi.hasClass("ui-menu-item") ) { + entry.setClass += " ui-menu-item"; + } + $entryLi.removeClass(); + $entryLi.addClass(entry.setClass); + } else if ( entry.addClass ) { + $entryLi.addClass(entry.addClass); + } + $entryLi.toggleClass("ui-state-disabled", !!entry.disabled); + // // #110: jQuery UI 1.12: refresh only works when this class is not set: + // $entryLi.removeClass("ui-menu-item"); + // this.getMenu().menu("refresh"); + } +}); + +/* + * Global functions + */ +$.extend($.moogle.contextmenu, { + /** Convert a menu description into a into a <li> content. */ + createEntryMarkup: function(entry, $parentLi) { + var $wrapper = null; + + $parentLi.attr("data-command", entry.cmd); + + if ( !/[^\-\u2014\u2013\s]/.test( entry.title ) ) { + // hyphen, em dash, en dash: separator as defined by UI Menu 1.10 + $parentLi.text(entry.title); + } else { + if ( isLTE110 ) { + // jQuery UI Menu 1.10 or before required an `<a>` tag + $wrapper = $("<a/>", { + html: "" + entry.title, + href: "#" + }).appendTo($parentLi); + + } else if ( isLTE111 ) { + // jQuery UI Menu 1.11 preferes to avoid `<a>` tags or <div> wrapper + $parentLi.html("" + entry.title); + $wrapper = $parentLi; + + } else { + // jQuery UI Menu 1.12 introduced `<div>` wrappers + $wrapper = $("<div/>", { + html: "" + entry.title + }).appendTo($parentLi); + } + if ( entry.uiIcon ) { + $wrapper.append($("<span class='ui-icon' />").addClass(entry.uiIcon)); + } + // Store option callbacks in entry's data + $.each( [ "action", "disabled", "title", "tooltip" ], function(i, attr) { + if ( $.isFunction(entry[attr]) ) { + $parentLi.data(attr + "Handler", entry[attr]); + } + }); + if ( entry.disabled === true ) { + $parentLi.addClass("ui-state-disabled"); + } + if ( entry.isHeader ) { + $parentLi.addClass("ui-widget-header"); + } + if ( entry.addClass ) { + $parentLi.addClass(entry.addClass); + } + if ( $.isPlainObject(entry.data) ) { + $parentLi.data(entry.data); + } + if ( typeof entry.tooltip === "string" ) { + $parentLi.attr("title", entry.tooltip); + } + } + }, + /** Convert a nested array of command objects into a <ul> structure. */ + createMenuMarkup: function(options, $parentUl, opts) { + var i, menu, $ul, $li, + appendTo = (opts && opts.appendTo) ? opts.appendTo : "body"; + + if ( $parentUl == null ) { + $parentUl = $("<ul class='ui-helper-hidden' />").appendTo(appendTo); + } + for (i = 0; i < options.length; i++) { + menu = options[i]; + $li = $("<li/>").appendTo($parentUl); + + $.moogle.contextmenu.createEntryMarkup(menu, $li); + + if ( $.isArray(menu.children) ) { + $ul = $("<ul/>").appendTo($li); + $.moogle.contextmenu.createMenuMarkup(menu.children, $ul); + } + } + return $parentUl; + }, + /** Returns true if the menu item has child menu items */ + isMenu: function(item) { + if ( isLTE110 ) { + return item.has(">a[aria-haspopup='true']").length > 0; + } else if ( isLTE111 ) { // jQuery UI 1.11 used no tag wrappers + return item.is("[aria-haspopup='true']"); + } else { + return item.has(">div[aria-haspopup='true']").length > 0; + } + }, + /** Replace the title of elem', but retain icons andchild entries. */ + replaceFirstTextNodeChild: function(elem, html) { + var $icons = elem.find(">span.ui-icon,>ul.ui-menu").detach(); + + elem + .empty() + .html(html) + .append($icons); + }, + /** Updates the menu item's title */ + updateTitle: function(item, title) { + if ( isLTE110 ) { // jQuery UI 1.10 and before used <a> tags + $.moogle.contextmenu.replaceFirstTextNodeChild($("a", item), title); + } else if ( isLTE111 ) { // jQuery UI 1.11 used no tag wrappers + $.moogle.contextmenu.replaceFirstTextNodeChild(item, title); + } else { // jQuery UI 1.12+ introduced <div> tag wrappers + $.moogle.contextmenu.replaceFirstTextNodeChild($("div", item), title); + } + } +}); + +})); diff --git a/plugins/55/indexmenu/scripts/contextmenu/jquery.ui-contextmenu.min.js b/plugins/55/indexmenu/scripts/contextmenu/jquery.ui-contextmenu.min.js new file mode 100644 index 0000000..4436aaa --- /dev/null +++ b/plugins/55/indexmenu/scripts/contextmenu/jquery.ui-contextmenu.min.js @@ -0,0 +1,4 @@ +/*! jQuery UI context menu plugin - v1.18.2-0 - 2019-01-28 | https://github.com/mar10/jquery-ui-contextmenu | Copyright (c) 2013 -2019 Martin Wendt; Licensed MIT */ + +!function(a){"use strict";"function"==typeof define&&define.amd?define(["jquery","jquery-ui/ui/widgets/menu"],a):a(jQuery)}(function(a){"use strict";var b="onselectstart"in document.createElement("div"),c=a.ui.menu.version.match(/^(\d)\.(\d+)/),d={major:parseInt(c[1],10),minor:parseInt(c[2],10)},e=d.major<2&&d.minor<=10,f=d.major<2&&d.minor<=11;a.widget("moogle.contextmenu",{version:"@VERSION",options:{addClass:"ui-contextmenu",closeOnWindowBlur:!0,appendTo:"body",autoFocus:!1,autoTrigger:!0,delegate:null,hide:{effect:"fadeOut",duration:"fast"},ignoreParentSelect:!0,menu:null,position:null,preventContextMenuForPopup:!1,preventSelect:!1,show:{effect:"slideDown",duration:"fast"},taphold:!1,uiMenuOptions:{},beforeOpen:a.noop,blur:a.noop,close:a.noop,create:a.noop,createMenu:a.noop,focus:a.noop,open:a.noop,select:a.noop},_create:function(){var c,d,e,f=this.options;if(this.$headStyle=null,this.$menu=null,this.menuIsTemp=!1,this.currentTarget=null,this.extraData={},this.previousFocus=null,null==f.delegate&&a.error("ui-contextmenu: Missing required option `delegate`."),f.preventSelect){e=(a(this.element).is(document)?a("body"):this.element).uniqueId().attr("id"),c="#"+e+" "+f.delegate+" { -webkit-user-select: none; -khtml-user-select: none; -moz-user-select: none; -ms-user-select: none; user-select: none; }",this.$headStyle=a("<style class='moogle-contextmenu-style' />").prop("type","text/css").appendTo("head");try{this.$headStyle.html(c)}catch(g){this.$headStyle[0].styleSheet.cssText=c}b&&this.element.on("selectstart"+this.eventNamespace,f.delegate,function(a){a.preventDefault()})}this._createUiMenu(f.menu),d="contextmenu"+this.eventNamespace,f.taphold&&(d+=" taphold"+this.eventNamespace),this.element.on(d,f.delegate,a.proxy(this._openMenu,this))},_destroy:function(){this.element.off(this.eventNamespace),this._createUiMenu(null),this.$headStyle&&(this.$headStyle.remove(),this.$headStyle=null)},_createUiMenu:function(b){var c,d,e=this.options;this.isOpen()&&(c=this.currentTarget,d=this.extraData,this._closeMenu(!0),this.currentTarget=c,this.extraData=d),this.menuIsTemp?this.$menu.remove():this.$menu&&this.$menu.menu("destroy").removeClass(e.addClass).hide(),this.$menu=null,this.menuIsTemp=!1,b&&(a.isArray(b)?(this.$menu=a.moogle.contextmenu.createMenuMarkup(b,null,e),this.menuIsTemp=!0):"string"==typeof b?this.$menu=a(b):this.$menu=b,this.$menu.hide().addClass(e.addClass).menu(a.extend(!0,{},e.uiMenuOptions,{items:"> :not(.ui-widget-header)",blur:a.proxy(e.blur,this),create:a.proxy(e.createMenu,this),focus:a.proxy(e.focus,this),select:a.proxy(function(b,c){var d,f=a.moogle.contextmenu.isMenu(c.item),g=c.item.data("actionHandler");c.cmd=c.item.attr("data-command"),c.target=a(this.currentTarget),c.extraData=this.extraData,f&&e.ignoreParentSelect||(d=this._trigger.call(this,"select",b,c),g&&(d=g.call(this,b,c)),d!==!1&&this._closeMenu.call(this),b.preventDefault())},this)})))},_openMenu:function(b,c){var d,e,f,g=this.options,h=g.position,i=this,j=!!b.isTrigger;if(g.autoTrigger||j){if(b.preventDefault(),this.currentTarget=b.target,this.extraData=b._extraData||{},f={menu:this.$menu,target:a(this.currentTarget),extraData:this.extraData,originalEvent:b,result:null},!c){if(d=this._trigger("beforeOpen",b,f),e=f.result&&a.isFunction(f.result.promise)?f.result:null,f.result=null,d===!1)return this.currentTarget=null,!1;if(e)return e.done(function(){i._openMenu(b,!0)}),this.currentTarget=null,!1;f.menu=this.$menu}a(document).on("keydown"+this.eventNamespace,function(b){b.which===a.ui.keyCode.ESCAPE&&i._closeMenu()}).on("mousedown"+this.eventNamespace+" touchstart"+this.eventNamespace,function(b){a(b.target).closest(".ui-menu-item").length||i._closeMenu()}),a(window).on("blur"+this.eventNamespace,function(a){g.closeOnWindowBlur&&i._closeMenu()}),a.isFunction(h)&&(h=h(b,f)),h=a.extend({my:"left top",at:"left bottom",of:void 0===b.pageX?b.target:b,collision:"fit"},h),this._updateEntries(this.$menu),this.$menu.show().css({position:"absolute",left:0,top:0}).position(h).hide(),g.preventContextMenuForPopup&&this.$menu.on("contextmenu"+this.eventNamespace,function(a){a.preventDefault()}),this._show(this.$menu,g.show,function(){var c;g.autoFocus&&(i.previousFocus=a(b.target),c=i.$menu.children("li.ui-menu-item").not(".ui-state-disabled").first(),i.$menu.menu("focus",null,c).focus()),i._trigger.call(i,"open",b,f)})}},_closeMenu:function(b){var c=this,d=!b&&this.options.hide,e={menu:this.$menu,target:a(this.currentTarget),extraData:this.extraData};a(document).off("mousedown"+this.eventNamespace).off("touchstart"+this.eventNamespace).off("keydown"+this.eventNamespace),a(window).off("blur"+this.eventNamespace),c.currentTarget=null,c.extraData={},this.$menu?(this.$menu.off("contextmenu"+this.eventNamespace),this._hide(this.$menu,d,function(){c.previousFocus&&(c.previousFocus.focus(),c.previousFocus=null),c._trigger("close",null,e)})):c._trigger("close",null,e)},_setOption:function(b,c){switch(b){case"menu":this.replaceMenu(c)}a.Widget.prototype._setOption.apply(this,arguments)},_getMenuEntry:function(a){return this.$menu.find("li[data-command="+a+"]")},close:function(){this.isOpen()&&this._closeMenu()},_updateEntries:function(){var b=this,c={menu:this.$menu,target:a(this.currentTarget),extraData:this.extraData};a.each(this.$menu.find(".ui-menu-item"),function(d,e){var f=a(e),g=f.data("disabledHandler"),h=g?g({type:"disabled"},c):null;c.item=f,c.cmd=f.attr("data-command"),null!=h&&(b.enableEntry(c.cmd,!h),b.showEntry(c.cmd,"hide"!==h)),g=f.data("titleHandler"),h=g?g({type:"title"},c):null,null!=h&&b.setTitle(c.cmd,""+h),g=f.data("tooltipHandler"),h=g?g({type:"tooltip"},c):null,null!=h&&f.attr("title",""+h)})},enableEntry:function(a,b){this._getMenuEntry(a).toggleClass("ui-state-disabled",b===!1)},getEntry:function(a){return this._getMenuEntry(a)},getEntryWrapper:function(a){return this._getMenuEntry(a).find(">[role=menuitem]").addBack("[role=menuitem]")},getMenu:function(){return this.$menu},isOpen:function(){return!!this.$menu&&!!this.currentTarget},open:function(b,c){c=c||{};var d=b&&b.type&&b.target,e=d?b:{},f=d?b.target:b,g=jQuery.Event("contextmenu",{target:a(f).get(0),pageX:e.pageX,pageY:e.pageY,originalEvent:d?b:void 0,_extraData:c});return this.element.trigger(g)},replaceMenu:function(a){this._createUiMenu(a)},setEntry:function(b,c){var d,e=this._getMenuEntry(b);return"string"==typeof c?(window.console&&window.console.warn("setEntry(cmd, t) with a plain string title is deprecated since v1.18.Use setTitle(cmd, '"+c+"') instead."),this.setTitle(b,c)):(e.empty(),c.cmd=c.cmd||b,a.moogle.contextmenu.createEntryMarkup(c,e),a.isArray(c.children)&&(d=a("<ul/>").appendTo(e),a.moogle.contextmenu.createMenuMarkup(c.children,d)),e.removeClass("ui-menu-item"),void this.getMenu().menu("refresh"))},setIcon:function(a,b){return this.updateEntry(a,{uiIcon:b})},setTitle:function(a,b){return this.updateEntry(a,{title:b})},showEntry:function(a,b){this._getMenuEntry(a).toggle(b!==!1)},updateEntry:function(b,c){var d,e,f=this._getMenuEntry(b);void 0!==c.title&&a.moogle.contextmenu.updateTitle(f,""+c.title),void 0!==c.tooltip&&(null===c.tooltip?f.removeAttr("title"):f.attr("title",c.tooltip)),void 0!==c.uiIcon&&(e=this.getEntryWrapper(b),d=e.find("span.ui-icon").not(".ui-menu-icon"),d.remove(),c.uiIcon&&e.append(a("<span class='ui-icon' />").addClass(c.uiIcon))),void 0!==c.hide?f.toggle(!c.hide):void 0!==c.show&&f.toggle(!!c.show),void 0!==c.data&&f.data(c.data),void 0===c.disabled&&(c.disabled=f.hasClass("ui-state-disabled")),c.setClass?(f.hasClass("ui-menu-item")&&(c.setClass+=" ui-menu-item"),f.removeClass(),f.addClass(c.setClass)):c.addClass&&f.addClass(c.addClass),f.toggleClass("ui-state-disabled",!!c.disabled)}}),a.extend(a.moogle.contextmenu,{createEntryMarkup:function(b,c){var d=null;c.attr("data-command",b.cmd),/[^\-\u2014\u2013\s]/.test(b.title)?(e?d=a("<a/>",{html:""+b.title,href:"#"}).appendTo(c):f?(c.html(""+b.title),d=c):d=a("<div/>",{html:""+b.title}).appendTo(c),b.uiIcon&&d.append(a("<span class='ui-icon' />").addClass(b.uiIcon)),a.each(["action","disabled","title","tooltip"],function(d,e){a.isFunction(b[e])&&c.data(e+"Handler",b[e])}),b.disabled===!0&&c.addClass("ui-state-disabled"),b.isHeader&&c.addClass("ui-widget-header"),b.addClass&&c.addClass(b.addClass),a.isPlainObject(b.data)&&c.data(b.data),"string"==typeof b.tooltip&&c.attr("title",b.tooltip)):c.text(b.title)},createMenuMarkup:function(b,c,d){var e,f,g,h,i=d&&d.appendTo?d.appendTo:"body";for(null==c&&(c=a("<ul class='ui-helper-hidden' />").appendTo(i)),e=0;e<b.length;e++)f=b[e],h=a("<li/>").appendTo(c),a.moogle.contextmenu.createEntryMarkup(f,h),a.isArray(f.children)&&(g=a("<ul/>").appendTo(h),a.moogle.contextmenu.createMenuMarkup(f.children,g));return c},isMenu:function(a){return e?a.has(">a[aria-haspopup='true']").length>0:f?a.is("[aria-haspopup='true']"):a.has(">div[aria-haspopup='true']").length>0},replaceFirstTextNodeChild:function(a,b){var c=a.find(">span.ui-icon,>ul.ui-menu").detach();a.empty().html(b).append(c)},updateTitle:function(b,c){e?a.moogle.contextmenu.replaceFirstTextNodeChild(a("a",b),c):f?a.moogle.contextmenu.replaceFirstTextNodeChild(b,c):a.moogle.contextmenu.replaceFirstTextNodeChild(a("div",b),c)}})}); +//# sourceMappingURL=jquery.ui-contextmenu.min.js.map
\ No newline at end of file diff --git a/plugins/55/indexmenu/scripts/contextmenu/jquery.ui-contextmenu.min.js.map b/plugins/55/indexmenu/scripts/contextmenu/jquery.ui-contextmenu.min.js.map new file mode 100644 index 0000000..28dfb80 --- /dev/null +++ b/plugins/55/indexmenu/scripts/contextmenu/jquery.ui-contextmenu.min.js.map @@ -0,0 +1 @@ +{"version":3,"sources":["jquery.ui-contextmenu.js"],"names":["factory","define","amd","jQuery","$","supportSelectstart","document","createElement","match","ui","menu","version","uiVersion","major","parseInt","minor","isLTE110","isLTE111","widget","options","addClass","closeOnWindowBlur","appendTo","autoFocus","autoTrigger","delegate","hide","effect","duration","ignoreParentSelect","position","preventContextMenuForPopup","preventSelect","show","taphold","uiMenuOptions","beforeOpen","noop","blur","close","create","createMenu","focus","open","select","_create","cssText","eventNames","targetId","opts","this","$headStyle","$menu","menuIsTemp","currentTarget","extraData","previousFocus","error","element","is","uniqueId","attr","prop","html","e","styleSheet","on","eventNamespace","event","preventDefault","_createUiMenu","proxy","_openMenu","_destroy","off","remove","menuDef","ct","ed","isOpen","_closeMenu","removeClass","isArray","moogle","contextmenu","createMenuMarkup","extend","items","retval","isParent","isMenu","item","actionHandler","data","cmd","target","_trigger","call","recursive","res","promise","posOption","self","manualTrigger","isTrigger","_extraData","originalEvent","result","isFunction","done","which","keyCode","ESCAPE","closest","length","window","my","at","of","undefined","pageX","collision","_updateEntries","css","left","top","_show","$first","children","not","first","immediately","hideOpts","_hide","_setOption","key","value","replaceMenu","Widget","prototype","apply","arguments","_getMenuEntry","find","each","i","o","$entry","fn","type","enableEntry","showEntry","setTitle","flag","toggleClass","getEntry","getEntryWrapper","addBack","getMenu","targetOrEvent","isEvent","Event","get","pageY","trigger","setEntry","entry","$ul","$entryLi","console","warn","empty","createEntryMarkup","setIcon","icon","updateEntry","uiIcon","title","toggle","$icon","$wrapper","updateTitle","tooltip","removeAttr","append","disabled","hasClass","setClass","$parentLi","test","href","isHeader","isPlainObject","text","$parentUl","$li","has","replaceFirstTextNodeChild","elem","$icons","detach"],"mappings":"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","file":"jquery.ui-contextmenu.min.js"}
\ No newline at end of file diff --git a/plugins/55/indexmenu/scripts/fancytree/LICENSE.txt b/plugins/55/indexmenu/scripts/fancytree/LICENSE.txt new file mode 100644 index 0000000..1a61571 --- /dev/null +++ b/plugins/55/indexmenu/scripts/fancytree/LICENSE.txt @@ -0,0 +1,21 @@ +Copyright 2008-2023 Martin Wendt, +https://wwWendt.de/ + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/plugins/55/indexmenu/scripts/fancytree/jquery.fancytree-all-deps.js b/plugins/55/indexmenu/scripts/fancytree/jquery.fancytree-all-deps.js new file mode 100644 index 0000000..ab9b9d2 --- /dev/null +++ b/plugins/55/indexmenu/scripts/fancytree/jquery.fancytree-all-deps.js @@ -0,0 +1,13856 @@ +/*! jQuery Fancytree Plugin - 2.38.3 - 2023-02-01T20:52:50Z + * https://github.com/mar10/fancytree + * Copyright (c) 2023 Martin Wendt; Licensed MIT + */ +/*! jQuery UI - v1.13.0 - 2021-11-09 +* http://jqueryui.com +* Includes: widget.js, position.js, jquery-patch.js, keycode.js, scroll-parent.js, unique-id.js +* Copyright jQuery Foundation and other contributors; Licensed MIT */ + +/* + NOTE: Original jQuery UI wrapper was replaced with a simple IIFE. + See README-Fancytree.md +*/ +(function( $ ) { + + $.ui = $.ui || {}; + + var version = $.ui.version = "1.13.2"; + + + /*! + * jQuery UI Widget 1.13.2 + * http://jqueryui.com + * + * Copyright jQuery Foundation and other contributors + * Released under the MIT license. + * http://jquery.org/license + */ + + //>>label: Widget + //>>group: Core + //>>description: Provides a factory for creating stateful widgets with a common API. + //>>docs: http://api.jqueryui.com/jQuery.widget/ + //>>demos: http://jqueryui.com/widget/ + + + var widgetUuid = 0; + var widgetHasOwnProperty = Array.prototype.hasOwnProperty; + var widgetSlice = Array.prototype.slice; + + $.cleanData = ( function( orig ) { + return function( elems ) { + var events, elem, i; + for ( i = 0; ( elem = elems[ i ] ) != null; i++ ) { + + // Only trigger remove when necessary to save time + events = $._data( elem, "events" ); + if ( events && events.remove ) { + $( elem ).triggerHandler( "remove" ); + } + } + orig( elems ); + }; + } )( $.cleanData ); + + $.widget = function( name, base, prototype ) { + var existingConstructor, constructor, basePrototype; + + // ProxiedPrototype allows the provided prototype to remain unmodified + // so that it can be used as a mixin for multiple widgets (#8876) + var proxiedPrototype = {}; + + var namespace = name.split( "." )[ 0 ]; + name = name.split( "." )[ 1 ]; + var fullName = namespace + "-" + name; + + if ( !prototype ) { + prototype = base; + base = $.Widget; + } + + if ( Array.isArray( prototype ) ) { + prototype = $.extend.apply( null, [ {} ].concat( prototype ) ); + } + + // Create selector for plugin + $.expr.pseudos[ fullName.toLowerCase() ] = function( elem ) { + return !!$.data( elem, fullName ); + }; + + $[ namespace ] = $[ namespace ] || {}; + existingConstructor = $[ namespace ][ name ]; + constructor = $[ namespace ][ name ] = function( options, element ) { + + // Allow instantiation without "new" keyword + if ( !this || !this._createWidget ) { + return new constructor( options, element ); + } + + // Allow instantiation without initializing for simple inheritance + // must use "new" keyword (the code above always passes args) + if ( arguments.length ) { + this._createWidget( options, element ); + } + }; + + // Extend with the existing constructor to carry over any static properties + $.extend( constructor, existingConstructor, { + version: prototype.version, + + // Copy the object used to create the prototype in case we need to + // redefine the widget later + _proto: $.extend( {}, prototype ), + + // Track widgets that inherit from this widget in case this widget is + // redefined after a widget inherits from it + _childConstructors: [] + } ); + + basePrototype = new base(); + + // We need to make the options hash a property directly on the new instance + // otherwise we'll modify the options hash on the prototype that we're + // inheriting from + basePrototype.options = $.widget.extend( {}, basePrototype.options ); + $.each( prototype, function( prop, value ) { + if ( typeof value !== "function" ) { + proxiedPrototype[ prop ] = value; + return; + } + proxiedPrototype[ prop ] = ( function() { + function _super() { + return base.prototype[ prop ].apply( this, arguments ); + } + + function _superApply( args ) { + return base.prototype[ prop ].apply( this, args ); + } + + return function() { + var __super = this._super; + var __superApply = this._superApply; + var returnValue; + + this._super = _super; + this._superApply = _superApply; + + returnValue = value.apply( this, arguments ); + + this._super = __super; + this._superApply = __superApply; + + return returnValue; + }; + } )(); + } ); + constructor.prototype = $.widget.extend( basePrototype, { + + // TODO: remove support for widgetEventPrefix + // always use the name + a colon as the prefix, e.g., draggable:start + // don't prefix for widgets that aren't DOM-based + widgetEventPrefix: existingConstructor ? ( basePrototype.widgetEventPrefix || name ) : name + }, proxiedPrototype, { + constructor: constructor, + namespace: namespace, + widgetName: name, + widgetFullName: fullName + } ); + + // If this widget is being redefined then we need to find all widgets that + // are inheriting from it and redefine all of them so that they inherit from + // the new version of this widget. We're essentially trying to replace one + // level in the prototype chain. + if ( existingConstructor ) { + $.each( existingConstructor._childConstructors, function( i, child ) { + var childPrototype = child.prototype; + + // Redefine the child widget using the same prototype that was + // originally used, but inherit from the new version of the base + $.widget( childPrototype.namespace + "." + childPrototype.widgetName, constructor, + child._proto ); + } ); + + // Remove the list of existing child constructors from the old constructor + // so the old child constructors can be garbage collected + delete existingConstructor._childConstructors; + } else { + base._childConstructors.push( constructor ); + } + + $.widget.bridge( name, constructor ); + + return constructor; + }; + + $.widget.extend = function( target ) { + var input = widgetSlice.call( arguments, 1 ); + var inputIndex = 0; + var inputLength = input.length; + var key; + var value; + + for ( ; inputIndex < inputLength; inputIndex++ ) { + for ( key in input[ inputIndex ] ) { + value = input[ inputIndex ][ key ]; + if ( widgetHasOwnProperty.call( input[ inputIndex ], key ) && value !== undefined ) { + + // Clone objects + if ( $.isPlainObject( value ) ) { + target[ key ] = $.isPlainObject( target[ key ] ) ? + $.widget.extend( {}, target[ key ], value ) : + + // Don't extend strings, arrays, etc. with objects + $.widget.extend( {}, value ); + + // Copy everything else by reference + } else { + target[ key ] = value; + } + } + } + } + return target; + }; + + $.widget.bridge = function( name, object ) { + var fullName = object.prototype.widgetFullName || name; + $.fn[ name ] = function( options ) { + var isMethodCall = typeof options === "string"; + var args = widgetSlice.call( arguments, 1 ); + var returnValue = this; + + if ( isMethodCall ) { + + // If this is an empty collection, we need to have the instance method + // return undefined instead of the jQuery instance + if ( !this.length && options === "instance" ) { + returnValue = undefined; + } else { + this.each( function() { + var methodValue; + var instance = $.data( this, fullName ); + + if ( options === "instance" ) { + returnValue = instance; + return false; + } + + if ( !instance ) { + return $.error( "cannot call methods on " + name + + " prior to initialization; " + + "attempted to call method '" + options + "'" ); + } + + if ( typeof instance[ options ] !== "function" || + options.charAt( 0 ) === "_" ) { + return $.error( "no such method '" + options + "' for " + name + + " widget instance" ); + } + + methodValue = instance[ options ].apply( instance, args ); + + if ( methodValue !== instance && methodValue !== undefined ) { + returnValue = methodValue && methodValue.jquery ? + returnValue.pushStack( methodValue.get() ) : + methodValue; + return false; + } + } ); + } + } else { + + // Allow multiple hashes to be passed on init + if ( args.length ) { + options = $.widget.extend.apply( null, [ options ].concat( args ) ); + } + + this.each( function() { + var instance = $.data( this, fullName ); + if ( instance ) { + instance.option( options || {} ); + if ( instance._init ) { + instance._init(); + } + } else { + $.data( this, fullName, new object( options, this ) ); + } + } ); + } + + return returnValue; + }; + }; + + $.Widget = function( /* options, element */ ) {}; + $.Widget._childConstructors = []; + + $.Widget.prototype = { + widgetName: "widget", + widgetEventPrefix: "", + defaultElement: "<div>", + + options: { + classes: {}, + disabled: false, + + // Callbacks + create: null + }, + + _createWidget: function( options, element ) { + element = $( element || this.defaultElement || this )[ 0 ]; + this.element = $( element ); + this.uuid = widgetUuid++; + this.eventNamespace = "." + this.widgetName + this.uuid; + + this.bindings = $(); + this.hoverable = $(); + this.focusable = $(); + this.classesElementLookup = {}; + + if ( element !== this ) { + $.data( element, this.widgetFullName, this ); + this._on( true, this.element, { + remove: function( event ) { + if ( event.target === element ) { + this.destroy(); + } + } + } ); + this.document = $( element.style ? + + // Element within the document + element.ownerDocument : + + // Element is window or document + element.document || element ); + this.window = $( this.document[ 0 ].defaultView || this.document[ 0 ].parentWindow ); + } + + this.options = $.widget.extend( {}, + this.options, + this._getCreateOptions(), + options ); + + this._create(); + + if ( this.options.disabled ) { + this._setOptionDisabled( this.options.disabled ); + } + + this._trigger( "create", null, this._getCreateEventData() ); + this._init(); + }, + + _getCreateOptions: function() { + return {}; + }, + + _getCreateEventData: $.noop, + + _create: $.noop, + + _init: $.noop, + + destroy: function() { + var that = this; + + this._destroy(); + $.each( this.classesElementLookup, function( key, value ) { + that._removeClass( value, key ); + } ); + + // We can probably remove the unbind calls in 2.0 + // all event bindings should go through this._on() + this.element + .off( this.eventNamespace ) + .removeData( this.widgetFullName ); + this.widget() + .off( this.eventNamespace ) + .removeAttr( "aria-disabled" ); + + // Clean up events and states + this.bindings.off( this.eventNamespace ); + }, + + _destroy: $.noop, + + widget: function() { + return this.element; + }, + + option: function( key, value ) { + var options = key; + var parts; + var curOption; + var i; + + if ( arguments.length === 0 ) { + + // Don't return a reference to the internal hash + return $.widget.extend( {}, this.options ); + } + + if ( typeof key === "string" ) { + + // Handle nested keys, e.g., "foo.bar" => { foo: { bar: ___ } } + options = {}; + parts = key.split( "." ); + key = parts.shift(); + if ( parts.length ) { + curOption = options[ key ] = $.widget.extend( {}, this.options[ key ] ); + for ( i = 0; i < parts.length - 1; i++ ) { + curOption[ parts[ i ] ] = curOption[ parts[ i ] ] || {}; + curOption = curOption[ parts[ i ] ]; + } + key = parts.pop(); + if ( arguments.length === 1 ) { + return curOption[ key ] === undefined ? null : curOption[ key ]; + } + curOption[ key ] = value; + } else { + if ( arguments.length === 1 ) { + return this.options[ key ] === undefined ? null : this.options[ key ]; + } + options[ key ] = value; + } + } + + this._setOptions( options ); + + return this; + }, + + _setOptions: function( options ) { + var key; + + for ( key in options ) { + this._setOption( key, options[ key ] ); + } + + return this; + }, + + _setOption: function( key, value ) { + if ( key === "classes" ) { + this._setOptionClasses( value ); + } + + this.options[ key ] = value; + + if ( key === "disabled" ) { + this._setOptionDisabled( value ); + } + + return this; + }, + + _setOptionClasses: function( value ) { + var classKey, elements, currentElements; + + for ( classKey in value ) { + currentElements = this.classesElementLookup[ classKey ]; + if ( value[ classKey ] === this.options.classes[ classKey ] || + !currentElements || + !currentElements.length ) { + continue; + } + + // We are doing this to create a new jQuery object because the _removeClass() call + // on the next line is going to destroy the reference to the current elements being + // tracked. We need to save a copy of this collection so that we can add the new classes + // below. + elements = $( currentElements.get() ); + this._removeClass( currentElements, classKey ); + + // We don't use _addClass() here, because that uses this.options.classes + // for generating the string of classes. We want to use the value passed in from + // _setOption(), this is the new value of the classes option which was passed to + // _setOption(). We pass this value directly to _classes(). + elements.addClass( this._classes( { + element: elements, + keys: classKey, + classes: value, + add: true + } ) ); + } + }, + + _setOptionDisabled: function( value ) { + this._toggleClass( this.widget(), this.widgetFullName + "-disabled", null, !!value ); + + // If the widget is becoming disabled, then nothing is interactive + if ( value ) { + this._removeClass( this.hoverable, null, "ui-state-hover" ); + this._removeClass( this.focusable, null, "ui-state-focus" ); + } + }, + + enable: function() { + return this._setOptions( { disabled: false } ); + }, + + disable: function() { + return this._setOptions( { disabled: true } ); + }, + + _classes: function( options ) { + var full = []; + var that = this; + + options = $.extend( { + element: this.element, + classes: this.options.classes || {} + }, options ); + + function bindRemoveEvent() { + var nodesToBind = []; + + options.element.each( function( _, element ) { + var isTracked = $.map( that.classesElementLookup, function( elements ) { + return elements; + } ) + .some( function( elements ) { + return elements.is( element ); + } ); + + if ( !isTracked ) { + nodesToBind.push( element ); + } + } ); + + that._on( $( nodesToBind ), { + remove: "_untrackClassesElement" + } ); + } + + function processClassString( classes, checkOption ) { + var current, i; + for ( i = 0; i < classes.length; i++ ) { + current = that.classesElementLookup[ classes[ i ] ] || $(); + if ( options.add ) { + bindRemoveEvent(); + current = $( $.uniqueSort( current.get().concat( options.element.get() ) ) ); + } else { + current = $( current.not( options.element ).get() ); + } + that.classesElementLookup[ classes[ i ] ] = current; + full.push( classes[ i ] ); + if ( checkOption && options.classes[ classes[ i ] ] ) { + full.push( options.classes[ classes[ i ] ] ); + } + } + } + + if ( options.keys ) { + processClassString( options.keys.match( /\S+/g ) || [], true ); + } + if ( options.extra ) { + processClassString( options.extra.match( /\S+/g ) || [] ); + } + + return full.join( " " ); + }, + + _untrackClassesElement: function( event ) { + var that = this; + $.each( that.classesElementLookup, function( key, value ) { + if ( $.inArray( event.target, value ) !== -1 ) { + that.classesElementLookup[ key ] = $( value.not( event.target ).get() ); + } + } ); + + this._off( $( event.target ) ); + }, + + _removeClass: function( element, keys, extra ) { + return this._toggleClass( element, keys, extra, false ); + }, + + _addClass: function( element, keys, extra ) { + return this._toggleClass( element, keys, extra, true ); + }, + + _toggleClass: function( element, keys, extra, add ) { + add = ( typeof add === "boolean" ) ? add : extra; + var shift = ( typeof element === "string" || element === null ), + options = { + extra: shift ? keys : extra, + keys: shift ? element : keys, + element: shift ? this.element : element, + add: add + }; + options.element.toggleClass( this._classes( options ), add ); + return this; + }, + + _on: function( suppressDisabledCheck, element, handlers ) { + var delegateElement; + var instance = this; + + // No suppressDisabledCheck flag, shuffle arguments + if ( typeof suppressDisabledCheck !== "boolean" ) { + handlers = element; + element = suppressDisabledCheck; + suppressDisabledCheck = false; + } + + // No element argument, shuffle and use this.element + if ( !handlers ) { + handlers = element; + element = this.element; + delegateElement = this.widget(); + } else { + element = delegateElement = $( element ); + this.bindings = this.bindings.add( element ); + } + + $.each( handlers, function( event, handler ) { + function handlerProxy() { + + // Allow widgets to customize the disabled handling + // - disabled as an array instead of boolean + // - disabled class as method for disabling individual parts + if ( !suppressDisabledCheck && + ( instance.options.disabled === true || + $( this ).hasClass( "ui-state-disabled" ) ) ) { + return; + } + return ( typeof handler === "string" ? instance[ handler ] : handler ) + .apply( instance, arguments ); + } + + // Copy the guid so direct unbinding works + if ( typeof handler !== "string" ) { + handlerProxy.guid = handler.guid = + handler.guid || handlerProxy.guid || $.guid++; + } + + var match = event.match( /^([\w:-]*)\s*(.*)$/ ); + var eventName = match[ 1 ] + instance.eventNamespace; + var selector = match[ 2 ]; + + if ( selector ) { + delegateElement.on( eventName, selector, handlerProxy ); + } else { + element.on( eventName, handlerProxy ); + } + } ); + }, + + _off: function( element, eventName ) { + eventName = ( eventName || "" ).split( " " ).join( this.eventNamespace + " " ) + + this.eventNamespace; + element.off( eventName ); + + // Clear the stack to avoid memory leaks (#10056) + this.bindings = $( this.bindings.not( element ).get() ); + this.focusable = $( this.focusable.not( element ).get() ); + this.hoverable = $( this.hoverable.not( element ).get() ); + }, + + _delay: function( handler, delay ) { + function handlerProxy() { + return ( typeof handler === "string" ? instance[ handler ] : handler ) + .apply( instance, arguments ); + } + var instance = this; + return setTimeout( handlerProxy, delay || 0 ); + }, + + _hoverable: function( element ) { + this.hoverable = this.hoverable.add( element ); + this._on( element, { + mouseenter: function( event ) { + this._addClass( $( event.currentTarget ), null, "ui-state-hover" ); + }, + mouseleave: function( event ) { + this._removeClass( $( event.currentTarget ), null, "ui-state-hover" ); + } + } ); + }, + + _focusable: function( element ) { + this.focusable = this.focusable.add( element ); + this._on( element, { + focusin: function( event ) { + this._addClass( $( event.currentTarget ), null, "ui-state-focus" ); + }, + focusout: function( event ) { + this._removeClass( $( event.currentTarget ), null, "ui-state-focus" ); + } + } ); + }, + + _trigger: function( type, event, data ) { + var prop, orig; + var callback = this.options[ type ]; + + data = data || {}; + event = $.Event( event ); + event.type = ( type === this.widgetEventPrefix ? + type : + this.widgetEventPrefix + type ).toLowerCase(); + + // The original event may come from any element + // so we need to reset the target on the new event + event.target = this.element[ 0 ]; + + // Copy original event properties over to the new event + orig = event.originalEvent; + if ( orig ) { + for ( prop in orig ) { + if ( !( prop in event ) ) { + event[ prop ] = orig[ prop ]; + } + } + } + + this.element.trigger( event, data ); + return !( typeof callback === "function" && + callback.apply( this.element[ 0 ], [ event ].concat( data ) ) === false || + event.isDefaultPrevented() ); + } + }; + + $.each( { show: "fadeIn", hide: "fadeOut" }, function( method, defaultEffect ) { + $.Widget.prototype[ "_" + method ] = function( element, options, callback ) { + if ( typeof options === "string" ) { + options = { effect: options }; + } + + var hasOptions; + var effectName = !options ? + method : + options === true || typeof options === "number" ? + defaultEffect : + options.effect || defaultEffect; + + options = options || {}; + if ( typeof options === "number" ) { + options = { duration: options }; + } else if ( options === true ) { + options = {}; + } + + hasOptions = !$.isEmptyObject( options ); + options.complete = callback; + + if ( options.delay ) { + element.delay( options.delay ); + } + + if ( hasOptions && $.effects && $.effects.effect[ effectName ] ) { + element[ method ]( options ); + } else if ( effectName !== method && element[ effectName ] ) { + element[ effectName ]( options.duration, options.easing, callback ); + } else { + element.queue( function( next ) { + $( this )[ method ](); + if ( callback ) { + callback.call( element[ 0 ] ); + } + next(); + } ); + } + }; + } ); + + var widget = $.widget; + + + /*! + * jQuery UI Position 1.13.2 + * http://jqueryui.com + * + * Copyright jQuery Foundation and other contributors + * Released under the MIT license. + * http://jquery.org/license + * + * http://api.jqueryui.com/position/ + */ + + //>>label: Position + //>>group: Core + //>>description: Positions elements relative to other elements. + //>>docs: http://api.jqueryui.com/position/ + //>>demos: http://jqueryui.com/position/ + + + ( function() { + var cachedScrollbarWidth, + max = Math.max, + abs = Math.abs, + rhorizontal = /left|center|right/, + rvertical = /top|center|bottom/, + roffset = /[\+\-]\d+(\.[\d]+)?%?/, + rposition = /^\w+/, + rpercent = /%$/, + _position = $.fn.position; + + function getOffsets( offsets, width, height ) { + return [ + parseFloat( offsets[ 0 ] ) * ( rpercent.test( offsets[ 0 ] ) ? width / 100 : 1 ), + parseFloat( offsets[ 1 ] ) * ( rpercent.test( offsets[ 1 ] ) ? height / 100 : 1 ) + ]; + } + + function parseCss( element, property ) { + return parseInt( $.css( element, property ), 10 ) || 0; + } + + function isWindow( obj ) { + return obj != null && obj === obj.window; + } + + function getDimensions( elem ) { + var raw = elem[ 0 ]; + if ( raw.nodeType === 9 ) { + return { + width: elem.width(), + height: elem.height(), + offset: { top: 0, left: 0 } + }; + } + if ( isWindow( raw ) ) { + return { + width: elem.width(), + height: elem.height(), + offset: { top: elem.scrollTop(), left: elem.scrollLeft() } + }; + } + if ( raw.preventDefault ) { + return { + width: 0, + height: 0, + offset: { top: raw.pageY, left: raw.pageX } + }; + } + return { + width: elem.outerWidth(), + height: elem.outerHeight(), + offset: elem.offset() + }; + } + + $.position = { + scrollbarWidth: function() { + if ( cachedScrollbarWidth !== undefined ) { + return cachedScrollbarWidth; + } + var w1, w2, + div = $( "<div style=" + + "'display:block;position:absolute;width:200px;height:200px;overflow:hidden;'>" + + "<div style='height:300px;width:auto;'></div></div>" ), + innerDiv = div.children()[ 0 ]; + + $( "body" ).append( div ); + w1 = innerDiv.offsetWidth; + div.css( "overflow", "scroll" ); + + w2 = innerDiv.offsetWidth; + + if ( w1 === w2 ) { + w2 = div[ 0 ].clientWidth; + } + + div.remove(); + + return ( cachedScrollbarWidth = w1 - w2 ); + }, + getScrollInfo: function( within ) { + var overflowX = within.isWindow || within.isDocument ? "" : + within.element.css( "overflow-x" ), + overflowY = within.isWindow || within.isDocument ? "" : + within.element.css( "overflow-y" ), + hasOverflowX = overflowX === "scroll" || + ( overflowX === "auto" && within.width < within.element[ 0 ].scrollWidth ), + hasOverflowY = overflowY === "scroll" || + ( overflowY === "auto" && within.height < within.element[ 0 ].scrollHeight ); + return { + width: hasOverflowY ? $.position.scrollbarWidth() : 0, + height: hasOverflowX ? $.position.scrollbarWidth() : 0 + }; + }, + getWithinInfo: function( element ) { + var withinElement = $( element || window ), + isElemWindow = isWindow( withinElement[ 0 ] ), + isDocument = !!withinElement[ 0 ] && withinElement[ 0 ].nodeType === 9, + hasOffset = !isElemWindow && !isDocument; + return { + element: withinElement, + isWindow: isElemWindow, + isDocument: isDocument, + offset: hasOffset ? $( element ).offset() : { left: 0, top: 0 }, + scrollLeft: withinElement.scrollLeft(), + scrollTop: withinElement.scrollTop(), + width: withinElement.outerWidth(), + height: withinElement.outerHeight() + }; + } + }; + + $.fn.position = function( options ) { + if ( !options || !options.of ) { + return _position.apply( this, arguments ); + } + + // Make a copy, we don't want to modify arguments + options = $.extend( {}, options ); + + var atOffset, targetWidth, targetHeight, targetOffset, basePosition, dimensions, + + // Make sure string options are treated as CSS selectors + target = typeof options.of === "string" ? + $( document ).find( options.of ) : + $( options.of ), + + within = $.position.getWithinInfo( options.within ), + scrollInfo = $.position.getScrollInfo( within ), + collision = ( options.collision || "flip" ).split( " " ), + offsets = {}; + + dimensions = getDimensions( target ); + if ( target[ 0 ].preventDefault ) { + + // Force left top to allow flipping + options.at = "left top"; + } + targetWidth = dimensions.width; + targetHeight = dimensions.height; + targetOffset = dimensions.offset; + + // Clone to reuse original targetOffset later + basePosition = $.extend( {}, targetOffset ); + + // Force my and at to have valid horizontal and vertical positions + // if a value is missing or invalid, it will be converted to center + $.each( [ "my", "at" ], function() { + var pos = ( options[ this ] || "" ).split( " " ), + horizontalOffset, + verticalOffset; + + if ( pos.length === 1 ) { + pos = rhorizontal.test( pos[ 0 ] ) ? + pos.concat( [ "center" ] ) : + rvertical.test( pos[ 0 ] ) ? + [ "center" ].concat( pos ) : + [ "center", "center" ]; + } + pos[ 0 ] = rhorizontal.test( pos[ 0 ] ) ? pos[ 0 ] : "center"; + pos[ 1 ] = rvertical.test( pos[ 1 ] ) ? pos[ 1 ] : "center"; + + // Calculate offsets + horizontalOffset = roffset.exec( pos[ 0 ] ); + verticalOffset = roffset.exec( pos[ 1 ] ); + offsets[ this ] = [ + horizontalOffset ? horizontalOffset[ 0 ] : 0, + verticalOffset ? verticalOffset[ 0 ] : 0 + ]; + + // Reduce to just the positions without the offsets + options[ this ] = [ + rposition.exec( pos[ 0 ] )[ 0 ], + rposition.exec( pos[ 1 ] )[ 0 ] + ]; + } ); + + // Normalize collision option + if ( collision.length === 1 ) { + collision[ 1 ] = collision[ 0 ]; + } + + if ( options.at[ 0 ] === "right" ) { + basePosition.left += targetWidth; + } else if ( options.at[ 0 ] === "center" ) { + basePosition.left += targetWidth / 2; + } + + if ( options.at[ 1 ] === "bottom" ) { + basePosition.top += targetHeight; + } else if ( options.at[ 1 ] === "center" ) { + basePosition.top += targetHeight / 2; + } + + atOffset = getOffsets( offsets.at, targetWidth, targetHeight ); + basePosition.left += atOffset[ 0 ]; + basePosition.top += atOffset[ 1 ]; + + return this.each( function() { + var collisionPosition, using, + elem = $( this ), + elemWidth = elem.outerWidth(), + elemHeight = elem.outerHeight(), + marginLeft = parseCss( this, "marginLeft" ), + marginTop = parseCss( this, "marginTop" ), + collisionWidth = elemWidth + marginLeft + parseCss( this, "marginRight" ) + + scrollInfo.width, + collisionHeight = elemHeight + marginTop + parseCss( this, "marginBottom" ) + + scrollInfo.height, + position = $.extend( {}, basePosition ), + myOffset = getOffsets( offsets.my, elem.outerWidth(), elem.outerHeight() ); + + if ( options.my[ 0 ] === "right" ) { + position.left -= elemWidth; + } else if ( options.my[ 0 ] === "center" ) { + position.left -= elemWidth / 2; + } + + if ( options.my[ 1 ] === "bottom" ) { + position.top -= elemHeight; + } else if ( options.my[ 1 ] === "center" ) { + position.top -= elemHeight / 2; + } + + position.left += myOffset[ 0 ]; + position.top += myOffset[ 1 ]; + + collisionPosition = { + marginLeft: marginLeft, + marginTop: marginTop + }; + + $.each( [ "left", "top" ], function( i, dir ) { + if ( $.ui.position[ collision[ i ] ] ) { + $.ui.position[ collision[ i ] ][ dir ]( position, { + targetWidth: targetWidth, + targetHeight: targetHeight, + elemWidth: elemWidth, + elemHeight: elemHeight, + collisionPosition: collisionPosition, + collisionWidth: collisionWidth, + collisionHeight: collisionHeight, + offset: [ atOffset[ 0 ] + myOffset[ 0 ], atOffset [ 1 ] + myOffset[ 1 ] ], + my: options.my, + at: options.at, + within: within, + elem: elem + } ); + } + } ); + + if ( options.using ) { + + // Adds feedback as second argument to using callback, if present + using = function( props ) { + var left = targetOffset.left - position.left, + right = left + targetWidth - elemWidth, + top = targetOffset.top - position.top, + bottom = top + targetHeight - elemHeight, + feedback = { + target: { + element: target, + left: targetOffset.left, + top: targetOffset.top, + width: targetWidth, + height: targetHeight + }, + element: { + element: elem, + left: position.left, + top: position.top, + width: elemWidth, + height: elemHeight + }, + horizontal: right < 0 ? "left" : left > 0 ? "right" : "center", + vertical: bottom < 0 ? "top" : top > 0 ? "bottom" : "middle" + }; + if ( targetWidth < elemWidth && abs( left + right ) < targetWidth ) { + feedback.horizontal = "center"; + } + if ( targetHeight < elemHeight && abs( top + bottom ) < targetHeight ) { + feedback.vertical = "middle"; + } + if ( max( abs( left ), abs( right ) ) > max( abs( top ), abs( bottom ) ) ) { + feedback.important = "horizontal"; + } else { + feedback.important = "vertical"; + } + options.using.call( this, props, feedback ); + }; + } + + elem.offset( $.extend( position, { using: using } ) ); + } ); + }; + + $.ui.position = { + fit: { + left: function( position, data ) { + var within = data.within, + withinOffset = within.isWindow ? within.scrollLeft : within.offset.left, + outerWidth = within.width, + collisionPosLeft = position.left - data.collisionPosition.marginLeft, + overLeft = withinOffset - collisionPosLeft, + overRight = collisionPosLeft + data.collisionWidth - outerWidth - withinOffset, + newOverRight; + + // Element is wider than within + if ( data.collisionWidth > outerWidth ) { + + // Element is initially over the left side of within + if ( overLeft > 0 && overRight <= 0 ) { + newOverRight = position.left + overLeft + data.collisionWidth - outerWidth - + withinOffset; + position.left += overLeft - newOverRight; + + // Element is initially over right side of within + } else if ( overRight > 0 && overLeft <= 0 ) { + position.left = withinOffset; + + // Element is initially over both left and right sides of within + } else { + if ( overLeft > overRight ) { + position.left = withinOffset + outerWidth - data.collisionWidth; + } else { + position.left = withinOffset; + } + } + + // Too far left -> align with left edge + } else if ( overLeft > 0 ) { + position.left += overLeft; + + // Too far right -> align with right edge + } else if ( overRight > 0 ) { + position.left -= overRight; + + // Adjust based on position and margin + } else { + position.left = max( position.left - collisionPosLeft, position.left ); + } + }, + top: function( position, data ) { + var within = data.within, + withinOffset = within.isWindow ? within.scrollTop : within.offset.top, + outerHeight = data.within.height, + collisionPosTop = position.top - data.collisionPosition.marginTop, + overTop = withinOffset - collisionPosTop, + overBottom = collisionPosTop + data.collisionHeight - outerHeight - withinOffset, + newOverBottom; + + // Element is taller than within + if ( data.collisionHeight > outerHeight ) { + + // Element is initially over the top of within + if ( overTop > 0 && overBottom <= 0 ) { + newOverBottom = position.top + overTop + data.collisionHeight - outerHeight - + withinOffset; + position.top += overTop - newOverBottom; + + // Element is initially over bottom of within + } else if ( overBottom > 0 && overTop <= 0 ) { + position.top = withinOffset; + + // Element is initially over both top and bottom of within + } else { + if ( overTop > overBottom ) { + position.top = withinOffset + outerHeight - data.collisionHeight; + } else { + position.top = withinOffset; + } + } + + // Too far up -> align with top + } else if ( overTop > 0 ) { + position.top += overTop; + + // Too far down -> align with bottom edge + } else if ( overBottom > 0 ) { + position.top -= overBottom; + + // Adjust based on position and margin + } else { + position.top = max( position.top - collisionPosTop, position.top ); + } + } + }, + flip: { + left: function( position, data ) { + var within = data.within, + withinOffset = within.offset.left + within.scrollLeft, + outerWidth = within.width, + offsetLeft = within.isWindow ? within.scrollLeft : within.offset.left, + collisionPosLeft = position.left - data.collisionPosition.marginLeft, + overLeft = collisionPosLeft - offsetLeft, + overRight = collisionPosLeft + data.collisionWidth - outerWidth - offsetLeft, + myOffset = data.my[ 0 ] === "left" ? + -data.elemWidth : + data.my[ 0 ] === "right" ? + data.elemWidth : + 0, + atOffset = data.at[ 0 ] === "left" ? + data.targetWidth : + data.at[ 0 ] === "right" ? + -data.targetWidth : + 0, + offset = -2 * data.offset[ 0 ], + newOverRight, + newOverLeft; + + if ( overLeft < 0 ) { + newOverRight = position.left + myOffset + atOffset + offset + data.collisionWidth - + outerWidth - withinOffset; + if ( newOverRight < 0 || newOverRight < abs( overLeft ) ) { + position.left += myOffset + atOffset + offset; + } + } else if ( overRight > 0 ) { + newOverLeft = position.left - data.collisionPosition.marginLeft + myOffset + + atOffset + offset - offsetLeft; + if ( newOverLeft > 0 || abs( newOverLeft ) < overRight ) { + position.left += myOffset + atOffset + offset; + } + } + }, + top: function( position, data ) { + var within = data.within, + withinOffset = within.offset.top + within.scrollTop, + outerHeight = within.height, + offsetTop = within.isWindow ? within.scrollTop : within.offset.top, + collisionPosTop = position.top - data.collisionPosition.marginTop, + overTop = collisionPosTop - offsetTop, + overBottom = collisionPosTop + data.collisionHeight - outerHeight - offsetTop, + top = data.my[ 1 ] === "top", + myOffset = top ? + -data.elemHeight : + data.my[ 1 ] === "bottom" ? + data.elemHeight : + 0, + atOffset = data.at[ 1 ] === "top" ? + data.targetHeight : + data.at[ 1 ] === "bottom" ? + -data.targetHeight : + 0, + offset = -2 * data.offset[ 1 ], + newOverTop, + newOverBottom; + if ( overTop < 0 ) { + newOverBottom = position.top + myOffset + atOffset + offset + data.collisionHeight - + outerHeight - withinOffset; + if ( newOverBottom < 0 || newOverBottom < abs( overTop ) ) { + position.top += myOffset + atOffset + offset; + } + } else if ( overBottom > 0 ) { + newOverTop = position.top - data.collisionPosition.marginTop + myOffset + atOffset + + offset - offsetTop; + if ( newOverTop > 0 || abs( newOverTop ) < overBottom ) { + position.top += myOffset + atOffset + offset; + } + } + } + }, + flipfit: { + left: function() { + $.ui.position.flip.left.apply( this, arguments ); + $.ui.position.fit.left.apply( this, arguments ); + }, + top: function() { + $.ui.position.flip.top.apply( this, arguments ); + $.ui.position.fit.top.apply( this, arguments ); + } + } + }; + + } )(); + + var position = $.ui.position; + + + /*! + * jQuery UI Support for jQuery core 1.8.x and newer 1.13.2 + * http://jqueryui.com + * + * Copyright jQuery Foundation and other contributors + * Released under the MIT license. + * http://jquery.org/license + * + */ + + //>>label: jQuery 1.8+ Support + //>>group: Core + //>>description: Support version 1.8.x and newer of jQuery core + + + // Support: jQuery 1.9.x or older + // $.expr[ ":" ] is deprecated. + if ( !$.expr.pseudos ) { + $.expr.pseudos = $.expr[ ":" ]; + } + + // Support: jQuery 1.11.x or older + // $.unique has been renamed to $.uniqueSort + if ( !$.uniqueSort ) { + $.uniqueSort = $.unique; + } + + // Support: jQuery 2.2.x or older. + // This method has been defined in jQuery 3.0.0. + // Code from https://github.com/jquery/jquery/blob/e539bac79e666bba95bba86d690b4e609dca2286/src/selector/escapeSelector.js + if ( !$.escapeSelector ) { + + // CSS string/identifier serialization + // https://drafts.csswg.org/cssom/#common-serializing-idioms + var rcssescape = /([\0-\x1f\x7f]|^-?\d)|^-$|[^\x80-\uFFFF\w-]/g; + + var fcssescape = function( ch, asCodePoint ) { + if ( asCodePoint ) { + + // U+0000 NULL becomes U+FFFD REPLACEMENT CHARACTER + if ( ch === "\0" ) { + return "\uFFFD"; + } + + // Control characters and (dependent upon position) numbers get escaped as code points + return ch.slice( 0, -1 ) + "\\" + ch.charCodeAt( ch.length - 1 ).toString( 16 ) + " "; + } + + // Other potentially-special ASCII characters get backslash-escaped + return "\\" + ch; + }; + + $.escapeSelector = function( sel ) { + return ( sel + "" ).replace( rcssescape, fcssescape ); + }; + } + + // Support: jQuery 3.4.x or older + // These methods have been defined in jQuery 3.5.0. + if ( !$.fn.even || !$.fn.odd ) { + $.fn.extend( { + even: function() { + return this.filter( function( i ) { + return i % 2 === 0; + } ); + }, + odd: function() { + return this.filter( function( i ) { + return i % 2 === 1; + } ); + } + } ); + } + + ; + /*! + * jQuery UI Keycode 1.13.2 + * http://jqueryui.com + * + * Copyright jQuery Foundation and other contributors + * Released under the MIT license. + * http://jquery.org/license + */ + + //>>label: Keycode + //>>group: Core + //>>description: Provide keycodes as keynames + //>>docs: http://api.jqueryui.com/jQuery.ui.keyCode/ + + + var keycode = $.ui.keyCode = { + BACKSPACE: 8, + COMMA: 188, + DELETE: 46, + DOWN: 40, + END: 35, + ENTER: 13, + ESCAPE: 27, + HOME: 36, + LEFT: 37, + PAGE_DOWN: 34, + PAGE_UP: 33, + PERIOD: 190, + RIGHT: 39, + SPACE: 32, + TAB: 9, + UP: 38 + }; + + + /*! + * jQuery UI Scroll Parent 1.13.2 + * http://jqueryui.com + * + * Copyright jQuery Foundation and other contributors + * Released under the MIT license. + * http://jquery.org/license + */ + + //>>label: scrollParent + //>>group: Core + //>>description: Get the closest ancestor element that is scrollable. + //>>docs: http://api.jqueryui.com/scrollParent/ + + + var scrollParent = $.fn.scrollParent = function( includeHidden ) { + var position = this.css( "position" ), + excludeStaticParent = position === "absolute", + overflowRegex = includeHidden ? /(auto|scroll|hidden)/ : /(auto|scroll)/, + scrollParent = this.parents().filter( function() { + var parent = $( this ); + if ( excludeStaticParent && parent.css( "position" ) === "static" ) { + return false; + } + return overflowRegex.test( parent.css( "overflow" ) + parent.css( "overflow-y" ) + + parent.css( "overflow-x" ) ); + } ).eq( 0 ); + + return position === "fixed" || !scrollParent.length ? + $( this[ 0 ].ownerDocument || document ) : + scrollParent; + }; + + + /*! + * jQuery UI Unique ID 1.13.2 + * http://jqueryui.com + * + * Copyright jQuery Foundation and other contributors + * Released under the MIT license. + * http://jquery.org/license + */ + + //>>label: uniqueId + //>>group: Core + //>>description: Functions to generate and remove uniqueId's + //>>docs: http://api.jqueryui.com/uniqueId/ + + + var uniqueId = $.fn.extend( { + uniqueId: ( function() { + var uuid = 0; + + return function() { + return this.each( function() { + if ( !this.id ) { + this.id = "ui-id-" + ( ++uuid ); + } + } ); + }; + } )(), + + removeUniqueId: function() { + return this.each( function() { + if ( /^ui-id-\d+$/.test( this.id ) ) { + $( this ).removeAttr( "id" ); + } + } ); + } + } ); + + + + +// NOTE: Original jQuery UI wrapper was replaced. See README-Fancytree.md +// })); +})(jQuery); + +(function( factory ) { + if ( typeof define === "function" && define.amd ) { + // AMD. Register as an anonymous module. + define( [ "jquery" ], factory ); + } else if ( typeof module === "object" && module.exports ) { + // Node/CommonJS + module.exports = factory(require("jquery")); + } else { + // Browser globals + factory( jQuery ); + } +}(function( $ ) { + + +/*! Fancytree Core *//*! + * jquery.fancytree.js + * Tree view control with support for lazy loading and much more. + * https://github.com/mar10/fancytree/ + * + * Copyright (c) 2008-2023, Martin Wendt (https://wwWendt.de) + * Released under the MIT license + * https://github.com/mar10/fancytree/wiki/LicenseInfo + * + * @version 2.38.3 + * @date 2023-02-01T20:52:50Z + */ + +/** Core Fancytree module. + */ + +// UMD wrapper for the Fancytree core module +(function (factory) { + if (typeof define === "function" && define.amd) { + // AMD. Register as an anonymous module. + define(["jquery", "./jquery.fancytree.ui-deps"], factory); + } else if (typeof module === "object" && module.exports) { + // Node/CommonJS + require("./jquery.fancytree.ui-deps"); + module.exports = factory(require("jquery")); + } else { + // Browser globals + factory(jQuery); + } +})(function ($) { + "use strict"; + + // prevent duplicate loading + if ($.ui && $.ui.fancytree) { + $.ui.fancytree.warn("Fancytree: ignored duplicate include"); + return; + } + + /****************************************************************************** + * Private functions and variables + */ + + var i, + attr, + FT = null, // initialized below + TEST_IMG = new RegExp(/\.|\//), // strings are considered image urls if they contain '.' or '/' + REX_HTML = /[&<>"'/]/g, // Escape those characters + REX_TOOLTIP = /[<>"'/]/g, // Don't escape `&` in tooltips + RECURSIVE_REQUEST_ERROR = "$recursive_request", + INVALID_REQUEST_TARGET_ERROR = "$request_target_invalid", + ENTITY_MAP = { + "&": "&", + "<": "<", + ">": ">", + '"': """, + "'": "'", + "/": "/", + }, + IGNORE_KEYCODES = { 16: true, 17: true, 18: true }, + SPECIAL_KEYCODES = { + 8: "backspace", + 9: "tab", + 10: "return", + 13: "return", + // 16: null, 17: null, 18: null, // ignore shift, ctrl, alt + 19: "pause", + 20: "capslock", + 27: "esc", + 32: "space", + 33: "pageup", + 34: "pagedown", + 35: "end", + 36: "home", + 37: "left", + 38: "up", + 39: "right", + 40: "down", + 45: "insert", + 46: "del", + 59: ";", + 61: "=", + // 91: null, 93: null, // ignore left and right meta + 96: "0", + 97: "1", + 98: "2", + 99: "3", + 100: "4", + 101: "5", + 102: "6", + 103: "7", + 104: "8", + 105: "9", + 106: "*", + 107: "+", + 109: "-", + 110: ".", + 111: "/", + 112: "f1", + 113: "f2", + 114: "f3", + 115: "f4", + 116: "f5", + 117: "f6", + 118: "f7", + 119: "f8", + 120: "f9", + 121: "f10", + 122: "f11", + 123: "f12", + 144: "numlock", + 145: "scroll", + 173: "-", + 186: ";", + 187: "=", + 188: ",", + 189: "-", + 190: ".", + 191: "/", + 192: "`", + 219: "[", + 220: "\\", + 221: "]", + 222: "'", + }, + MODIFIERS = { + 16: "shift", + 17: "ctrl", + 18: "alt", + 91: "meta", + 93: "meta", + }, + MOUSE_BUTTONS = { 0: "", 1: "left", 2: "middle", 3: "right" }, + // Boolean attributes that can be set with equivalent class names in the LI tags + // Note: v2.23: checkbox and hideCheckbox are *not* in this list + CLASS_ATTRS = + "active expanded focus folder lazy radiogroup selected unselectable unselectableIgnore".split( + " " + ), + CLASS_ATTR_MAP = {}, + // Top-level Fancytree attributes, that can be set by dict + TREE_ATTRS = "columns types".split(" "), + // TREE_ATTR_MAP = {}, + // Top-level FancytreeNode attributes, that can be set by dict + NODE_ATTRS = + "checkbox expanded extraClasses folder icon iconTooltip key lazy partsel radiogroup refKey selected statusNodeType title tooltip type unselectable unselectableIgnore unselectableStatus".split( + " " + ), + NODE_ATTR_MAP = {}, + // Mapping of lowercase -> real name (because HTML5 data-... attribute only supports lowercase) + NODE_ATTR_LOWERCASE_MAP = {}, + // Attribute names that should NOT be added to node.data + NONE_NODE_DATA_MAP = { + active: true, + children: true, + data: true, + focus: true, + }; + + for (i = 0; i < CLASS_ATTRS.length; i++) { + CLASS_ATTR_MAP[CLASS_ATTRS[i]] = true; + } + for (i = 0; i < NODE_ATTRS.length; i++) { + attr = NODE_ATTRS[i]; + NODE_ATTR_MAP[attr] = true; + if (attr !== attr.toLowerCase()) { + NODE_ATTR_LOWERCASE_MAP[attr.toLowerCase()] = attr; + } + } + // for(i=0; i<TREE_ATTRS.length; i++) { + // TREE_ATTR_MAP[TREE_ATTRS[i]] = true; + // } + + function _assert(cond, msg) { + // TODO: see qunit.js extractStacktrace() + if (!cond) { + msg = msg ? ": " + msg : ""; + msg = "Fancytree assertion failed" + msg; + + // consoleApply("assert", [!!cond, msg]); + + // #1041: Raised exceptions may not be visible in the browser + // console if inside promise chains, so we also print directly: + $.ui.fancytree.error(msg); + + // Throw exception: + $.error(msg); + } + } + + function _hasProp(object, property) { + return Object.prototype.hasOwnProperty.call(object, property); + } + + /* Replacement for the deprecated `jQuery.isFunction()`. */ + function _isFunction(obj) { + return typeof obj === "function"; + } + + /* Replacement for the deprecated `jQuery.trim()`. */ + function _trim(text) { + return text == null ? "" : text.trim(); + } + + /* Replacement for the deprecated `jQuery.isArray()`. */ + var _isArray = Array.isArray; + + _assert($.ui, "Fancytree requires jQuery UI (http://jqueryui.com)"); + + function consoleApply(method, args) { + var i, + s, + fn = window.console ? window.console[method] : null; + + if (fn) { + try { + fn.apply(window.console, args); + } catch (e) { + // IE 8? + s = ""; + for (i = 0; i < args.length; i++) { + s += args[i]; + } + fn(s); + } + } + } + + /* support: IE8 Polyfil for Date.now() */ + if (!Date.now) { + Date.now = function now() { + return new Date().getTime(); + }; + } + + /*Return true if x is a FancytreeNode.*/ + function _isNode(x) { + return !!(x.tree && x.statusNodeType !== undefined); + } + + /** Return true if dotted version string is equal or higher than requested version. + * + * See http://jsfiddle.net/mar10/FjSAN/ + */ + function isVersionAtLeast(dottedVersion, major, minor, patch) { + var i, + v, + t, + verParts = $.map(_trim(dottedVersion).split("."), function (e) { + return parseInt(e, 10); + }), + testParts = $.map( + Array.prototype.slice.call(arguments, 1), + function (e) { + return parseInt(e, 10); + } + ); + + for (i = 0; i < testParts.length; i++) { + v = verParts[i] || 0; + t = testParts[i] || 0; + if (v !== t) { + return v > t; + } + } + return true; + } + + /** + * Deep-merge a list of objects (but replace array-type options). + * + * jQuery's $.extend(true, ...) method does a deep merge, that also merges Arrays. + * This variant is used to merge extension defaults with user options, and should + * merge objects, but override arrays (for example the `triggerStart: [...]` option + * of ext-edit). Also `null` values are copied over and not skipped. + * + * See issue #876 + * + * Example: + * _simpleDeepMerge({}, o1, o2); + */ + function _simpleDeepMerge() { + var options, + name, + src, + copy, + clone, + target = arguments[0] || {}, + i = 1, + length = arguments.length; + + // Handle case when target is a string or something (possible in deep copy) + if (typeof target !== "object" && !_isFunction(target)) { + target = {}; + } + if (i === length) { + throw Error("need at least two args"); + } + for (; i < length; i++) { + // Only deal with non-null/undefined values + if ((options = arguments[i]) != null) { + // Extend the base object + for (name in options) { + if (_hasProp(options, name)) { + src = target[name]; + copy = options[name]; + // Prevent never-ending loop + if (target === copy) { + continue; + } + // Recurse if we're merging plain objects + // (NOTE: unlike $.extend, we don't merge arrays, but replace them) + if (copy && $.isPlainObject(copy)) { + clone = src && $.isPlainObject(src) ? src : {}; + // Never move original objects, clone them + target[name] = _simpleDeepMerge(clone, copy); + // Don't bring in undefined values + } else if (copy !== undefined) { + target[name] = copy; + } + } + } + } + } + // Return the modified object + return target; + } + + /** Return a wrapper that calls sub.methodName() and exposes + * this : tree + * this._local : tree.ext.EXTNAME + * this._super : base.methodName.call() + * this._superApply : base.methodName.apply() + */ + function _makeVirtualFunction(methodName, tree, base, extension, extName) { + // $.ui.fancytree.debug("_makeVirtualFunction", methodName, tree, base, extension, extName); + // if(rexTestSuper && !rexTestSuper.test(func)){ + // // extension.methodName() doesn't call _super(), so no wrapper required + // return func; + // } + // Use an immediate function as closure + var proxy = (function () { + var prevFunc = tree[methodName], // org. tree method or prev. proxy + baseFunc = extension[methodName], // + _local = tree.ext[extName], + _super = function () { + return prevFunc.apply(tree, arguments); + }, + _superApply = function (args) { + return prevFunc.apply(tree, args); + }; + + // Return the wrapper function + return function () { + var prevLocal = tree._local, + prevSuper = tree._super, + prevSuperApply = tree._superApply; + + try { + tree._local = _local; + tree._super = _super; + tree._superApply = _superApply; + return baseFunc.apply(tree, arguments); + } finally { + tree._local = prevLocal; + tree._super = prevSuper; + tree._superApply = prevSuperApply; + } + }; + })(); // end of Immediate Function + return proxy; + } + + /** + * Subclass `base` by creating proxy functions + */ + function _subclassObject(tree, base, extension, extName) { + // $.ui.fancytree.debug("_subclassObject", tree, base, extension, extName); + for (var attrName in extension) { + if (typeof extension[attrName] === "function") { + if (typeof tree[attrName] === "function") { + // override existing method + tree[attrName] = _makeVirtualFunction( + attrName, + tree, + base, + extension, + extName + ); + } else if (attrName.charAt(0) === "_") { + // Create private methods in tree.ext.EXTENSION namespace + tree.ext[extName][attrName] = _makeVirtualFunction( + attrName, + tree, + base, + extension, + extName + ); + } else { + $.error( + "Could not override tree." + + attrName + + ". Use prefix '_' to create tree." + + extName + + "._" + + attrName + ); + } + } else { + // Create member variables in tree.ext.EXTENSION namespace + if (attrName !== "options") { + tree.ext[extName][attrName] = extension[attrName]; + } + } + } + } + + function _getResolvedPromise(context, argArray) { + if (context === undefined) { + return $.Deferred(function () { + this.resolve(); + }).promise(); + } + return $.Deferred(function () { + this.resolveWith(context, argArray); + }).promise(); + } + + function _getRejectedPromise(context, argArray) { + if (context === undefined) { + return $.Deferred(function () { + this.reject(); + }).promise(); + } + return $.Deferred(function () { + this.rejectWith(context, argArray); + }).promise(); + } + + function _makeResolveFunc(deferred, context) { + return function () { + deferred.resolveWith(context); + }; + } + + function _getElementDataAsDict($el) { + // Evaluate 'data-NAME' attributes with special treatment for 'data-json'. + var d = $.extend({}, $el.data()), + json = d.json; + + delete d.fancytree; // added to container by widget factory (old jQuery UI) + delete d.uiFancytree; // added to container by widget factory + + if (json) { + delete d.json; + // <li data-json='...'> is already returned as object (http://api.jquery.com/data/#data-html5) + d = $.extend(d, json); + } + return d; + } + + function _escapeTooltip(s) { + return ("" + s).replace(REX_TOOLTIP, function (s) { + return ENTITY_MAP[s]; + }); + } + + // TODO: use currying + function _makeNodeTitleMatcher(s) { + s = s.toLowerCase(); + return function (node) { + return node.title.toLowerCase().indexOf(s) >= 0; + }; + } + + function _makeNodeTitleStartMatcher(s) { + var reMatch = new RegExp("^" + s, "i"); + return function (node) { + return reMatch.test(node.title); + }; + } + + /****************************************************************************** + * FancytreeNode + */ + + /** + * Creates a new FancytreeNode + * + * @class FancytreeNode + * @classdesc A FancytreeNode represents the hierarchical data model and operations. + * + * @param {FancytreeNode} parent + * @param {NodeData} obj + * + * @property {Fancytree} tree The tree instance + * @property {FancytreeNode} parent The parent node + * @property {string} key Node id (must be unique inside the tree) + * @property {string} title Display name (may contain HTML) + * @property {object} data Contains all extra data that was passed on node creation + * @property {FancytreeNode[] | null | undefined} children Array of child nodes.<br> + * For lazy nodes, null or undefined means 'not yet loaded'. Use an empty array + * to define a node that has no children. + * @property {boolean} expanded Use isExpanded(), setExpanded() to access this property. + * @property {string} extraClasses Additional CSS classes, added to the node's `<span>`.<br> + * Note: use `node.add/remove/toggleClass()` to modify. + * @property {boolean} folder Folder nodes have different default icons and click behavior.<br> + * Note: Also non-folders may have children. + * @property {string} statusNodeType null for standard nodes. Otherwise type of special system node: 'error', 'loading', 'nodata', or 'paging'. + * @property {boolean} lazy True if this node is loaded on demand, i.e. on first expansion. + * @property {boolean} selected Use isSelected(), setSelected() to access this property. + * @property {string} tooltip Alternative description used as hover popup + * @property {string} iconTooltip Description used as hover popup for icon. @since 2.27 + * @property {string} type Node type, used with tree.types map. @since 2.27 + */ + function FancytreeNode(parent, obj) { + var i, l, name, cl; + + this.parent = parent; + this.tree = parent.tree; + this.ul = null; + this.li = null; // <li id='key' ftnode=this> tag + this.statusNodeType = null; // if this is a temp. node to display the status of its parent + this._isLoading = false; // if this node itself is loading + this._error = null; // {message: '...'} if a load error occurred + this.data = {}; + + // TODO: merge this code with node.toDict() + // copy attributes from obj object + for (i = 0, l = NODE_ATTRS.length; i < l; i++) { + name = NODE_ATTRS[i]; + this[name] = obj[name]; + } + // unselectableIgnore and unselectableStatus imply unselectable + if ( + this.unselectableIgnore != null || + this.unselectableStatus != null + ) { + this.unselectable = true; + } + if (obj.hideCheckbox) { + $.error( + "'hideCheckbox' node option was removed in v2.23.0: use 'checkbox: false'" + ); + } + // node.data += obj.data + if (obj.data) { + $.extend(this.data, obj.data); + } + // Copy all other attributes to this.data.NAME + for (name in obj) { + if ( + !NODE_ATTR_MAP[name] && + (this.tree.options.copyFunctionsToData || + !_isFunction(obj[name])) && + !NONE_NODE_DATA_MAP[name] + ) { + // node.data.NAME = obj.NAME + this.data[name] = obj[name]; + } + } + + // Fix missing key + if (this.key == null) { + // test for null OR undefined + if (this.tree.options.defaultKey) { + this.key = "" + this.tree.options.defaultKey(this); + _assert(this.key, "defaultKey() must return a unique key"); + } else { + this.key = "_" + FT._nextNodeKey++; + } + } else { + this.key = "" + this.key; // Convert to string (#217) + } + + // Fix tree.activeNode + // TODO: not elegant: we use obj.active as marker to set tree.activeNode + // when loading from a dictionary. + if (obj.active) { + _assert( + this.tree.activeNode === null, + "only one active node allowed" + ); + this.tree.activeNode = this; + } + if (obj.selected) { + // #186 + this.tree.lastSelectedNode = this; + } + // TODO: handle obj.focus = true + + // Create child nodes + cl = obj.children; + if (cl) { + if (cl.length) { + this._setChildren(cl); + } else { + // if an empty array was passed for a lazy node, keep it, in order to mark it 'loaded' + this.children = this.lazy ? [] : null; + } + } else { + this.children = null; + } + // Add to key/ref map (except for root node) + // if( parent ) { + this.tree._callHook("treeRegisterNode", this.tree, true, this); + // } + } + + FancytreeNode.prototype = /** @lends FancytreeNode# */ { + /* Return the direct child FancytreeNode with a given key, index. */ + _findDirectChild: function (ptr) { + var i, + l, + cl = this.children; + + if (cl) { + if (typeof ptr === "string") { + for (i = 0, l = cl.length; i < l; i++) { + if (cl[i].key === ptr) { + return cl[i]; + } + } + } else if (typeof ptr === "number") { + return this.children[ptr]; + } else if (ptr.parent === this) { + return ptr; + } + } + return null; + }, + // TODO: activate() + // TODO: activateSilently() + /* Internal helper called in recursive addChildren sequence.*/ + _setChildren: function (children) { + _assert( + children && (!this.children || this.children.length === 0), + "only init supported" + ); + this.children = []; + for (var i = 0, l = children.length; i < l; i++) { + this.children.push(new FancytreeNode(this, children[i])); + } + this.tree._callHook( + "treeStructureChanged", + this.tree, + "setChildren" + ); + }, + /** + * Append (or insert) a list of child nodes. + * + * @param {NodeData[]} children array of child node definitions (also single child accepted) + * @param {FancytreeNode | string | Integer} [insertBefore] child node (or key or index of such). + * If omitted, the new children are appended. + * @returns {FancytreeNode} first child added + * + * @see FancytreeNode#applyPatch + */ + addChildren: function (children, insertBefore) { + var i, + l, + pos, + origFirstChild = this.getFirstChild(), + origLastChild = this.getLastChild(), + firstNode = null, + nodeList = []; + + if ($.isPlainObject(children)) { + children = [children]; + } + if (!this.children) { + this.children = []; + } + for (i = 0, l = children.length; i < l; i++) { + nodeList.push(new FancytreeNode(this, children[i])); + } + firstNode = nodeList[0]; + if (insertBefore == null) { + this.children = this.children.concat(nodeList); + } else { + // Returns null if insertBefore is not a direct child: + insertBefore = this._findDirectChild(insertBefore); + pos = $.inArray(insertBefore, this.children); + _assert(pos >= 0, "insertBefore must be an existing child"); + // insert nodeList after children[pos] + this.children.splice.apply( + this.children, + [pos, 0].concat(nodeList) + ); + } + if (origFirstChild && !insertBefore) { + // #708: Fast path -- don't render every child of root, just the new ones! + // #723, #729: but only if it's appended to an existing child list + for (i = 0, l = nodeList.length; i < l; i++) { + nodeList[i].render(); // New nodes were never rendered before + } + // Adjust classes where status may have changed + // Has a first child + if (origFirstChild !== this.getFirstChild()) { + // Different first child -- recompute classes + origFirstChild.renderStatus(); + } + if (origLastChild !== this.getLastChild()) { + // Different last child -- recompute classes + origLastChild.renderStatus(); + } + } else if (!this.parent || this.parent.ul || this.tr) { + // render if the parent was rendered (or this is a root node) + this.render(); + } + if (this.tree.options.selectMode === 3) { + this.fixSelection3FromEndNodes(); + } + this.triggerModifyChild( + "add", + nodeList.length === 1 ? nodeList[0] : null + ); + return firstNode; + }, + /** + * Add class to node's span tag and to .extraClasses. + * + * @param {string} className class name + * + * @since 2.17 + */ + addClass: function (className) { + return this.toggleClass(className, true); + }, + /** + * Append or prepend a node, or append a child node. + * + * This a convenience function that calls addChildren() + * + * @param {NodeData} node node definition + * @param {string} [mode=child] 'before', 'after', 'firstChild', or 'child' ('over' is a synonym for 'child') + * @returns {FancytreeNode} new node + */ + addNode: function (node, mode) { + if (mode === undefined || mode === "over") { + mode = "child"; + } + switch (mode) { + case "after": + return this.getParent().addChildren( + node, + this.getNextSibling() + ); + case "before": + return this.getParent().addChildren(node, this); + case "firstChild": + // Insert before the first child if any + var insertBefore = this.children ? this.children[0] : null; + return this.addChildren(node, insertBefore); + case "child": + case "over": + return this.addChildren(node); + } + _assert(false, "Invalid mode: " + mode); + }, + /**Add child status nodes that indicate 'More...', etc. + * + * This also maintains the node's `partload` property. + * @param {boolean|object} node optional node definition. Pass `false` to remove all paging nodes. + * @param {string} [mode='child'] 'child'|firstChild' + * @since 2.15 + */ + addPagingNode: function (node, mode) { + var i, n; + + mode = mode || "child"; + if (node === false) { + for (i = this.children.length - 1; i >= 0; i--) { + n = this.children[i]; + if (n.statusNodeType === "paging") { + this.removeChild(n); + } + } + this.partload = false; + return; + } + node = $.extend( + { + title: this.tree.options.strings.moreData, + statusNodeType: "paging", + icon: false, + }, + node + ); + this.partload = true; + return this.addNode(node, mode); + }, + /** + * Append new node after this. + * + * This a convenience function that calls addNode(node, 'after') + * + * @param {NodeData} node node definition + * @returns {FancytreeNode} new node + */ + appendSibling: function (node) { + return this.addNode(node, "after"); + }, + /** + * (experimental) Apply a modification (or navigation) operation. + * + * @param {string} cmd + * @param {object} [opts] + * @see Fancytree#applyCommand + * @since 2.32 + */ + applyCommand: function (cmd, opts) { + return this.tree.applyCommand(cmd, this, opts); + }, + /** + * Modify existing child nodes. + * + * @param {NodePatch} patch + * @returns {$.Promise} + * @see FancytreeNode#addChildren + */ + applyPatch: function (patch) { + // patch [key, null] means 'remove' + if (patch === null) { + this.remove(); + return _getResolvedPromise(this); + } + // TODO: make sure that root node is not collapsed or modified + // copy (most) attributes to node.ATTR or node.data.ATTR + var name, + promise, + v, + IGNORE_MAP = { children: true, expanded: true, parent: true }; // TODO: should be global + + for (name in patch) { + if (_hasProp(patch, name)) { + v = patch[name]; + if (!IGNORE_MAP[name] && !_isFunction(v)) { + if (NODE_ATTR_MAP[name]) { + this[name] = v; + } else { + this.data[name] = v; + } + } + } + } + // Remove and/or create children + if (_hasProp(patch, "children")) { + this.removeChildren(); + if (patch.children) { + // only if not null and not empty list + // TODO: addChildren instead? + this._setChildren(patch.children); + } + // TODO: how can we APPEND or INSERT child nodes? + } + if (this.isVisible()) { + this.renderTitle(); + this.renderStatus(); + } + // Expand collapse (final step, since this may be async) + if (_hasProp(patch, "expanded")) { + promise = this.setExpanded(patch.expanded); + } else { + promise = _getResolvedPromise(this); + } + return promise; + }, + /** Collapse all sibling nodes. + * @returns {$.Promise} + */ + collapseSiblings: function () { + return this.tree._callHook("nodeCollapseSiblings", this); + }, + /** Copy this node as sibling or child of `node`. + * + * @param {FancytreeNode} node source node + * @param {string} [mode=child] 'before' | 'after' | 'child' + * @param {Function} [map] callback function(NodeData, FancytreeNode) that could modify the new node + * @returns {FancytreeNode} new + */ + copyTo: function (node, mode, map) { + return node.addNode(this.toDict(true, map), mode); + }, + /** Count direct and indirect children. + * + * @param {boolean} [deep=true] pass 'false' to only count direct children + * @returns {int} number of child nodes + */ + countChildren: function (deep) { + var cl = this.children, + i, + l, + n; + if (!cl) { + return 0; + } + n = cl.length; + if (deep !== false) { + for (i = 0, l = n; i < l; i++) { + n += cl[i].countChildren(); + } + } + return n; + }, + // TODO: deactivate() + /** Write to browser console if debugLevel >= 4 (prepending node info) + * + * @param {*} msg string or object or array of such + */ + debug: function (msg) { + if (this.tree.options.debugLevel >= 4) { + Array.prototype.unshift.call(arguments, this.toString()); + consoleApply("log", arguments); + } + }, + /** Deprecated. + * @deprecated since 2014-02-16. Use resetLazy() instead. + */ + discard: function () { + this.warn( + "FancytreeNode.discard() is deprecated since 2014-02-16. Use .resetLazy() instead." + ); + return this.resetLazy(); + }, + /** Remove DOM elements for all descendents. May be called on .collapse event + * to keep the DOM small. + * @param {boolean} [includeSelf=false] + */ + discardMarkup: function (includeSelf) { + var fn = includeSelf ? "nodeRemoveMarkup" : "nodeRemoveChildMarkup"; + this.tree._callHook(fn, this); + }, + /** Write error to browser console if debugLevel >= 1 (prepending tree info) + * + * @param {*} msg string or object or array of such + */ + error: function (msg) { + if (this.tree.options.debugLevel >= 1) { + Array.prototype.unshift.call(arguments, this.toString()); + consoleApply("error", arguments); + } + }, + /**Find all nodes that match condition (excluding self). + * + * @param {string | function(node)} match title string to search for, or a + * callback function that returns `true` if a node is matched. + * @returns {FancytreeNode[]} array of nodes (may be empty) + */ + findAll: function (match) { + match = _isFunction(match) ? match : _makeNodeTitleMatcher(match); + var res = []; + this.visit(function (n) { + if (match(n)) { + res.push(n); + } + }); + return res; + }, + /**Find first node that matches condition (excluding self). + * + * @param {string | function(node)} match title string to search for, or a + * callback function that returns `true` if a node is matched. + * @returns {FancytreeNode} matching node or null + * @see FancytreeNode#findAll + */ + findFirst: function (match) { + match = _isFunction(match) ? match : _makeNodeTitleMatcher(match); + var res = null; + this.visit(function (n) { + if (match(n)) { + res = n; + return false; + } + }); + return res; + }, + /** Find a node relative to self. + * + * @param {number|string} where The keyCode that would normally trigger this move, + * or a keyword ('down', 'first', 'last', 'left', 'parent', 'right', 'up'). + * @returns {FancytreeNode} + * @since v2.31 + */ + findRelatedNode: function (where, includeHidden) { + return this.tree.findRelatedNode(this, where, includeHidden); + }, + /* Apply selection state (internal use only) */ + _changeSelectStatusAttrs: function (state) { + var changed = false, + opts = this.tree.options, + unselectable = FT.evalOption( + "unselectable", + this, + this, + opts, + false + ), + unselectableStatus = FT.evalOption( + "unselectableStatus", + this, + this, + opts, + undefined + ); + + if (unselectable && unselectableStatus != null) { + state = unselectableStatus; + } + switch (state) { + case false: + changed = this.selected || this.partsel; + this.selected = false; + this.partsel = false; + break; + case true: + changed = !this.selected || !this.partsel; + this.selected = true; + this.partsel = true; + break; + case undefined: + changed = this.selected || !this.partsel; + this.selected = false; + this.partsel = true; + break; + default: + _assert(false, "invalid state: " + state); + } + // this.debug("fixSelection3AfterLoad() _changeSelectStatusAttrs()", state, changed); + if (changed) { + this.renderStatus(); + } + return changed; + }, + /** + * Fix selection status, after this node was (de)selected in multi-hier mode. + * This includes (de)selecting all children. + */ + fixSelection3AfterClick: function (callOpts) { + var flag = this.isSelected(); + + // this.debug("fixSelection3AfterClick()"); + + this.visit(function (node) { + node._changeSelectStatusAttrs(flag); + if (node.radiogroup) { + // #931: don't (de)select this branch + return "skip"; + } + }); + this.fixSelection3FromEndNodes(callOpts); + }, + /** + * Fix selection status for multi-hier mode. + * Only end-nodes are considered to update the descendants branch and parents. + * Should be called after this node has loaded new children or after + * children have been modified using the API. + */ + fixSelection3FromEndNodes: function (callOpts) { + var opts = this.tree.options; + + // this.debug("fixSelection3FromEndNodes()"); + _assert(opts.selectMode === 3, "expected selectMode 3"); + + // Visit all end nodes and adjust their parent's `selected` and `partsel` + // attributes. Return selection state true, false, or undefined. + function _walk(node) { + var i, + l, + child, + s, + state, + allSelected, + someSelected, + unselIgnore, + unselState, + children = node.children; + + if (children && children.length) { + // check all children recursively + allSelected = true; + someSelected = false; + + for (i = 0, l = children.length; i < l; i++) { + child = children[i]; + // the selection state of a node is not relevant; we need the end-nodes + s = _walk(child); + // if( !child.unselectableIgnore ) { + unselIgnore = FT.evalOption( + "unselectableIgnore", + child, + child, + opts, + false + ); + if (!unselIgnore) { + if (s !== false) { + someSelected = true; + } + if (s !== true) { + allSelected = false; + } + } + } + // eslint-disable-next-line no-nested-ternary + state = allSelected + ? true + : someSelected + ? undefined + : false; + } else { + // This is an end-node: simply report the status + unselState = FT.evalOption( + "unselectableStatus", + node, + node, + opts, + undefined + ); + state = unselState == null ? !!node.selected : !!unselState; + } + // #939: Keep a `partsel` flag that was explicitly set on a lazy node + if ( + node.partsel && + !node.selected && + node.lazy && + node.children == null + ) { + state = undefined; + } + node._changeSelectStatusAttrs(state); + return state; + } + _walk(this); + + // Update parent's state + this.visitParents(function (node) { + var i, + l, + child, + state, + unselIgnore, + unselState, + children = node.children, + allSelected = true, + someSelected = false; + + for (i = 0, l = children.length; i < l; i++) { + child = children[i]; + unselIgnore = FT.evalOption( + "unselectableIgnore", + child, + child, + opts, + false + ); + if (!unselIgnore) { + unselState = FT.evalOption( + "unselectableStatus", + child, + child, + opts, + undefined + ); + state = + unselState == null + ? !!child.selected + : !!unselState; + // When fixing the parents, we trust the sibling status (i.e. + // we don't recurse) + if (state || child.partsel) { + someSelected = true; + } + if (!state) { + allSelected = false; + } + } + } + // eslint-disable-next-line no-nested-ternary + state = allSelected ? true : someSelected ? undefined : false; + node._changeSelectStatusAttrs(state); + }); + }, + // TODO: focus() + /** + * Update node data. If dict contains 'children', then also replace + * the hole sub tree. + * @param {NodeData} dict + * + * @see FancytreeNode#addChildren + * @see FancytreeNode#applyPatch + */ + fromDict: function (dict) { + // copy all other attributes to this.data.xxx + for (var name in dict) { + if (NODE_ATTR_MAP[name]) { + // node.NAME = dict.NAME + this[name] = dict[name]; + } else if (name === "data") { + // node.data += dict.data + $.extend(this.data, dict.data); + } else if ( + !_isFunction(dict[name]) && + !NONE_NODE_DATA_MAP[name] + ) { + // node.data.NAME = dict.NAME + this.data[name] = dict[name]; + } + } + if (dict.children) { + // recursively set children and render + this.removeChildren(); + this.addChildren(dict.children); + } + this.renderTitle(); + /* + var children = dict.children; + if(children === undefined){ + this.data = $.extend(this.data, dict); + this.render(); + return; + } + dict = $.extend({}, dict); + dict.children = undefined; + this.data = $.extend(this.data, dict); + this.removeChildren(); + this.addChild(children); + */ + }, + /** Return the list of child nodes (undefined for unexpanded lazy nodes). + * @returns {FancytreeNode[] | undefined} + */ + getChildren: function () { + if (this.hasChildren() === undefined) { + // TODO: only required for lazy nodes? + return undefined; // Lazy node: unloaded, currently loading, or load error + } + return this.children; + }, + /** Return the first child node or null. + * @returns {FancytreeNode | null} + */ + getFirstChild: function () { + return this.children ? this.children[0] : null; + }, + /** Return the 0-based child index. + * @returns {int} + */ + getIndex: function () { + // return this.parent.children.indexOf(this); + return $.inArray(this, this.parent.children); // indexOf doesn't work in IE7 + }, + /** Return the hierarchical child index (1-based, e.g. '3.2.4'). + * @param {string} [separator="."] + * @param {int} [digits=1] + * @returns {string} + */ + getIndexHier: function (separator, digits) { + separator = separator || "."; + var s, + res = []; + $.each(this.getParentList(false, true), function (i, o) { + s = "" + (o.getIndex() + 1); + if (digits) { + // prepend leading zeroes + s = ("0000000" + s).substr(-digits); + } + res.push(s); + }); + return res.join(separator); + }, + /** Return the parent keys separated by options.keyPathSeparator, e.g. "/id_1/id_17/id_32". + * + * (Unlike `node.getPath()`, this method prepends a "/" and inverts the first argument.) + * + * @see FancytreeNode#getPath + * @param {boolean} [excludeSelf=false] + * @returns {string} + */ + getKeyPath: function (excludeSelf) { + var sep = this.tree.options.keyPathSeparator; + + return sep + this.getPath(!excludeSelf, "key", sep); + }, + /** Return the last child of this node or null. + * @returns {FancytreeNode | null} + */ + getLastChild: function () { + return this.children + ? this.children[this.children.length - 1] + : null; + }, + /** Return node depth. 0: System root node, 1: visible top-level node, 2: first sub-level, ... . + * @returns {int} + */ + getLevel: function () { + var level = 0, + dtn = this.parent; + while (dtn) { + level++; + dtn = dtn.parent; + } + return level; + }, + /** Return the successor node (under the same parent) or null. + * @returns {FancytreeNode | null} + */ + getNextSibling: function () { + // TODO: use indexOf, if available: (not in IE6) + if (this.parent) { + var i, + l, + ac = this.parent.children; + + for (i = 0, l = ac.length - 1; i < l; i++) { + // up to length-2, so next(last) = null + if (ac[i] === this) { + return ac[i + 1]; + } + } + } + return null; + }, + /** Return the parent node (null for the system root node). + * @returns {FancytreeNode | null} + */ + getParent: function () { + // TODO: return null for top-level nodes? + return this.parent; + }, + /** Return an array of all parent nodes (top-down). + * @param {boolean} [includeRoot=false] Include the invisible system root node. + * @param {boolean} [includeSelf=false] Include the node itself. + * @returns {FancytreeNode[]} + */ + getParentList: function (includeRoot, includeSelf) { + var l = [], + dtn = includeSelf ? this : this.parent; + while (dtn) { + if (includeRoot || dtn.parent) { + l.unshift(dtn); + } + dtn = dtn.parent; + } + return l; + }, + /** Return a string representing the hierachical node path, e.g. "a/b/c". + * @param {boolean} [includeSelf=true] + * @param {string | function} [part="title"] node property name or callback + * @param {string} [separator="/"] + * @returns {string} + * @since v2.31 + */ + getPath: function (includeSelf, part, separator) { + includeSelf = includeSelf !== false; + part = part || "title"; + separator = separator || "/"; + + var val, + path = [], + isFunc = _isFunction(part); + + this.visitParents(function (n) { + if (n.parent) { + val = isFunc ? part(n) : n[part]; + path.unshift(val); + } + }, includeSelf); + return path.join(separator); + }, + /** Return the predecessor node (under the same parent) or null. + * @returns {FancytreeNode | null} + */ + getPrevSibling: function () { + if (this.parent) { + var i, + l, + ac = this.parent.children; + + for (i = 1, l = ac.length; i < l; i++) { + // start with 1, so prev(first) = null + if (ac[i] === this) { + return ac[i - 1]; + } + } + } + return null; + }, + /** + * Return an array of selected descendant nodes. + * @param {boolean} [stopOnParents=false] only return the topmost selected + * node (useful with selectMode 3) + * @returns {FancytreeNode[]} + */ + getSelectedNodes: function (stopOnParents) { + var nodeList = []; + this.visit(function (node) { + if (node.selected) { + nodeList.push(node); + if (stopOnParents === true) { + return "skip"; // stop processing this branch + } + } + }); + return nodeList; + }, + /** Return true if node has children. Return undefined if not sure, i.e. the node is lazy and not yet loaded). + * @returns {boolean | undefined} + */ + hasChildren: function () { + if (this.lazy) { + if (this.children == null) { + // null or undefined: Not yet loaded + return undefined; + } else if (this.children.length === 0) { + // Loaded, but response was empty + return false; + } else if ( + this.children.length === 1 && + this.children[0].isStatusNode() + ) { + // Currently loading or load error + return undefined; + } + return true; + } + return !!(this.children && this.children.length); + }, + /** + * Return true if node has `className` defined in .extraClasses. + * + * @param {string} className class name (separate multiple classes by space) + * @returns {boolean} + * + * @since 2.32 + */ + hasClass: function (className) { + return ( + (" " + (this.extraClasses || "") + " ").indexOf( + " " + className + " " + ) >= 0 + ); + }, + /** Return true if node has keyboard focus. + * @returns {boolean} + */ + hasFocus: function () { + return this.tree.hasFocus() && this.tree.focusNode === this; + }, + /** Write to browser console if debugLevel >= 3 (prepending node info) + * + * @param {*} msg string or object or array of such + */ + info: function (msg) { + if (this.tree.options.debugLevel >= 3) { + Array.prototype.unshift.call(arguments, this.toString()); + consoleApply("info", arguments); + } + }, + /** Return true if node is active (see also FancytreeNode#isSelected). + * @returns {boolean} + */ + isActive: function () { + return this.tree.activeNode === this; + }, + /** Return true if node is vertically below `otherNode`, i.e. rendered in a subsequent row. + * @param {FancytreeNode} otherNode + * @returns {boolean} + * @since 2.28 + */ + isBelowOf: function (otherNode) { + return this.getIndexHier(".", 5) > otherNode.getIndexHier(".", 5); + }, + /** Return true if node is a direct child of otherNode. + * @param {FancytreeNode} otherNode + * @returns {boolean} + */ + isChildOf: function (otherNode) { + return this.parent && this.parent === otherNode; + }, + /** Return true, if node is a direct or indirect sub node of otherNode. + * @param {FancytreeNode} otherNode + * @returns {boolean} + */ + isDescendantOf: function (otherNode) { + if (!otherNode || otherNode.tree !== this.tree) { + return false; + } + var p = this.parent; + while (p) { + if (p === otherNode) { + return true; + } + if (p === p.parent) { + $.error("Recursive parent link: " + p); + } + p = p.parent; + } + return false; + }, + /** Return true if node is expanded. + * @returns {boolean} + */ + isExpanded: function () { + return !!this.expanded; + }, + /** Return true if node is the first node of its parent's children. + * @returns {boolean} + */ + isFirstSibling: function () { + var p = this.parent; + return !p || p.children[0] === this; + }, + /** Return true if node is a folder, i.e. has the node.folder attribute set. + * @returns {boolean} + */ + isFolder: function () { + return !!this.folder; + }, + /** Return true if node is the last node of its parent's children. + * @returns {boolean} + */ + isLastSibling: function () { + var p = this.parent; + return !p || p.children[p.children.length - 1] === this; + }, + /** Return true if node is lazy (even if data was already loaded) + * @returns {boolean} + */ + isLazy: function () { + return !!this.lazy; + }, + /** Return true if node is lazy and loaded. For non-lazy nodes always return true. + * @returns {boolean} + */ + isLoaded: function () { + return !this.lazy || this.hasChildren() !== undefined; // Also checks if the only child is a status node + }, + /** Return true if children are currently beeing loaded, i.e. a Ajax request is pending. + * @returns {boolean} + */ + isLoading: function () { + return !!this._isLoading; + }, + /* + * @deprecated since v2.4.0: Use isRootNode() instead + */ + isRoot: function () { + return this.isRootNode(); + }, + /** Return true if node is partially selected (tri-state). + * @returns {boolean} + * @since 2.23 + */ + isPartsel: function () { + return !this.selected && !!this.partsel; + }, + /** (experimental) Return true if this is partially loaded. + * @returns {boolean} + * @since 2.15 + */ + isPartload: function () { + return !!this.partload; + }, + /** Return true if this is the (invisible) system root node. + * @returns {boolean} + * @since 2.4 + */ + isRootNode: function () { + return this.tree.rootNode === this; + }, + /** Return true if node is selected, i.e. has a checkmark set (see also FancytreeNode#isActive). + * @returns {boolean} + */ + isSelected: function () { + return !!this.selected; + }, + /** Return true if this node is a temporarily generated system node like + * 'loading', 'paging', or 'error' (node.statusNodeType contains the type). + * @returns {boolean} + */ + isStatusNode: function () { + return !!this.statusNodeType; + }, + /** Return true if this node is a status node of type 'paging'. + * @returns {boolean} + * @since 2.15 + */ + isPagingNode: function () { + return this.statusNodeType === "paging"; + }, + /** Return true if this a top level node, i.e. a direct child of the (invisible) system root node. + * @returns {boolean} + * @since 2.4 + */ + isTopLevel: function () { + return this.tree.rootNode === this.parent; + }, + /** Return true if node is lazy and not yet loaded. For non-lazy nodes always return false. + * @returns {boolean} + */ + isUndefined: function () { + return this.hasChildren() === undefined; // also checks if the only child is a status node + }, + /** Return true if all parent nodes are expanded. Note: this does not check + * whether the node is scrolled into the visible part of the screen. + * @returns {boolean} + */ + isVisible: function () { + var i, + l, + n, + hasFilter = this.tree.enableFilter, + parents = this.getParentList(false, false); + + // TODO: check $(n.span).is(":visible") + // i.e. return false for nodes (but not parents) that are hidden + // by a filter + if (hasFilter && !this.match && !this.subMatchCount) { + // this.debug( "isVisible: HIDDEN (" + hasFilter + ", " + this.match + ", " + this.match + ")" ); + return false; + } + + for (i = 0, l = parents.length; i < l; i++) { + n = parents[i]; + + if (!n.expanded) { + // this.debug("isVisible: HIDDEN (parent collapsed)"); + return false; + } + // if (hasFilter && !n.match && !n.subMatchCount) { + // this.debug("isVisible: HIDDEN (" + hasFilter + ", " + this.match + ", " + this.match + ")"); + // return false; + // } + } + // this.debug("isVisible: VISIBLE"); + return true; + }, + /** Deprecated. + * @deprecated since 2014-02-16: use load() instead. + */ + lazyLoad: function (discard) { + $.error( + "FancytreeNode.lazyLoad() is deprecated since 2014-02-16. Use .load() instead." + ); + }, + /** + * Load all children of a lazy node if neccessary. The <i>expanded</i> state is maintained. + * @param {boolean} [forceReload=false] Pass true to discard any existing nodes before. Otherwise this method does nothing if the node was already loaded. + * @returns {$.Promise} + */ + load: function (forceReload) { + var res, + source, + self = this, + wasExpanded = this.isExpanded(); + + _assert(this.isLazy(), "load() requires a lazy node"); + // _assert( forceReload || this.isUndefined(), "Pass forceReload=true to re-load a lazy node" ); + if (!forceReload && !this.isUndefined()) { + return _getResolvedPromise(this); + } + if (this.isLoaded()) { + this.resetLazy(); // also collapses + } + // This method is also called by setExpanded() and loadKeyPath(), so we + // have to avoid recursion. + source = this.tree._triggerNodeEvent("lazyLoad", this); + if (source === false) { + // #69 + return _getResolvedPromise(this); + } + _assert( + typeof source !== "boolean", + "lazyLoad event must return source in data.result" + ); + res = this.tree._callHook("nodeLoadChildren", this, source); + if (wasExpanded) { + this.expanded = true; + res.always(function () { + self.render(); + }); + } else { + res.always(function () { + self.renderStatus(); // fix expander icon to 'loaded' + }); + } + return res; + }, + /** Expand all parents and optionally scroll into visible area as neccessary. + * Promise is resolved, when lazy loading and animations are done. + * @param {object} [opts] passed to `setExpanded()`. + * Defaults to {noAnimation: false, noEvents: false, scrollIntoView: true} + * @returns {$.Promise} + */ + makeVisible: function (opts) { + var i, + self = this, + deferreds = [], + dfd = new $.Deferred(), + parents = this.getParentList(false, false), + len = parents.length, + effects = !(opts && opts.noAnimation === true), + scroll = !(opts && opts.scrollIntoView === false); + + // Expand bottom-up, so only the top node is animated + for (i = len - 1; i >= 0; i--) { + // self.debug("pushexpand" + parents[i]); + deferreds.push(parents[i].setExpanded(true, opts)); + } + $.when.apply($, deferreds).done(function () { + // All expands have finished + // self.debug("expand DONE", scroll); + if (scroll) { + self.scrollIntoView(effects).done(function () { + // self.debug("scroll DONE"); + dfd.resolve(); + }); + } else { + dfd.resolve(); + } + }); + return dfd.promise(); + }, + /** Move this node to targetNode. + * @param {FancytreeNode} targetNode + * @param {string} mode <pre> + * 'child': append this node as last child of targetNode. + * This is the default. To be compatble with the D'n'd + * hitMode, we also accept 'over'. + * 'firstChild': add this node as first child of targetNode. + * 'before': add this node as sibling before targetNode. + * 'after': add this node as sibling after targetNode.</pre> + * @param {function} [map] optional callback(FancytreeNode) to allow modifcations + */ + moveTo: function (targetNode, mode, map) { + if (mode === undefined || mode === "over") { + mode = "child"; + } else if (mode === "firstChild") { + if (targetNode.children && targetNode.children.length) { + mode = "before"; + targetNode = targetNode.children[0]; + } else { + mode = "child"; + } + } + var pos, + tree = this.tree, + prevParent = this.parent, + targetParent = + mode === "child" ? targetNode : targetNode.parent; + + if (this === targetNode) { + return; + } else if (!this.parent) { + $.error("Cannot move system root"); + } else if (targetParent.isDescendantOf(this)) { + $.error("Cannot move a node to its own descendant"); + } + if (targetParent !== prevParent) { + prevParent.triggerModifyChild("remove", this); + } + // Unlink this node from current parent + if (this.parent.children.length === 1) { + if (this.parent === targetParent) { + return; // #258 + } + this.parent.children = this.parent.lazy ? [] : null; + this.parent.expanded = false; + } else { + pos = $.inArray(this, this.parent.children); + _assert(pos >= 0, "invalid source parent"); + this.parent.children.splice(pos, 1); + } + // Remove from source DOM parent + // if(this.parent.ul){ + // this.parent.ul.removeChild(this.li); + // } + + // Insert this node to target parent's child list + this.parent = targetParent; + if (targetParent.hasChildren()) { + switch (mode) { + case "child": + // Append to existing target children + targetParent.children.push(this); + break; + case "before": + // Insert this node before target node + pos = $.inArray(targetNode, targetParent.children); + _assert(pos >= 0, "invalid target parent"); + targetParent.children.splice(pos, 0, this); + break; + case "after": + // Insert this node after target node + pos = $.inArray(targetNode, targetParent.children); + _assert(pos >= 0, "invalid target parent"); + targetParent.children.splice(pos + 1, 0, this); + break; + default: + $.error("Invalid mode " + mode); + } + } else { + targetParent.children = [this]; + } + // Parent has no <ul> tag yet: + // if( !targetParent.ul ) { + // // This is the parent's first child: create UL tag + // // (Hidden, because it will be + // targetParent.ul = document.createElement("ul"); + // targetParent.ul.style.display = "none"; + // targetParent.li.appendChild(targetParent.ul); + // } + // // Issue 319: Add to target DOM parent (only if node was already rendered(expanded)) + // if(this.li){ + // targetParent.ul.appendChild(this.li); + // } + + // Let caller modify the nodes + if (map) { + targetNode.visit(map, true); + } + if (targetParent === prevParent) { + targetParent.triggerModifyChild("move", this); + } else { + // prevParent.triggerModifyChild("remove", this); + targetParent.triggerModifyChild("add", this); + } + // Handle cross-tree moves + if (tree !== targetNode.tree) { + // Fix node.tree for all source nodes + // _assert(false, "Cross-tree move is not yet implemented."); + this.warn("Cross-tree moveTo is experimental!"); + this.visit(function (n) { + // TODO: fix selection state and activation, ... + n.tree = targetNode.tree; + }, true); + } + + // A collaposed node won't re-render children, so we have to remove it manually + // if( !targetParent.expanded ){ + // prevParent.ul.removeChild(this.li); + // } + tree._callHook("treeStructureChanged", tree, "moveTo"); + + // Update HTML markup + if (!prevParent.isDescendantOf(targetParent)) { + prevParent.render(); + } + if ( + !targetParent.isDescendantOf(prevParent) && + targetParent !== prevParent + ) { + targetParent.render(); + } + // TODO: fix selection state + // TODO: fix active state + + /* + var tree = this.tree; + var opts = tree.options; + var pers = tree.persistence; + + // Always expand, if it's below minExpandLevel + // tree.logDebug ("%s._addChildNode(%o), l=%o", this, ftnode, ftnode.getLevel()); + if ( opts.minExpandLevel >= ftnode.getLevel() ) { + // tree.logDebug ("Force expand for %o", ftnode); + this.bExpanded = true; + } + + // In multi-hier mode, update the parents selection state + // DT issue #82: only if not initializing, because the children may not exist yet + // if( !ftnode.data.isStatusNode() && opts.selectMode==3 && !isInitializing ) + // ftnode._fixSelectionState(); + + // In multi-hier mode, update the parents selection state + if( ftnode.bSelected && opts.selectMode==3 ) { + var p = this; + while( p ) { + if( !p.hasSubSel ) + p._setSubSel(true); + p = p.parent; + } + } + // render this node and the new child + if ( tree.bEnableUpdate ) + this.render(); + return ftnode; + */ + }, + /** Set focus relative to this node and optionally activate. + * + * 'left' collapses the node if it is expanded, or move to the parent + * otherwise. + * 'right' expands the node if it is collapsed, or move to the first + * child otherwise. + * + * @param {string|number} where 'down', 'first', 'last', 'left', 'parent', 'right', or 'up'. + * (Alternatively the keyCode that would normally trigger this move, + * e.g. `$.ui.keyCode.LEFT` = 'left'. + * @param {boolean} [activate=true] + * @returns {$.Promise} + */ + navigate: function (where, activate) { + var node, + KC = $.ui.keyCode; + + // Handle optional expand/collapse action for LEFT/RIGHT + switch (where) { + case "left": + case KC.LEFT: + if (this.expanded) { + return this.setExpanded(false); + } + break; + case "right": + case KC.RIGHT: + if (!this.expanded && (this.children || this.lazy)) { + return this.setExpanded(); + } + break; + } + // Otherwise activate or focus the related node + node = this.findRelatedNode(where); + if (node) { + // setFocus/setActive will scroll later (if autoScroll is specified) + try { + node.makeVisible({ scrollIntoView: false }); + } catch (e) {} // #272 + if (activate === false) { + node.setFocus(); + return _getResolvedPromise(); + } + return node.setActive(); + } + this.warn("Could not find related node '" + where + "'."); + return _getResolvedPromise(); + }, + /** + * Remove this node (not allowed for system root). + */ + remove: function () { + return this.parent.removeChild(this); + }, + /** + * Remove childNode from list of direct children. + * @param {FancytreeNode} childNode + */ + removeChild: function (childNode) { + return this.tree._callHook("nodeRemoveChild", this, childNode); + }, + /** + * Remove all child nodes and descendents. This converts the node into a leaf.<br> + * If this was a lazy node, it is still considered 'loaded'; call node.resetLazy() + * in order to trigger lazyLoad on next expand. + */ + removeChildren: function () { + return this.tree._callHook("nodeRemoveChildren", this); + }, + /** + * Remove class from node's span tag and .extraClasses. + * + * @param {string} className class name + * + * @since 2.17 + */ + removeClass: function (className) { + return this.toggleClass(className, false); + }, + /** + * This method renders and updates all HTML markup that is required + * to display this node in its current state.<br> + * Note: + * <ul> + * <li>It should only be neccessary to call this method after the node object + * was modified by direct access to its properties, because the common + * API methods (node.setTitle(), moveTo(), addChildren(), remove(), ...) + * already handle this. + * <li> {@link FancytreeNode#renderTitle} and {@link FancytreeNode#renderStatus} + * are implied. If changes are more local, calling only renderTitle() or + * renderStatus() may be sufficient and faster. + * </ul> + * + * @param {boolean} [force=false] re-render, even if html markup was already created + * @param {boolean} [deep=false] also render all descendants, even if parent is collapsed + */ + render: function (force, deep) { + return this.tree._callHook("nodeRender", this, force, deep); + }, + /** Create HTML markup for the node's outer `<span>` (expander, checkbox, icon, and title). + * Implies {@link FancytreeNode#renderStatus}. + * @see Fancytree_Hooks#nodeRenderTitle + */ + renderTitle: function () { + return this.tree._callHook("nodeRenderTitle", this); + }, + /** Update element's CSS classes according to node state. + * @see Fancytree_Hooks#nodeRenderStatus + */ + renderStatus: function () { + return this.tree._callHook("nodeRenderStatus", this); + }, + /** + * (experimental) Replace this node with `source`. + * (Currently only available for paging nodes.) + * @param {NodeData[]} source List of child node definitions + * @since 2.15 + */ + replaceWith: function (source) { + var res, + parent = this.parent, + pos = $.inArray(this, parent.children), + self = this; + + _assert( + this.isPagingNode(), + "replaceWith() currently requires a paging status node" + ); + + res = this.tree._callHook("nodeLoadChildren", this, source); + res.done(function (data) { + // New nodes are currently children of `this`. + var children = self.children; + // Prepend newly loaded child nodes to `this` + // Move new children after self + for (i = 0; i < children.length; i++) { + children[i].parent = parent; + } + parent.children.splice.apply( + parent.children, + [pos + 1, 0].concat(children) + ); + + // Remove self + self.children = null; + self.remove(); + // Redraw new nodes + parent.render(); + // TODO: set node.partload = false if this was tha last paging node? + // parent.addPagingNode(false); + }).fail(function () { + self.setExpanded(); + }); + return res; + // $.error("Not implemented: replaceWith()"); + }, + /** + * Remove all children, collapse, and set the lazy-flag, so that the lazyLoad + * event is triggered on next expand. + */ + resetLazy: function () { + this.removeChildren(); + this.expanded = false; + this.lazy = true; + this.children = undefined; + this.renderStatus(); + }, + /** Schedule activity for delayed execution (cancel any pending request). + * scheduleAction('cancel') will only cancel a pending request (if any). + * @param {string} mode + * @param {number} ms + */ + scheduleAction: function (mode, ms) { + if (this.tree.timer) { + clearTimeout(this.tree.timer); + this.tree.debug("clearTimeout(%o)", this.tree.timer); + } + this.tree.timer = null; + var self = this; // required for closures + switch (mode) { + case "cancel": + // Simply made sure that timer was cleared + break; + case "expand": + this.tree.timer = setTimeout(function () { + self.tree.debug("setTimeout: trigger expand"); + self.setExpanded(true); + }, ms); + break; + case "activate": + this.tree.timer = setTimeout(function () { + self.tree.debug("setTimeout: trigger activate"); + self.setActive(true); + }, ms); + break; + default: + $.error("Invalid mode " + mode); + } + // this.tree.debug("setTimeout(%s, %s): %s", mode, ms, this.tree.timer); + }, + /** + * + * @param {boolean | PlainObject} [effects=false] animation options. + * @param {object} [options=null] {topNode: null, effects: ..., parent: ...} this node will remain visible in + * any case, even if `this` is outside the scroll pane. + * @returns {$.Promise} + */ + scrollIntoView: function (effects, options) { + if (options !== undefined && _isNode(options)) { + throw Error( + "scrollIntoView() with 'topNode' option is deprecated since 2014-05-08. Use 'options.topNode' instead." + ); + } + // The scroll parent is typically the plain tree's <UL> container. + // For ext-table, we choose the nearest parent that has `position: relative` + // and `overflow` set. + // (This default can be overridden by the local or global `scrollParent` option.) + var opts = $.extend( + { + effects: + effects === true + ? { duration: 200, queue: false } + : effects, + scrollOfs: this.tree.options.scrollOfs, + scrollParent: this.tree.options.scrollParent, + topNode: null, + }, + options + ), + $scrollParent = opts.scrollParent, + $container = this.tree.$container, + overflowY = $container.css("overflow-y"); + + if (!$scrollParent) { + if (this.tree.tbody) { + $scrollParent = $container.scrollParent(); + } else if (overflowY === "scroll" || overflowY === "auto") { + $scrollParent = $container; + } else { + // #922 plain tree in a non-fixed-sized UL scrolls inside its parent + $scrollParent = $container.scrollParent(); + } + } else if (!$scrollParent.jquery) { + // Make sure we have a jQuery object + $scrollParent = $($scrollParent); + } + if ( + $scrollParent[0] === document || + $scrollParent[0] === document.body + ) { + // `document` may be returned by $().scrollParent(), if nothing is found, + // but would not work: (see #894) + this.debug( + "scrollIntoView(): normalizing scrollParent to 'window':", + $scrollParent[0] + ); + $scrollParent = $(window); + } + // eslint-disable-next-line one-var + var topNodeY, + nodeY, + horzScrollbarHeight, + containerOffsetTop, + dfd = new $.Deferred(), + self = this, + nodeHeight = $(this.span).height(), + topOfs = opts.scrollOfs.top || 0, + bottomOfs = opts.scrollOfs.bottom || 0, + containerHeight = $scrollParent.height(), + scrollTop = $scrollParent.scrollTop(), + $animateTarget = $scrollParent, + isParentWindow = $scrollParent[0] === window, + topNode = opts.topNode || null, + newScrollTop = null; + + // this.debug("scrollIntoView(), scrollTop=" + scrollTop, opts.scrollOfs); + // _assert($(this.span).is(":visible"), "scrollIntoView node is invisible"); // otherwise we cannot calc offsets + if (this.isRootNode() || !this.isVisible()) { + // We cannot calc offsets for hidden elements + this.info("scrollIntoView(): node is invisible."); + return _getResolvedPromise(); + } + if (isParentWindow) { + nodeY = $(this.span).offset().top; + topNodeY = + topNode && topNode.span ? $(topNode.span).offset().top : 0; + $animateTarget = $("html,body"); + } else { + _assert( + $scrollParent[0] !== document && + $scrollParent[0] !== document.body, + "scrollParent should be a simple element or `window`, not document or body." + ); + + containerOffsetTop = $scrollParent.offset().top; + nodeY = + $(this.span).offset().top - containerOffsetTop + scrollTop; // relative to scroll parent + topNodeY = topNode + ? $(topNode.span).offset().top - + containerOffsetTop + + scrollTop + : 0; + horzScrollbarHeight = Math.max( + 0, + $scrollParent.innerHeight() - $scrollParent[0].clientHeight + ); + containerHeight -= horzScrollbarHeight; + } + + // this.debug(" scrollIntoView(), nodeY=" + nodeY + ", containerHeight=" + containerHeight); + if (nodeY < scrollTop + topOfs) { + // Node is above visible container area + newScrollTop = nodeY - topOfs; + // this.debug(" scrollIntoView(), UPPER newScrollTop=" + newScrollTop); + } else if ( + nodeY + nodeHeight > + scrollTop + containerHeight - bottomOfs + ) { + newScrollTop = nodeY + nodeHeight - containerHeight + bottomOfs; + // this.debug(" scrollIntoView(), LOWER newScrollTop=" + newScrollTop); + // If a topNode was passed, make sure that it is never scrolled + // outside the upper border + if (topNode) { + _assert( + topNode.isRootNode() || topNode.isVisible(), + "topNode must be visible" + ); + if (topNodeY < newScrollTop) { + newScrollTop = topNodeY - topOfs; + // this.debug(" scrollIntoView(), TOP newScrollTop=" + newScrollTop); + } + } + } + + if (newScrollTop === null) { + dfd.resolveWith(this); + } else { + // this.debug(" scrollIntoView(), SET newScrollTop=" + newScrollTop); + if (opts.effects) { + opts.effects.complete = function () { + dfd.resolveWith(self); + }; + $animateTarget.stop(true).animate( + { + scrollTop: newScrollTop, + }, + opts.effects + ); + } else { + $animateTarget[0].scrollTop = newScrollTop; + dfd.resolveWith(this); + } + } + return dfd.promise(); + }, + + /**Activate this node. + * + * The `cell` option requires the ext-table and ext-ariagrid extensions. + * + * @param {boolean} [flag=true] pass false to deactivate + * @param {object} [opts] additional options. Defaults to {noEvents: false, noFocus: false, cell: null} + * @returns {$.Promise} + */ + setActive: function (flag, opts) { + return this.tree._callHook("nodeSetActive", this, flag, opts); + }, + /**Expand or collapse this node. Promise is resolved, when lazy loading and animations are done. + * @param {boolean} [flag=true] pass false to collapse + * @param {object} [opts] additional options. Defaults to {noAnimation: false, noEvents: false} + * @returns {$.Promise} + */ + setExpanded: function (flag, opts) { + return this.tree._callHook("nodeSetExpanded", this, flag, opts); + }, + /**Set keyboard focus to this node. + * @param {boolean} [flag=true] pass false to blur + * @see Fancytree#setFocus + */ + setFocus: function (flag) { + return this.tree._callHook("nodeSetFocus", this, flag); + }, + /**Select this node, i.e. check the checkbox. + * @param {boolean} [flag=true] pass false to deselect + * @param {object} [opts] additional options. Defaults to {noEvents: false, p + * propagateDown: null, propagateUp: null, callback: null } + */ + setSelected: function (flag, opts) { + return this.tree._callHook("nodeSetSelected", this, flag, opts); + }, + /**Mark a lazy node as 'error', 'loading', 'nodata', or 'ok'. + * @param {string} status 'error'|'loading'|'nodata'|'ok' + * @param {string} [message] + * @param {string} [details] + */ + setStatus: function (status, message, details) { + return this.tree._callHook( + "nodeSetStatus", + this, + status, + message, + details + ); + }, + /**Rename this node. + * @param {string} title + */ + setTitle: function (title) { + this.title = title; + this.renderTitle(); + this.triggerModify("rename"); + }, + /**Sort child list by title. + * @param {function} [cmp] custom compare function(a, b) that returns -1, 0, or 1 (defaults to sort by title). + * @param {boolean} [deep=false] pass true to sort all descendant nodes + */ + sortChildren: function (cmp, deep) { + var i, + l, + cl = this.children; + + if (!cl) { + return; + } + cmp = + cmp || + function (a, b) { + var x = a.title.toLowerCase(), + y = b.title.toLowerCase(); + + // eslint-disable-next-line no-nested-ternary + return x === y ? 0 : x > y ? 1 : -1; + }; + cl.sort(cmp); + if (deep) { + for (i = 0, l = cl.length; i < l; i++) { + if (cl[i].children) { + cl[i].sortChildren(cmp, "$norender$"); + } + } + } + if (deep !== "$norender$") { + this.render(); + } + this.triggerModifyChild("sort"); + }, + /** Convert node (or whole branch) into a plain object. + * + * The result is compatible with node.addChildren(). + * + * @param {boolean} [recursive=false] include child nodes + * @param {function} [callback] callback(dict, node) is called for every node, in order to allow modifications. + * Return `false` to ignore this node or `"skip"` to include this node without its children. + * @returns {NodeData} + */ + toDict: function (recursive, callback) { + var i, + l, + node, + res, + dict = {}, + self = this; + + $.each(NODE_ATTRS, function (i, a) { + if (self[a] || self[a] === false) { + dict[a] = self[a]; + } + }); + if (!$.isEmptyObject(this.data)) { + dict.data = $.extend({}, this.data); + if ($.isEmptyObject(dict.data)) { + delete dict.data; + } + } + if (callback) { + res = callback(dict, self); + if (res === false) { + return false; // Don't include this node nor its children + } + if (res === "skip") { + recursive = false; // Include this node, but not the children + } + } + if (recursive) { + if (_isArray(this.children)) { + dict.children = []; + for (i = 0, l = this.children.length; i < l; i++) { + node = this.children[i]; + if (!node.isStatusNode()) { + res = node.toDict(true, callback); + if (res !== false) { + dict.children.push(res); + } + } + } + } + } + return dict; + }, + /** + * Set, clear, or toggle class of node's span tag and .extraClasses. + * + * @param {string} className class name (separate multiple classes by space) + * @param {boolean} [flag] true/false to add/remove class. If omitted, class is toggled. + * @returns {boolean} true if a class was added + * + * @since 2.17 + */ + toggleClass: function (value, flag) { + var className, + hasClass, + rnotwhite = /\S+/g, + classNames = value.match(rnotwhite) || [], + i = 0, + wasAdded = false, + statusElem = this[this.tree.statusClassPropName], + curClasses = " " + (this.extraClasses || "") + " "; + + // this.info("toggleClass('" + value + "', " + flag + ")", curClasses); + // Modify DOM element directly if it already exists + if (statusElem) { + $(statusElem).toggleClass(value, flag); + } + // Modify node.extraClasses to make this change persistent + // Toggle if flag was not passed + while ((className = classNames[i++])) { + hasClass = curClasses.indexOf(" " + className + " ") >= 0; + flag = flag === undefined ? !hasClass : !!flag; + if (flag) { + if (!hasClass) { + curClasses += className + " "; + wasAdded = true; + } + } else { + while (curClasses.indexOf(" " + className + " ") > -1) { + curClasses = curClasses.replace( + " " + className + " ", + " " + ); + } + } + } + this.extraClasses = _trim(curClasses); + // this.info("-> toggleClass('" + value + "', " + flag + "): '" + this.extraClasses + "'"); + return wasAdded; + }, + /** Flip expanded status. */ + toggleExpanded: function () { + return this.tree._callHook("nodeToggleExpanded", this); + }, + /** Flip selection status. */ + toggleSelected: function () { + return this.tree._callHook("nodeToggleSelected", this); + }, + toString: function () { + return "FancytreeNode@" + this.key + "[title='" + this.title + "']"; + // return "<FancytreeNode(#" + this.key + ", '" + this.title + "')>"; + }, + /** + * Trigger `modifyChild` event on a parent to signal that a child was modified. + * @param {string} operation Type of change: 'add', 'remove', 'rename', 'move', 'data', ... + * @param {FancytreeNode} [childNode] + * @param {object} [extra] + */ + triggerModifyChild: function (operation, childNode, extra) { + var data, + modifyChild = this.tree.options.modifyChild; + + if (modifyChild) { + if (childNode && childNode.parent !== this) { + $.error( + "childNode " + childNode + " is not a child of " + this + ); + } + data = { + node: this, + tree: this.tree, + operation: operation, + childNode: childNode || null, + }; + if (extra) { + $.extend(data, extra); + } + modifyChild({ type: "modifyChild" }, data); + } + }, + /** + * Trigger `modifyChild` event on node.parent(!). + * @param {string} operation Type of change: 'add', 'remove', 'rename', 'move', 'data', ... + * @param {object} [extra] + */ + triggerModify: function (operation, extra) { + this.parent.triggerModifyChild(operation, this, extra); + }, + /** Call fn(node) for all child nodes in hierarchical order (depth-first).<br> + * Stop iteration, if fn() returns false. Skip current branch, if fn() returns "skip".<br> + * Return false if iteration was stopped. + * + * @param {function} fn the callback function. + * Return false to stop iteration, return "skip" to skip this node and + * its children only. + * @param {boolean} [includeSelf=false] + * @returns {boolean} + */ + visit: function (fn, includeSelf) { + var i, + l, + res = true, + children = this.children; + + if (includeSelf === true) { + res = fn(this); + if (res === false || res === "skip") { + return res; + } + } + if (children) { + for (i = 0, l = children.length; i < l; i++) { + res = children[i].visit(fn, true); + if (res === false) { + break; + } + } + } + return res; + }, + /** Call fn(node) for all child nodes and recursively load lazy children.<br> + * <b>Note:</b> If you need this method, you probably should consider to review + * your architecture! Recursivley loading nodes is a perfect way for lazy + * programmers to flood the server with requests ;-) + * + * @param {function} [fn] optional callback function. + * Return false to stop iteration, return "skip" to skip this node and + * its children only. + * @param {boolean} [includeSelf=false] + * @returns {$.Promise} + * @since 2.4 + */ + visitAndLoad: function (fn, includeSelf, _recursion) { + var dfd, + res, + loaders, + node = this; + + // node.debug("visitAndLoad"); + if (fn && includeSelf === true) { + res = fn(node); + if (res === false || res === "skip") { + return _recursion ? res : _getResolvedPromise(); + } + } + if (!node.children && !node.lazy) { + return _getResolvedPromise(); + } + dfd = new $.Deferred(); + loaders = []; + // node.debug("load()..."); + node.load().done(function () { + // node.debug("load()... done."); + for (var i = 0, l = node.children.length; i < l; i++) { + res = node.children[i].visitAndLoad(fn, true, true); + if (res === false) { + dfd.reject(); + break; + } else if (res !== "skip") { + loaders.push(res); // Add promise to the list + } + } + $.when.apply(this, loaders).then(function () { + dfd.resolve(); + }); + }); + return dfd.promise(); + }, + /** Call fn(node) for all parent nodes, bottom-up, including invisible system root.<br> + * Stop iteration, if fn() returns false.<br> + * Return false if iteration was stopped. + * + * @param {function} fn the callback function. + * Return false to stop iteration, return "skip" to skip this node and children only. + * @param {boolean} [includeSelf=false] + * @returns {boolean} + */ + visitParents: function (fn, includeSelf) { + // Visit parent nodes (bottom up) + if (includeSelf && fn(this) === false) { + return false; + } + var p = this.parent; + while (p) { + if (fn(p) === false) { + return false; + } + p = p.parent; + } + return true; + }, + /** Call fn(node) for all sibling nodes.<br> + * Stop iteration, if fn() returns false.<br> + * Return false if iteration was stopped. + * + * @param {function} fn the callback function. + * Return false to stop iteration. + * @param {boolean} [includeSelf=false] + * @returns {boolean} + */ + visitSiblings: function (fn, includeSelf) { + var i, + l, + n, + ac = this.parent.children; + + for (i = 0, l = ac.length; i < l; i++) { + n = ac[i]; + if (includeSelf || n !== this) { + if (fn(n) === false) { + return false; + } + } + } + return true; + }, + /** Write warning to browser console if debugLevel >= 2 (prepending node info) + * + * @param {*} msg string or object or array of such + */ + warn: function (msg) { + if (this.tree.options.debugLevel >= 2) { + Array.prototype.unshift.call(arguments, this.toString()); + consoleApply("warn", arguments); + } + }, + }; + + /****************************************************************************** + * Fancytree + */ + /** + * Construct a new tree object. + * + * @class Fancytree + * @classdesc The controller behind a fancytree. + * This class also contains 'hook methods': see {@link Fancytree_Hooks}. + * + * @param {Widget} widget + * + * @property {string} _id Automatically generated unique tree instance ID, e.g. "1". + * @property {string} _ns Automatically generated unique tree namespace, e.g. ".fancytree-1". + * @property {FancytreeNode} activeNode Currently active node or null. + * @property {string} ariaPropName Property name of FancytreeNode that contains the element which will receive the aria attributes. + * Typically "li", but "tr" for table extension. + * @property {jQueryObject} $container Outer `<ul>` element (or `<table>` element for ext-table). + * @property {jQueryObject} $div A jQuery object containing the element used to instantiate the tree widget (`widget.element`) + * @property {object|array} columns Recommended place to store shared column meta data. @since 2.27 + * @property {object} data Metadata, i.e. properties that may be passed to `source` in addition to a children array. + * @property {object} ext Hash of all active plugin instances. + * @property {FancytreeNode} focusNode Currently focused node or null. + * @property {FancytreeNode} lastSelectedNode Used to implement selectMode 1 (single select) + * @property {string} nodeContainerAttrName Property name of FancytreeNode that contains the outer element of single nodes. + * Typically "li", but "tr" for table extension. + * @property {FancytreeOptions} options Current options, i.e. default options + options passed to constructor. + * @property {FancytreeNode} rootNode Invisible system root node. + * @property {string} statusClassPropName Property name of FancytreeNode that contains the element which will receive the status classes. + * Typically "span", but "tr" for table extension. + * @property {object} types Map for shared type specific meta data, used with node.type attribute. @since 2.27 + * @property {object} viewport See ext-vieport. @since v2.31 + * @property {object} widget Base widget instance. + */ + function Fancytree(widget) { + this.widget = widget; + this.$div = widget.element; + this.options = widget.options; + if (this.options) { + if (this.options.lazyload !== undefined) { + $.error( + "The 'lazyload' event is deprecated since 2014-02-25. Use 'lazyLoad' (with uppercase L) instead." + ); + } + if (this.options.loaderror !== undefined) { + $.error( + "The 'loaderror' event was renamed since 2014-07-03. Use 'loadError' (with uppercase E) instead." + ); + } + if (this.options.fx !== undefined) { + $.error( + "The 'fx' option was replaced by 'toggleEffect' since 2014-11-30." + ); + } + if (this.options.removeNode !== undefined) { + $.error( + "The 'removeNode' event was replaced by 'modifyChild' since 2.20 (2016-09-10)." + ); + } + } + this.ext = {}; // Active extension instances + this.types = {}; + this.columns = {}; + // allow to init tree.data.foo from <div data-foo=''> + this.data = _getElementDataAsDict(this.$div); + // TODO: use widget.uuid instead? + this._id = "" + (this.options.treeId || $.ui.fancytree._nextId++); + // TODO: use widget.eventNamespace instead? + this._ns = ".fancytree-" + this._id; // append for namespaced events + this.activeNode = null; + this.focusNode = null; + this._hasFocus = null; + this._tempCache = {}; + this._lastMousedownNode = null; + this._enableUpdate = true; + this.lastSelectedNode = null; + this.systemFocusElement = null; + this.lastQuicksearchTerm = ""; + this.lastQuicksearchTime = 0; + this.viewport = null; // ext-grid + + this.statusClassPropName = "span"; + this.ariaPropName = "li"; + this.nodeContainerAttrName = "li"; + + // Remove previous markup if any + this.$div.find(">ul.fancytree-container").remove(); + + // Create a node without parent. + var fakeParent = { tree: this }, + $ul; + this.rootNode = new FancytreeNode(fakeParent, { + title: "root", + key: "root_" + this._id, + children: null, + expanded: true, + }); + this.rootNode.parent = null; + + // Create root markup + $ul = $("<ul>", { + id: "ft-id-" + this._id, + class: "ui-fancytree fancytree-container fancytree-plain", + }).appendTo(this.$div); + this.$container = $ul; + this.rootNode.ul = $ul[0]; + + if (this.options.debugLevel == null) { + this.options.debugLevel = FT.debugLevel; + } + // // Add container to the TAB chain + // // See http://www.w3.org/TR/wai-aria-practices/#focus_activedescendant + // // #577: Allow to set tabindex to "0", "-1" and "" + // this.$container.attr("tabindex", this.options.tabindex); + + // if( this.options.rtl ) { + // this.$container.attr("DIR", "RTL").addClass("fancytree-rtl"); + // // }else{ + // // this.$container.attr("DIR", null).removeClass("fancytree-rtl"); + // } + // if(this.options.aria){ + // this.$container.attr("role", "tree"); + // if( this.options.selectMode !== 1 ) { + // this.$container.attr("aria-multiselectable", true); + // } + // } + } + + Fancytree.prototype = /** @lends Fancytree# */ { + /* Return a context object that can be re-used for _callHook(). + * @param {Fancytree | FancytreeNode | EventData} obj + * @param {Event} originalEvent + * @param {Object} extra + * @returns {EventData} + */ + _makeHookContext: function (obj, originalEvent, extra) { + var ctx, tree; + if (obj.node !== undefined) { + // obj is already a context object + if (originalEvent && obj.originalEvent !== originalEvent) { + $.error("invalid args"); + } + ctx = obj; + } else if (obj.tree) { + // obj is a FancytreeNode + tree = obj.tree; + ctx = { + node: obj, + tree: tree, + widget: tree.widget, + options: tree.widget.options, + originalEvent: originalEvent, + typeInfo: tree.types[obj.type] || {}, + }; + } else if (obj.widget) { + // obj is a Fancytree + ctx = { + node: null, + tree: obj, + widget: obj.widget, + options: obj.widget.options, + originalEvent: originalEvent, + }; + } else { + $.error("invalid args"); + } + if (extra) { + $.extend(ctx, extra); + } + return ctx; + }, + /* Trigger a hook function: funcName(ctx, [...]). + * + * @param {string} funcName + * @param {Fancytree|FancytreeNode|EventData} contextObject + * @param {any} [_extraArgs] optional additional arguments + * @returns {any} + */ + _callHook: function (funcName, contextObject, _extraArgs) { + var ctx = this._makeHookContext(contextObject), + fn = this[funcName], + args = Array.prototype.slice.call(arguments, 2); + if (!_isFunction(fn)) { + $.error("_callHook('" + funcName + "') is not a function"); + } + args.unshift(ctx); + // this.debug("_hook", funcName, ctx.node && ctx.node.toString() || ctx.tree.toString(), args); + return fn.apply(this, args); + }, + _setExpiringValue: function (key, value, ms) { + this._tempCache[key] = { + value: value, + expire: Date.now() + (+ms || 50), + }; + }, + _getExpiringValue: function (key) { + var entry = this._tempCache[key]; + if (entry && entry.expire > Date.now()) { + return entry.value; + } + delete this._tempCache[key]; + return null; + }, + /* Check if this tree has extension `name` enabled. + * + * @param {string} name name of the required extension + */ + _usesExtension: function (name) { + return $.inArray(name, this.options.extensions) >= 0; + }, + /* Check if current extensions dependencies are met and throw an error if not. + * + * This method may be called inside the `treeInit` hook for custom extensions. + * + * @param {string} name name of the required extension + * @param {boolean} [required=true] pass `false` if the extension is optional, but we want to check for order if it is present + * @param {boolean} [before] `true` if `name` must be included before this, `false` otherwise (use `null` if order doesn't matter) + * @param {string} [message] optional error message (defaults to a descriptve error message) + */ + _requireExtension: function (name, required, before, message) { + if (before != null) { + before = !!before; + } + var thisName = this._local.name, + extList = this.options.extensions, + isBefore = + $.inArray(name, extList) < $.inArray(thisName, extList), + isMissing = required && this.ext[name] == null, + badOrder = !isMissing && before != null && before !== isBefore; + + _assert( + thisName && thisName !== name, + "invalid or same name '" + thisName + "' (require yourself?)" + ); + + if (isMissing || badOrder) { + if (!message) { + if (isMissing || required) { + message = + "'" + + thisName + + "' extension requires '" + + name + + "'"; + if (badOrder) { + message += + " to be registered " + + (before ? "before" : "after") + + " itself"; + } + } else { + message = + "If used together, `" + + name + + "` must be registered " + + (before ? "before" : "after") + + " `" + + thisName + + "`"; + } + } + $.error(message); + return false; + } + return true; + }, + /** Activate node with a given key and fire focus and activate events. + * + * A previously activated node will be deactivated. + * If activeVisible option is set, all parents will be expanded as necessary. + * Pass key = false, to deactivate the current node only. + * @param {string} key + * @param {object} [opts] additional options. Defaults to {noEvents: false, noFocus: false} + * @returns {FancytreeNode} activated node (null, if not found) + */ + activateKey: function (key, opts) { + var node = this.getNodeByKey(key); + if (node) { + node.setActive(true, opts); + } else if (this.activeNode) { + this.activeNode.setActive(false, opts); + } + return node; + }, + /** (experimental) Add child status nodes that indicate 'More...', .... + * @param {boolean|object} node optional node definition. Pass `false` to remove all paging nodes. + * @param {string} [mode='append'] 'child'|firstChild' + * @since 2.15 + */ + addPagingNode: function (node, mode) { + return this.rootNode.addPagingNode(node, mode); + }, + /** + * (experimental) Apply a modification (or navigation) operation. + * + * Valid commands: + * - 'moveUp', 'moveDown' + * - 'indent', 'outdent' + * - 'remove' + * - 'edit', 'addChild', 'addSibling': (reqires ext-edit extension) + * - 'cut', 'copy', 'paste': (use an internal singleton 'clipboard') + * - 'down', 'first', 'last', 'left', 'parent', 'right', 'up': navigate + * + * @param {string} cmd + * @param {FancytreeNode} [node=active_node] + * @param {object} [opts] Currently unused + * + * @since 2.32 + */ + applyCommand: function (cmd, node, opts_) { + var // clipboard, + refNode; + // opts = $.extend( + // { setActive: true, clipboard: CLIPBOARD }, + // opts_ + // ); + + node = node || this.getActiveNode(); + // clipboard = opts.clipboard; + + switch (cmd) { + // Sorting and indentation: + case "moveUp": + refNode = node.getPrevSibling(); + if (refNode) { + node.moveTo(refNode, "before"); + node.setActive(); + } + break; + case "moveDown": + refNode = node.getNextSibling(); + if (refNode) { + node.moveTo(refNode, "after"); + node.setActive(); + } + break; + case "indent": + refNode = node.getPrevSibling(); + if (refNode) { + node.moveTo(refNode, "child"); + refNode.setExpanded(); + node.setActive(); + } + break; + case "outdent": + if (!node.isTopLevel()) { + node.moveTo(node.getParent(), "after"); + node.setActive(); + } + break; + // Remove: + case "remove": + refNode = node.getPrevSibling() || node.getParent(); + node.remove(); + if (refNode) { + refNode.setActive(); + } + break; + // Add, edit (requires ext-edit): + case "addChild": + node.editCreateNode("child", ""); + break; + case "addSibling": + node.editCreateNode("after", ""); + break; + case "rename": + node.editStart(); + break; + // Simple clipboard simulation: + // case "cut": + // clipboard = { mode: cmd, data: node }; + // break; + // case "copy": + // clipboard = { + // mode: cmd, + // data: node.toDict(function(d, n) { + // delete d.key; + // }), + // }; + // break; + // case "clear": + // clipboard = null; + // break; + // case "paste": + // if (clipboard.mode === "cut") { + // // refNode = node.getPrevSibling(); + // clipboard.data.moveTo(node, "child"); + // clipboard.data.setActive(); + // } else if (clipboard.mode === "copy") { + // node.addChildren(clipboard.data).setActive(); + // } + // break; + // Navigation commands: + case "down": + case "first": + case "last": + case "left": + case "parent": + case "right": + case "up": + return node.navigate(cmd); + default: + $.error("Unhandled command: '" + cmd + "'"); + } + }, + /** (experimental) Modify existing data model. + * + * @param {Array} patchList array of [key, NodePatch] arrays + * @returns {$.Promise} resolved, when all patches have been applied + * @see TreePatch + */ + applyPatch: function (patchList) { + var dfd, + i, + p2, + key, + patch, + node, + patchCount = patchList.length, + deferredList = []; + + for (i = 0; i < patchCount; i++) { + p2 = patchList[i]; + _assert( + p2.length === 2, + "patchList must be an array of length-2-arrays" + ); + key = p2[0]; + patch = p2[1]; + node = key === null ? this.rootNode : this.getNodeByKey(key); + if (node) { + dfd = new $.Deferred(); + deferredList.push(dfd); + node.applyPatch(patch).always(_makeResolveFunc(dfd, node)); + } else { + this.warn("could not find node with key '" + key + "'"); + } + } + // Return a promise that is resolved, when ALL patches were applied + return $.when.apply($, deferredList).promise(); + }, + /* TODO: implement in dnd extension + cancelDrag: function() { + var dd = $.ui.ddmanager.current; + if(dd){ + dd.cancel(); + } + }, + */ + /** Remove all nodes. + * @since 2.14 + */ + clear: function (source) { + this._callHook("treeClear", this); + }, + /** Return the number of nodes. + * @returns {integer} + */ + count: function () { + return this.rootNode.countChildren(); + }, + /** Write to browser console if debugLevel >= 4 (prepending tree name) + * + * @param {*} msg string or object or array of such + */ + debug: function (msg) { + if (this.options.debugLevel >= 4) { + Array.prototype.unshift.call(arguments, this.toString()); + consoleApply("log", arguments); + } + }, + /** Destroy this widget, restore previous markup and cleanup resources. + * + * @since 2.34 + */ + destroy: function () { + this.widget.destroy(); + }, + /** Enable (or disable) the tree control. + * + * @param {boolean} [flag=true] pass false to disable + * @since 2.30 + */ + enable: function (flag) { + if (flag === false) { + this.widget.disable(); + } else { + this.widget.enable(); + } + }, + /** Temporarily suppress rendering to improve performance on bulk-updates. + * + * @param {boolean} flag + * @returns {boolean} previous status + * @since 2.19 + */ + enableUpdate: function (flag) { + flag = flag !== false; + if (!!this._enableUpdate === !!flag) { + return flag; + } + this._enableUpdate = flag; + if (flag) { + this.debug("enableUpdate(true): redraw "); //, this._dirtyRoots); + this._callHook("treeStructureChanged", this, "enableUpdate"); + this.render(); + } else { + // this._dirtyRoots = null; + this.debug("enableUpdate(false)..."); + } + return !flag; // return previous value + }, + /** Write error to browser console if debugLevel >= 1 (prepending tree info) + * + * @param {*} msg string or object or array of such + */ + error: function (msg) { + if (this.options.debugLevel >= 1) { + Array.prototype.unshift.call(arguments, this.toString()); + consoleApply("error", arguments); + } + }, + /** Expand (or collapse) all parent nodes. + * + * This convenience method uses `tree.visit()` and `tree.setExpanded()` + * internally. + * + * @param {boolean} [flag=true] pass false to collapse + * @param {object} [opts] passed to setExpanded() + * @since 2.30 + */ + expandAll: function (flag, opts) { + var prev = this.enableUpdate(false); + + flag = flag !== false; + this.visit(function (node) { + if ( + node.hasChildren() !== false && + node.isExpanded() !== flag + ) { + node.setExpanded(flag, opts); + } + }); + this.enableUpdate(prev); + }, + /**Find all nodes that matches condition. + * + * @param {string | function(node)} match title string to search for, or a + * callback function that returns `true` if a node is matched. + * @returns {FancytreeNode[]} array of nodes (may be empty) + * @see FancytreeNode#findAll + * @since 2.12 + */ + findAll: function (match) { + return this.rootNode.findAll(match); + }, + /**Find first node that matches condition. + * + * @param {string | function(node)} match title string to search for, or a + * callback function that returns `true` if a node is matched. + * @returns {FancytreeNode} matching node or null + * @see FancytreeNode#findFirst + * @since 2.12 + */ + findFirst: function (match) { + return this.rootNode.findFirst(match); + }, + /** Find the next visible node that starts with `match`, starting at `startNode` + * and wrap-around at the end. + * + * @param {string|function} match + * @param {FancytreeNode} [startNode] defaults to first node + * @returns {FancytreeNode} matching node or null + */ + findNextNode: function (match, startNode) { + //, visibleOnly) { + var res = null, + firstNode = this.getFirstChild(); + + match = + typeof match === "string" + ? _makeNodeTitleStartMatcher(match) + : match; + startNode = startNode || firstNode; + + function _checkNode(n) { + // console.log("_check " + n) + if (match(n)) { + res = n; + } + if (res || n === startNode) { + return false; + } + } + this.visitRows(_checkNode, { + start: startNode, + includeSelf: false, + }); + // Wrap around search + if (!res && startNode !== firstNode) { + this.visitRows(_checkNode, { + start: firstNode, + includeSelf: true, + }); + } + return res; + }, + /** Find a node relative to another node. + * + * @param {FancytreeNode} node + * @param {string|number} where 'down', 'first', 'last', 'left', 'parent', 'right', or 'up'. + * (Alternatively the keyCode that would normally trigger this move, + * e.g. `$.ui.keyCode.LEFT` = 'left'. + * @param {boolean} [includeHidden=false] Not yet implemented + * @returns {FancytreeNode|null} + * @since v2.31 + */ + findRelatedNode: function (node, where, includeHidden) { + var res = null, + KC = $.ui.keyCode; + + switch (where) { + case "parent": + case KC.BACKSPACE: + if (node.parent && node.parent.parent) { + res = node.parent; + } + break; + case "first": + case KC.HOME: + // First visible node + this.visit(function (n) { + if (n.isVisible()) { + res = n; + return false; + } + }); + break; + case "last": + case KC.END: + this.visit(function (n) { + // last visible node + if (n.isVisible()) { + res = n; + } + }); + break; + case "left": + case KC.LEFT: + if (node.expanded) { + node.setExpanded(false); + } else if (node.parent && node.parent.parent) { + res = node.parent; + } + break; + case "right": + case KC.RIGHT: + if (!node.expanded && (node.children || node.lazy)) { + node.setExpanded(); + res = node; + } else if (node.children && node.children.length) { + res = node.children[0]; + } + break; + case "up": + case KC.UP: + this.visitRows( + function (n) { + res = n; + return false; + }, + { start: node, reverse: true, includeSelf: false } + ); + break; + case "down": + case KC.DOWN: + this.visitRows( + function (n) { + res = n; + return false; + }, + { start: node, includeSelf: false } + ); + break; + default: + this.tree.warn("Unknown relation '" + where + "'."); + } + return res; + }, + // TODO: fromDict + /** + * Generate INPUT elements that can be submitted with html forms. + * + * In selectMode 3 only the topmost selected nodes are considered, unless + * `opts.stopOnParents: false` is passed. + * + * @example + * // Generate input elements for active and selected nodes + * tree.generateFormElements(); + * // Generate input elements selected nodes, using a custom `name` attribute + * tree.generateFormElements("cust_sel", false); + * // Generate input elements using a custom filter + * tree.generateFormElements(true, true, { filter: function(node) { + * return node.isSelected() && node.data.yes; + * }}); + * + * @param {boolean | string} [selected=true] Pass false to disable, pass a string to override the field name (default: 'ft_ID[]') + * @param {boolean | string} [active=true] Pass false to disable, pass a string to override the field name (default: 'ft_ID_active') + * @param {object} [opts] default { filter: null, stopOnParents: true } + */ + generateFormElements: function (selected, active, opts) { + opts = opts || {}; + + var nodeList, + selectedName = + typeof selected === "string" + ? selected + : "ft_" + this._id + "[]", + activeName = + typeof active === "string" + ? active + : "ft_" + this._id + "_active", + id = "fancytree_result_" + this._id, + $result = $("#" + id), + stopOnParents = + this.options.selectMode === 3 && + opts.stopOnParents !== false; + + if ($result.length) { + $result.empty(); + } else { + $result = $("<div>", { + id: id, + }) + .hide() + .insertAfter(this.$container); + } + if (active !== false && this.activeNode) { + $result.append( + $("<input>", { + type: "radio", + name: activeName, + value: this.activeNode.key, + checked: true, + }) + ); + } + function _appender(node) { + $result.append( + $("<input>", { + type: "checkbox", + name: selectedName, + value: node.key, + checked: true, + }) + ); + } + if (opts.filter) { + this.visit(function (node) { + var res = opts.filter(node); + if (res === "skip") { + return res; + } + if (res !== false) { + _appender(node); + } + }); + } else if (selected !== false) { + nodeList = this.getSelectedNodes(stopOnParents); + $.each(nodeList, function (idx, node) { + _appender(node); + }); + } + }, + /** + * Return the currently active node or null. + * @returns {FancytreeNode} + */ + getActiveNode: function () { + return this.activeNode; + }, + /** Return the first top level node if any (not the invisible root node). + * @returns {FancytreeNode | null} + */ + getFirstChild: function () { + return this.rootNode.getFirstChild(); + }, + /** + * Return node that has keyboard focus or null. + * @returns {FancytreeNode} + */ + getFocusNode: function () { + return this.focusNode; + }, + /** + * Return current option value. + * (Note: this is the preferred variant of `$().fancytree("option", "KEY")`) + * + * @param {string} name option name (may contain '.') + * @returns {any} + */ + getOption: function (optionName) { + return this.widget.option(optionName); + }, + /** + * Return node with a given key or null if not found. + * + * @param {string} key + * @param {FancytreeNode} [searchRoot] only search below this node + * @returns {FancytreeNode | null} + */ + getNodeByKey: function (key, searchRoot) { + // Search the DOM by element ID (assuming this is faster than traversing all nodes). + var el, match; + // TODO: use tree.keyMap if available + // TODO: check opts.generateIds === true + if (!searchRoot) { + el = document.getElementById(this.options.idPrefix + key); + if (el) { + return el.ftnode ? el.ftnode : null; + } + } + // Not found in the DOM, but still may be in an unrendered part of tree + searchRoot = searchRoot || this.rootNode; + match = null; + key = "" + key; // Convert to string (#1005) + searchRoot.visit(function (node) { + if (node.key === key) { + match = node; + return false; // Stop iteration + } + }, true); + return match; + }, + /** Return the invisible system root node. + * @returns {FancytreeNode} + */ + getRootNode: function () { + return this.rootNode; + }, + /** + * Return an array of selected nodes. + * + * Note: you cannot send this result via Ajax directly. Instead the + * node object need to be converted to plain objects, for example + * by using `$.map()` and `node.toDict()`. + * @param {boolean} [stopOnParents=false] only return the topmost selected + * node (useful with selectMode 3) + * @returns {FancytreeNode[]} + */ + getSelectedNodes: function (stopOnParents) { + return this.rootNode.getSelectedNodes(stopOnParents); + }, + /** Return true if the tree control has keyboard focus + * @returns {boolean} + */ + hasFocus: function () { + // var ae = document.activeElement, + // hasFocus = !!( + // ae && $(ae).closest(".fancytree-container").length + // ); + + // if (hasFocus !== !!this._hasFocus) { + // this.warn( + // "hasFocus(): fix inconsistent container state, now: " + + // hasFocus + // ); + // this._hasFocus = hasFocus; + // this.$container.toggleClass("fancytree-treefocus", hasFocus); + // } + // return hasFocus; + return !!this._hasFocus; + }, + /** Write to browser console if debugLevel >= 3 (prepending tree name) + * @param {*} msg string or object or array of such + */ + info: function (msg) { + if (this.options.debugLevel >= 3) { + Array.prototype.unshift.call(arguments, this.toString()); + consoleApply("info", arguments); + } + }, + /** Return true if any node is currently beeing loaded, i.e. a Ajax request is pending. + * @returns {boolean} + * @since 2.32 + */ + isLoading: function () { + var res = false; + + this.rootNode.visit(function (n) { + // also visit rootNode + if (n._isLoading || n._requestId) { + res = true; + return false; + } + }, true); + return res; + }, + /* + TODO: isInitializing: function() { + return ( this.phase=="init" || this.phase=="postInit" ); + }, + TODO: isReloading: function() { + return ( this.phase=="init" || this.phase=="postInit" ) && this.options.persist && this.persistence.cookiesFound; + }, + TODO: isUserEvent: function() { + return ( this.phase=="userEvent" ); + }, + */ + + /** + * Make sure that a node with a given ID is loaded, by traversing - and + * loading - its parents. This method is meant for lazy hierarchies. + * A callback is executed for every node as we go. + * @example + * // Resolve using node.key: + * tree.loadKeyPath("/_3/_23/_26/_27", function(node, status){ + * if(status === "loaded") { + * console.log("loaded intermediate node " + node); + * }else if(status === "ok") { + * node.activate(); + * } + * }); + * // Use deferred promise: + * tree.loadKeyPath("/_3/_23/_26/_27").progress(function(data){ + * if(data.status === "loaded") { + * console.log("loaded intermediate node " + data.node); + * }else if(data.status === "ok") { + * node.activate(); + * } + * }).done(function(){ + * ... + * }); + * // Custom path segment resolver: + * tree.loadKeyPath("/321/431/21/2", { + * matchKey: function(node, key){ + * return node.data.refKey === key; + * }, + * callback: function(node, status){ + * if(status === "loaded") { + * console.log("loaded intermediate node " + node); + * }else if(status === "ok") { + * node.activate(); + * } + * } + * }); + * @param {string | string[]} keyPathList one or more key paths (e.g. '/3/2_1/7') + * @param {function | object} optsOrCallback callback(node, status) is called for every visited node ('loading', 'loaded', 'ok', 'error'). + * Pass an object to define custom key matchers for the path segments: {callback: function, matchKey: function}. + * @returns {$.Promise} + */ + loadKeyPath: function (keyPathList, optsOrCallback) { + var callback, + i, + path, + self = this, + dfd = new $.Deferred(), + parent = this.getRootNode(), + sep = this.options.keyPathSeparator, + pathSegList = [], + opts = $.extend({}, optsOrCallback); + + // Prepare options + if (typeof optsOrCallback === "function") { + callback = optsOrCallback; + } else if (optsOrCallback && optsOrCallback.callback) { + callback = optsOrCallback.callback; + } + opts.callback = function (ctx, node, status) { + if (callback) { + callback.call(ctx, node, status); + } + dfd.notifyWith(ctx, [{ node: node, status: status }]); + }; + if (opts.matchKey == null) { + opts.matchKey = function (node, key) { + return node.key === key; + }; + } + // Convert array of path strings to array of segment arrays + if (!_isArray(keyPathList)) { + keyPathList = [keyPathList]; + } + for (i = 0; i < keyPathList.length; i++) { + path = keyPathList[i]; + // strip leading slash + if (path.charAt(0) === sep) { + path = path.substr(1); + } + // segListMap[path] = { parent: parent, segList: path.split(sep) }; + pathSegList.push(path.split(sep)); + // targetList.push({ parent: parent, segList: path.split(sep)/* , path: path*/}); + } + // The timeout forces async behavior always (even if nodes are all loaded) + // This way a potential progress() event will fire. + setTimeout(function () { + self._loadKeyPathImpl(dfd, opts, parent, pathSegList).done( + function () { + dfd.resolve(); + } + ); + }, 0); + return dfd.promise(); + }, + /* + * Resolve a list of paths, relative to one parent node. + */ + _loadKeyPathImpl: function (dfd, opts, parent, pathSegList) { + var deferredList, + i, + key, + node, + nodeKey, + remain, + remainMap, + tmpParent, + segList, + subDfd, + self = this; + + function __findChild(parent, key) { + // console.log("__findChild", key, parent); + var i, + l, + cl = parent.children; + + if (cl) { + for (i = 0, l = cl.length; i < l; i++) { + if (opts.matchKey(cl[i], key)) { + return cl[i]; + } + } + } + return null; + } + + // console.log("_loadKeyPathImpl, parent=", parent, ", pathSegList=", pathSegList); + + // Pass 1: + // Handle all path segments for nodes that are already loaded. + // Collect distinct top-most lazy nodes in a map. + // Note that we can use node.key to de-dupe entries, even if a custom matcher would + // look for other node attributes. + // map[node.key] => {node: node, pathList: [list of remaining rest-paths]} + remainMap = {}; + + for (i = 0; i < pathSegList.length; i++) { + segList = pathSegList[i]; + // target = targetList[i]; + + // Traverse and pop path segments (i.e. keys), until we hit a lazy, unloaded node + tmpParent = parent; + while (segList.length) { + key = segList.shift(); + node = __findChild(tmpParent, key); + if (!node) { + this.warn( + "loadKeyPath: key not found: " + + key + + " (parent: " + + tmpParent + + ")" + ); + opts.callback(this, key, "error"); + break; + } else if (segList.length === 0) { + opts.callback(this, node, "ok"); + break; + } else if (!node.lazy || node.hasChildren() !== undefined) { + opts.callback(this, node, "loaded"); + tmpParent = node; + } else { + opts.callback(this, node, "loaded"); + key = node.key; //target.segList.join(sep); + if (remainMap[key]) { + remainMap[key].pathSegList.push(segList); + } else { + remainMap[key] = { + parent: node, + pathSegList: [segList], + }; + } + break; + } + } + } + // console.log("_loadKeyPathImpl AFTER pass 1, remainMap=", remainMap); + + // Now load all lazy nodes and continue iteration for remaining paths + deferredList = []; + + // Avoid jshint warning 'Don't make functions within a loop.': + function __lazyload(dfd, parent, pathSegList) { + // console.log("__lazyload", parent, "pathSegList=", pathSegList); + opts.callback(self, parent, "loading"); + parent + .load() + .done(function () { + self._loadKeyPathImpl + .call(self, dfd, opts, parent, pathSegList) + .always(_makeResolveFunc(dfd, self)); + }) + .fail(function (errMsg) { + self.warn("loadKeyPath: error loading lazy " + parent); + opts.callback(self, node, "error"); + dfd.rejectWith(self); + }); + } + // remainMap contains parent nodes, each with a list of relative sub-paths. + // We start loading all of them now, and pass the the list to each loader. + for (nodeKey in remainMap) { + if (_hasProp(remainMap, nodeKey)) { + remain = remainMap[nodeKey]; + // console.log("for(): remain=", remain, "remainMap=", remainMap); + // key = remain.segList.shift(); + // node = __findChild(remain.parent, key); + // if (node == null) { // #576 + // // Issue #576, refactored for v2.27: + // // The root cause was, that sometimes the wrong parent was used here + // // to find the next segment. + // // Falling back to getNodeByKey() was a hack that no longer works if a custom + // // matcher is used, because we cannot assume that a single segment-key is unique + // // throughout the tree. + // self.error("loadKeyPath: error loading child by key '" + key + "' (parent: " + target.parent + ")", target); + // // node = self.getNodeByKey(key); + // continue; + // } + subDfd = new $.Deferred(); + deferredList.push(subDfd); + __lazyload(subDfd, remain.parent, remain.pathSegList); + } + } + // Return a promise that is resolved, when ALL paths were loaded + return $.when.apply($, deferredList).promise(); + }, + /** Re-fire beforeActivate, activate, and (optional) focus events. + * Calling this method in the `init` event, will activate the node that + * was marked 'active' in the source data, and optionally set the keyboard + * focus. + * @param [setFocus=false] + */ + reactivate: function (setFocus) { + var res, + node = this.activeNode; + + if (!node) { + return _getResolvedPromise(); + } + this.activeNode = null; // Force re-activating + res = node.setActive(true, { noFocus: true }); + if (setFocus) { + node.setFocus(); + } + return res; + }, + /** Reload tree from source and return a promise. + * @param [source] optional new source (defaults to initial source data) + * @returns {$.Promise} + */ + reload: function (source) { + this._callHook("treeClear", this); + return this._callHook("treeLoad", this, source); + }, + /**Render tree (i.e. create DOM elements for all top-level nodes). + * @param {boolean} [force=false] create DOM elemnts, even if parent is collapsed + * @param {boolean} [deep=false] + */ + render: function (force, deep) { + return this.rootNode.render(force, deep); + }, + /**(De)select all nodes. + * @param {boolean} [flag=true] + * @since 2.28 + */ + selectAll: function (flag) { + this.visit(function (node) { + node.setSelected(flag); + }); + }, + // TODO: selectKey: function(key, select) + // TODO: serializeArray: function(stopOnParents) + /** + * @param {boolean} [flag=true] + */ + setFocus: function (flag) { + return this._callHook("treeSetFocus", this, flag); + }, + /** + * Set current option value. + * (Note: this is the preferred variant of `$().fancytree("option", "KEY", VALUE)`) + * @param {string} name option name (may contain '.') + * @param {any} new value + */ + setOption: function (optionName, value) { + return this.widget.option(optionName, value); + }, + /** + * Call console.time() when in debug mode (verbose >= 4). + * + * @param {string} label + */ + debugTime: function (label) { + if (this.options.debugLevel >= 4) { + window.console.time(this + " - " + label); + } + }, + /** + * Call console.timeEnd() when in debug mode (verbose >= 4). + * + * @param {string} label + */ + debugTimeEnd: function (label) { + if (this.options.debugLevel >= 4) { + window.console.timeEnd(this + " - " + label); + } + }, + /** + * Return all nodes as nested list of {@link NodeData}. + * + * @param {boolean} [includeRoot=false] Returns the hidden system root node (and its children) + * @param {function} [callback] callback(dict, node) is called for every node, in order to allow modifications. + * Return `false` to ignore this node or "skip" to include this node without its children. + * @returns {Array | object} + * @see FancytreeNode#toDict + */ + toDict: function (includeRoot, callback) { + var res = this.rootNode.toDict(true, callback); + return includeRoot ? res : res.children; + }, + /* Implicitly called for string conversions. + * @returns {string} + */ + toString: function () { + return "Fancytree@" + this._id; + // return "<Fancytree(#" + this._id + ")>"; + }, + /* _trigger a widget event with additional node ctx. + * @see EventData + */ + _triggerNodeEvent: function (type, node, originalEvent, extra) { + // this.debug("_trigger(" + type + "): '" + ctx.node.title + "'", ctx); + var ctx = this._makeHookContext(node, originalEvent, extra), + res = this.widget._trigger(type, originalEvent, ctx); + if (res !== false && ctx.result !== undefined) { + return ctx.result; + } + return res; + }, + /* _trigger a widget event with additional tree data. */ + _triggerTreeEvent: function (type, originalEvent, extra) { + // this.debug("_trigger(" + type + ")", ctx); + var ctx = this._makeHookContext(this, originalEvent, extra), + res = this.widget._trigger(type, originalEvent, ctx); + + if (res !== false && ctx.result !== undefined) { + return ctx.result; + } + return res; + }, + /** Call fn(node) for all nodes in hierarchical order (depth-first). + * + * @param {function} fn the callback function. + * Return false to stop iteration, return "skip" to skip this node and children only. + * @returns {boolean} false, if the iterator was stopped. + */ + visit: function (fn) { + return this.rootNode.visit(fn, false); + }, + /** Call fn(node) for all nodes in vertical order, top down (or bottom up).<br> + * Stop iteration, if fn() returns false.<br> + * Return false if iteration was stopped. + * + * @param {function} fn the callback function. + * Return false to stop iteration, return "skip" to skip this node and children only. + * @param {object} [options] + * Defaults: + * {start: First top node, reverse: false, includeSelf: true, includeHidden: false} + * @returns {boolean} false if iteration was cancelled + * @since 2.28 + */ + visitRows: function (fn, opts) { + if (!this.rootNode.hasChildren()) { + return false; + } + if (opts && opts.reverse) { + delete opts.reverse; + return this._visitRowsUp(fn, opts); + } + opts = opts || {}; + + var i, + nextIdx, + parent, + res, + siblings, + siblingOfs = 0, + skipFirstNode = opts.includeSelf === false, + includeHidden = !!opts.includeHidden, + checkFilter = !includeHidden && this.enableFilter, + node = opts.start || this.rootNode.children[0]; + + parent = node.parent; + while (parent) { + // visit siblings + siblings = parent.children; + nextIdx = siblings.indexOf(node) + siblingOfs; + _assert( + nextIdx >= 0, + "Could not find " + + node + + " in parent's children: " + + parent + ); + + for (i = nextIdx; i < siblings.length; i++) { + node = siblings[i]; + if (checkFilter && !node.match && !node.subMatchCount) { + continue; + } + if (!skipFirstNode && fn(node) === false) { + return false; + } + skipFirstNode = false; + // Dive into node's child nodes + if ( + node.children && + node.children.length && + (includeHidden || node.expanded) + ) { + // Disable warning: Functions declared within loops referencing an outer + // scoped variable may lead to confusing semantics: + /*jshint -W083 */ + res = node.visit(function (n) { + if (checkFilter && !n.match && !n.subMatchCount) { + return "skip"; + } + if (fn(n) === false) { + return false; + } + if (!includeHidden && n.children && !n.expanded) { + return "skip"; + } + }, false); + /*jshint +W083 */ + if (res === false) { + return false; + } + } + } + // Visit parent nodes (bottom up) + node = parent; + parent = parent.parent; + siblingOfs = 1; // + } + return true; + }, + /* Call fn(node) for all nodes in vertical order, bottom up. + */ + _visitRowsUp: function (fn, opts) { + var children, + idx, + parent, + includeHidden = !!opts.includeHidden, + node = opts.start || this.rootNode.children[0]; + + while (true) { + parent = node.parent; + children = parent.children; + + if (children[0] === node) { + // If this is already the first sibling, goto parent + node = parent; + if (!node.parent) { + break; // first node of the tree + } + children = parent.children; + } else { + // Otherwise, goto prev. sibling + idx = children.indexOf(node); + node = children[idx - 1]; + // If the prev. sibling has children, follow down to last descendant + while ( + // See: https://github.com/eslint/eslint/issues/11302 + // eslint-disable-next-line no-unmodified-loop-condition + (includeHidden || node.expanded) && + node.children && + node.children.length + ) { + children = node.children; + parent = node; + node = children[children.length - 1]; + } + } + // Skip invisible + if (!includeHidden && !node.isVisible()) { + continue; + } + if (fn(node) === false) { + return false; + } + } + }, + /** Write warning to browser console if debugLevel >= 2 (prepending tree info) + * + * @param {*} msg string or object or array of such + */ + warn: function (msg) { + if (this.options.debugLevel >= 2) { + Array.prototype.unshift.call(arguments, this.toString()); + consoleApply("warn", arguments); + } + }, + }; + + /** + * These additional methods of the {@link Fancytree} class are 'hook functions' + * that can be used and overloaded by extensions. + * + * @see [writing extensions](https://github.com/mar10/fancytree/wiki/TutorialExtensions) + * @mixin Fancytree_Hooks + */ + $.extend( + Fancytree.prototype, + /** @lends Fancytree_Hooks# */ + { + /** Default handling for mouse click events. + * + * @param {EventData} ctx + */ + nodeClick: function (ctx) { + var activate, + expand, + // event = ctx.originalEvent, + targetType = ctx.targetType, + node = ctx.node; + + // this.debug("ftnode.onClick(" + event.type + "): ftnode:" + this + ", button:" + event.button + ", which: " + event.which, ctx); + // TODO: use switch + // TODO: make sure clicks on embedded <input> doesn't steal focus (see table sample) + if (targetType === "expander") { + if (node.isLoading()) { + // #495: we probably got a click event while a lazy load is pending. + // The 'expanded' state is not yet set, so 'toggle' would expand + // and trigger lazyLoad again. + // It would be better to allow to collapse/expand the status node + // while loading (instead of ignoring), but that would require some + // more work. + node.debug("Got 2nd click while loading: ignored"); + return; + } + // Clicking the expander icon always expands/collapses + this._callHook("nodeToggleExpanded", ctx); + } else if (targetType === "checkbox") { + // Clicking the checkbox always (de)selects + this._callHook("nodeToggleSelected", ctx); + if (ctx.options.focusOnSelect) { + // #358 + this._callHook("nodeSetFocus", ctx, true); + } + } else { + // Honor `clickFolderMode` for + expand = false; + activate = true; + if (node.folder) { + switch (ctx.options.clickFolderMode) { + case 2: // expand only + expand = true; + activate = false; + break; + case 3: // expand and activate + activate = true; + expand = true; //!node.isExpanded(); + break; + // else 1 or 4: just activate + } + } + if (activate) { + this.nodeSetFocus(ctx); + this._callHook("nodeSetActive", ctx, true); + } + if (expand) { + if (!activate) { + // this._callHook("nodeSetFocus", ctx); + } + // this._callHook("nodeSetExpanded", ctx, true); + this._callHook("nodeToggleExpanded", ctx); + } + } + // Make sure that clicks stop, otherwise <a href='#'> jumps to the top + // if(event.target.localName === "a" && event.target.className === "fancytree-title"){ + // event.preventDefault(); + // } + // TODO: return promise? + }, + /** Collapse all other children of same parent. + * + * @param {EventData} ctx + * @param {object} callOpts + */ + nodeCollapseSiblings: function (ctx, callOpts) { + // TODO: return promise? + var ac, + i, + l, + node = ctx.node; + + if (node.parent) { + ac = node.parent.children; + for (i = 0, l = ac.length; i < l; i++) { + if (ac[i] !== node && ac[i].expanded) { + this._callHook( + "nodeSetExpanded", + ac[i], + false, + callOpts + ); + } + } + } + }, + /** Default handling for mouse douleclick events. + * @param {EventData} ctx + */ + nodeDblclick: function (ctx) { + // TODO: return promise? + if ( + ctx.targetType === "title" && + ctx.options.clickFolderMode === 4 + ) { + // this.nodeSetFocus(ctx); + // this._callHook("nodeSetActive", ctx, true); + this._callHook("nodeToggleExpanded", ctx); + } + // TODO: prevent text selection on dblclicks + if (ctx.targetType === "title") { + ctx.originalEvent.preventDefault(); + } + }, + /** Default handling for mouse keydown events. + * + * NOTE: this may be called with node == null if tree (but no node) has focus. + * @param {EventData} ctx + */ + nodeKeydown: function (ctx) { + // TODO: return promise? + var matchNode, + stamp, + _res, + focusNode, + event = ctx.originalEvent, + node = ctx.node, + tree = ctx.tree, + opts = ctx.options, + which = event.which, + // #909: Use event.key, to get unicode characters. + // We can't use `/\w/.test(key)`, because that would + // only detect plain ascii alpha-numerics. But we still need + // to ignore modifier-only, whitespace, cursor-keys, etc. + key = event.key || String.fromCharCode(which), + specialModifiers = !!( + event.altKey || + event.ctrlKey || + event.metaKey + ), + isAlnum = + !MODIFIERS[which] && + !SPECIAL_KEYCODES[which] && + !specialModifiers, + $target = $(event.target), + handled = true, + activate = !(event.ctrlKey || !opts.autoActivate); + + // (node || FT).debug("ftnode.nodeKeydown(" + event.type + "): ftnode:" + this + ", charCode:" + event.charCode + ", keyCode: " + event.keyCode + ", which: " + event.which); + // FT.debug( "eventToString(): " + FT.eventToString(event) + ", key='" + key + "', isAlnum: " + isAlnum ); + + // Set focus to active (or first node) if no other node has the focus yet + if (!node) { + focusNode = this.getActiveNode() || this.getFirstChild(); + if (focusNode) { + focusNode.setFocus(); + node = ctx.node = this.focusNode; + node.debug("Keydown force focus on active node"); + } + } + + if ( + opts.quicksearch && + isAlnum && + !$target.is(":input:enabled") + ) { + // Allow to search for longer streaks if typed in quickly + stamp = Date.now(); + if (stamp - tree.lastQuicksearchTime > 500) { + tree.lastQuicksearchTerm = ""; + } + tree.lastQuicksearchTime = stamp; + tree.lastQuicksearchTerm += key; + // tree.debug("quicksearch find", tree.lastQuicksearchTerm); + matchNode = tree.findNextNode( + tree.lastQuicksearchTerm, + tree.getActiveNode() + ); + if (matchNode) { + matchNode.setActive(); + } + event.preventDefault(); + return; + } + switch (FT.eventToString(event)) { + case "+": + case "=": // 187: '+' @ Chrome, Safari + tree.nodeSetExpanded(ctx, true); + break; + case "-": + tree.nodeSetExpanded(ctx, false); + break; + case "space": + if (node.isPagingNode()) { + tree._triggerNodeEvent("clickPaging", ctx, event); + } else if ( + FT.evalOption("checkbox", node, node, opts, false) + ) { + // #768 + tree.nodeToggleSelected(ctx); + } else { + tree.nodeSetActive(ctx, true); + } + break; + case "return": + tree.nodeSetActive(ctx, true); + break; + case "home": + case "end": + case "backspace": + case "left": + case "right": + case "up": + case "down": + _res = node.navigate(event.which, activate); + break; + default: + handled = false; + } + if (handled) { + event.preventDefault(); + } + }, + + // /** Default handling for mouse keypress events. */ + // nodeKeypress: function(ctx) { + // var event = ctx.originalEvent; + // }, + + // /** Trigger lazyLoad event (async). */ + // nodeLazyLoad: function(ctx) { + // var node = ctx.node; + // if(this._triggerNodeEvent()) + // }, + /** Load child nodes (async). + * + * @param {EventData} ctx + * @param {object[]|object|string|$.Promise|function} source + * @returns {$.Promise} The deferred will be resolved as soon as the (ajax) + * data was rendered. + */ + nodeLoadChildren: function (ctx, source) { + var ajax, + delay, + ajaxDfd = null, + resultDfd, + isAsync = true, + tree = ctx.tree, + node = ctx.node, + nodePrevParent = node.parent, + tag = "nodeLoadChildren", + requestId = Date.now(); + + // `source` is a callback: use the returned result instead: + if (_isFunction(source)) { + source = source.call(tree, { type: "source" }, ctx); + _assert( + !_isFunction(source), + "source callback must not return another function" + ); + } + // `source` is already a promise: + if (_isFunction(source.then)) { + // _assert(_isFunction(source.always), "Expected jQuery?"); + ajaxDfd = source; + } else if (source.url) { + // `source` is an Ajax options object + ajax = $.extend({}, ctx.options.ajax, source); + if (ajax.debugDelay) { + // Simulate a slow server + delay = ajax.debugDelay; + delete ajax.debugDelay; // remove debug option + if (_isArray(delay)) { + // random delay range [min..max] + delay = + delay[0] + + Math.random() * (delay[1] - delay[0]); + } + node.warn( + "nodeLoadChildren waiting debugDelay " + + Math.round(delay) + + " ms ..." + ); + ajaxDfd = $.Deferred(function (ajaxDfd) { + setTimeout(function () { + $.ajax(ajax) + .done(function () { + ajaxDfd.resolveWith(this, arguments); + }) + .fail(function () { + ajaxDfd.rejectWith(this, arguments); + }); + }, delay); + }); + } else { + ajaxDfd = $.ajax(ajax); + } + } else if ($.isPlainObject(source) || _isArray(source)) { + // `source` is already a constant dict or list, but we convert + // to a thenable for unified processing. + // 2020-01-03: refactored. + // `ajaxDfd = $.when(source)` would do the trick, but the returned + // promise will resolve async, which broke some tests and + // would probably also break current implementations out there. + // So we mock-up a thenable that resolves synchronously: + ajaxDfd = { + then: function (resolve, reject) { + resolve(source, null, null); + }, + }; + isAsync = false; + } else { + $.error("Invalid source type: " + source); + } + + // Check for overlapping requests + if (node._requestId) { + node.warn( + "Recursive load request #" + + requestId + + " while #" + + node._requestId + + " is pending." + ); + node._requestId = requestId; + // node.debug("Send load request #" + requestId); + } + + if (isAsync) { + tree.debugTime(tag); + tree.nodeSetStatus(ctx, "loading"); + } + + // The async Ajax request has now started... + // Defer the deferred: + // we want to be able to reject invalid responses, even if + // the raw HTTP Ajax XHR resolved as Ok. + // We use the ajaxDfd.then() syntax here, which is compatible with + // jQuery and ECMA6. + // However resultDfd is a jQuery deferred, which is currently the + // expected result type of nodeLoadChildren() + resultDfd = new $.Deferred(); + ajaxDfd.then( + function (data, textStatus, jqXHR) { + // ajaxDfd was resolved, but we reject or resolve resultDfd + // depending on the response data + var errorObj, res; + + if ( + (source.dataType === "json" || + source.dataType === "jsonp") && + typeof data === "string" + ) { + $.error( + "Ajax request returned a string (did you get the JSON dataType wrong?)." + ); + } + if (node._requestId && node._requestId > requestId) { + // The expected request time stamp is later than `requestId` + // (which was kept as as closure variable to this handler function) + // node.warn("Ignored load response for obsolete request #" + requestId + " (expected #" + node._requestId + ")"); + resultDfd.rejectWith(this, [ + RECURSIVE_REQUEST_ERROR, + ]); + return; + // } else { + // node.debug("Response returned for load request #" + requestId); + } + if (node.parent === null && nodePrevParent !== null) { + resultDfd.rejectWith(this, [ + INVALID_REQUEST_TARGET_ERROR, + ]); + return; + } + // Allow to adjust the received response data in the `postProcess` event. + if (ctx.options.postProcess) { + // The handler may either + // - modify `ctx.response` in-place (and leave `ctx.result` undefined) + // => res = undefined + // - return a replacement in `ctx.result` + // => res = <new data> + // If res contains an `error` property, an error status is displayed + try { + res = tree._triggerNodeEvent( + "postProcess", + ctx, + ctx.originalEvent, + { + response: data, + error: null, + dataType: source.dataType, + } + ); + if (res.error) { + tree.warn( + "postProcess returned error:", + res + ); + } + } catch (e) { + res = { + error: e, + message: "" + e, + details: "postProcess failed", + }; + } + if (res.error) { + // Either postProcess failed with an exception, or the returned + // result object has an 'error' property attached: + errorObj = $.isPlainObject(res.error) + ? res.error + : { message: res.error }; + errorObj = tree._makeHookContext( + node, + null, + errorObj + ); + resultDfd.rejectWith(this, [errorObj]); + return; + } + if ( + _isArray(res) || + ($.isPlainObject(res) && _isArray(res.children)) + ) { + // Use `ctx.result` if valid + // (otherwise use existing data, which may have been modified in-place) + data = res; + } + } else if ( + data && + _hasProp(data, "d") && + ctx.options.enableAspx + ) { + // Process ASPX WebMethod JSON object inside "d" property + // (only if no postProcess event was defined) + if (ctx.options.enableAspx === 42) { + tree.warn( + "The default for enableAspx will change to `false` in the fututure. " + + "Pass `enableAspx: true` or implement postProcess to silence this warning." + ); + } + data = + typeof data.d === "string" + ? $.parseJSON(data.d) + : data.d; + } + resultDfd.resolveWith(this, [data]); + }, + function (jqXHR, textStatus, errorThrown) { + // ajaxDfd was rejected, so we reject resultDfd as well + var errorObj = tree._makeHookContext(node, null, { + error: jqXHR, + args: Array.prototype.slice.call(arguments), + message: errorThrown, + details: jqXHR.status + ": " + errorThrown, + }); + resultDfd.rejectWith(this, [errorObj]); + } + ); + + // The async Ajax request has now started. + // resultDfd will be resolved/rejected after the response arrived, + // was postProcessed, and checked. + // Now we implement the UI update and add the data to the tree. + // We also return this promise to the caller. + resultDfd + .done(function (data) { + tree.nodeSetStatus(ctx, "ok"); + var children, metaData, noDataRes; + + if ($.isPlainObject(data)) { + // We got {foo: 'abc', children: [...]} + // Copy extra properties to tree.data.foo + _assert( + node.isRootNode(), + "source may only be an object for root nodes (expecting an array of child objects otherwise)" + ); + _assert( + _isArray(data.children), + "if an object is passed as source, it must contain a 'children' array (all other properties are added to 'tree.data')" + ); + metaData = data; + children = data.children; + delete metaData.children; + // Copy some attributes to tree.data + $.each(TREE_ATTRS, function (i, attr) { + if (metaData[attr] !== undefined) { + tree[attr] = metaData[attr]; + delete metaData[attr]; + } + }); + // Copy all other attributes to tree.data.NAME + $.extend(tree.data, metaData); + } else { + children = data; + } + _assert( + _isArray(children), + "expected array of children" + ); + node._setChildren(children); + + if (tree.options.nodata && children.length === 0) { + if (_isFunction(tree.options.nodata)) { + noDataRes = tree.options.nodata.call( + tree, + { type: "nodata" }, + ctx + ); + } else if ( + tree.options.nodata === true && + node.isRootNode() + ) { + noDataRes = tree.options.strings.noData; + } else if ( + typeof tree.options.nodata === "string" && + node.isRootNode() + ) { + noDataRes = tree.options.nodata; + } + if (noDataRes) { + node.setStatus("nodata", noDataRes); + } + } + // trigger fancytreeloadchildren + tree._triggerNodeEvent("loadChildren", node); + }) + .fail(function (error) { + var ctxErr; + + if (error === RECURSIVE_REQUEST_ERROR) { + node.warn( + "Ignored response for obsolete load request #" + + requestId + + " (expected #" + + node._requestId + + ")" + ); + return; + } else if (error === INVALID_REQUEST_TARGET_ERROR) { + node.warn( + "Lazy parent node was removed while loading: discarding response." + ); + return; + } else if (error.node && error.error && error.message) { + // error is already a context object + ctxErr = error; + } else { + ctxErr = tree._makeHookContext(node, null, { + error: error, // it can be jqXHR or any custom error + args: Array.prototype.slice.call(arguments), + message: error + ? error.message || error.toString() + : "", + }); + if (ctxErr.message === "[object Object]") { + ctxErr.message = ""; + } + } + node.warn( + "Load children failed (" + ctxErr.message + ")", + ctxErr + ); + if ( + tree._triggerNodeEvent( + "loadError", + ctxErr, + null + ) !== false + ) { + tree.nodeSetStatus( + ctx, + "error", + ctxErr.message, + ctxErr.details + ); + } + }) + .always(function () { + node._requestId = null; + if (isAsync) { + tree.debugTimeEnd(tag); + } + }); + + return resultDfd.promise(); + }, + /** [Not Implemented] */ + nodeLoadKeyPath: function (ctx, keyPathList) { + // TODO: implement and improve + // http://code.google.com/p/dynatree/issues/detail?id=222 + }, + /** + * Remove a single direct child of ctx.node. + * @param {EventData} ctx + * @param {FancytreeNode} childNode dircect child of ctx.node + */ + nodeRemoveChild: function (ctx, childNode) { + var idx, + node = ctx.node, + // opts = ctx.options, + subCtx = $.extend({}, ctx, { node: childNode }), + children = node.children; + + // FT.debug("nodeRemoveChild()", node.toString(), childNode.toString()); + + if (children.length === 1) { + _assert(childNode === children[0], "invalid single child"); + return this.nodeRemoveChildren(ctx); + } + if ( + this.activeNode && + (childNode === this.activeNode || + this.activeNode.isDescendantOf(childNode)) + ) { + this.activeNode.setActive(false); // TODO: don't fire events + } + if ( + this.focusNode && + (childNode === this.focusNode || + this.focusNode.isDescendantOf(childNode)) + ) { + this.focusNode = null; + } + // TODO: persist must take care to clear select and expand cookies + this.nodeRemoveMarkup(subCtx); + this.nodeRemoveChildren(subCtx); + idx = $.inArray(childNode, children); + _assert(idx >= 0, "invalid child"); + // Notify listeners + node.triggerModifyChild("remove", childNode); + // Unlink to support GC + childNode.visit(function (n) { + n.parent = null; + }, true); + this._callHook("treeRegisterNode", this, false, childNode); + // remove from child list + children.splice(idx, 1); + }, + /**Remove HTML markup for all descendents of ctx.node. + * @param {EventData} ctx + */ + nodeRemoveChildMarkup: function (ctx) { + var node = ctx.node; + + // FT.debug("nodeRemoveChildMarkup()", node.toString()); + // TODO: Unlink attr.ftnode to support GC + if (node.ul) { + if (node.isRootNode()) { + $(node.ul).empty(); + } else { + $(node.ul).remove(); + node.ul = null; + } + node.visit(function (n) { + n.li = n.ul = null; + }); + } + }, + /**Remove all descendants of ctx.node. + * @param {EventData} ctx + */ + nodeRemoveChildren: function (ctx) { + var //subCtx, + tree = ctx.tree, + node = ctx.node, + children = node.children; + // opts = ctx.options; + + // FT.debug("nodeRemoveChildren()", node.toString()); + if (!children) { + return; + } + if (this.activeNode && this.activeNode.isDescendantOf(node)) { + this.activeNode.setActive(false); // TODO: don't fire events + } + if (this.focusNode && this.focusNode.isDescendantOf(node)) { + this.focusNode = null; + } + // TODO: persist must take care to clear select and expand cookies + this.nodeRemoveChildMarkup(ctx); + // Unlink children to support GC + // TODO: also delete this.children (not possible using visit()) + // subCtx = $.extend({}, ctx); + node.triggerModifyChild("remove", null); + node.visit(function (n) { + n.parent = null; + tree._callHook("treeRegisterNode", tree, false, n); + }); + if (node.lazy) { + // 'undefined' would be interpreted as 'not yet loaded' for lazy nodes + node.children = []; + } else { + node.children = null; + } + if (!node.isRootNode()) { + node.expanded = false; // #449, #459 + } + this.nodeRenderStatus(ctx); + }, + /**Remove HTML markup for ctx.node and all its descendents. + * @param {EventData} ctx + */ + nodeRemoveMarkup: function (ctx) { + var node = ctx.node; + // FT.debug("nodeRemoveMarkup()", node.toString()); + // TODO: Unlink attr.ftnode to support GC + if (node.li) { + $(node.li).remove(); + node.li = null; + } + this.nodeRemoveChildMarkup(ctx); + }, + /** + * Create `<li><span>..</span> .. </li>` tags for this node. + * + * This method takes care that all HTML markup is created that is required + * to display this node in its current state. + * + * Call this method to create new nodes, or after the strucuture + * was changed (e.g. after moving this node or adding/removing children) + * nodeRenderTitle() and nodeRenderStatus() are implied. + * + * ```html + * <li id='KEY' ftnode=NODE> + * <span class='fancytree-node fancytree-expanded fancytree-has-children fancytree-lastsib fancytree-exp-el fancytree-ico-e'> + * <span class="fancytree-expander"></span> + * <span class="fancytree-checkbox"></span> // only present in checkbox mode + * <span class="fancytree-icon"></span> + * <a href="#" class="fancytree-title"> Node 1 </a> + * </span> + * <ul> // only present if node has children + * <li id='KEY' ftnode=NODE> child1 ... </li> + * <li id='KEY' ftnode=NODE> child2 ... </li> + * </ul> + * </li> + * ``` + * + * @param {EventData} ctx + * @param {boolean} [force=false] re-render, even if html markup was already created + * @param {boolean} [deep=false] also render all descendants, even if parent is collapsed + * @param {boolean} [collapsed=false] force root node to be collapsed, so we can apply animated expand later + */ + nodeRender: function (ctx, force, deep, collapsed, _recursive) { + /* This method must take care of all cases where the current data mode + * (i.e. node hierarchy) does not match the current markup. + * + * - node was not yet rendered: + * create markup + * - node was rendered: exit fast + * - children have been added + * - children have been removed + */ + var childLI, + childNode1, + childNode2, + i, + l, + next, + subCtx, + node = ctx.node, + tree = ctx.tree, + opts = ctx.options, + aria = opts.aria, + firstTime = false, + parent = node.parent, + isRootNode = !parent, + children = node.children, + successorLi = null; + // FT.debug("nodeRender(" + !!force + ", " + !!deep + ")", node.toString()); + + if (tree._enableUpdate === false) { + // tree.debug("no render", tree._enableUpdate); + return; + } + if (!isRootNode && !parent.ul) { + // Calling node.collapse on a deep, unrendered node + return; + } + _assert(isRootNode || parent.ul, "parent UL must exist"); + + // Render the node + if (!isRootNode) { + // Discard markup on force-mode, or if it is not linked to parent <ul> + if ( + node.li && + (force || node.li.parentNode !== node.parent.ul) + ) { + if (node.li.parentNode === node.parent.ul) { + // #486: store following node, so we can insert the new markup there later + successorLi = node.li.nextSibling; + } else { + // May happen, when a top-level node was dropped over another + this.debug( + "Unlinking " + + node + + " (must be child of " + + node.parent + + ")" + ); + } + // this.debug("nodeRemoveMarkup..."); + this.nodeRemoveMarkup(ctx); + } + // Create <li><span /> </li> + // node.debug("render..."); + if (node.li) { + // this.nodeRenderTitle(ctx); + this.nodeRenderStatus(ctx); + } else { + // node.debug("render... really"); + firstTime = true; + node.li = document.createElement("li"); + node.li.ftnode = node; + + if (node.key && opts.generateIds) { + node.li.id = opts.idPrefix + node.key; + } + node.span = document.createElement("span"); + node.span.className = "fancytree-node"; + if (aria && !node.tr) { + $(node.li).attr("role", "treeitem"); + } + node.li.appendChild(node.span); + + // Create inner HTML for the <span> (expander, checkbox, icon, and title) + this.nodeRenderTitle(ctx); + + // Allow tweaking and binding, after node was created for the first time + if (opts.createNode) { + opts.createNode.call( + tree, + { type: "createNode" }, + ctx + ); + } + } + // Allow tweaking after node state was rendered + if (opts.renderNode) { + opts.renderNode.call(tree, { type: "renderNode" }, ctx); + } + } + + // Visit child nodes + if (children) { + if (isRootNode || node.expanded || deep === true) { + // Create a UL to hold the children + if (!node.ul) { + node.ul = document.createElement("ul"); + if ( + (collapsed === true && !_recursive) || + !node.expanded + ) { + // hide top UL, so we can use an animation to show it later + node.ul.style.display = "none"; + } + if (aria) { + $(node.ul).attr("role", "group"); + } + if (node.li) { + // issue #67 + node.li.appendChild(node.ul); + } else { + node.tree.$div.append(node.ul); + } + } + // Add child markup + for (i = 0, l = children.length; i < l; i++) { + subCtx = $.extend({}, ctx, { node: children[i] }); + this.nodeRender(subCtx, force, deep, false, true); + } + // Remove <li> if nodes have moved to another parent + childLI = node.ul.firstChild; + while (childLI) { + childNode2 = childLI.ftnode; + if (childNode2 && childNode2.parent !== node) { + node.debug( + "_fixParent: remove missing " + childNode2, + childLI + ); + next = childLI.nextSibling; + childLI.parentNode.removeChild(childLI); + childLI = next; + } else { + childLI = childLI.nextSibling; + } + } + // Make sure, that <li> order matches node.children order. + childLI = node.ul.firstChild; + for (i = 0, l = children.length - 1; i < l; i++) { + childNode1 = children[i]; + childNode2 = childLI.ftnode; + if (childNode1 === childNode2) { + childLI = childLI.nextSibling; + } else { + // node.debug("_fixOrder: mismatch at index " + i + ": " + childNode1 + " != " + childNode2); + node.ul.insertBefore( + childNode1.li, + childNode2.li + ); + } + } + } + } else { + // No children: remove markup if any + if (node.ul) { + // alert("remove child markup for " + node); + this.warn("remove child markup for " + node); + this.nodeRemoveChildMarkup(ctx); + } + } + if (!isRootNode) { + // Update element classes according to node state + // this.nodeRenderStatus(ctx); + // Finally add the whole structure to the DOM, so the browser can render + if (firstTime) { + // #486: successorLi is set, if we re-rendered (i.e. discarded) + // existing markup, which we want to insert at the same position. + // (null is equivalent to append) + // parent.ul.appendChild(node.li); + parent.ul.insertBefore(node.li, successorLi); + } + } + }, + /** Create HTML inside the node's outer `<span>` (i.e. expander, checkbox, + * icon, and title). + * + * nodeRenderStatus() is implied. + * @param {EventData} ctx + * @param {string} [title] optinal new title + */ + nodeRenderTitle: function (ctx, title) { + // set node connector images, links and text + var checkbox, + className, + icon, + nodeTitle, + role, + tabindex, + tooltip, + iconTooltip, + node = ctx.node, + tree = ctx.tree, + opts = ctx.options, + aria = opts.aria, + level = node.getLevel(), + ares = []; + + if (title !== undefined) { + node.title = title; + } + if (!node.span || tree._enableUpdate === false) { + // Silently bail out if node was not rendered yet, assuming + // node.render() will be called as the node becomes visible + return; + } + // Connector (expanded, expandable or simple) + role = + aria && node.hasChildren() !== false + ? " role='button'" + : ""; + if (level < opts.minExpandLevel) { + if (!node.lazy) { + node.expanded = true; + } + if (level > 1) { + ares.push( + "<span " + + role + + " class='fancytree-expander fancytree-expander-fixed'></span>" + ); + } + // .. else (i.e. for root level) skip expander/connector alltogether + } else { + ares.push( + "<span " + role + " class='fancytree-expander'></span>" + ); + } + // Checkbox mode + checkbox = FT.evalOption("checkbox", node, node, opts, false); + + if (checkbox && !node.isStatusNode()) { + role = aria ? " role='checkbox'" : ""; + className = "fancytree-checkbox"; + if ( + checkbox === "radio" || + (node.parent && node.parent.radiogroup) + ) { + className += " fancytree-radio"; + } + ares.push( + "<span " + role + " class='" + className + "'></span>" + ); + } + // Folder or doctype icon + if (node.data.iconClass !== undefined) { + // 2015-11-16 + // Handle / warn about backward compatibility + if (node.icon) { + $.error( + "'iconClass' node option is deprecated since v2.14.0: use 'icon' only instead" + ); + } else { + node.warn( + "'iconClass' node option is deprecated since v2.14.0: use 'icon' instead" + ); + node.icon = node.data.iconClass; + } + } + // If opts.icon is a callback and returns something other than undefined, use that + // else if node.icon is a boolean or string, use that + // else if opts.icon is a boolean or string, use that + // else show standard icon (which may be different for folders or documents) + icon = FT.evalOption("icon", node, node, opts, true); + // if( typeof icon !== "boolean" ) { + // // icon is defined, but not true/false: must be a string + // icon = "" + icon; + // } + if (icon !== false) { + role = aria ? " role='presentation'" : ""; + + iconTooltip = FT.evalOption( + "iconTooltip", + node, + node, + opts, + null + ); + iconTooltip = iconTooltip + ? " title='" + _escapeTooltip(iconTooltip) + "'" + : ""; + + if (typeof icon === "string") { + if (TEST_IMG.test(icon)) { + // node.icon is an image url. Prepend imagePath + icon = + icon.charAt(0) === "/" + ? icon + : (opts.imagePath || "") + icon; + ares.push( + "<img src='" + + icon + + "' class='fancytree-icon'" + + iconTooltip + + " alt='' />" + ); + } else { + ares.push( + "<span " + + role + + " class='fancytree-custom-icon " + + icon + + "'" + + iconTooltip + + "></span>" + ); + } + } else if (icon.text) { + ares.push( + "<span " + + role + + " class='fancytree-custom-icon " + + (icon.addClass || "") + + "'" + + iconTooltip + + ">" + + FT.escapeHtml(icon.text) + + "</span>" + ); + } else if (icon.html) { + ares.push( + "<span " + + role + + " class='fancytree-custom-icon " + + (icon.addClass || "") + + "'" + + iconTooltip + + ">" + + icon.html + + "</span>" + ); + } else { + // standard icon: theme css will take care of this + ares.push( + "<span " + + role + + " class='fancytree-icon'" + + iconTooltip + + "></span>" + ); + } + } + // Node title + nodeTitle = ""; + if (opts.renderTitle) { + nodeTitle = + opts.renderTitle.call( + tree, + { type: "renderTitle" }, + ctx + ) || ""; + } + if (!nodeTitle) { + tooltip = FT.evalOption("tooltip", node, node, opts, null); + if (tooltip === true) { + tooltip = node.title; + } + // if( node.tooltip ) { + // tooltip = node.tooltip; + // } else if ( opts.tooltip ) { + // tooltip = opts.tooltip === true ? node.title : opts.tooltip.call(tree, node); + // } + tooltip = tooltip + ? " title='" + _escapeTooltip(tooltip) + "'" + : ""; + tabindex = opts.titlesTabbable ? " tabindex='0'" : ""; + + nodeTitle = + "<span class='fancytree-title'" + + tooltip + + tabindex + + ">" + + (opts.escapeTitles + ? FT.escapeHtml(node.title) + : node.title) + + "</span>"; + } + ares.push(nodeTitle); + // Note: this will trigger focusout, if node had the focus + //$(node.span).html(ares.join("")); // it will cleanup the jQuery data currently associated with SPAN (if any), but it executes more slowly + node.span.innerHTML = ares.join(""); + // Update CSS classes + this.nodeRenderStatus(ctx); + if (opts.enhanceTitle) { + ctx.$title = $(">span.fancytree-title", node.span); + nodeTitle = + opts.enhanceTitle.call( + tree, + { type: "enhanceTitle" }, + ctx + ) || ""; + } + }, + /** Update element classes according to node state. + * @param {EventData} ctx + */ + nodeRenderStatus: function (ctx) { + // Set classes for current status + var $ariaElem, + node = ctx.node, + tree = ctx.tree, + opts = ctx.options, + // nodeContainer = node[tree.nodeContainerAttrName], + hasChildren = node.hasChildren(), + isLastSib = node.isLastSibling(), + aria = opts.aria, + cn = opts._classNames, + cnList = [], + statusElem = node[tree.statusClassPropName]; + + if (!statusElem || tree._enableUpdate === false) { + // if this function is called for an unrendered node, ignore it (will be updated on nect render anyway) + return; + } + if (aria) { + $ariaElem = $(node.tr || node.li); + } + // Build a list of class names that we will add to the node <span> + cnList.push(cn.node); + if (tree.activeNode === node) { + cnList.push(cn.active); + // $(">span.fancytree-title", statusElem).attr("tabindex", "0"); + // tree.$container.removeAttr("tabindex"); + // }else{ + // $(">span.fancytree-title", statusElem).removeAttr("tabindex"); + // tree.$container.attr("tabindex", "0"); + } + if (tree.focusNode === node) { + cnList.push(cn.focused); + } + if (node.expanded) { + cnList.push(cn.expanded); + } + if (aria) { + if (hasChildren === false) { + $ariaElem.removeAttr("aria-expanded"); + } else { + $ariaElem.attr("aria-expanded", Boolean(node.expanded)); + } + } + if (node.folder) { + cnList.push(cn.folder); + } + if (hasChildren !== false) { + cnList.push(cn.hasChildren); + } + // TODO: required? + if (isLastSib) { + cnList.push(cn.lastsib); + } + if (node.lazy && node.children == null) { + cnList.push(cn.lazy); + } + if (node.partload) { + cnList.push(cn.partload); + } + if (node.partsel) { + cnList.push(cn.partsel); + } + if (FT.evalOption("unselectable", node, node, opts, false)) { + cnList.push(cn.unselectable); + } + if (node._isLoading) { + cnList.push(cn.loading); + } + if (node._error) { + cnList.push(cn.error); + } + if (node.statusNodeType) { + cnList.push(cn.statusNodePrefix + node.statusNodeType); + } + if (node.selected) { + cnList.push(cn.selected); + if (aria) { + $ariaElem.attr("aria-selected", true); + } + } else if (aria) { + $ariaElem.attr("aria-selected", false); + } + if (node.extraClasses) { + cnList.push(node.extraClasses); + } + // IE6 doesn't correctly evaluate multiple class names, + // so we create combined class names that can be used in the CSS + if (hasChildren === false) { + cnList.push( + cn.combinedExpanderPrefix + "n" + (isLastSib ? "l" : "") + ); + } else { + cnList.push( + cn.combinedExpanderPrefix + + (node.expanded ? "e" : "c") + + (node.lazy && node.children == null ? "d" : "") + + (isLastSib ? "l" : "") + ); + } + cnList.push( + cn.combinedIconPrefix + + (node.expanded ? "e" : "c") + + (node.folder ? "f" : "") + ); + // node.span.className = cnList.join(" "); + statusElem.className = cnList.join(" "); + + // TODO: we should not set this in the <span> tag also, if we set it here: + // Maybe most (all) of the classes should be set in LI instead of SPAN? + if (node.li) { + // #719: we have to consider that there may be already other classes: + $(node.li).toggleClass(cn.lastsib, isLastSib); + } + }, + /** Activate node. + * flag defaults to true. + * If flag is true, the node is activated (must be a synchronous operation) + * If flag is false, the node is deactivated (must be a synchronous operation) + * @param {EventData} ctx + * @param {boolean} [flag=true] + * @param {object} [opts] additional options. Defaults to {noEvents: false, noFocus: false} + * @returns {$.Promise} + */ + nodeSetActive: function (ctx, flag, callOpts) { + // Handle user click / [space] / [enter], according to clickFolderMode. + callOpts = callOpts || {}; + var subCtx, + node = ctx.node, + tree = ctx.tree, + opts = ctx.options, + noEvents = callOpts.noEvents === true, + noFocus = callOpts.noFocus === true, + scroll = callOpts.scrollIntoView !== false, + isActive = node === tree.activeNode; + + // flag defaults to true + flag = flag !== false; + // node.debug("nodeSetActive", flag); + + if (isActive === flag) { + // Nothing to do + return _getResolvedPromise(node); + } + // #1042: don't scroll between mousedown/-up when clicking an embedded link + if ( + scroll && + ctx.originalEvent && + $(ctx.originalEvent.target).is("a,:checkbox") + ) { + node.info("Not scrolling while clicking an embedded link."); + scroll = false; + } + if ( + flag && + !noEvents && + this._triggerNodeEvent( + "beforeActivate", + node, + ctx.originalEvent + ) === false + ) { + // Callback returned false + return _getRejectedPromise(node, ["rejected"]); + } + if (flag) { + if (tree.activeNode) { + _assert( + tree.activeNode !== node, + "node was active (inconsistency)" + ); + subCtx = $.extend({}, ctx, { node: tree.activeNode }); + tree.nodeSetActive(subCtx, false); + _assert( + tree.activeNode === null, + "deactivate was out of sync?" + ); + } + + if (opts.activeVisible) { + // If no focus is set (noFocus: true) and there is no focused node, this node is made visible. + // scroll = noFocus && tree.focusNode == null; + // #863: scroll by default (unless `scrollIntoView: false` was passed) + node.makeVisible({ scrollIntoView: scroll }); + } + tree.activeNode = node; + tree.nodeRenderStatus(ctx); + if (!noFocus) { + tree.nodeSetFocus(ctx); + } + if (!noEvents) { + tree._triggerNodeEvent( + "activate", + node, + ctx.originalEvent + ); + } + } else { + _assert( + tree.activeNode === node, + "node was not active (inconsistency)" + ); + tree.activeNode = null; + this.nodeRenderStatus(ctx); + if (!noEvents) { + ctx.tree._triggerNodeEvent( + "deactivate", + node, + ctx.originalEvent + ); + } + } + return _getResolvedPromise(node); + }, + /** Expand or collapse node, return Deferred.promise. + * + * @param {EventData} ctx + * @param {boolean} [flag=true] + * @param {object} [opts] additional options. Defaults to `{noAnimation: false, noEvents: false}` + * @returns {$.Promise} The deferred will be resolved as soon as the (lazy) + * data was retrieved, rendered, and the expand animation finished. + */ + nodeSetExpanded: function (ctx, flag, callOpts) { + callOpts = callOpts || {}; + var _afterLoad, + dfd, + i, + l, + parents, + prevAC, + node = ctx.node, + tree = ctx.tree, + opts = ctx.options, + noAnimation = callOpts.noAnimation === true, + noEvents = callOpts.noEvents === true; + + // flag defaults to true + flag = flag !== false; + + // node.debug("nodeSetExpanded(" + flag + ")"); + + if ($(node.li).hasClass(opts._classNames.animating)) { + node.warn( + "setExpanded(" + flag + ") while animating: ignored." + ); + return _getRejectedPromise(node, ["recursion"]); + } + + if ((node.expanded && flag) || (!node.expanded && !flag)) { + // Nothing to do + // node.debug("nodeSetExpanded(" + flag + "): nothing to do"); + return _getResolvedPromise(node); + } else if (flag && !node.lazy && !node.hasChildren()) { + // Prevent expanding of empty nodes + // return _getRejectedPromise(node, ["empty"]); + return _getResolvedPromise(node); + } else if (!flag && node.getLevel() < opts.minExpandLevel) { + // Prevent collapsing locked levels + return _getRejectedPromise(node, ["locked"]); + } else if ( + !noEvents && + this._triggerNodeEvent( + "beforeExpand", + node, + ctx.originalEvent + ) === false + ) { + // Callback returned false + return _getRejectedPromise(node, ["rejected"]); + } + // If this node inside a collpased node, no animation and scrolling is needed + if (!noAnimation && !node.isVisible()) { + noAnimation = callOpts.noAnimation = true; + } + + dfd = new $.Deferred(); + + // Auto-collapse mode: collapse all siblings + if (flag && !node.expanded && opts.autoCollapse) { + parents = node.getParentList(false, true); + prevAC = opts.autoCollapse; + try { + opts.autoCollapse = false; + for (i = 0, l = parents.length; i < l; i++) { + // TODO: should return promise? + this._callHook( + "nodeCollapseSiblings", + parents[i], + callOpts + ); + } + } finally { + opts.autoCollapse = prevAC; + } + } + // Trigger expand/collapse after expanding + dfd.done(function () { + var lastChild = node.getLastChild(); + + if ( + flag && + opts.autoScroll && + !noAnimation && + lastChild && + tree._enableUpdate + ) { + // Scroll down to last child, but keep current node visible + lastChild + .scrollIntoView(true, { topNode: node }) + .always(function () { + if (!noEvents) { + ctx.tree._triggerNodeEvent( + flag ? "expand" : "collapse", + ctx + ); + } + }); + } else { + if (!noEvents) { + ctx.tree._triggerNodeEvent( + flag ? "expand" : "collapse", + ctx + ); + } + } + }); + // vvv Code below is executed after loading finished: + _afterLoad = function (callback) { + var cn = opts._classNames, + isVisible, + isExpanded, + effect = opts.toggleEffect; + + node.expanded = flag; + tree._callHook( + "treeStructureChanged", + ctx, + flag ? "expand" : "collapse" + ); + // Create required markup, but make sure the top UL is hidden, so we + // can animate later + tree._callHook("nodeRender", ctx, false, false, true); + + // Hide children, if node is collapsed + if (node.ul) { + isVisible = node.ul.style.display !== "none"; + isExpanded = !!node.expanded; + if (isVisible === isExpanded) { + node.warn( + "nodeSetExpanded: UL.style.display already set" + ); + } else if (!effect || noAnimation) { + node.ul.style.display = + node.expanded || !parent ? "" : "none"; + } else { + // The UI toggle() effect works with the ext-wide extension, + // while jQuery.animate() has problems when the title span + // has position: absolute. + // Since jQuery UI 1.12, the blind effect requires the parent + // element to have 'position: relative'. + // See #716, #717 + $(node.li).addClass(cn.animating); // #717 + + if (_isFunction($(node.ul)[effect.effect])) { + // tree.debug( "use jquery." + effect.effect + " method" ); + $(node.ul)[effect.effect]({ + duration: effect.duration, + always: function () { + // node.debug("fancytree-animating end: " + node.li.className); + $(this).removeClass(cn.animating); // #716 + $(node.li).removeClass(cn.animating); // #717 + callback(); + }, + }); + } else { + // The UI toggle() effect works with the ext-wide extension, + // while jQuery.animate() has problems when the title span + // has positon: absolute. + // Since jQuery UI 1.12, the blind effect requires the parent + // element to have 'position: relative'. + // See #716, #717 + // tree.debug("use specified effect (" + effect.effect + ") with the jqueryui.toggle method"); + + // try to stop an animation that might be already in progress + $(node.ul).stop(true, true); //< does not work after resetLazy has been called for a node whose animation wasn't complete and effect was "blind" + + // dirty fix to remove a defunct animation (effect: "blind") after resetLazy has been called + $(node.ul) + .parent() + .find(".ui-effects-placeholder") + .remove(); + + $(node.ul).toggle( + effect.effect, + effect.options, + effect.duration, + function () { + // node.debug("fancytree-animating end: " + node.li.className); + $(this).removeClass(cn.animating); // #716 + $(node.li).removeClass(cn.animating); // #717 + callback(); + } + ); + } + return; + } + } + callback(); + }; + // ^^^ Code above is executed after loading finshed. + + // Load lazy nodes, if any. Then continue with _afterLoad() + if (flag && node.lazy && node.hasChildren() === undefined) { + // node.debug("nodeSetExpanded: load start..."); + node.load() + .done(function () { + // node.debug("nodeSetExpanded: load done"); + if (dfd.notifyWith) { + // requires jQuery 1.6+ + dfd.notifyWith(node, ["loaded"]); + } + _afterLoad(function () { + dfd.resolveWith(node); + }); + }) + .fail(function (errMsg) { + _afterLoad(function () { + dfd.rejectWith(node, [ + "load failed (" + errMsg + ")", + ]); + }); + }); + /* + var source = tree._triggerNodeEvent("lazyLoad", node, ctx.originalEvent); + _assert(typeof source !== "boolean", "lazyLoad event must return source in data.result"); + node.debug("nodeSetExpanded: load start..."); + this._callHook("nodeLoadChildren", ctx, source).done(function(){ + node.debug("nodeSetExpanded: load done"); + if(dfd.notifyWith){ // requires jQuery 1.6+ + dfd.notifyWith(node, ["loaded"]); + } + _afterLoad.call(tree); + }).fail(function(errMsg){ + dfd.rejectWith(node, ["load failed (" + errMsg + ")"]); + }); + */ + } else { + _afterLoad(function () { + dfd.resolveWith(node); + }); + } + // node.debug("nodeSetExpanded: returns"); + return dfd.promise(); + }, + /** Focus or blur this node. + * @param {EventData} ctx + * @param {boolean} [flag=true] + */ + nodeSetFocus: function (ctx, flag) { + // ctx.node.debug("nodeSetFocus(" + flag + ")"); + var ctx2, + tree = ctx.tree, + node = ctx.node, + opts = tree.options, + // et = ctx.originalEvent && ctx.originalEvent.type, + isInput = ctx.originalEvent + ? $(ctx.originalEvent.target).is(":input") + : false; + + flag = flag !== false; + + // (node || tree).debug("nodeSetFocus(" + flag + "), event: " + et + ", isInput: "+ isInput); + // Blur previous node if any + if (tree.focusNode) { + if (tree.focusNode === node && flag) { + // node.debug("nodeSetFocus(" + flag + "): nothing to do"); + return; + } + ctx2 = $.extend({}, ctx, { node: tree.focusNode }); + tree.focusNode = null; + this._triggerNodeEvent("blur", ctx2); + this._callHook("nodeRenderStatus", ctx2); + } + // Set focus to container and node + if (flag) { + if (!this.hasFocus()) { + node.debug("nodeSetFocus: forcing container focus"); + this._callHook("treeSetFocus", ctx, true, { + calledByNode: true, + }); + } + node.makeVisible({ scrollIntoView: false }); + tree.focusNode = node; + if (opts.titlesTabbable) { + if (!isInput) { + // #621 + $(node.span).find(".fancytree-title").focus(); + } + } + if (opts.aria) { + // Set active descendant to node's span ID (create one, if needed) + $(tree.$container).attr( + "aria-activedescendant", + $(node.tr || node.li) + .uniqueId() + .attr("id") + ); + // "ftal_" + opts.idPrefix + node.key); + } + // $(node.span).find(".fancytree-title").focus(); + this._triggerNodeEvent("focus", ctx); + + // determine if we have focus on or inside tree container + var hasFancytreeFocus = + document.activeElement === tree.$container.get(0) || + $(document.activeElement, tree.$container).length >= 1; + + if (!hasFancytreeFocus) { + // We cannot set KB focus to a node, so use the tree container + // #563, #570: IE scrolls on every call to .focus(), if the container + // is partially outside the viewport. So do it only, when absolutely + // necessary. + $(tree.$container).focus(); + } + + // if( opts.autoActivate ){ + // tree.nodeSetActive(ctx, true); + // } + if (opts.autoScroll) { + node.scrollIntoView(); + } + this._callHook("nodeRenderStatus", ctx); + } + }, + /** (De)Select node, return new status (sync). + * + * @param {EventData} ctx + * @param {boolean} [flag=true] + * @param {object} [opts] additional options. Defaults to {noEvents: false, + * propagateDown: null, propagateUp: null, + * callback: null, + * } + * @returns {boolean} previous status + */ + nodeSetSelected: function (ctx, flag, callOpts) { + callOpts = callOpts || {}; + var node = ctx.node, + tree = ctx.tree, + opts = ctx.options, + noEvents = callOpts.noEvents === true, + parent = node.parent; + + // flag defaults to true + flag = flag !== false; + + // node.debug("nodeSetSelected(" + flag + ")", ctx); + + // Cannot (de)select unselectable nodes directly (only by propagation or + // by setting the `.selected` property) + if (FT.evalOption("unselectable", node, node, opts, false)) { + return; + } + + // Remember the user's intent, in case down -> up propagation prevents + // applying it to node.selected + node._lastSelectIntent = flag; // Confusing use of '!' + + // Nothing to do? + if (!!node.selected === flag) { + if (opts.selectMode === 3 && node.partsel && !flag) { + // If propagation prevented selecting this node last time, we still + // want to allow to apply setSelected(false) now + } else { + return flag; + } + } + + if ( + !noEvents && + this._triggerNodeEvent( + "beforeSelect", + node, + ctx.originalEvent + ) === false + ) { + return !!node.selected; + } + if (flag && opts.selectMode === 1) { + // single selection mode (we don't uncheck all tree nodes, for performance reasons) + if (tree.lastSelectedNode) { + tree.lastSelectedNode.setSelected(false); + } + node.selected = flag; + } else if ( + opts.selectMode === 3 && + parent && + !parent.radiogroup && + !node.radiogroup + ) { + // multi-hierarchical selection mode + node.selected = flag; + node.fixSelection3AfterClick(callOpts); + } else if (parent && parent.radiogroup) { + node.visitSiblings(function (n) { + n._changeSelectStatusAttrs(flag && n === node); + }, true); + } else { + // default: selectMode: 2, multi selection mode + node.selected = flag; + } + this.nodeRenderStatus(ctx); + tree.lastSelectedNode = flag ? node : null; + if (!noEvents) { + tree._triggerNodeEvent("select", ctx); + } + }, + /** Show node status (ok, loading, error, nodata) using styles and a dummy child node. + * + * @param {EventData} ctx + * @param status + * @param message + * @param details + * @since 2.3 + */ + nodeSetStatus: function (ctx, status, message, details) { + var node = ctx.node, + tree = ctx.tree; + + function _clearStatusNode() { + // Remove dedicated dummy node, if any + var firstChild = node.children ? node.children[0] : null; + if (firstChild && firstChild.isStatusNode()) { + try { + // I've seen exceptions here with loadKeyPath... + if (node.ul) { + node.ul.removeChild(firstChild.li); + firstChild.li = null; // avoid leaks (DT issue 215) + } + } catch (e) {} + if (node.children.length === 1) { + node.children = []; + } else { + node.children.shift(); + } + tree._callHook( + "treeStructureChanged", + ctx, + "clearStatusNode" + ); + } + } + function _setStatusNode(data, type) { + // Create/modify the dedicated dummy node for 'loading...' or + // 'error!' status. (only called for direct child of the invisible + // system root) + var firstChild = node.children ? node.children[0] : null; + if (firstChild && firstChild.isStatusNode()) { + $.extend(firstChild, data); + firstChild.statusNodeType = type; + tree._callHook("nodeRenderTitle", firstChild); + } else { + node._setChildren([data]); + tree._callHook( + "treeStructureChanged", + ctx, + "setStatusNode" + ); + node.children[0].statusNodeType = type; + tree.render(); + } + return node.children[0]; + } + + switch (status) { + case "ok": + _clearStatusNode(); + node._isLoading = false; + node._error = null; + node.renderStatus(); + break; + case "loading": + if (!node.parent) { + _setStatusNode( + { + title: + tree.options.strings.loading + + (message ? " (" + message + ")" : ""), + // icon: true, // needed for 'loding' icon + checkbox: false, + tooltip: details, + }, + status + ); + } + node._isLoading = true; + node._error = null; + node.renderStatus(); + break; + case "error": + _setStatusNode( + { + title: + tree.options.strings.loadError + + (message ? " (" + message + ")" : ""), + // icon: false, + checkbox: false, + tooltip: details, + }, + status + ); + node._isLoading = false; + node._error = { message: message, details: details }; + node.renderStatus(); + break; + case "nodata": + _setStatusNode( + { + title: message || tree.options.strings.noData, + // icon: false, + checkbox: false, + tooltip: details, + }, + status + ); + node._isLoading = false; + node._error = null; + node.renderStatus(); + break; + default: + $.error("invalid node status " + status); + } + }, + /** + * + * @param {EventData} ctx + */ + nodeToggleExpanded: function (ctx) { + return this.nodeSetExpanded(ctx, !ctx.node.expanded); + }, + /** + * @param {EventData} ctx + */ + nodeToggleSelected: function (ctx) { + var node = ctx.node, + flag = !node.selected; + + // In selectMode: 3 this node may be unselected+partsel, even if + // setSelected(true) was called before, due to `unselectable` children. + // In this case, we now toggle as `setSelected(false)` + if ( + node.partsel && + !node.selected && + node._lastSelectIntent === true + ) { + flag = false; + node.selected = true; // so it is not considered 'nothing to do' + } + node._lastSelectIntent = flag; + return this.nodeSetSelected(ctx, flag); + }, + /** Remove all nodes. + * @param {EventData} ctx + */ + treeClear: function (ctx) { + var tree = ctx.tree; + tree.activeNode = null; + tree.focusNode = null; + tree.$div.find(">ul.fancytree-container").empty(); + // TODO: call destructors and remove reference loops + tree.rootNode.children = null; + tree._callHook("treeStructureChanged", ctx, "clear"); + }, + /** Widget was created (called only once, even it re-initialized). + * @param {EventData} ctx + */ + treeCreate: function (ctx) {}, + /** Widget was destroyed. + * @param {EventData} ctx + */ + treeDestroy: function (ctx) { + this.$div.find(">ul.fancytree-container").remove(); + if (this.$source) { + this.$source.removeClass("fancytree-helper-hidden"); + } + }, + /** Widget was (re-)initialized. + * @param {EventData} ctx + */ + treeInit: function (ctx) { + var tree = ctx.tree, + opts = tree.options; + + //this.debug("Fancytree.treeInit()"); + // Add container to the TAB chain + // See http://www.w3.org/TR/wai-aria-practices/#focus_activedescendant + // #577: Allow to set tabindex to "0", "-1" and "" + tree.$container.attr("tabindex", opts.tabindex); + + // Copy some attributes to tree.data + $.each(TREE_ATTRS, function (i, attr) { + if (opts[attr] !== undefined) { + tree.info("Move option " + attr + " to tree"); + tree[attr] = opts[attr]; + delete opts[attr]; + } + }); + + if (opts.checkboxAutoHide) { + tree.$container.addClass("fancytree-checkbox-auto-hide"); + } + if (opts.rtl) { + tree.$container + .attr("DIR", "RTL") + .addClass("fancytree-rtl"); + } else { + tree.$container + .removeAttr("DIR") + .removeClass("fancytree-rtl"); + } + if (opts.aria) { + tree.$container.attr("role", "tree"); + if (opts.selectMode !== 1) { + tree.$container.attr("aria-multiselectable", true); + } + } + this.treeLoad(ctx); + }, + /** Parse Fancytree from source, as configured in the options. + * @param {EventData} ctx + * @param {object} [source] optional new source (use last data otherwise) + */ + treeLoad: function (ctx, source) { + var metaData, + type, + $ul, + tree = ctx.tree, + $container = ctx.widget.element, + dfd, + // calling context for root node + rootCtx = $.extend({}, ctx, { node: this.rootNode }); + + if (tree.rootNode.children) { + this.treeClear(ctx); + } + source = source || this.options.source; + + if (!source) { + type = $container.data("type") || "html"; + switch (type) { + case "html": + // There should be an embedded `<ul>` with initial nodes, + // but another `<ul class='fancytree-container'>` is appended + // to the tree's <div> on startup anyway. + $ul = $container + .find(">ul") + .not(".fancytree-container") + .first(); + + if ($ul.length) { + $ul.addClass( + "ui-fancytree-source fancytree-helper-hidden" + ); + source = $.ui.fancytree.parseHtml($ul); + // allow to init tree.data.foo from <ul data-foo=''> + this.data = $.extend( + this.data, + _getElementDataAsDict($ul) + ); + } else { + FT.warn( + "No `source` option was passed and container does not contain `<ul>`: assuming `source: []`." + ); + source = []; + } + break; + case "json": + source = $.parseJSON($container.text()); + // $container already contains the <ul>, but we remove the plain (json) text + // $container.empty(); + $container + .contents() + .filter(function () { + return this.nodeType === 3; + }) + .remove(); + if ($.isPlainObject(source)) { + // We got {foo: 'abc', children: [...]} + _assert( + _isArray(source.children), + "if an object is passed as source, it must contain a 'children' array (all other properties are added to 'tree.data')" + ); + metaData = source; + source = source.children; + delete metaData.children; + // Copy some attributes to tree.data + $.each(TREE_ATTRS, function (i, attr) { + if (metaData[attr] !== undefined) { + tree[attr] = metaData[attr]; + delete metaData[attr]; + } + }); + // Copy extra properties to tree.data.foo + $.extend(tree.data, metaData); + } + break; + default: + $.error("Invalid data-type: " + type); + } + } else if (typeof source === "string") { + // TODO: source is an element ID + $.error("Not implemented"); + } + + // preInit is fired when the widget markup is created, but nodes + // not yet loaded + tree._triggerTreeEvent("preInit", null); + + // Trigger fancytreeinit after nodes have been loaded + dfd = this.nodeLoadChildren(rootCtx, source) + .done(function () { + tree._callHook( + "treeStructureChanged", + ctx, + "loadChildren" + ); + tree.render(); + if (ctx.options.selectMode === 3) { + tree.rootNode.fixSelection3FromEndNodes(); + } + if (tree.activeNode && tree.options.activeVisible) { + tree.activeNode.makeVisible(); + } + tree._triggerTreeEvent("init", null, { status: true }); + }) + .fail(function () { + tree.render(); + tree._triggerTreeEvent("init", null, { status: false }); + }); + return dfd; + }, + /** Node was inserted into or removed from the tree. + * @param {EventData} ctx + * @param {boolean} add + * @param {FancytreeNode} node + */ + treeRegisterNode: function (ctx, add, node) { + ctx.tree._callHook( + "treeStructureChanged", + ctx, + add ? "addNode" : "removeNode" + ); + }, + /** Widget got focus. + * @param {EventData} ctx + * @param {boolean} [flag=true] + */ + treeSetFocus: function (ctx, flag, callOpts) { + var targetNode; + + flag = flag !== false; + + // this.debug("treeSetFocus(" + flag + "), callOpts: ", callOpts, this.hasFocus()); + // this.debug(" focusNode: " + this.focusNode); + // this.debug(" activeNode: " + this.activeNode); + if (flag !== this.hasFocus()) { + this._hasFocus = flag; + if (!flag && this.focusNode) { + // Node also looses focus if widget blurs + this.focusNode.setFocus(false); + } else if (flag && (!callOpts || !callOpts.calledByNode)) { + $(this.$container).focus(); + } + this.$container.toggleClass("fancytree-treefocus", flag); + this._triggerTreeEvent(flag ? "focusTree" : "blurTree"); + if (flag && !this.activeNode) { + // #712: Use last mousedowned node ('click' event fires after focusin) + targetNode = + this._lastMousedownNode || this.getFirstChild(); + if (targetNode) { + targetNode.setFocus(); + } + } + } + }, + /** Widget option was set using `$().fancytree("option", "KEY", VALUE)`. + * + * Note: `key` may reference a nested option, e.g. 'dnd5.scroll'. + * In this case `value`contains the complete, modified `dnd5` option hash. + * We can check for changed values like + * if( value.scroll !== tree.options.dnd5.scroll ) {...} + * + * @param {EventData} ctx + * @param {string} key option name + * @param {any} value option value + */ + treeSetOption: function (ctx, key, value) { + var tree = ctx.tree, + callDefault = true, + callCreate = false, + callRender = false; + + switch (key) { + case "aria": + case "checkbox": + case "icon": + case "minExpandLevel": + case "tabindex": + // tree._callHook("treeCreate", tree); + callCreate = true; + callRender = true; + break; + case "checkboxAutoHide": + tree.$container.toggleClass( + "fancytree-checkbox-auto-hide", + !!value + ); + break; + case "escapeTitles": + case "tooltip": + callRender = true; + break; + case "rtl": + if (value === false) { + tree.$container + .removeAttr("DIR") + .removeClass("fancytree-rtl"); + } else { + tree.$container + .attr("DIR", "RTL") + .addClass("fancytree-rtl"); + } + callRender = true; + break; + case "source": + callDefault = false; + tree._callHook("treeLoad", tree, value); + callRender = true; + break; + } + tree.debug( + "set option " + + key + + "=" + + value + + " <" + + typeof value + + ">" + ); + if (callDefault) { + if (this.widget._super) { + // jQuery UI 1.9+ + this.widget._super.call(this.widget, key, value); + } else { + // jQuery UI <= 1.8, we have to manually invoke the _setOption method from the base widget + $.Widget.prototype._setOption.call( + this.widget, + key, + value + ); + } + } + if (callCreate) { + tree._callHook("treeCreate", tree); + } + if (callRender) { + tree.render(true, false); // force, not-deep + } + }, + /** A Node was added, removed, moved, or it's visibility changed. + * @param {EventData} ctx + */ + treeStructureChanged: function (ctx, type) {}, + } + ); + + /******************************************************************************* + * jQuery UI widget boilerplate + */ + + /** + * The plugin (derrived from [jQuery.Widget](http://api.jqueryui.com/jQuery.widget/)). + * + * **Note:** + * These methods implement the standard jQuery UI widget API. + * It is recommended to use methods of the {Fancytree} instance instead + * + * @example + * // DEPRECATED: Access jQuery UI widget methods and members: + * var tree = $("#tree").fancytree("getTree"); + * var node = $("#tree").fancytree("getActiveNode"); + * + * // RECOMMENDED: Use the Fancytree object API + * var tree = $.ui.fancytree.getTree("#tree"); + * var node = tree.getActiveNode(); + * + * // or you may already have stored the tree instance upon creation: + * import {createTree, version} from 'jquery.fancytree' + * const tree = createTree('#tree', { ... }); + * var node = tree.getActiveNode(); + * + * @see {Fancytree_Static#getTree} + * @deprecated Use methods of the {Fancytree} instance instead + * @mixin Fancytree_Widget + */ + + $.widget( + "ui.fancytree", + /** @lends Fancytree_Widget# */ + { + /**These options will be used as defaults + * @type {FancytreeOptions} + */ + options: { + activeVisible: true, + ajax: { + type: "GET", + cache: false, // false: Append random '_' argument to the request url to prevent caching. + // timeout: 0, // >0: Make sure we get an ajax error if server is unreachable + dataType: "json", // Expect json format and pass json object to callbacks. + }, + aria: true, + autoActivate: true, + autoCollapse: false, + autoScroll: false, + checkbox: false, + clickFolderMode: 4, + copyFunctionsToData: false, + debugLevel: null, // 0..4 (null: use global setting $.ui.fancytree.debugLevel) + disabled: false, // TODO: required anymore? + enableAspx: 42, // TODO: this is truethy, but distinguishable from true: default will change to false in the future + escapeTitles: false, + extensions: [], + focusOnSelect: false, + generateIds: false, + icon: true, + idPrefix: "ft_", + keyboard: true, + keyPathSeparator: "/", + minExpandLevel: 1, + nodata: true, // (bool, string, or callback) display message, when no data available + quicksearch: false, + rtl: false, + scrollOfs: { top: 0, bottom: 0 }, + scrollParent: null, + selectMode: 2, + strings: { + loading: "Loading...", // … would be escaped when escapeTitles is true + loadError: "Load error!", + moreData: "More...", + noData: "No data.", + }, + tabindex: "0", + titlesTabbable: false, + toggleEffect: { effect: "slideToggle", duration: 200 }, //< "toggle" or "slideToggle" to use jQuery instead of jQueryUI for toggleEffect animation + tooltip: false, + treeId: null, + _classNames: { + active: "fancytree-active", + animating: "fancytree-animating", + combinedExpanderPrefix: "fancytree-exp-", + combinedIconPrefix: "fancytree-ico-", + error: "fancytree-error", + expanded: "fancytree-expanded", + focused: "fancytree-focused", + folder: "fancytree-folder", + hasChildren: "fancytree-has-children", + lastsib: "fancytree-lastsib", + lazy: "fancytree-lazy", + loading: "fancytree-loading", + node: "fancytree-node", + partload: "fancytree-partload", + partsel: "fancytree-partsel", + radio: "fancytree-radio", + selected: "fancytree-selected", + statusNodePrefix: "fancytree-statusnode-", + unselectable: "fancytree-unselectable", + }, + // events + lazyLoad: null, + postProcess: null, + }, + _deprecationWarning: function (name) { + var tree = this.tree; + + if (tree && tree.options.debugLevel >= 3) { + tree.warn( + "$().fancytree('" + + name + + "') is deprecated (see https://wwwendt.de/tech/fancytree/doc/jsdoc/Fancytree_Widget.html" + ); + } + }, + /* Set up the widget, Called on first $().fancytree() */ + _create: function () { + this.tree = new Fancytree(this); + + this.$source = + this.source || this.element.data("type") === "json" + ? this.element + : this.element.find(">ul").first(); + // Subclass Fancytree instance with all enabled extensions + var extension, + extName, + i, + opts = this.options, + extensions = opts.extensions, + base = this.tree; + + for (i = 0; i < extensions.length; i++) { + extName = extensions[i]; + extension = $.ui.fancytree._extensions[extName]; + if (!extension) { + $.error( + "Could not apply extension '" + + extName + + "' (it is not registered, did you forget to include it?)" + ); + } + // Add extension options as tree.options.EXTENSION + // _assert(!this.tree.options[extName], "Extension name must not exist as option name: " + extName); + + // console.info("extend " + extName, extension.options, this.tree.options[extName]) + // issue #876: we want to replace custom array-options, not merge them + this.tree.options[extName] = _simpleDeepMerge( + {}, + extension.options, + this.tree.options[extName] + ); + // this.tree.options[extName] = $.extend(true, {}, extension.options, this.tree.options[extName]); + + // console.info("extend " + extName + " =>", this.tree.options[extName]) + // console.info("extend " + extName + " org default =>", extension.options) + + // Add a namespace tree.ext.EXTENSION, to hold instance data + _assert( + this.tree.ext[extName] === undefined, + "Extension name must not exist as Fancytree.ext attribute: '" + + extName + + "'" + ); + // this.tree[extName] = extension; + this.tree.ext[extName] = {}; + // Subclass Fancytree methods using proxies. + _subclassObject(this.tree, base, extension, extName); + // current extension becomes base for the next extension + base = extension; + } + // + if (opts.icons !== undefined) { + // 2015-11-16 + if (opts.icon === true) { + this.tree.warn( + "'icons' tree option is deprecated since v2.14.0: use 'icon' instead" + ); + opts.icon = opts.icons; + } else { + $.error( + "'icons' tree option is deprecated since v2.14.0: use 'icon' only instead" + ); + } + } + if (opts.iconClass !== undefined) { + // 2015-11-16 + if (opts.icon) { + $.error( + "'iconClass' tree option is deprecated since v2.14.0: use 'icon' only instead" + ); + } else { + this.tree.warn( + "'iconClass' tree option is deprecated since v2.14.0: use 'icon' instead" + ); + opts.icon = opts.iconClass; + } + } + if (opts.tabbable !== undefined) { + // 2016-04-04 + opts.tabindex = opts.tabbable ? "0" : "-1"; + this.tree.warn( + "'tabbable' tree option is deprecated since v2.17.0: use 'tabindex='" + + opts.tabindex + + "' instead" + ); + } + // + this.tree._callHook("treeCreate", this.tree); + // Note: 'fancytreecreate' event is fired by widget base class + // this.tree._triggerTreeEvent("create"); + }, + + /* Called on every $().fancytree() */ + _init: function () { + this.tree._callHook("treeInit", this.tree); + // TODO: currently we call bind after treeInit, because treeInit + // might change tree.$container. + // It would be better, to move event binding into hooks altogether + this._bind(); + }, + + /* Use the _setOption method to respond to changes to options. */ + _setOption: function (key, value) { + return this.tree._callHook( + "treeSetOption", + this.tree, + key, + value + ); + }, + + /** Use the destroy method to clean up any modifications your widget has made to the DOM */ + _destroy: function () { + this._unbind(); + this.tree._callHook("treeDestroy", this.tree); + // In jQuery UI 1.8, you must invoke the destroy method from the base widget + // $.Widget.prototype.destroy.call(this); + // TODO: delete tree and nodes to make garbage collect easier? + // TODO: In jQuery UI 1.9 and above, you would define _destroy instead of destroy and not call the base method + }, + + // ------------------------------------------------------------------------- + + /* Remove all event handlers for our namespace */ + _unbind: function () { + var ns = this.tree._ns; + this.element.off(ns); + this.tree.$container.off(ns); + $(document).off(ns); + }, + /* Add mouse and kyboard handlers to the container */ + _bind: function () { + var self = this, + opts = this.options, + tree = this.tree, + ns = tree._ns; + // selstartEvent = ( $.support.selectstart ? "selectstart" : "mousedown" ) + + // Remove all previuous handlers for this tree + this._unbind(); + + //alert("keydown" + ns + "foc=" + tree.hasFocus() + tree.$container); + // tree.debug("bind events; container: ", tree.$container); + tree.$container + .on("focusin" + ns + " focusout" + ns, function (event) { + var node = FT.getNode(event), + flag = event.type === "focusin"; + + if (!flag && node && $(event.target).is("a")) { + // #764 + node.debug( + "Ignored focusout on embedded <a> element." + ); + return; + } + // tree.treeOnFocusInOut.call(tree, event); + // tree.debug("Tree container got event " + event.type, node, event, FT.getEventTarget(event)); + if (flag) { + if (tree._getExpiringValue("focusin")) { + // #789: IE 11 may send duplicate focusin events + tree.debug("Ignored double focusin."); + return; + } + tree._setExpiringValue("focusin", true, 50); + + if (!node) { + // #789: IE 11 may send focusin before mousdown(?) + node = tree._getExpiringValue("mouseDownNode"); + if (node) { + tree.debug( + "Reconstruct mouse target for focusin from recent event." + ); + } + } + } + if (node) { + // For example clicking into an <input> that is part of a node + tree._callHook( + "nodeSetFocus", + tree._makeHookContext(node, event), + flag + ); + } else { + if ( + tree.tbody && + $(event.target).parents( + "table.fancytree-container > thead" + ).length + ) { + // #767: ignore events in the table's header + tree.debug( + "Ignore focus event outside table body.", + event + ); + } else { + tree._callHook("treeSetFocus", tree, flag); + } + } + }) + .on( + "selectstart" + ns, + "span.fancytree-title", + function (event) { + // prevent mouse-drags to select text ranges + // tree.debug("<span title> got event " + event.type); + event.preventDefault(); + } + ) + .on("keydown" + ns, function (event) { + // TODO: also bind keyup and keypress + // tree.debug("got event " + event.type + ", hasFocus:" + tree.hasFocus()); + // if(opts.disabled || opts.keyboard === false || !tree.hasFocus() ){ + if (opts.disabled || opts.keyboard === false) { + return true; + } + var res, + node = tree.focusNode, // node may be null + ctx = tree._makeHookContext(node || tree, event), + prevPhase = tree.phase; + + try { + tree.phase = "userEvent"; + // If a 'fancytreekeydown' handler returns false, skip the default + // handling (implemented by tree.nodeKeydown()). + if (node) { + res = tree._triggerNodeEvent( + "keydown", + node, + event + ); + } else { + res = tree._triggerTreeEvent("keydown", event); + } + if (res === "preventNav") { + res = true; // prevent keyboard navigation, but don't prevent default handling of embedded input controls + } else if (res !== false) { + res = tree._callHook("nodeKeydown", ctx); + } + return res; + } finally { + tree.phase = prevPhase; + } + }) + .on("mousedown" + ns, function (event) { + var et = FT.getEventTarget(event); + // self.tree.debug("event(" + event.type + "): node: ", et.node); + // #712: Store the clicked node, so we can use it when we get a focusin event + // ('click' event fires after focusin) + // tree.debug("event(" + event.type + "): node: ", et.node); + tree._lastMousedownNode = et ? et.node : null; + // #789: Store the node also for a short period, so we can use it + // in a *resulting* focusin event + tree._setExpiringValue( + "mouseDownNode", + tree._lastMousedownNode + ); + }) + .on("click" + ns + " dblclick" + ns, function (event) { + if (opts.disabled) { + return true; + } + var ctx, + et = FT.getEventTarget(event), + node = et.node, + tree = self.tree, + prevPhase = tree.phase; + + // self.tree.debug("event(" + event.type + "): node: ", node); + if (!node) { + return true; // Allow bubbling of other events + } + ctx = tree._makeHookContext(node, event); + // self.tree.debug("event(" + event.type + "): node: ", node); + try { + tree.phase = "userEvent"; + switch (event.type) { + case "click": + ctx.targetType = et.type; + if (node.isPagingNode()) { + return ( + tree._triggerNodeEvent( + "clickPaging", + ctx, + event + ) === true + ); + } + return tree._triggerNodeEvent( + "click", + ctx, + event + ) === false + ? false + : tree._callHook("nodeClick", ctx); + case "dblclick": + ctx.targetType = et.type; + return tree._triggerNodeEvent( + "dblclick", + ctx, + event + ) === false + ? false + : tree._callHook("nodeDblclick", ctx); + } + } finally { + tree.phase = prevPhase; + } + }); + }, + /** Return the active node or null. + * @returns {FancytreeNode} + * @deprecated Use methods of the Fancytree instance instead (<a href="Fancytree_Widget.html">example above</a>). + */ + getActiveNode: function () { + this._deprecationWarning("getActiveNode"); + return this.tree.activeNode; + }, + /** Return the matching node or null. + * @param {string} key + * @returns {FancytreeNode} + * @deprecated Use methods of the Fancytree instance instead (<a href="Fancytree_Widget.html">example above</a>). + */ + getNodeByKey: function (key) { + this._deprecationWarning("getNodeByKey"); + return this.tree.getNodeByKey(key); + }, + /** Return the invisible system root node. + * @returns {FancytreeNode} + * @deprecated Use methods of the Fancytree instance instead (<a href="Fancytree_Widget.html">example above</a>). + */ + getRootNode: function () { + this._deprecationWarning("getRootNode"); + return this.tree.rootNode; + }, + /** Return the current tree instance. + * @returns {Fancytree} + * @deprecated Use `$.ui.fancytree.getTree()` instead (<a href="Fancytree_Widget.html">example above</a>). + */ + getTree: function () { + this._deprecationWarning("getTree"); + return this.tree; + }, + } + ); + + // $.ui.fancytree was created by the widget factory. Create a local shortcut: + FT = $.ui.fancytree; + + /** + * Static members in the `$.ui.fancytree` namespace. + * This properties and methods can be accessed without instantiating a concrete + * Fancytree instance. + * + * @example + * // Access static members: + * var node = $.ui.fancytree.getNode(element); + * alert($.ui.fancytree.version); + * + * @mixin Fancytree_Static + */ + $.extend( + $.ui.fancytree, + /** @lends Fancytree_Static# */ + { + /** Version number `"MAJOR.MINOR.PATCH"` + * @type {string} */ + version: "2.38.3", // Set to semver by 'grunt release' + /** @type {string} + * @description `"production" for release builds` */ + buildType: "production", // Set to 'production' by 'grunt build' + /** @type {int} + * @description 0: silent .. 5: verbose (default: 3 for release builds). */ + debugLevel: 3, // Set to 3 by 'grunt build' + // Used by $.ui.fancytree.debug() and as default for tree.options.debugLevel + + _nextId: 1, + _nextNodeKey: 1, + _extensions: {}, + // focusTree: null, + + /** Expose class object as `$.ui.fancytree._FancytreeClass`. + * Useful to extend `$.ui.fancytree._FancytreeClass.prototype`. + * @type {Fancytree} + */ + _FancytreeClass: Fancytree, + /** Expose class object as $.ui.fancytree._FancytreeNodeClass + * Useful to extend `$.ui.fancytree._FancytreeNodeClass.prototype`. + * @type {FancytreeNode} + */ + _FancytreeNodeClass: FancytreeNode, + /* Feature checks to provide backwards compatibility */ + jquerySupports: { + // http://jqueryui.com/upgrade-guide/1.9/#deprecated-offset-option-merged-into-my-and-at + positionMyOfs: isVersionAtLeast($.ui.version, 1, 9), + }, + /** Throw an error if condition fails (debug method). + * @param {boolean} cond + * @param {string} msg + */ + assert: function (cond, msg) { + return _assert(cond, msg); + }, + /** Create a new Fancytree instance on a target element. + * + * @param {Element | jQueryObject | string} el Target DOM element or selector + * @param {FancytreeOptions} [opts] Fancytree options + * @returns {Fancytree} new tree instance + * @example + * var tree = $.ui.fancytree.createTree("#tree", { + * source: {url: "my/webservice"} + * }); // Create tree for this matching element + * + * @since 2.25 + */ + createTree: function (el, opts) { + var $tree = $(el).fancytree(opts); + return FT.getTree($tree); + }, + /** Return a function that executes *fn* at most every *timeout* ms. + * @param {integer} timeout + * @param {function} fn + * @param {boolean} [invokeAsap=false] + * @param {any} [ctx] + */ + debounce: function (timeout, fn, invokeAsap, ctx) { + var timer; + if (arguments.length === 3 && typeof invokeAsap !== "boolean") { + ctx = invokeAsap; + invokeAsap = false; + } + return function () { + var args = arguments; + ctx = ctx || this; + // eslint-disable-next-line no-unused-expressions + invokeAsap && !timer && fn.apply(ctx, args); + clearTimeout(timer); + timer = setTimeout(function () { + // eslint-disable-next-line no-unused-expressions + invokeAsap || fn.apply(ctx, args); + timer = null; + }, timeout); + }; + }, + /** Write message to console if debugLevel >= 4 + * @param {string} msg + */ + debug: function (msg) { + if ($.ui.fancytree.debugLevel >= 4) { + consoleApply("log", arguments); + } + }, + /** Write error message to console if debugLevel >= 1. + * @param {string} msg + */ + error: function (msg) { + if ($.ui.fancytree.debugLevel >= 1) { + consoleApply("error", arguments); + } + }, + /** Convert `<`, `>`, `&`, `"`, `'`, and `/` to the equivalent entities. + * + * @param {string} s + * @returns {string} + */ + escapeHtml: function (s) { + return ("" + s).replace(REX_HTML, function (s) { + return ENTITY_MAP[s]; + }); + }, + /** Make jQuery.position() arguments backwards compatible, i.e. if + * jQuery UI version <= 1.8, convert + * { my: "left+3 center", at: "left bottom", of: $target } + * to + * { my: "left center", at: "left bottom", of: $target, offset: "3 0" } + * + * See http://jqueryui.com/upgrade-guide/1.9/#deprecated-offset-option-merged-into-my-and-at + * and http://jsfiddle.net/mar10/6xtu9a4e/ + * + * @param {object} opts + * @returns {object} the (potentially modified) original opts hash object + */ + fixPositionOptions: function (opts) { + if (opts.offset || ("" + opts.my + opts.at).indexOf("%") >= 0) { + $.error( + "expected new position syntax (but '%' is not supported)" + ); + } + if (!$.ui.fancytree.jquerySupports.positionMyOfs) { + var // parse 'left+3 center' into ['left+3 center', 'left', '+3', 'center', undefined] + myParts = /(\w+)([+-]?\d+)?\s+(\w+)([+-]?\d+)?/.exec( + opts.my + ), + atParts = /(\w+)([+-]?\d+)?\s+(\w+)([+-]?\d+)?/.exec( + opts.at + ), + // convert to numbers + dx = + (myParts[2] ? +myParts[2] : 0) + + (atParts[2] ? +atParts[2] : 0), + dy = + (myParts[4] ? +myParts[4] : 0) + + (atParts[4] ? +atParts[4] : 0); + + opts = $.extend({}, opts, { + // make a copy and overwrite + my: myParts[1] + " " + myParts[3], + at: atParts[1] + " " + atParts[3], + }); + if (dx || dy) { + opts.offset = "" + dx + " " + dy; + } + } + return opts; + }, + /** Return a {node: FancytreeNode, type: TYPE} object for a mouse event. + * + * @param {Event} event Mouse event, e.g. click, ... + * @returns {object} Return a {node: FancytreeNode, type: TYPE} object + * TYPE: 'title' | 'prefix' | 'expander' | 'checkbox' | 'icon' | undefined + */ + getEventTarget: function (event) { + var $target, + tree, + tcn = event && event.target ? event.target.className : "", + res = { node: this.getNode(event.target), type: undefined }; + // We use a fast version of $(res.node).hasClass() + // See http://jsperf.com/test-for-classname/2 + if (/\bfancytree-title\b/.test(tcn)) { + res.type = "title"; + } else if (/\bfancytree-expander\b/.test(tcn)) { + res.type = + res.node.hasChildren() === false + ? "prefix" + : "expander"; + // }else if( /\bfancytree-checkbox\b/.test(tcn) || /\bfancytree-radio\b/.test(tcn) ){ + } else if (/\bfancytree-checkbox\b/.test(tcn)) { + res.type = "checkbox"; + } else if (/\bfancytree(-custom)?-icon\b/.test(tcn)) { + res.type = "icon"; + } else if (/\bfancytree-node\b/.test(tcn)) { + // Somewhere near the title + res.type = "title"; + } else if (event && event.target) { + $target = $(event.target); + if ($target.is("ul[role=group]")) { + // #nnn: Clicking right to a node may hit the surrounding UL + tree = res.node && res.node.tree; + (tree || FT).debug("Ignoring click on outer UL."); + res.node = null; + } else if ($target.closest(".fancytree-title").length) { + // #228: clicking an embedded element inside a title + res.type = "title"; + } else if ($target.closest(".fancytree-checkbox").length) { + // E.g. <svg> inside checkbox span + res.type = "checkbox"; + } else if ($target.closest(".fancytree-expander").length) { + res.type = "expander"; + } + } + return res; + }, + /** Return a string describing the affected node region for a mouse event. + * + * @param {Event} event Mouse event, e.g. click, mousemove, ... + * @returns {string} 'title' | 'prefix' | 'expander' | 'checkbox' | 'icon' | undefined + */ + getEventTargetType: function (event) { + return this.getEventTarget(event).type; + }, + /** Return a FancytreeNode instance from element, event, or jQuery object. + * + * @param {Element | jQueryObject | Event} el + * @returns {FancytreeNode} matching node or null + */ + getNode: function (el) { + if (el instanceof FancytreeNode) { + return el; // el already was a FancytreeNode + } else if (el instanceof $) { + el = el[0]; // el was a jQuery object: use the DOM element + } else if (el.originalEvent !== undefined) { + el = el.target; // el was an Event + } + while (el) { + if (el.ftnode) { + return el.ftnode; + } + el = el.parentNode; + } + return null; + }, + /** Return a Fancytree instance, from element, index, event, or jQueryObject. + * + * @param {Element | jQueryObject | Event | integer | string} [el] + * @returns {Fancytree} matching tree or null + * @example + * $.ui.fancytree.getTree(); // Get first Fancytree instance on page + * $.ui.fancytree.getTree(1); // Get second Fancytree instance on page + * $.ui.fancytree.getTree(event); // Get tree for this mouse- or keyboard event + * $.ui.fancytree.getTree("foo"); // Get tree for this `opts.treeId` + * $.ui.fancytree.getTree("#tree"); // Get tree for this matching element + * + * @since 2.13 + */ + getTree: function (el) { + var widget, + orgEl = el; + + if (el instanceof Fancytree) { + return el; // el already was a Fancytree + } + if (el === undefined) { + el = 0; // get first tree + } + if (typeof el === "number") { + el = $(".fancytree-container").eq(el); // el was an integer: return nth instance + } else if (typeof el === "string") { + // `el` may be a treeId or a selector: + el = $("#ft-id-" + orgEl).eq(0); + if (!el.length) { + el = $(orgEl).eq(0); // el was a selector: use first match + } + } else if ( + el instanceof Element || + el instanceof HTMLDocument + ) { + el = $(el); + } else if (el instanceof $) { + el = el.eq(0); // el was a jQuery object: use the first + } else if (el.originalEvent !== undefined) { + el = $(el.target); // el was an Event + } + // el is a jQuery object wit one element here + el = el.closest(":ui-fancytree"); + widget = el.data("ui-fancytree") || el.data("fancytree"); // the latter is required by jQuery <= 1.8 + return widget ? widget.tree : null; + }, + /** Return an option value that has a default, but may be overridden by a + * callback or a node instance attribute. + * + * Evaluation sequence: + * + * If `tree.options.<optionName>` is a callback that returns something, use that. + * Else if `node.<optionName>` is defined, use that. + * Else if `tree.options.<optionName>` is a value, use that. + * Else use `defaultValue`. + * + * @param {string} optionName name of the option property (on node and tree) + * @param {FancytreeNode} node passed to the callback + * @param {object} nodeObject where to look for the local option property, e.g. `node` or `node.data` + * @param {object} treeOption where to look for the tree option, e.g. `tree.options` or `tree.options.dnd5` + * @param {any} [defaultValue] + * @returns {any} + * + * @example + * // Check for node.foo, tree,options.foo(), and tree.options.foo: + * $.ui.fancytree.evalOption("foo", node, node, tree.options); + * // Check for node.data.bar, tree,options.qux.bar(), and tree.options.qux.bar: + * $.ui.fancytree.evalOption("bar", node, node.data, tree.options.qux); + * + * @since 2.22 + */ + evalOption: function ( + optionName, + node, + nodeObject, + treeOptions, + defaultValue + ) { + var ctx, + res, + tree = node.tree, + treeOpt = treeOptions[optionName], + nodeOpt = nodeObject[optionName]; + + if (_isFunction(treeOpt)) { + ctx = { + node: node, + tree: tree, + widget: tree.widget, + options: tree.widget.options, + typeInfo: tree.types[node.type] || {}, + }; + res = treeOpt.call(tree, { type: optionName }, ctx); + if (res == null) { + res = nodeOpt; + } + } else { + res = nodeOpt == null ? treeOpt : nodeOpt; + } + if (res == null) { + res = defaultValue; // no option set at all: return default + } + return res; + }, + /** Set expander, checkbox, or node icon, supporting string and object format. + * + * @param {Element | jQueryObject} span + * @param {string} baseClass + * @param {string | object} icon + * @since 2.27 + */ + setSpanIcon: function (span, baseClass, icon) { + var $span = $(span); + + if (typeof icon === "string") { + $span.attr("class", baseClass + " " + icon); + } else { + // support object syntax: { text: ligature, addClasse: classname } + if (icon.text) { + $span.text("" + icon.text); + } else if (icon.html) { + span.innerHTML = icon.html; + } + $span.attr( + "class", + baseClass + " " + (icon.addClass || "") + ); + } + }, + /** Convert a keydown or mouse event to a canonical string like 'ctrl+a', + * 'ctrl+shift+f2', 'shift+leftdblclick'. + * + * This is especially handy for switch-statements in event handlers. + * + * @param {event} + * @returns {string} + * + * @example + + switch( $.ui.fancytree.eventToString(event) ) { + case "-": + tree.nodeSetExpanded(ctx, false); + break; + case "shift+return": + tree.nodeSetActive(ctx, true); + break; + case "down": + res = node.navigate(event.which, activate); + break; + default: + handled = false; + } + if( handled ){ + event.preventDefault(); + } + */ + eventToString: function (event) { + // Poor-man's hotkeys. See here for a complete implementation: + // https://github.com/jeresig/jquery.hotkeys + var which = event.which, + et = event.type, + s = []; + + if (event.altKey) { + s.push("alt"); + } + if (event.ctrlKey) { + s.push("ctrl"); + } + if (event.metaKey) { + s.push("meta"); + } + if (event.shiftKey) { + s.push("shift"); + } + + if (et === "click" || et === "dblclick") { + s.push(MOUSE_BUTTONS[event.button] + et); + } else if (et === "wheel") { + s.push(et); + } else if (!IGNORE_KEYCODES[which]) { + s.push( + SPECIAL_KEYCODES[which] || + String.fromCharCode(which).toLowerCase() + ); + } + return s.join("+"); + }, + /** Write message to console if debugLevel >= 3 + * @param {string} msg + */ + info: function (msg) { + if ($.ui.fancytree.debugLevel >= 3) { + consoleApply("info", arguments); + } + }, + /* @deprecated: use eventToString(event) instead. + */ + keyEventToString: function (event) { + this.warn( + "keyEventToString() is deprecated: use eventToString()" + ); + return this.eventToString(event); + }, + /** Return a wrapped handler method, that provides `this._super`. + * + * @example + // Implement `opts.createNode` event to add the 'draggable' attribute + $.ui.fancytree.overrideMethod(ctx.options, "createNode", function(event, data) { + // Default processing if any + this._super.apply(this, arguments); + // Add 'draggable' attribute + data.node.span.draggable = true; + }); + * + * @param {object} instance + * @param {string} methodName + * @param {function} handler + * @param {object} [context] optional context + */ + overrideMethod: function (instance, methodName, handler, context) { + var prevSuper, + _super = instance[methodName] || $.noop; + + instance[methodName] = function () { + var self = context || this; + + try { + prevSuper = self._super; + self._super = _super; + return handler.apply(self, arguments); + } finally { + self._super = prevSuper; + } + }; + }, + /** + * Parse tree data from HTML <ul> markup + * + * @param {jQueryObject} $ul + * @returns {NodeData[]} + */ + parseHtml: function ($ul) { + var classes, + className, + extraClasses, + i, + iPos, + l, + tmp, + tmp2, + $children = $ul.find(">li"), + children = []; + + $children.each(function () { + var allData, + lowerCaseAttr, + $li = $(this), + $liSpan = $li.find(">span", this).first(), + $liA = $liSpan.length ? null : $li.find(">a").first(), + d = { tooltip: null, data: {} }; + + if ($liSpan.length) { + d.title = $liSpan.html(); + } else if ($liA && $liA.length) { + // If a <li><a> tag is specified, use it literally and extract href/target. + d.title = $liA.html(); + d.data.href = $liA.attr("href"); + d.data.target = $liA.attr("target"); + d.tooltip = $liA.attr("title"); + } else { + // If only a <li> tag is specified, use the trimmed string up to + // the next child <ul> tag. + d.title = $li.html(); + iPos = d.title.search(/<ul/i); + if (iPos >= 0) { + d.title = d.title.substring(0, iPos); + } + } + d.title = _trim(d.title); + + // Make sure all fields exist + for (i = 0, l = CLASS_ATTRS.length; i < l; i++) { + d[CLASS_ATTRS[i]] = undefined; + } + // Initialize to `true`, if class is set and collect extraClasses + classes = this.className.split(" "); + extraClasses = []; + for (i = 0, l = classes.length; i < l; i++) { + className = classes[i]; + if (CLASS_ATTR_MAP[className]) { + d[className] = true; + } else { + extraClasses.push(className); + } + } + d.extraClasses = extraClasses.join(" "); + + // Parse node options from ID, title and class attributes + tmp = $li.attr("title"); + if (tmp) { + d.tooltip = tmp; // overrides <a title='...'> + } + tmp = $li.attr("id"); + if (tmp) { + d.key = tmp; + } + // Translate hideCheckbox -> checkbox:false + if ($li.attr("hideCheckbox")) { + d.checkbox = false; + } + // Add <li data-NAME='...'> as node.data.NAME + allData = _getElementDataAsDict($li); + if (allData && !$.isEmptyObject(allData)) { + // #507: convert data-hidecheckbox (lower case) to hideCheckbox + for (lowerCaseAttr in NODE_ATTR_LOWERCASE_MAP) { + if (_hasProp(allData, lowerCaseAttr)) { + allData[ + NODE_ATTR_LOWERCASE_MAP[lowerCaseAttr] + ] = allData[lowerCaseAttr]; + delete allData[lowerCaseAttr]; + } + } + // #56: Allow to set special node.attributes from data-... + for (i = 0, l = NODE_ATTRS.length; i < l; i++) { + tmp = NODE_ATTRS[i]; + tmp2 = allData[tmp]; + if (tmp2 != null) { + delete allData[tmp]; + d[tmp] = tmp2; + } + } + // All other data-... goes to node.data... + $.extend(d.data, allData); + } + // Recursive reading of child nodes, if LI tag contains an UL tag + $ul = $li.find(">ul").first(); + if ($ul.length) { + d.children = $.ui.fancytree.parseHtml($ul); + } else { + d.children = d.lazy ? undefined : null; + } + children.push(d); + // FT.debug("parse ", d, children); + }); + return children; + }, + /** Add Fancytree extension definition to the list of globally available extensions. + * + * @param {object} definition + */ + registerExtension: function (definition) { + _assert( + definition.name != null, + "extensions must have a `name` property." + ); + _assert( + definition.version != null, + "extensions must have a `version` property." + ); + $.ui.fancytree._extensions[definition.name] = definition; + }, + /** Replacement for the deprecated `jQuery.trim()`. + * + * @param {string} text + */ + trim: _trim, + /** Inverse of escapeHtml(). + * + * @param {string} s + * @returns {string} + */ + unescapeHtml: function (s) { + var e = document.createElement("div"); + e.innerHTML = s; + return e.childNodes.length === 0 + ? "" + : e.childNodes[0].nodeValue; + }, + /** Write warning message to console if debugLevel >= 2. + * @param {string} msg + */ + warn: function (msg) { + if ($.ui.fancytree.debugLevel >= 2) { + consoleApply("warn", arguments); + } + }, + } + ); + + // Value returned by `require('jquery.fancytree')` + return $.ui.fancytree; +}); // End of closure + + +/*! Extension 'jquery.fancytree.childcounter.js' */// Extending Fancytree +// =================== +// +// See also the [live demo](https://wwWendt.de/tech/fancytree/demo/sample-ext-childcounter.html) of this code. +// +// Every extension should have a comment header containing some information +// about the author, copyright and licensing. Also a pointer to the latest +// source code. +// Prefix with `/*!` so the comment is not removed by the minifier. + +/*! + * jquery.fancytree.childcounter.js + * + * Add a child counter bubble to tree nodes. + * (Extension module for jquery.fancytree.js: https://github.com/mar10/fancytree/) + * + * Copyright (c) 2008-2023, Martin Wendt (https://wwWendt.de) + * + * Released under the MIT license + * https://github.com/mar10/fancytree/wiki/LicenseInfo + * + * @version 2.38.3 + * @date 2023-02-01T20:52:50Z + */ + +// To keep the global namespace clean, we wrap everything in a closure. +// The UMD wrapper pattern defines the dependencies on jQuery and the +// Fancytree core module, and makes sure that we can use the `require()` +// syntax with package loaders. + +(function (factory) { + if (typeof define === "function" && define.amd) { + // AMD. Register as an anonymous module. + define(["jquery", "./jquery.fancytree"], factory); + } else if (typeof module === "object" && module.exports) { + // Node/CommonJS + require("./jquery.fancytree"); + module.exports = factory(require("jquery")); + } else { + // Browser globals + factory(jQuery); + } +})(function ($) { + // Consider to use [strict mode](http://ejohn.org/blog/ecmascript-5-strict-mode-json-and-more/) + "use strict"; + + // The [coding guidelines](http://contribute.jquery.org/style-guide/js/) + // require jshint /eslint compliance. + // But for this sample, we want to allow unused variables for demonstration purpose. + + /*eslint-disable no-unused-vars */ + + // Adding methods + // -------------- + + // New member functions can be added to the `Fancytree` class. + // This function will be available for every tree instance: + // + // var tree = $.ui.fancytree.getTree("#tree"); + // tree.countSelected(false); + + $.ui.fancytree._FancytreeClass.prototype.countSelected = function ( + topOnly + ) { + var tree = this, + treeOptions = tree.options; + + return tree.getSelectedNodes(topOnly).length; + }; + + // The `FancytreeNode` class can also be easily extended. This would be called + // like + // node.updateCounters(); + // + // It is also good practice to add a docstring comment. + /** + * [ext-childcounter] Update counter badges for `node` and its parents. + * May be called in the `loadChildren` event, to update parents of lazy loaded + * nodes. + * @alias FancytreeNode#updateCounters + * @requires jquery.fancytree.childcounters.js + */ + $.ui.fancytree._FancytreeNodeClass.prototype.updateCounters = function () { + var node = this, + $badge = $("span.fancytree-childcounter", node.span), + extOpts = node.tree.options.childcounter, + count = node.countChildren(extOpts.deep); + + node.data.childCounter = count; + if ( + (count || !extOpts.hideZeros) && + (!node.isExpanded() || !extOpts.hideExpanded) + ) { + if (!$badge.length) { + $badge = $("<span class='fancytree-childcounter'/>").appendTo( + $( + "span.fancytree-icon,span.fancytree-custom-icon", + node.span + ) + ); + } + $badge.text(count); + } else { + $badge.remove(); + } + if (extOpts.deep && !node.isTopLevel() && !node.isRootNode()) { + node.parent.updateCounters(); + } + }; + + // Finally, we can extend the widget API and create functions that are called + // like so: + // + // $("#tree").fancytree("widgetMethod1", "abc"); + + $.ui.fancytree.prototype.widgetMethod1 = function (arg1) { + var tree = this.tree; + return arg1; + }; + + // Register a Fancytree extension + // ------------------------------ + // A full blown extension, extension is available for all trees and can be + // enabled like so (see also the [live demo](https://wwWendt.de/tech/fancytree/demo/sample-ext-childcounter.html)): + // + // <script src="../src/jquery.fancytree.js"></script> + // <script src="../src/jquery.fancytree.childcounter.js"></script> + // ... + // + // $("#tree").fancytree({ + // extensions: ["childcounter"], + // childcounter: { + // hideExpanded: true + // }, + // ... + // }); + // + + /* 'childcounter' extension */ + $.ui.fancytree.registerExtension({ + // Every extension must be registered by a unique name. + name: "childcounter", + // Version information should be compliant with [semver](http://semver.org) + version: "2.38.3", + + // Extension specific options and their defaults. + // This options will be available as `tree.options.childcounter.hideExpanded` + + options: { + deep: true, + hideZeros: true, + hideExpanded: false, + }, + + // Attributes other than `options` (or functions) can be defined here, and + // will be added to the tree.ext.EXTNAME namespace, in this case `tree.ext.childcounter.foo`. + // They can also be accessed as `this._local.foo` from within the extension + // methods. + foo: 42, + + // Local functions are prefixed with an underscore '_'. + // Callable as `this._local._appendCounter()`. + + _appendCounter: function (bar) { + var tree = this; + }, + + // **Override virtual methods for this extension.** + // + // Fancytree implements a number of 'hook methods', prefixed by 'node...' or 'tree...'. + // with a `ctx` argument (see [EventData](https://wwWendt.de/tech/fancytree/doc/jsdoc/global.html#EventData) + // for details) and an extended calling context:<br> + // `this` : the Fancytree instance<br> + // `this._local`: the namespace that contains extension attributes and private methods (same as this.ext.EXTNAME)<br> + // `this._super`: the virtual function that was overridden (member of previous extension or Fancytree) + // + // See also the [complete list of available hook functions](https://wwWendt.de/tech/fancytree/doc/jsdoc/Fancytree_Hooks.html). + + /* Init */ + // `treeInit` is triggered when a tree is initalized. We can set up classes or + // bind event handlers here... + treeInit: function (ctx) { + var tree = this, // same as ctx.tree, + opts = ctx.options, + extOpts = ctx.options.childcounter; + // Optionally check for dependencies with other extensions + /* this._requireExtension("glyph", false, false); */ + // Call the base implementation + this._superApply(arguments); + // Add a class to the tree container + this.$container.addClass("fancytree-ext-childcounter"); + }, + + // Destroy this tree instance (we only call the default implementation, so + // this method could as well be omitted). + + treeDestroy: function (ctx) { + this._superApply(arguments); + }, + + // Overload the `renderTitle` hook, to append a counter badge + nodeRenderTitle: function (ctx, title) { + var node = ctx.node, + extOpts = ctx.options.childcounter, + count = + node.data.childCounter == null + ? node.countChildren(extOpts.deep) + : +node.data.childCounter; + // Let the base implementation render the title + // We use `_super()` instead of `_superApply()` here, since it is a little bit + // more performant when called often + this._super(ctx, title); + // Append a counter badge + if ( + (count || !extOpts.hideZeros) && + (!node.isExpanded() || !extOpts.hideExpanded) + ) { + $( + "span.fancytree-icon,span.fancytree-custom-icon", + node.span + ).append( + $("<span class='fancytree-childcounter'/>").text(count) + ); + } + }, + // Overload the `setExpanded` hook, so the counters are updated + nodeSetExpanded: function (ctx, flag, callOpts) { + var tree = ctx.tree, + node = ctx.node; + // Let the base implementation expand/collapse the node, then redraw the title + // after the animation has finished + return this._superApply(arguments).always(function () { + tree.nodeRenderTitle(ctx); + }); + }, + + // End of extension definition + }); + // Value returned by `require('jquery.fancytree..')` + return $.ui.fancytree; +}); // End of closure + + +/*! Extension 'jquery.fancytree.clones.js' *//*! + * + * jquery.fancytree.clones.js + * Support faster lookup of nodes by key and shared ref-ids. + * (Extension module for jquery.fancytree.js: https://github.com/mar10/fancytree/) + * + * Copyright (c) 2008-2023, Martin Wendt (https://wwWendt.de) + * + * Released under the MIT license + * https://github.com/mar10/fancytree/wiki/LicenseInfo + * + * @version 2.38.3 + * @date 2023-02-01T20:52:50Z + */ + +(function (factory) { + if (typeof define === "function" && define.amd) { + // AMD. Register as an anonymous module. + define(["jquery", "./jquery.fancytree"], factory); + } else if (typeof module === "object" && module.exports) { + // Node/CommonJS + require("./jquery.fancytree"); + module.exports = factory(require("jquery")); + } else { + // Browser globals + factory(jQuery); + } +})(function ($) { + "use strict"; + + /******************************************************************************* + * Private functions and variables + */ + + var _assert = $.ui.fancytree.assert; + + /* Return first occurrence of member from array. */ + function _removeArrayMember(arr, elem) { + // TODO: use Array.indexOf for IE >= 9 + var i; + for (i = arr.length - 1; i >= 0; i--) { + if (arr[i] === elem) { + arr.splice(i, 1); + return true; + } + } + return false; + } + + /** + * JS Implementation of MurmurHash3 (r136) (as of May 20, 2011) + * + * @author <a href="mailto:gary.court@gmail.com">Gary Court</a> + * @see http://github.com/garycourt/murmurhash-js + * @author <a href="mailto:aappleby@gmail.com">Austin Appleby</a> + * @see http://sites.google.com/site/murmurhash/ + * + * @param {string} key ASCII only + * @param {boolean} [asString=false] + * @param {number} seed Positive integer only + * @return {number} 32-bit positive integer hash + */ + function hashMurmur3(key, asString, seed) { + /*eslint-disable no-bitwise */ + var h1b, + k1, + remainder = key.length & 3, + bytes = key.length - remainder, + h1 = seed, + c1 = 0xcc9e2d51, + c2 = 0x1b873593, + i = 0; + + while (i < bytes) { + k1 = + (key.charCodeAt(i) & 0xff) | + ((key.charCodeAt(++i) & 0xff) << 8) | + ((key.charCodeAt(++i) & 0xff) << 16) | + ((key.charCodeAt(++i) & 0xff) << 24); + ++i; + + k1 = + ((k1 & 0xffff) * c1 + ((((k1 >>> 16) * c1) & 0xffff) << 16)) & + 0xffffffff; + k1 = (k1 << 15) | (k1 >>> 17); + k1 = + ((k1 & 0xffff) * c2 + ((((k1 >>> 16) * c2) & 0xffff) << 16)) & + 0xffffffff; + + h1 ^= k1; + h1 = (h1 << 13) | (h1 >>> 19); + h1b = + ((h1 & 0xffff) * 5 + ((((h1 >>> 16) * 5) & 0xffff) << 16)) & + 0xffffffff; + h1 = + (h1b & 0xffff) + + 0x6b64 + + ((((h1b >>> 16) + 0xe654) & 0xffff) << 16); + } + + k1 = 0; + + switch (remainder) { + case 3: + k1 ^= (key.charCodeAt(i + 2) & 0xff) << 16; + // fall through + case 2: + k1 ^= (key.charCodeAt(i + 1) & 0xff) << 8; + // fall through + case 1: + k1 ^= key.charCodeAt(i) & 0xff; + + k1 = + ((k1 & 0xffff) * c1 + + ((((k1 >>> 16) * c1) & 0xffff) << 16)) & + 0xffffffff; + k1 = (k1 << 15) | (k1 >>> 17); + k1 = + ((k1 & 0xffff) * c2 + + ((((k1 >>> 16) * c2) & 0xffff) << 16)) & + 0xffffffff; + h1 ^= k1; + } + + h1 ^= key.length; + + h1 ^= h1 >>> 16; + h1 = + ((h1 & 0xffff) * 0x85ebca6b + + ((((h1 >>> 16) * 0x85ebca6b) & 0xffff) << 16)) & + 0xffffffff; + h1 ^= h1 >>> 13; + h1 = + ((h1 & 0xffff) * 0xc2b2ae35 + + ((((h1 >>> 16) * 0xc2b2ae35) & 0xffff) << 16)) & + 0xffffffff; + h1 ^= h1 >>> 16; + + if (asString) { + // Convert to 8 digit hex string + return ("0000000" + (h1 >>> 0).toString(16)).substr(-8); + } + return h1 >>> 0; + /*eslint-enable no-bitwise */ + } + + /* + * Return a unique key for node by calculating the hash of the parents refKey-list. + */ + function calcUniqueKey(node) { + var key, + h1, + path = $.map(node.getParentList(false, true), function (e) { + return e.refKey || e.key; + }); + + path = path.join("/"); + // 32-bit has a high probability of collisions, so we pump up to 64-bit + // https://security.stackexchange.com/q/209882/207588 + + h1 = hashMurmur3(path, true); + key = "id_" + h1 + hashMurmur3(h1 + path, true); + + return key; + } + + /** + * [ext-clones] Return a list of clone-nodes (i.e. same refKey) or null. + * @param {boolean} [includeSelf=false] + * @returns {FancytreeNode[] | null} + * + * @alias FancytreeNode#getCloneList + * @requires jquery.fancytree.clones.js + */ + $.ui.fancytree._FancytreeNodeClass.prototype.getCloneList = function ( + includeSelf + ) { + var key, + tree = this.tree, + refList = tree.refMap[this.refKey] || null, + keyMap = tree.keyMap; + + if (refList) { + key = this.key; + // Convert key list to node list + if (includeSelf) { + refList = $.map(refList, function (val) { + return keyMap[val]; + }); + } else { + refList = $.map(refList, function (val) { + return val === key ? null : keyMap[val]; + }); + if (refList.length < 1) { + refList = null; + } + } + } + return refList; + }; + + /** + * [ext-clones] Return true if this node has at least another clone with same refKey. + * @returns {boolean} + * + * @alias FancytreeNode#isClone + * @requires jquery.fancytree.clones.js + */ + $.ui.fancytree._FancytreeNodeClass.prototype.isClone = function () { + var refKey = this.refKey || null, + refList = (refKey && this.tree.refMap[refKey]) || null; + return !!(refList && refList.length > 1); + }; + + /** + * [ext-clones] Update key and/or refKey for an existing node. + * @param {string} key + * @param {string} refKey + * @returns {boolean} + * + * @alias FancytreeNode#reRegister + * @requires jquery.fancytree.clones.js + */ + $.ui.fancytree._FancytreeNodeClass.prototype.reRegister = function ( + key, + refKey + ) { + key = key == null ? null : "" + key; + refKey = refKey == null ? null : "" + refKey; + // this.debug("reRegister", key, refKey); + + var tree = this.tree, + prevKey = this.key, + prevRefKey = this.refKey, + keyMap = tree.keyMap, + refMap = tree.refMap, + refList = refMap[prevRefKey] || null, + // curCloneKeys = refList ? node.getCloneList(true), + modified = false; + + // Key has changed: update all references + if (key != null && key !== this.key) { + if (keyMap[key]) { + $.error( + "[ext-clones] reRegister(" + + key + + "): already exists: " + + this + ); + } + // Update keyMap + delete keyMap[prevKey]; + keyMap[key] = this; + // Update refMap + if (refList) { + refMap[prevRefKey] = $.map(refList, function (e) { + return e === prevKey ? key : e; + }); + } + this.key = key; + modified = true; + } + + // refKey has changed + if (refKey != null && refKey !== this.refKey) { + // Remove previous refKeys + if (refList) { + if (refList.length === 1) { + delete refMap[prevRefKey]; + } else { + refMap[prevRefKey] = $.map(refList, function (e) { + return e === prevKey ? null : e; + }); + } + } + // Add refKey + if (refMap[refKey]) { + refMap[refKey].append(key); + } else { + refMap[refKey] = [this.key]; + } + this.refKey = refKey; + modified = true; + } + return modified; + }; + + /** + * [ext-clones] Define a refKey for an existing node. + * @param {string} refKey + * @returns {boolean} + * + * @alias FancytreeNode#setRefKey + * @requires jquery.fancytree.clones.js + * @since 2.16 + */ + $.ui.fancytree._FancytreeNodeClass.prototype.setRefKey = function (refKey) { + return this.reRegister(null, refKey); + }; + + /** + * [ext-clones] Return all nodes with a given refKey (null if not found). + * @param {string} refKey + * @param {FancytreeNode} [rootNode] optionally restrict results to descendants of this node + * @returns {FancytreeNode[] | null} + * @alias Fancytree#getNodesByRef + * @requires jquery.fancytree.clones.js + */ + $.ui.fancytree._FancytreeClass.prototype.getNodesByRef = function ( + refKey, + rootNode + ) { + var keyMap = this.keyMap, + refList = this.refMap[refKey] || null; + + if (refList) { + // Convert key list to node list + if (rootNode) { + refList = $.map(refList, function (val) { + var node = keyMap[val]; + return node.isDescendantOf(rootNode) ? node : null; + }); + } else { + refList = $.map(refList, function (val) { + return keyMap[val]; + }); + } + if (refList.length < 1) { + refList = null; + } + } + return refList; + }; + + /** + * [ext-clones] Replace a refKey with a new one. + * @param {string} oldRefKey + * @param {string} newRefKey + * @alias Fancytree#changeRefKey + * @requires jquery.fancytree.clones.js + */ + $.ui.fancytree._FancytreeClass.prototype.changeRefKey = function ( + oldRefKey, + newRefKey + ) { + var i, + node, + keyMap = this.keyMap, + refList = this.refMap[oldRefKey] || null; + + if (refList) { + for (i = 0; i < refList.length; i++) { + node = keyMap[refList[i]]; + node.refKey = newRefKey; + } + delete this.refMap[oldRefKey]; + this.refMap[newRefKey] = refList; + } + }; + + /******************************************************************************* + * Extension code + */ + $.ui.fancytree.registerExtension({ + name: "clones", + version: "2.38.3", + // Default options for this extension. + options: { + highlightActiveClones: true, // set 'fancytree-active-clone' on active clones and all peers + highlightClones: false, // set 'fancytree-clone' class on any node that has at least one clone + }, + + treeCreate: function (ctx) { + this._superApply(arguments); + ctx.tree.refMap = {}; + ctx.tree.keyMap = {}; + }, + treeInit: function (ctx) { + this.$container.addClass("fancytree-ext-clones"); + _assert(ctx.options.defaultKey == null); + // Generate unique / reproducible default keys + ctx.options.defaultKey = function (node) { + return calcUniqueKey(node); + }; + // The default implementation loads initial data + this._superApply(arguments); + }, + treeClear: function (ctx) { + ctx.tree.refMap = {}; + ctx.tree.keyMap = {}; + return this._superApply(arguments); + }, + treeRegisterNode: function (ctx, add, node) { + var refList, + len, + tree = ctx.tree, + keyMap = tree.keyMap, + refMap = tree.refMap, + key = node.key, + refKey = node && node.refKey != null ? "" + node.refKey : null; + + // ctx.tree.debug("clones.treeRegisterNode", add, node); + + if (node.isStatusNode()) { + return this._super(ctx, add, node); + } + + if (add) { + if (keyMap[node.key] != null) { + var other = keyMap[node.key], + msg = + "clones.treeRegisterNode: duplicate key '" + + node.key + + "': /" + + node.getPath(true) + + " => " + + other.getPath(true); + // Sometimes this exception is not visible in the console, + // so we also write it: + tree.error(msg); + $.error(msg); + } + keyMap[key] = node; + + if (refKey) { + refList = refMap[refKey]; + if (refList) { + refList.push(key); + if ( + refList.length === 2 && + ctx.options.clones.highlightClones + ) { + // Mark peer node, if it just became a clone (no need to + // mark current node, since it will be rendered later anyway) + keyMap[refList[0]].renderStatus(); + } + } else { + refMap[refKey] = [key]; + } + // node.debug("clones.treeRegisterNode: add clone =>", refMap[refKey]); + } + } else { + if (keyMap[key] == null) { + $.error( + "clones.treeRegisterNode: node.key not registered: " + + node.key + ); + } + delete keyMap[key]; + if (refKey) { + refList = refMap[refKey]; + // node.debug("clones.treeRegisterNode: remove clone BEFORE =>", refMap[refKey]); + if (refList) { + len = refList.length; + if (len <= 1) { + _assert(len === 1); + _assert(refList[0] === key); + delete refMap[refKey]; + } else { + _removeArrayMember(refList, key); + // Unmark peer node, if this was the only clone + if ( + len === 2 && + ctx.options.clones.highlightClones + ) { + // node.debug("clones.treeRegisterNode: last =>", node.getCloneList()); + keyMap[refList[0]].renderStatus(); + } + } + // node.debug("clones.treeRegisterNode: remove clone =>", refMap[refKey]); + } + } + } + return this._super(ctx, add, node); + }, + nodeRenderStatus: function (ctx) { + var $span, + res, + node = ctx.node; + + res = this._super(ctx); + + if (ctx.options.clones.highlightClones) { + $span = $(node[ctx.tree.statusClassPropName]); + // Only if span already exists + if ($span.length && node.isClone()) { + // node.debug("clones.nodeRenderStatus: ", ctx.options.clones.highlightClones); + $span.addClass("fancytree-clone"); + } + } + return res; + }, + nodeSetActive: function (ctx, flag, callOpts) { + var res, + scpn = ctx.tree.statusClassPropName, + node = ctx.node; + + res = this._superApply(arguments); + + if (ctx.options.clones.highlightActiveClones && node.isClone()) { + $.each(node.getCloneList(true), function (idx, n) { + // n.debug("clones.nodeSetActive: ", flag !== false); + $(n[scpn]).toggleClass( + "fancytree-active-clone", + flag !== false + ); + }); + } + return res; + }, + }); + // Value returned by `require('jquery.fancytree..')` + return $.ui.fancytree; +}); // End of closure + + +/*! Extension 'jquery.fancytree.dnd5.js' *//*! + * jquery.fancytree.dnd5.js + * + * Drag-and-drop support (native HTML5). + * (Extension module for jquery.fancytree.js: https://github.com/mar10/fancytree/) + * + * Copyright (c) 2008-2023, Martin Wendt (https://wwWendt.de) + * + * Released under the MIT license + * https://github.com/mar10/fancytree/wiki/LicenseInfo + * + * @version 2.38.3 + * @date 2023-02-01T20:52:50Z + */ + +/* + #TODO + Compatiblity when dragging between *separate* windows: + + Drag from Chrome Edge FF IE11 Safari + To Chrome ok ok ok NO ? + Edge ok ok ok NO ? + FF ok ok ok NO ? + IE 11 ok ok ok ok ? + Safari ? ? ? ? ok + + */ + +(function (factory) { + if (typeof define === "function" && define.amd) { + // AMD. Register as an anonymous module. + define(["jquery", "./jquery.fancytree"], factory); + } else if (typeof module === "object" && module.exports) { + // Node/CommonJS + require("./jquery.fancytree"); + module.exports = factory(require("jquery")); + } else { + // Browser globals + factory(jQuery); + } +})(function ($) { + "use strict"; + + /****************************************************************************** + * Private functions and variables + */ + var FT = $.ui.fancytree, + isMac = /Mac/.test(navigator.platform), + classDragSource = "fancytree-drag-source", + classDragRemove = "fancytree-drag-remove", + classDropAccept = "fancytree-drop-accept", + classDropAfter = "fancytree-drop-after", + classDropBefore = "fancytree-drop-before", + classDropOver = "fancytree-drop-over", + classDropReject = "fancytree-drop-reject", + classDropTarget = "fancytree-drop-target", + nodeMimeType = "application/x-fancytree-node", + $dropMarker = null, + $dragImage, + $extraHelper, + SOURCE_NODE = null, + SOURCE_NODE_LIST = null, + $sourceList = null, + DRAG_ENTER_RESPONSE = null, + // SESSION_DATA = null, // plain object passed to events as `data` + SUGGESTED_DROP_EFFECT = null, + REQUESTED_DROP_EFFECT = null, + REQUESTED_EFFECT_ALLOWED = null, + LAST_HIT_MODE = null, + DRAG_OVER_STAMP = null; // Time when a node entered the 'over' hitmode + + /* */ + function _clearGlobals() { + DRAG_ENTER_RESPONSE = null; + DRAG_OVER_STAMP = null; + REQUESTED_DROP_EFFECT = null; + REQUESTED_EFFECT_ALLOWED = null; + SUGGESTED_DROP_EFFECT = null; + SOURCE_NODE = null; + SOURCE_NODE_LIST = null; + if ($sourceList) { + $sourceList.removeClass(classDragSource + " " + classDragRemove); + } + $sourceList = null; + if ($dropMarker) { + $dropMarker.hide(); + } + // Take this badge off of me - I can't use it anymore: + if ($extraHelper) { + $extraHelper.remove(); + $extraHelper = null; + } + } + + /* Convert number to string and prepend +/-; return empty string for 0.*/ + function offsetString(n) { + // eslint-disable-next-line no-nested-ternary + return n === 0 ? "" : n > 0 ? "+" + n : "" + n; + } + + /* Convert a dragEnter() or dragOver() response to a canonical form. + * Return false or plain object + * @param {string|object|boolean} r + * @return {object|false} + */ + function normalizeDragEnterResponse(r) { + var res; + + if (!r) { + return false; + } + if ($.isPlainObject(r)) { + res = { + over: !!r.over, + before: !!r.before, + after: !!r.after, + }; + } else if (Array.isArray(r)) { + res = { + over: $.inArray("over", r) >= 0, + before: $.inArray("before", r) >= 0, + after: $.inArray("after", r) >= 0, + }; + } else { + res = { + over: r === true || r === "over", + before: r === true || r === "before", + after: r === true || r === "after", + }; + } + if (Object.keys(res).length === 0) { + return false; + } + // if( Object.keys(res).length === 1 ) { + // res.unique = res[0]; + // } + return res; + } + + /* Convert a dataTransfer.effectAllowed to a canonical form. + * Return false or plain object + * @param {string|boolean} r + * @return {object|false} + */ + // function normalizeEffectAllowed(r) { + // if (!r || r === "none") { + // return false; + // } + // var all = r === "all", + // res = { + // copy: all || /copy/i.test(r), + // link: all || /link/i.test(r), + // move: all || /move/i.test(r), + // }; + + // return res; + // } + + /* Implement auto scrolling when drag cursor is in top/bottom area of scroll parent. */ + function autoScroll(tree, event) { + var spOfs, + scrollTop, + delta, + dndOpts = tree.options.dnd5, + sp = tree.$scrollParent[0], + sensitivity = dndOpts.scrollSensitivity, + speed = dndOpts.scrollSpeed, + scrolled = 0; + + if (sp !== document && sp.tagName !== "HTML") { + spOfs = tree.$scrollParent.offset(); + scrollTop = sp.scrollTop; + if (spOfs.top + sp.offsetHeight - event.pageY < sensitivity) { + delta = + sp.scrollHeight - + tree.$scrollParent.innerHeight() - + scrollTop; + // console.log ("sp.offsetHeight: " + sp.offsetHeight + // + ", spOfs.top: " + spOfs.top + // + ", scrollTop: " + scrollTop + // + ", innerHeight: " + tree.$scrollParent.innerHeight() + // + ", scrollHeight: " + sp.scrollHeight + // + ", delta: " + delta + // ); + if (delta > 0) { + sp.scrollTop = scrolled = scrollTop + speed; + } + } else if (scrollTop > 0 && event.pageY - spOfs.top < sensitivity) { + sp.scrollTop = scrolled = scrollTop - speed; + } + } else { + scrollTop = $(document).scrollTop(); + if (scrollTop > 0 && event.pageY - scrollTop < sensitivity) { + scrolled = scrollTop - speed; + $(document).scrollTop(scrolled); + } else if ( + $(window).height() - (event.pageY - scrollTop) < + sensitivity + ) { + scrolled = scrollTop + speed; + $(document).scrollTop(scrolled); + } + } + if (scrolled) { + tree.debug("autoScroll: " + scrolled + "px"); + } + return scrolled; + } + + /* Guess dropEffect from modifier keys. + * Using rules suggested here: + * https://ux.stackexchange.com/a/83769 + * @returns + * 'copy', 'link', 'move', or 'none' + */ + function evalEffectModifiers(tree, event, effectDefault) { + var res = effectDefault; + + if (isMac) { + if (event.metaKey && event.altKey) { + // Mac: [Control] + [Option] + res = "link"; + } else if (event.ctrlKey) { + // Chrome on Mac: [Control] + res = "link"; + } else if (event.metaKey) { + // Mac: [Command] + res = "move"; + } else if (event.altKey) { + // Mac: [Option] + res = "copy"; + } + } else { + if (event.ctrlKey) { + // Windows: [Ctrl] + res = "copy"; + } else if (event.shiftKey) { + // Windows: [Shift] + res = "move"; + } else if (event.altKey) { + // Windows: [Alt] + res = "link"; + } + } + if (res !== SUGGESTED_DROP_EFFECT) { + tree.info( + "evalEffectModifiers: " + + event.type + + " - evalEffectModifiers(): " + + SUGGESTED_DROP_EFFECT + + " -> " + + res + ); + } + SUGGESTED_DROP_EFFECT = res; + // tree.debug("evalEffectModifiers: " + res); + return res; + } + /* + * Check if the previous callback (dragEnter, dragOver, ...) has changed + * the `data` object and apply those settings. + * + * Safari: + * It seems that `dataTransfer.dropEffect` can only be set on dragStart, and will remain + * even if the cursor changes when [Alt] or [Ctrl] are pressed (?) + * Using rules suggested here: + * https://ux.stackexchange.com/a/83769 + * @returns + * 'copy', 'link', 'move', or 'none' + */ + function prepareDropEffectCallback(event, data) { + var tree = data.tree, + dataTransfer = data.dataTransfer; + + if (event.type === "dragstart") { + data.effectAllowed = tree.options.dnd5.effectAllowed; + data.dropEffect = tree.options.dnd5.dropEffectDefault; + } else { + data.effectAllowed = REQUESTED_EFFECT_ALLOWED; + data.dropEffect = REQUESTED_DROP_EFFECT; + } + data.dropEffectSuggested = evalEffectModifiers( + tree, + event, + tree.options.dnd5.dropEffectDefault + ); + data.isMove = data.dropEffect === "move"; + data.files = dataTransfer.files || []; + + // if (REQUESTED_EFFECT_ALLOWED !== dataTransfer.effectAllowed) { + // tree.warn( + // "prepareDropEffectCallback(" + + // event.type + + // "): dataTransfer.effectAllowed changed from " + + // REQUESTED_EFFECT_ALLOWED + + // " -> " + + // dataTransfer.effectAllowed + // ); + // } + // if (REQUESTED_DROP_EFFECT !== dataTransfer.dropEffect) { + // tree.warn( + // "prepareDropEffectCallback(" + + // event.type + + // "): dataTransfer.dropEffect changed from requested " + + // REQUESTED_DROP_EFFECT + + // " to " + + // dataTransfer.dropEffect + // ); + // } + } + + function applyDropEffectCallback(event, data, allowDrop) { + var tree = data.tree, + dataTransfer = data.dataTransfer; + + if ( + event.type !== "dragstart" && + REQUESTED_EFFECT_ALLOWED !== data.effectAllowed + ) { + tree.warn( + "effectAllowed should only be changed in dragstart event: " + + event.type + + ": data.effectAllowed changed from " + + REQUESTED_EFFECT_ALLOWED + + " -> " + + data.effectAllowed + ); + } + + if (allowDrop === false) { + tree.info("applyDropEffectCallback: allowDrop === false"); + data.effectAllowed = "none"; + data.dropEffect = "none"; + } + // if (REQUESTED_DROP_EFFECT !== data.dropEffect) { + // tree.debug( + // "applyDropEffectCallback(" + + // event.type + + // "): data.dropEffect changed from previous " + + // REQUESTED_DROP_EFFECT + + // " to " + + // data.dropEffect + // ); + // } + + data.isMove = data.dropEffect === "move"; + // data.isMove = data.dropEffectSuggested === "move"; + + // `effectAllowed` must only be defined in dragstart event, so we + // store it in a global variable for reference + if (event.type === "dragstart") { + REQUESTED_EFFECT_ALLOWED = data.effectAllowed; + REQUESTED_DROP_EFFECT = data.dropEffect; + } + + // if (REQUESTED_DROP_EFFECT !== dataTransfer.dropEffect) { + // data.tree.info( + // "applyDropEffectCallback(" + + // event.type + + // "): dataTransfer.dropEffect changed from " + + // REQUESTED_DROP_EFFECT + + // " -> " + + // dataTransfer.dropEffect + // ); + // } + dataTransfer.effectAllowed = REQUESTED_EFFECT_ALLOWED; + dataTransfer.dropEffect = REQUESTED_DROP_EFFECT; + + // tree.debug( + // "applyDropEffectCallback(" + + // event.type + + // "): set " + + // dataTransfer.dropEffect + + // "/" + + // dataTransfer.effectAllowed + // ); + // if (REQUESTED_DROP_EFFECT !== dataTransfer.dropEffect) { + // data.tree.warn( + // "applyDropEffectCallback(" + + // event.type + + // "): could not set dataTransfer.dropEffect to " + + // REQUESTED_DROP_EFFECT + + // ": got " + + // dataTransfer.dropEffect + // ); + // } + return REQUESTED_DROP_EFFECT; + } + + /* Handle dragover event (fired every x ms) on valid drop targets. + * + * - Auto-scroll when cursor is in border regions + * - Apply restrictioan like 'preventVoidMoves' + * - Calculate hit mode + * - Calculate drop effect + * - Trigger dragOver() callback to let user modify hit mode and drop effect + * - Adjust the drop marker accordingly + * + * @returns hitMode + */ + function handleDragOver(event, data) { + // Implement auto-scrolling + if (data.options.dnd5.scroll) { + autoScroll(data.tree, event); + } + // Bail out with previous response if we get an invalid dragover + if (!data.node) { + data.tree.warn("Ignored dragover for non-node"); //, event, data); + return LAST_HIT_MODE; + } + + var markerOffsetX, + nodeOfs, + pos, + relPosY, + hitMode = null, + tree = data.tree, + options = tree.options, + dndOpts = options.dnd5, + targetNode = data.node, + sourceNode = data.otherNode, + markerAt = "center", + $target = $(targetNode.span), + $targetTitle = $target.find("span.fancytree-title"); + + if (DRAG_ENTER_RESPONSE === false) { + tree.debug("Ignored dragover, since dragenter returned false."); + return false; + } else if (typeof DRAG_ENTER_RESPONSE === "string") { + $.error("assert failed: dragenter returned string"); + } + // Calculate hitMode from relative cursor position. + nodeOfs = $target.offset(); + relPosY = (event.pageY - nodeOfs.top) / $target.height(); + if (event.pageY === undefined) { + tree.warn("event.pageY is undefined: see issue #1013."); + } + + if (DRAG_ENTER_RESPONSE.after && relPosY > 0.75) { + hitMode = "after"; + } else if ( + !DRAG_ENTER_RESPONSE.over && + DRAG_ENTER_RESPONSE.after && + relPosY > 0.5 + ) { + hitMode = "after"; + } else if (DRAG_ENTER_RESPONSE.before && relPosY <= 0.25) { + hitMode = "before"; + } else if ( + !DRAG_ENTER_RESPONSE.over && + DRAG_ENTER_RESPONSE.before && + relPosY <= 0.5 + ) { + hitMode = "before"; + } else if (DRAG_ENTER_RESPONSE.over) { + hitMode = "over"; + } + // Prevent no-ops like 'before source node' + // TODO: these are no-ops when moving nodes, but not in copy mode + if (dndOpts.preventVoidMoves && data.dropEffect === "move") { + if (targetNode === sourceNode) { + targetNode.debug("Drop over source node prevented."); + hitMode = null; + } else if ( + hitMode === "before" && + sourceNode && + targetNode === sourceNode.getNextSibling() + ) { + targetNode.debug("Drop after source node prevented."); + hitMode = null; + } else if ( + hitMode === "after" && + sourceNode && + targetNode === sourceNode.getPrevSibling() + ) { + targetNode.debug("Drop before source node prevented."); + hitMode = null; + } else if ( + hitMode === "over" && + sourceNode && + sourceNode.parent === targetNode && + sourceNode.isLastSibling() + ) { + targetNode.debug("Drop last child over own parent prevented."); + hitMode = null; + } + } + // Let callback modify the calculated hitMode + data.hitMode = hitMode; + if (hitMode && dndOpts.dragOver) { + prepareDropEffectCallback(event, data); + dndOpts.dragOver(targetNode, data); + var allowDrop = !!hitMode; + applyDropEffectCallback(event, data, allowDrop); + hitMode = data.hitMode; + } + LAST_HIT_MODE = hitMode; + // + if (hitMode === "after" || hitMode === "before" || hitMode === "over") { + markerOffsetX = dndOpts.dropMarkerOffsetX || 0; + switch (hitMode) { + case "before": + markerAt = "top"; + markerOffsetX += dndOpts.dropMarkerInsertOffsetX || 0; + break; + case "after": + markerAt = "bottom"; + markerOffsetX += dndOpts.dropMarkerInsertOffsetX || 0; + break; + } + + pos = { + my: "left" + offsetString(markerOffsetX) + " center", + at: "left " + markerAt, + of: $targetTitle, + }; + if (options.rtl) { + pos.my = "right" + offsetString(-markerOffsetX) + " center"; + pos.at = "right " + markerAt; + // console.log("rtl", pos); + } + $dropMarker + .toggleClass(classDropAfter, hitMode === "after") + .toggleClass(classDropOver, hitMode === "over") + .toggleClass(classDropBefore, hitMode === "before") + .show() + .position(FT.fixPositionOptions(pos)); + } else { + $dropMarker.hide(); + // console.log("hide dropmarker") + } + + $(targetNode.span) + .toggleClass( + classDropTarget, + hitMode === "after" || + hitMode === "before" || + hitMode === "over" + ) + .toggleClass(classDropAfter, hitMode === "after") + .toggleClass(classDropBefore, hitMode === "before") + .toggleClass(classDropAccept, hitMode === "over") + .toggleClass(classDropReject, hitMode === false); + + return hitMode; + } + + /* + * Handle dragstart drag dragend events on the container + */ + function onDragEvent(event) { + var json, + tree = this, + dndOpts = tree.options.dnd5, + node = FT.getNode(event), + dataTransfer = + event.dataTransfer || event.originalEvent.dataTransfer, + data = { + tree: tree, + node: node, + options: tree.options, + originalEvent: event.originalEvent, + widget: tree.widget, + dataTransfer: dataTransfer, + useDefaultImage: true, + dropEffect: undefined, + dropEffectSuggested: undefined, + effectAllowed: undefined, // set by dragstart + files: undefined, // only for drop events + isCancelled: undefined, // set by dragend + isMove: undefined, + }; + + switch (event.type) { + case "dragstart": + if (!node) { + tree.info("Ignored dragstart on a non-node."); + return false; + } + // Store current source node in different formats + SOURCE_NODE = node; + + // Also optionally store selected nodes + if (dndOpts.multiSource === false) { + SOURCE_NODE_LIST = [node]; + } else if (dndOpts.multiSource === true) { + if (node.isSelected()) { + SOURCE_NODE_LIST = tree.getSelectedNodes(); + } else { + SOURCE_NODE_LIST = [node]; + } + } else { + SOURCE_NODE_LIST = dndOpts.multiSource(node, data); + } + // Cache as array of jQuery objects for faster access: + $sourceList = $( + $.map(SOURCE_NODE_LIST, function (n) { + return n.span; + }) + ); + // Set visual feedback + $sourceList.addClass(classDragSource); + + // Set payload + // Note: + // Transfer data is only accessible on dragstart and drop! + // For all other events the formats and kinds in the drag + // data store list of items representing dragged data can be + // enumerated, but the data itself is unavailable and no new + // data can be added. + var nodeData = node.toDict(true, dndOpts.sourceCopyHook); + nodeData.treeId = node.tree._id; + json = JSON.stringify(nodeData); + try { + dataTransfer.setData(nodeMimeType, json); + dataTransfer.setData("text/html", $(node.span).html()); + dataTransfer.setData("text/plain", node.title); + } catch (ex) { + // IE only accepts 'text' type + tree.warn( + "Could not set data (IE only accepts 'text') - " + ex + ); + } + // We always need to set the 'text' type if we want to drag + // Because IE 11 only accepts this single type. + // If we pass JSON here, IE can can access all node properties, + // even when the source lives in another window. (D'n'd inside + // the same window will always work.) + // The drawback is, that in this case ALL browsers will see + // the JSON representation as 'text', so dragging + // to a text field will insert the JSON string instead of + // the node title. + if (dndOpts.setTextTypeJson) { + dataTransfer.setData("text", json); + } else { + dataTransfer.setData("text", node.title); + } + + // Set the allowed drag modes (combinations of move, copy, and link) + // (effectAllowed can only be set in the dragstart event.) + // This can be overridden in the dragStart() callback + prepareDropEffectCallback(event, data); + + // Let user cancel or modify above settings + // Realize potential changes by previous callback + if (dndOpts.dragStart(node, data) === false) { + // Cancel dragging + // dataTransfer.dropEffect = "none"; + _clearGlobals(); + return false; + } + applyDropEffectCallback(event, data); + + // Unless user set `data.useDefaultImage` to false in dragStart, + // generata a default drag image now: + $extraHelper = null; + + if (data.useDefaultImage) { + // Set the title as drag image (otherwise it would contain the expander) + $dragImage = $(node.span).find(".fancytree-title"); + + if (SOURCE_NODE_LIST && SOURCE_NODE_LIST.length > 1) { + // Add a counter badge to node title if dragging more than one node. + // We want this, because the element that is used as drag image + // must be *visible* in the DOM, so we cannot create some hidden + // custom markup. + // See https://kryogenix.org/code/browser/custom-drag-image.html + // Also, since IE 11 and Edge don't support setDragImage() alltogether, + // it gives som feedback to the user. + // The badge will be removed later on drag end. + $extraHelper = $( + "<span class='fancytree-childcounter'/>" + ) + .text("+" + (SOURCE_NODE_LIST.length - 1)) + .appendTo($dragImage); + } + if (dataTransfer.setDragImage) { + // IE 11 and Edge do not support this + dataTransfer.setDragImage($dragImage[0], -10, -10); + } + } + return true; + + case "drag": + // Called every few milliseconds (no matter if the + // cursor is over a valid drop target) + // data.tree.info("drag", SOURCE_NODE) + prepareDropEffectCallback(event, data); + dndOpts.dragDrag(node, data); + applyDropEffectCallback(event, data); + + $sourceList.toggleClass(classDragRemove, data.isMove); + break; + + case "dragend": + // Called at the end of a d'n'd process (after drop) + // Note caveat: If drop removed the dragged source element, + // we may not get this event, since the target does not exist + // anymore + prepareDropEffectCallback(event, data); + + _clearGlobals(); + + data.isCancelled = !LAST_HIT_MODE; + dndOpts.dragEnd(node, data, !LAST_HIT_MODE); + // applyDropEffectCallback(event, data); + break; + } + } + /* + * Handle dragenter dragover dragleave drop events on the container + */ + function onDropEvent(event) { + var json, + allowAutoExpand, + nodeData, + isSourceFtNode, + r, + res, + tree = this, + dndOpts = tree.options.dnd5, + allowDrop = null, + node = FT.getNode(event), + dataTransfer = + event.dataTransfer || event.originalEvent.dataTransfer, + data = { + tree: tree, + node: node, + options: tree.options, + originalEvent: event.originalEvent, + widget: tree.widget, + hitMode: DRAG_ENTER_RESPONSE, + dataTransfer: dataTransfer, + otherNode: SOURCE_NODE || null, + otherNodeList: SOURCE_NODE_LIST || null, + otherNodeData: null, // set by drop event + useDefaultImage: true, + dropEffect: undefined, + dropEffectSuggested: undefined, + effectAllowed: undefined, // set by dragstart + files: null, // list of File objects (may be []) + isCancelled: undefined, // set by drop event + isMove: undefined, + }; + + // data.isMove = dropEffect === "move"; + + switch (event.type) { + case "dragenter": + // The dragenter event is fired when a dragged element or + // text selection enters a valid drop target. + + DRAG_OVER_STAMP = null; + if (!node) { + // Sometimes we get dragenter for the container element + tree.debug( + "Ignore non-node " + + event.type + + ": " + + event.target.tagName + + "." + + event.target.className + ); + DRAG_ENTER_RESPONSE = false; + break; + } + + $(node.span) + .addClass(classDropOver) + .removeClass(classDropAccept + " " + classDropReject); + + // Data is only readable in the dragstart and drop event, + // but we can check for the type: + isSourceFtNode = + $.inArray(nodeMimeType, dataTransfer.types) >= 0; + + if (dndOpts.preventNonNodes && !isSourceFtNode) { + node.debug("Reject dropping a non-node."); + DRAG_ENTER_RESPONSE = false; + break; + } else if ( + dndOpts.preventForeignNodes && + (!SOURCE_NODE || SOURCE_NODE.tree !== node.tree) + ) { + node.debug("Reject dropping a foreign node."); + DRAG_ENTER_RESPONSE = false; + break; + } else if ( + dndOpts.preventSameParent && + data.otherNode && + data.otherNode.tree === node.tree && + node.parent === data.otherNode.parent + ) { + node.debug("Reject dropping as sibling (same parent)."); + DRAG_ENTER_RESPONSE = false; + break; + } else if ( + dndOpts.preventRecursion && + data.otherNode && + data.otherNode.tree === node.tree && + node.isDescendantOf(data.otherNode) + ) { + node.debug("Reject dropping below own ancestor."); + DRAG_ENTER_RESPONSE = false; + break; + } else if (dndOpts.preventLazyParents && !node.isLoaded()) { + node.warn("Drop over unloaded target node prevented."); + DRAG_ENTER_RESPONSE = false; + break; + } + $dropMarker.show(); + + // Call dragEnter() to figure out if (and where) dropping is allowed + prepareDropEffectCallback(event, data); + r = dndOpts.dragEnter(node, data); + + res = normalizeDragEnterResponse(r); + // alert("res:" + JSON.stringify(res)) + DRAG_ENTER_RESPONSE = res; + + allowDrop = res && (res.over || res.before || res.after); + + applyDropEffectCallback(event, data, allowDrop); + break; + + case "dragover": + if (!node) { + tree.debug( + "Ignore non-node " + + event.type + + ": " + + event.target.tagName + + "." + + event.target.className + ); + break; + } + // The dragover event is fired when an element or text + // selection is being dragged over a valid drop target + // (every few hundred milliseconds). + // tree.debug( + // event.type + + // ": dropEffect: " + + // dataTransfer.dropEffect + // ); + prepareDropEffectCallback(event, data); + LAST_HIT_MODE = handleDragOver(event, data); + + // The flag controls the preventDefault() below: + allowDrop = !!LAST_HIT_MODE; + allowAutoExpand = + LAST_HIT_MODE === "over" || LAST_HIT_MODE === false; + + if ( + allowAutoExpand && + !node.expanded && + node.hasChildren() !== false + ) { + if (!DRAG_OVER_STAMP) { + DRAG_OVER_STAMP = Date.now(); + } else if ( + dndOpts.autoExpandMS && + Date.now() - DRAG_OVER_STAMP > dndOpts.autoExpandMS && + !node.isLoading() && + (!dndOpts.dragExpand || + dndOpts.dragExpand(node, data) !== false) + ) { + node.setExpanded(); + } + } else { + DRAG_OVER_STAMP = null; + } + break; + + case "dragleave": + // NOTE: dragleave is fired AFTER the dragenter event of the + // FOLLOWING element. + if (!node) { + tree.debug( + "Ignore non-node " + + event.type + + ": " + + event.target.tagName + + "." + + event.target.className + ); + break; + } + if (!$(node.span).hasClass(classDropOver)) { + node.debug("Ignore dragleave (multi)."); + break; + } + $(node.span).removeClass( + classDropOver + + " " + + classDropAccept + + " " + + classDropReject + ); + node.scheduleAction("cancel"); + dndOpts.dragLeave(node, data); + $dropMarker.hide(); + break; + + case "drop": + // Data is only readable in the (dragstart and) drop event: + + if ($.inArray(nodeMimeType, dataTransfer.types) >= 0) { + nodeData = dataTransfer.getData(nodeMimeType); + tree.info( + event.type + + ": getData('application/x-fancytree-node'): '" + + nodeData + + "'" + ); + } + if (!nodeData) { + // 1. Source is not a Fancytree node, or + // 2. If the FT mime type was set, but returns '', this + // is probably IE 11 (which only supports 'text') + nodeData = dataTransfer.getData("text"); + tree.info( + event.type + ": getData('text'): '" + nodeData + "'" + ); + } + if (nodeData) { + try { + // 'text' type may contain JSON if IE is involved + // and setTextTypeJson option was set + json = JSON.parse(nodeData); + if (json.title !== undefined) { + data.otherNodeData = json; + } + } catch (ex) { + // assume 'text' type contains plain text, so `otherNodeData` + // should not be set + } + } + tree.debug( + event.type + + ": nodeData: '" + + nodeData + + "', otherNodeData: ", + data.otherNodeData + ); + + $(node.span).removeClass( + classDropOver + + " " + + classDropAccept + + " " + + classDropReject + ); + + // Let user implement the actual drop operation + data.hitMode = LAST_HIT_MODE; + prepareDropEffectCallback(event, data, !LAST_HIT_MODE); + data.isCancelled = !LAST_HIT_MODE; + + var orgSourceElem = SOURCE_NODE && SOURCE_NODE.span, + orgSourceTree = SOURCE_NODE && SOURCE_NODE.tree; + + dndOpts.dragDrop(node, data); + // applyDropEffectCallback(event, data); + + // Prevent browser's default drop handling, i.e. open as link, ... + event.preventDefault(); + + if (orgSourceElem && !document.body.contains(orgSourceElem)) { + // The drop handler removed the original drag source from + // the DOM, so the dragend event will probaly not fire. + if (orgSourceTree === tree) { + tree.debug( + "Drop handler removed source element: generating dragEnd." + ); + dndOpts.dragEnd(SOURCE_NODE, data); + } else { + tree.warn( + "Drop handler removed source element: dragend event may be lost." + ); + } + } + + _clearGlobals(); + + break; + } + // Dnd API madness: we must PREVENT default handling to enable dropping + if (allowDrop) { + event.preventDefault(); + return false; + } + } + + /** [ext-dnd5] Return a Fancytree instance, from element, index, event, or jQueryObject. + * + * @returns {FancytreeNode[]} List of nodes (empty if no drag operation) + * @example + * $.ui.fancytree.getDragNodeList(); + * + * @alias Fancytree_Static#getDragNodeList + * @requires jquery.fancytree.dnd5.js + * @since 2.31 + */ + $.ui.fancytree.getDragNodeList = function () { + return SOURCE_NODE_LIST || []; + }; + + /** [ext-dnd5] Return the FancytreeNode that is currently being dragged. + * + * If multiple nodes are dragged, only the first is returned. + * + * @returns {FancytreeNode | null} dragged nodes or null if no drag operation + * @example + * $.ui.fancytree.getDragNode(); + * + * @alias Fancytree_Static#getDragNode + * @requires jquery.fancytree.dnd5.js + * @since 2.31 + */ + $.ui.fancytree.getDragNode = function () { + return SOURCE_NODE; + }; + + /****************************************************************************** + * + */ + + $.ui.fancytree.registerExtension({ + name: "dnd5", + version: "2.38.3", + // Default options for this extension. + options: { + autoExpandMS: 1500, // Expand nodes after n milliseconds of hovering + dropMarkerInsertOffsetX: -16, // Additional offset for drop-marker with hitMode = "before"/"after" + dropMarkerOffsetX: -24, // Absolute position offset for .fancytree-drop-marker relatively to ..fancytree-title (icon/img near a node accepting drop) + // #1021 `document.body` is not available yet + dropMarkerParent: "body", // Root Container used for drop marker (could be a shadow root) + multiSource: false, // true: Drag multiple (i.e. selected) nodes. Also a callback() is allowed + effectAllowed: "all", // Restrict the possible cursor shapes and modifier operations (can also be set in the dragStart event) + // dropEffect: "auto", // 'copy'|'link'|'move'|'auto'(calculate from `effectAllowed`+modifier keys) or callback(node, data) that returns such string. + dropEffectDefault: "move", // Default dropEffect ('copy', 'link', or 'move') when no modifier is pressed (overide in dragDrag, dragOver). + preventForeignNodes: false, // Prevent dropping nodes from different Fancytrees + preventLazyParents: true, // Prevent dropping items on unloaded lazy Fancytree nodes + preventNonNodes: false, // Prevent dropping items other than Fancytree nodes + preventRecursion: true, // Prevent dropping nodes on own descendants + preventSameParent: false, // Prevent dropping nodes under same direct parent + preventVoidMoves: true, // Prevent dropping nodes 'before self', etc. + scroll: true, // Enable auto-scrolling while dragging + scrollSensitivity: 20, // Active top/bottom margin in pixel + scrollSpeed: 5, // Pixel per event + setTextTypeJson: false, // Allow dragging of nodes to different IE windows + sourceCopyHook: null, // Optional callback passed to `toDict` on dragStart @since 2.38 + // Events (drag support) + dragStart: null, // Callback(sourceNode, data), return true, to enable dnd drag + dragDrag: $.noop, // Callback(sourceNode, data) + dragEnd: $.noop, // Callback(sourceNode, data) + // Events (drop support) + dragEnter: null, // Callback(targetNode, data), return true, to enable dnd drop + dragOver: $.noop, // Callback(targetNode, data) + dragExpand: $.noop, // Callback(targetNode, data), return false to prevent autoExpand + dragDrop: $.noop, // Callback(targetNode, data) + dragLeave: $.noop, // Callback(targetNode, data) + }, + + treeInit: function (ctx) { + var $temp, + tree = ctx.tree, + opts = ctx.options, + glyph = opts.glyph || null, + dndOpts = opts.dnd5; + + if ($.inArray("dnd", opts.extensions) >= 0) { + $.error("Extensions 'dnd' and 'dnd5' are mutually exclusive."); + } + if (dndOpts.dragStop) { + $.error( + "dragStop is not used by ext-dnd5. Use dragEnd instead." + ); + } + if (dndOpts.preventRecursiveMoves != null) { + $.error( + "preventRecursiveMoves was renamed to preventRecursion." + ); + } + + // Implement `opts.createNode` event to add the 'draggable' attribute + // #680: this must happen before calling super.treeInit() + if (dndOpts.dragStart) { + FT.overrideMethod( + ctx.options, + "createNode", + function (event, data) { + // Default processing if any + this._super.apply(this, arguments); + if (data.node.span) { + data.node.span.draggable = true; + } else { + data.node.warn( + "Cannot add `draggable`: no span tag" + ); + } + } + ); + } + this._superApply(arguments); + + this.$container.addClass("fancytree-ext-dnd5"); + + // Store the current scroll parent, which may be the tree + // container, any enclosing div, or the document. + // #761: scrollParent() always needs a container child + $temp = $("<span>").appendTo(this.$container); + this.$scrollParent = $temp.scrollParent(); + $temp.remove(); + + $dropMarker = $("#fancytree-drop-marker"); + if (!$dropMarker.length) { + $dropMarker = $("<div id='fancytree-drop-marker'></div>") + .hide() + .css({ + "z-index": 1000, + // Drop marker should not steal dragenter/dragover events: + "pointer-events": "none", + }) + .prependTo(dndOpts.dropMarkerParent); + if (glyph) { + FT.setSpanIcon( + $dropMarker[0], + glyph.map._addClass, + glyph.map.dropMarker + ); + } + } + $dropMarker.toggleClass("fancytree-rtl", !!opts.rtl); + + // Enable drag support if dragStart() is specified: + if (dndOpts.dragStart) { + // Bind drag event handlers + tree.$container.on( + "dragstart drag dragend", + onDragEvent.bind(tree) + ); + } + // Enable drop support if dragEnter() is specified: + if (dndOpts.dragEnter) { + // Bind drop event handlers + tree.$container.on( + "dragenter dragover dragleave drop", + onDropEvent.bind(tree) + ); + } + }, + }); + // Value returned by `require('jquery.fancytree..')` + return $.ui.fancytree; +}); // End of closure + + +/*! Extension 'jquery.fancytree.edit.js' *//*! + * jquery.fancytree.edit.js + * + * Make node titles editable. + * (Extension module for jquery.fancytree.js: https://github.com/mar10/fancytree/) + * + * Copyright (c) 2008-2023, Martin Wendt (https://wwWendt.de) + * + * Released under the MIT license + * https://github.com/mar10/fancytree/wiki/LicenseInfo + * + * @version 2.38.3 + * @date 2023-02-01T20:52:50Z + */ + +(function (factory) { + if (typeof define === "function" && define.amd) { + // AMD. Register as an anonymous module. + define(["jquery", "./jquery.fancytree"], factory); + } else if (typeof module === "object" && module.exports) { + // Node/CommonJS + require("./jquery.fancytree"); + module.exports = factory(require("jquery")); + } else { + // Browser globals + factory(jQuery); + } +})(function ($) { + "use strict"; + + /******************************************************************************* + * Private functions and variables + */ + + var isMac = /Mac/.test(navigator.platform), + escapeHtml = $.ui.fancytree.escapeHtml, + trim = $.ui.fancytree.trim, + unescapeHtml = $.ui.fancytree.unescapeHtml; + + /** + * [ext-edit] Start inline editing of current node title. + * + * @alias FancytreeNode#editStart + * @requires Fancytree + */ + $.ui.fancytree._FancytreeNodeClass.prototype.editStart = function () { + var $input, + node = this, + tree = this.tree, + local = tree.ext.edit, + instOpts = tree.options.edit, + $title = $(".fancytree-title", node.span), + eventData = { + node: node, + tree: tree, + options: tree.options, + isNew: $(node[tree.statusClassPropName]).hasClass( + "fancytree-edit-new" + ), + orgTitle: node.title, + input: null, + dirty: false, + }; + + // beforeEdit may want to modify the title before editing + if ( + instOpts.beforeEdit.call( + node, + { type: "beforeEdit" }, + eventData + ) === false + ) { + return false; + } + $.ui.fancytree.assert(!local.currentNode, "recursive edit"); + local.currentNode = this; + local.eventData = eventData; + + // Disable standard Fancytree mouse- and key handling + tree.widget._unbind(); + + local.lastDraggableAttrValue = node.span.draggable; + if (local.lastDraggableAttrValue) { + node.span.draggable = false; + } + + // #116: ext-dnd prevents the blur event, so we have to catch outer clicks + $(document).on("mousedown.fancytree-edit", function (event) { + if (!$(event.target).hasClass("fancytree-edit-input")) { + node.editEnd(true, event); + } + }); + + // Replace node with <input> + $input = $("<input />", { + class: "fancytree-edit-input", + type: "text", + value: tree.options.escapeTitles + ? eventData.orgTitle + : unescapeHtml(eventData.orgTitle), + }); + local.eventData.input = $input; + if (instOpts.adjustWidthOfs != null) { + $input.width($title.width() + instOpts.adjustWidthOfs); + } + if (instOpts.inputCss != null) { + $input.css(instOpts.inputCss); + } + + $title.html($input); + + // Focus <input> and bind keyboard handler + $input + .focus() + .change(function (event) { + $input.addClass("fancytree-edit-dirty"); + }) + .on("keydown", function (event) { + switch (event.which) { + case $.ui.keyCode.ESCAPE: + node.editEnd(false, event); + break; + case $.ui.keyCode.ENTER: + node.editEnd(true, event); + return false; // so we don't start editmode on Mac + } + event.stopPropagation(); + }) + .blur(function (event) { + return node.editEnd(true, event); + }); + + instOpts.edit.call(node, { type: "edit" }, eventData); + }; + + /** + * [ext-edit] Stop inline editing. + * @param {Boolean} [applyChanges=false] false: cancel edit, true: save (if modified) + * @alias FancytreeNode#editEnd + * @requires jquery.fancytree.edit.js + */ + $.ui.fancytree._FancytreeNodeClass.prototype.editEnd = function ( + applyChanges, + _event + ) { + var newVal, + node = this, + tree = this.tree, + local = tree.ext.edit, + eventData = local.eventData, + instOpts = tree.options.edit, + $title = $(".fancytree-title", node.span), + $input = $title.find("input.fancytree-edit-input"); + + if (instOpts.trim) { + $input.val(trim($input.val())); + } + newVal = $input.val(); + + eventData.dirty = newVal !== node.title; + eventData.originalEvent = _event; + + // Find out, if saving is required + if (applyChanges === false) { + // If true/false was passed, honor this (except in rename mode, if unchanged) + eventData.save = false; + } else if (eventData.isNew) { + // In create mode, we save everything, except for empty text + eventData.save = newVal !== ""; + } else { + // In rename mode, we save everyting, except for empty or unchanged text + eventData.save = eventData.dirty && newVal !== ""; + } + // Allow to break (keep editor open), modify input, or re-define data.save + if ( + instOpts.beforeClose.call( + node, + { type: "beforeClose" }, + eventData + ) === false + ) { + return false; + } + if ( + eventData.save && + instOpts.save.call(node, { type: "save" }, eventData) === false + ) { + return false; + } + $input.removeClass("fancytree-edit-dirty").off(); + // Unbind outer-click handler + $(document).off(".fancytree-edit"); + + if (eventData.save) { + // # 171: escape user input (not required if global escaping is on) + node.setTitle( + tree.options.escapeTitles ? newVal : escapeHtml(newVal) + ); + node.setFocus(); + } else { + if (eventData.isNew) { + node.remove(); + node = eventData.node = null; + local.relatedNode.setFocus(); + } else { + node.renderTitle(); + node.setFocus(); + } + } + local.eventData = null; + local.currentNode = null; + local.relatedNode = null; + // Re-enable mouse and keyboard handling + tree.widget._bind(); + + if (node && local.lastDraggableAttrValue) { + node.span.draggable = true; + } + + // Set keyboard focus, even if setFocus() claims 'nothing to do' + tree.$container.get(0).focus({ preventScroll: true }); + eventData.input = null; + instOpts.close.call(node, { type: "close" }, eventData); + return true; + }; + + /** + * [ext-edit] Create a new child or sibling node and start edit mode. + * + * @param {String} [mode='child'] 'before', 'after', or 'child' + * @param {Object} [init] NodeData (or simple title string) + * @alias FancytreeNode#editCreateNode + * @requires jquery.fancytree.edit.js + * @since 2.4 + */ + $.ui.fancytree._FancytreeNodeClass.prototype.editCreateNode = function ( + mode, + init + ) { + var newNode, + tree = this.tree, + self = this; + + mode = mode || "child"; + if (init == null) { + init = { title: "" }; + } else if (typeof init === "string") { + init = { title: init }; + } else { + $.ui.fancytree.assert($.isPlainObject(init)); + } + // Make sure node is expanded (and loaded) in 'child' mode + if ( + mode === "child" && + !this.isExpanded() && + this.hasChildren() !== false + ) { + this.setExpanded().done(function () { + self.editCreateNode(mode, init); + }); + return; + } + newNode = this.addNode(init, mode); + + // #644: Don't filter new nodes. + newNode.match = true; + $(newNode[tree.statusClassPropName]) + .removeClass("fancytree-hide") + .addClass("fancytree-match"); + + newNode.makeVisible(/*{noAnimation: true}*/).done(function () { + $(newNode[tree.statusClassPropName]).addClass("fancytree-edit-new"); + self.tree.ext.edit.relatedNode = self; + newNode.editStart(); + }); + }; + + /** + * [ext-edit] Check if any node in this tree in edit mode. + * + * @returns {FancytreeNode | null} + * @alias Fancytree#isEditing + * @requires jquery.fancytree.edit.js + */ + $.ui.fancytree._FancytreeClass.prototype.isEditing = function () { + return this.ext.edit ? this.ext.edit.currentNode : null; + }; + + /** + * [ext-edit] Check if this node is in edit mode. + * @returns {Boolean} true if node is currently beeing edited + * @alias FancytreeNode#isEditing + * @requires jquery.fancytree.edit.js + */ + $.ui.fancytree._FancytreeNodeClass.prototype.isEditing = function () { + return this.tree.ext.edit + ? this.tree.ext.edit.currentNode === this + : false; + }; + + /******************************************************************************* + * Extension code + */ + $.ui.fancytree.registerExtension({ + name: "edit", + version: "2.38.3", + // Default options for this extension. + options: { + adjustWidthOfs: 4, // null: don't adjust input size to content + allowEmpty: false, // Prevent empty input + inputCss: { minWidth: "3em" }, + // triggerCancel: ["esc", "tab", "click"], + triggerStart: ["f2", "mac+enter", "shift+click"], + trim: true, // Trim whitespace before save + // Events: + beforeClose: $.noop, // Return false to prevent cancel/save (data.input is available) + beforeEdit: $.noop, // Return false to prevent edit mode + close: $.noop, // Editor was removed + edit: $.noop, // Editor was opened (available as data.input) + // keypress: $.noop, // Not yet implemented + save: $.noop, // Save data.input.val() or return false to keep editor open + }, + // Local attributes + currentNode: null, + + treeInit: function (ctx) { + var tree = ctx.tree; + + this._superApply(arguments); + + this.$container + .addClass("fancytree-ext-edit") + .on("fancytreebeforeupdateviewport", function (event, data) { + var editNode = tree.isEditing(); + // When scrolling, the TR may be re-used by another node, so the + // active cell marker an + if (editNode) { + editNode.info("Cancel edit due to scroll event."); + editNode.editEnd(false, event); + } + }); + }, + nodeClick: function (ctx) { + var eventStr = $.ui.fancytree.eventToString(ctx.originalEvent), + triggerStart = ctx.options.edit.triggerStart; + + if ( + eventStr === "shift+click" && + $.inArray("shift+click", triggerStart) >= 0 + ) { + if (ctx.originalEvent.shiftKey) { + ctx.node.editStart(); + return false; + } + } + if ( + eventStr === "click" && + $.inArray("clickActive", triggerStart) >= 0 + ) { + // Only when click was inside title text (not aynwhere else in the row) + if ( + ctx.node.isActive() && + !ctx.node.isEditing() && + $(ctx.originalEvent.target).hasClass("fancytree-title") + ) { + ctx.node.editStart(); + return false; + } + } + return this._superApply(arguments); + }, + nodeDblclick: function (ctx) { + if ($.inArray("dblclick", ctx.options.edit.triggerStart) >= 0) { + ctx.node.editStart(); + return false; + } + return this._superApply(arguments); + }, + nodeKeydown: function (ctx) { + switch (ctx.originalEvent.which) { + case 113: // [F2] + if ($.inArray("f2", ctx.options.edit.triggerStart) >= 0) { + ctx.node.editStart(); + return false; + } + break; + case $.ui.keyCode.ENTER: + if ( + $.inArray("mac+enter", ctx.options.edit.triggerStart) >= + 0 && + isMac + ) { + ctx.node.editStart(); + return false; + } + break; + } + return this._superApply(arguments); + }, + }); + // Value returned by `require('jquery.fancytree..')` + return $.ui.fancytree; +}); // End of closure + + +/*! Extension 'jquery.fancytree.filter.js' *//*! + * jquery.fancytree.filter.js + * + * Remove or highlight tree nodes, based on a filter. + * (Extension module for jquery.fancytree.js: https://github.com/mar10/fancytree/) + * + * Copyright (c) 2008-2023, Martin Wendt (https://wwWendt.de) + * + * Released under the MIT license + * https://github.com/mar10/fancytree/wiki/LicenseInfo + * + * @version 2.38.3 + * @date 2023-02-01T20:52:50Z + */ + +(function (factory) { + if (typeof define === "function" && define.amd) { + // AMD. Register as an anonymous module. + define(["jquery", "./jquery.fancytree"], factory); + } else if (typeof module === "object" && module.exports) { + // Node/CommonJS + require("./jquery.fancytree"); + module.exports = factory(require("jquery")); + } else { + // Browser globals + factory(jQuery); + } +})(function ($) { + "use strict"; + + /******************************************************************************* + * Private functions and variables + */ + + var KeyNoData = "__not_found__", + escapeHtml = $.ui.fancytree.escapeHtml, + exoticStartChar = "\uFFF7", + exoticEndChar = "\uFFF8"; + function _escapeRegex(str) { + return (str + "").replace(/([.?*+^$[\]\\(){}|-])/g, "\\$1"); + } + + function extractHtmlText(s) { + if (s.indexOf(">") >= 0) { + return $("<div/>").html(s).text(); + } + return s; + } + + /** + * @description Marks the matching charecters of `text` either by `mark` or + * by exotic*Chars (if `escapeTitles` is `true`) based on `regexMatchArray` + * which is an array of matching groups. + * @param {string} text + * @param {RegExpMatchArray} regexMatchArray + */ + function _markFuzzyMatchedChars(text, regexMatchArray, escapeTitles) { + // It is extremely infuriating that we can not use `let` or `const` or arrow functions. + // Damn you IE!!! + var matchingIndices = []; + // get the indices of matched characters (Iterate through `RegExpMatchArray`) + for ( + var _matchingArrIdx = 1; + _matchingArrIdx < regexMatchArray.length; + _matchingArrIdx++ + ) { + var _mIdx = + // get matching char index by cumulatively adding + // the matched group length + regexMatchArray[_matchingArrIdx].length + + (_matchingArrIdx === 1 ? 0 : 1) + + (matchingIndices[matchingIndices.length - 1] || 0); + matchingIndices.push(_mIdx); + } + // Map each `text` char to its position and store in `textPoses`. + var textPoses = text.split(""); + if (escapeTitles) { + // If escaping the title, then wrap the matchng char within exotic chars + matchingIndices.forEach(function (v) { + textPoses[v] = exoticStartChar + textPoses[v] + exoticEndChar; + }); + } else { + // Otherwise, Wrap the matching chars within `mark`. + matchingIndices.forEach(function (v) { + textPoses[v] = "<mark>" + textPoses[v] + "</mark>"; + }); + } + // Join back the modified `textPoses` to create final highlight markup. + return textPoses.join(""); + } + $.ui.fancytree._FancytreeClass.prototype._applyFilterImpl = function ( + filter, + branchMode, + _opts + ) { + var match, + statusNode, + re, + reHighlight, + reExoticStartChar, + reExoticEndChar, + temp, + prevEnableUpdate, + count = 0, + treeOpts = this.options, + escapeTitles = treeOpts.escapeTitles, + prevAutoCollapse = treeOpts.autoCollapse, + opts = $.extend({}, treeOpts.filter, _opts), + hideMode = opts.mode === "hide", + leavesOnly = !!opts.leavesOnly && !branchMode; + + // Default to 'match title substring (not case sensitive)' + if (typeof filter === "string") { + if (filter === "") { + this.warn( + "Fancytree passing an empty string as a filter is handled as clearFilter()." + ); + this.clearFilter(); + return; + } + if (opts.fuzzy) { + // See https://codereview.stackexchange.com/questions/23899/faster-javascript-fuzzy-string-matching-function/23905#23905 + // and http://www.quora.com/How-is-the-fuzzy-search-algorithm-in-Sublime-Text-designed + // and http://www.dustindiaz.com/autocomplete-fuzzy-matching + match = filter + .split("") + // Escaping the `filter` will not work because, + // it gets further split into individual characters. So, + // escape each character after splitting + .map(_escapeRegex) + .reduce(function (a, b) { + // create capture groups for parts that comes before + // the character + return a + "([^" + b + "]*)" + b; + }, ""); + } else { + match = _escapeRegex(filter); // make sure a '.' is treated literally + } + re = new RegExp(match, "i"); + reHighlight = new RegExp(_escapeRegex(filter), "gi"); + if (escapeTitles) { + reExoticStartChar = new RegExp( + _escapeRegex(exoticStartChar), + "g" + ); + reExoticEndChar = new RegExp(_escapeRegex(exoticEndChar), "g"); + } + filter = function (node) { + if (!node.title) { + return false; + } + var text = escapeTitles + ? node.title + : extractHtmlText(node.title), + // `.match` instead of `.test` to get the capture groups + res = text.match(re); + if (res && opts.highlight) { + if (escapeTitles) { + if (opts.fuzzy) { + temp = _markFuzzyMatchedChars( + text, + res, + escapeTitles + ); + } else { + // #740: we must not apply the marks to escaped entity names, e.g. `"` + // Use some exotic characters to mark matches: + temp = text.replace(reHighlight, function (s) { + return exoticStartChar + s + exoticEndChar; + }); + } + // now we can escape the title... + node.titleWithHighlight = escapeHtml(temp) + // ... and finally insert the desired `<mark>` tags + .replace(reExoticStartChar, "<mark>") + .replace(reExoticEndChar, "</mark>"); + } else { + if (opts.fuzzy) { + node.titleWithHighlight = _markFuzzyMatchedChars( + text, + res + ); + } else { + node.titleWithHighlight = text.replace( + reHighlight, + function (s) { + return "<mark>" + s + "</mark>"; + } + ); + } + } + // node.debug("filter", escapeTitles, text, node.titleWithHighlight); + } + return !!res; + }; + } + + this.enableFilter = true; + this.lastFilterArgs = arguments; + + prevEnableUpdate = this.enableUpdate(false); + + this.$div.addClass("fancytree-ext-filter"); + if (hideMode) { + this.$div.addClass("fancytree-ext-filter-hide"); + } else { + this.$div.addClass("fancytree-ext-filter-dimm"); + } + this.$div.toggleClass( + "fancytree-ext-filter-hide-expanders", + !!opts.hideExpanders + ); + // Reset current filter + this.rootNode.subMatchCount = 0; + this.visit(function (node) { + delete node.match; + delete node.titleWithHighlight; + node.subMatchCount = 0; + }); + statusNode = this.getRootNode()._findDirectChild(KeyNoData); + if (statusNode) { + statusNode.remove(); + } + + // Adjust node.hide, .match, and .subMatchCount properties + treeOpts.autoCollapse = false; // #528 + + this.visit(function (node) { + if (leavesOnly && node.children != null) { + return; + } + var res = filter(node), + matchedByBranch = false; + + if (res === "skip") { + node.visit(function (c) { + c.match = false; + }, true); + return "skip"; + } + if (!res && (branchMode || res === "branch") && node.parent.match) { + res = true; + matchedByBranch = true; + } + if (res) { + count++; + node.match = true; + node.visitParents(function (p) { + if (p !== node) { + p.subMatchCount += 1; + } + // Expand match (unless this is no real match, but only a node in a matched branch) + if (opts.autoExpand && !matchedByBranch && !p.expanded) { + p.setExpanded(true, { + noAnimation: true, + noEvents: true, + scrollIntoView: false, + }); + p._filterAutoExpanded = true; + } + }, true); + } + }); + treeOpts.autoCollapse = prevAutoCollapse; + + if (count === 0 && opts.nodata && hideMode) { + statusNode = opts.nodata; + if (typeof statusNode === "function") { + statusNode = statusNode(); + } + if (statusNode === true) { + statusNode = {}; + } else if (typeof statusNode === "string") { + statusNode = { title: statusNode }; + } + statusNode = $.extend( + { + statusNodeType: "nodata", + key: KeyNoData, + title: this.options.strings.noData, + }, + statusNode + ); + + this.getRootNode().addNode(statusNode).match = true; + } + // Redraw whole tree + this._callHook("treeStructureChanged", this, "applyFilter"); + // this.render(); + this.enableUpdate(prevEnableUpdate); + return count; + }; + + /** + * [ext-filter] Dimm or hide nodes. + * + * @param {function | string} filter + * @param {boolean} [opts={autoExpand: false, leavesOnly: false}] + * @returns {integer} count + * @alias Fancytree#filterNodes + * @requires jquery.fancytree.filter.js + */ + $.ui.fancytree._FancytreeClass.prototype.filterNodes = function ( + filter, + opts + ) { + if (typeof opts === "boolean") { + opts = { leavesOnly: opts }; + this.warn( + "Fancytree.filterNodes() leavesOnly option is deprecated since 2.9.0 / 2015-04-19. Use opts.leavesOnly instead." + ); + } + return this._applyFilterImpl(filter, false, opts); + }; + + /** + * [ext-filter] Dimm or hide whole branches. + * + * @param {function | string} filter + * @param {boolean} [opts={autoExpand: false}] + * @returns {integer} count + * @alias Fancytree#filterBranches + * @requires jquery.fancytree.filter.js + */ + $.ui.fancytree._FancytreeClass.prototype.filterBranches = function ( + filter, + opts + ) { + return this._applyFilterImpl(filter, true, opts); + }; + + /** + * [ext-filter] Re-apply current filter. + * + * @returns {integer} count + * @alias Fancytree#updateFilter + * @requires jquery.fancytree.filter.js + * @since 2.38 + */ + $.ui.fancytree._FancytreeClass.prototype.updateFilter = function () { + if ( + this.enableFilter && + this.lastFilterArgs && + this.options.filter.autoApply + ) { + this._applyFilterImpl.apply(this, this.lastFilterArgs); + } else { + this.warn("updateFilter(): no filter active."); + } + }; + + /** + * [ext-filter] Reset the filter. + * + * @alias Fancytree#clearFilter + * @requires jquery.fancytree.filter.js + */ + $.ui.fancytree._FancytreeClass.prototype.clearFilter = function () { + var $title, + statusNode = this.getRootNode()._findDirectChild(KeyNoData), + escapeTitles = this.options.escapeTitles, + enhanceTitle = this.options.enhanceTitle, + prevEnableUpdate = this.enableUpdate(false); + + if (statusNode) { + statusNode.remove(); + } + // we also counted root node's subMatchCount + delete this.rootNode.match; + delete this.rootNode.subMatchCount; + + this.visit(function (node) { + if (node.match && node.span) { + // #491, #601 + $title = $(node.span).find(">span.fancytree-title"); + if (escapeTitles) { + $title.text(node.title); + } else { + $title.html(node.title); + } + if (enhanceTitle) { + enhanceTitle( + { type: "enhanceTitle" }, + { node: node, $title: $title } + ); + } + } + delete node.match; + delete node.subMatchCount; + delete node.titleWithHighlight; + if (node.$subMatchBadge) { + node.$subMatchBadge.remove(); + delete node.$subMatchBadge; + } + if (node._filterAutoExpanded && node.expanded) { + node.setExpanded(false, { + noAnimation: true, + noEvents: true, + scrollIntoView: false, + }); + } + delete node._filterAutoExpanded; + }); + this.enableFilter = false; + this.lastFilterArgs = null; + this.$div.removeClass( + "fancytree-ext-filter fancytree-ext-filter-dimm fancytree-ext-filter-hide" + ); + this._callHook("treeStructureChanged", this, "clearFilter"); + // this.render(); + this.enableUpdate(prevEnableUpdate); + }; + + /** + * [ext-filter] Return true if a filter is currently applied. + * + * @returns {Boolean} + * @alias Fancytree#isFilterActive + * @requires jquery.fancytree.filter.js + * @since 2.13 + */ + $.ui.fancytree._FancytreeClass.prototype.isFilterActive = function () { + return !!this.enableFilter; + }; + + /** + * [ext-filter] Return true if this node is matched by current filter (or no filter is active). + * + * @returns {Boolean} + * @alias FancytreeNode#isMatched + * @requires jquery.fancytree.filter.js + * @since 2.13 + */ + $.ui.fancytree._FancytreeNodeClass.prototype.isMatched = function () { + return !(this.tree.enableFilter && !this.match); + }; + + /******************************************************************************* + * Extension code + */ + $.ui.fancytree.registerExtension({ + name: "filter", + version: "2.38.3", + // Default options for this extension. + options: { + autoApply: true, // Re-apply last filter if lazy data is loaded + autoExpand: false, // Expand all branches that contain matches while filtered + counter: true, // Show a badge with number of matching child nodes near parent icons + fuzzy: false, // Match single characters in order, e.g. 'fb' will match 'FooBar' + hideExpandedCounter: true, // Hide counter badge if parent is expanded + hideExpanders: false, // Hide expanders if all child nodes are hidden by filter + highlight: true, // Highlight matches by wrapping inside <mark> tags + leavesOnly: false, // Match end nodes only + nodata: true, // Display a 'no data' status node if result is empty + mode: "dimm", // Grayout unmatched nodes (pass "hide" to remove unmatched node instead) + }, + nodeLoadChildren: function (ctx, source) { + var tree = ctx.tree; + + return this._superApply(arguments).done(function () { + if ( + tree.enableFilter && + tree.lastFilterArgs && + ctx.options.filter.autoApply + ) { + tree._applyFilterImpl.apply(tree, tree.lastFilterArgs); + } + }); + }, + nodeSetExpanded: function (ctx, flag, callOpts) { + var node = ctx.node; + + delete node._filterAutoExpanded; + // Make sure counter badge is displayed again, when node is beeing collapsed + if ( + !flag && + ctx.options.filter.hideExpandedCounter && + node.$subMatchBadge + ) { + node.$subMatchBadge.show(); + } + return this._superApply(arguments); + }, + nodeRenderStatus: function (ctx) { + // Set classes for current status + var res, + node = ctx.node, + tree = ctx.tree, + opts = ctx.options.filter, + $title = $(node.span).find("span.fancytree-title"), + $span = $(node[tree.statusClassPropName]), + enhanceTitle = ctx.options.enhanceTitle, + escapeTitles = ctx.options.escapeTitles; + + res = this._super(ctx); + // nothing to do, if node was not yet rendered + if (!$span.length || !tree.enableFilter) { + return res; + } + $span + .toggleClass("fancytree-match", !!node.match) + .toggleClass("fancytree-submatch", !!node.subMatchCount) + .toggleClass( + "fancytree-hide", + !(node.match || node.subMatchCount) + ); + // Add/update counter badge + if ( + opts.counter && + node.subMatchCount && + (!node.isExpanded() || !opts.hideExpandedCounter) + ) { + if (!node.$subMatchBadge) { + node.$subMatchBadge = $( + "<span class='fancytree-childcounter'/>" + ); + $( + "span.fancytree-icon, span.fancytree-custom-icon", + node.span + ).append(node.$subMatchBadge); + } + node.$subMatchBadge.show().text(node.subMatchCount); + } else if (node.$subMatchBadge) { + node.$subMatchBadge.hide(); + } + // node.debug("nodeRenderStatus", node.titleWithHighlight, node.title) + // #601: also check for $title.length, because we don't need to render + // if node.span is null (i.e. not rendered) + if (node.span && (!node.isEditing || !node.isEditing.call(node))) { + if (node.titleWithHighlight) { + $title.html(node.titleWithHighlight); + } else if (escapeTitles) { + $title.text(node.title); + } else { + $title.html(node.title); + } + if (enhanceTitle) { + enhanceTitle( + { type: "enhanceTitle" }, + { node: node, $title: $title } + ); + } + } + return res; + }, + }); + // Value returned by `require('jquery.fancytree..')` + return $.ui.fancytree; +}); // End of closure + + +/*! Extension 'jquery.fancytree.glyph.js' *//*! + * jquery.fancytree.glyph.js + * + * Use glyph-fonts, ligature-fonts, or SVG icons instead of icon sprites. + * (Extension module for jquery.fancytree.js: https://github.com/mar10/fancytree/) + * + * Copyright (c) 2008-2023, Martin Wendt (https://wwWendt.de) + * + * Released under the MIT license + * https://github.com/mar10/fancytree/wiki/LicenseInfo + * + * @version 2.38.3 + * @date 2023-02-01T20:52:50Z + */ + +(function (factory) { + if (typeof define === "function" && define.amd) { + // AMD. Register as an anonymous module. + define(["jquery", "./jquery.fancytree"], factory); + } else if (typeof module === "object" && module.exports) { + // Node/CommonJS + require("./jquery.fancytree"); + module.exports = factory(require("jquery")); + } else { + // Browser globals + factory(jQuery); + } +})(function ($) { + "use strict"; + + /****************************************************************************** + * Private functions and variables + */ + + var FT = $.ui.fancytree, + PRESETS = { + awesome3: { + // Outdated! + _addClass: "", + checkbox: "icon-check-empty", + checkboxSelected: "icon-check", + checkboxUnknown: "icon-check icon-muted", + dragHelper: "icon-caret-right", + dropMarker: "icon-caret-right", + error: "icon-exclamation-sign", + expanderClosed: "icon-caret-right", + expanderLazy: "icon-angle-right", + expanderOpen: "icon-caret-down", + loading: "icon-refresh icon-spin", + nodata: "icon-meh", + noExpander: "", + radio: "icon-circle-blank", + radioSelected: "icon-circle", + // radioUnknown: "icon-circle icon-muted", + // Default node icons. + // (Use tree.options.icon callback to define custom icons based on node data) + doc: "icon-file-alt", + docOpen: "icon-file-alt", + folder: "icon-folder-close-alt", + folderOpen: "icon-folder-open-alt", + }, + awesome4: { + _addClass: "fa", + checkbox: "fa-square-o", + checkboxSelected: "fa-check-square-o", + checkboxUnknown: "fa-square fancytree-helper-indeterminate-cb", + dragHelper: "fa-arrow-right", + dropMarker: "fa-long-arrow-right", + error: "fa-warning", + expanderClosed: "fa-caret-right", + expanderLazy: "fa-angle-right", + expanderOpen: "fa-caret-down", + // We may prevent wobbling rotations on FF by creating a separate sub element: + loading: { html: "<span class='fa fa-spinner fa-pulse' />" }, + nodata: "fa-meh-o", + noExpander: "", + radio: "fa-circle-thin", // "fa-circle-o" + radioSelected: "fa-circle", + // radioUnknown: "fa-dot-circle-o", + // Default node icons. + // (Use tree.options.icon callback to define custom icons based on node data) + doc: "fa-file-o", + docOpen: "fa-file-o", + folder: "fa-folder-o", + folderOpen: "fa-folder-open-o", + }, + awesome5: { + // fontawesome 5 have several different base classes + // "far, fas, fal and fab" The rendered svg puts that prefix + // in a different location so we have to keep them separate here + _addClass: "", + checkbox: "far fa-square", + checkboxSelected: "far fa-check-square", + // checkboxUnknown: "far fa-window-close", + checkboxUnknown: + "fas fa-square fancytree-helper-indeterminate-cb", + radio: "far fa-circle", + radioSelected: "fas fa-circle", + radioUnknown: "far fa-dot-circle", + dragHelper: "fas fa-arrow-right", + dropMarker: "fas fa-long-arrow-alt-right", + error: "fas fa-exclamation-triangle", + expanderClosed: "fas fa-caret-right", + expanderLazy: "fas fa-angle-right", + expanderOpen: "fas fa-caret-down", + loading: "fas fa-spinner fa-pulse", + nodata: "far fa-meh", + noExpander: "", + // Default node icons. + // (Use tree.options.icon callback to define custom icons based on node data) + doc: "far fa-file", + docOpen: "far fa-file", + folder: "far fa-folder", + folderOpen: "far fa-folder-open", + }, + bootstrap3: { + _addClass: "glyphicon", + checkbox: "glyphicon-unchecked", + checkboxSelected: "glyphicon-check", + checkboxUnknown: + "glyphicon-expand fancytree-helper-indeterminate-cb", // "glyphicon-share", + dragHelper: "glyphicon-play", + dropMarker: "glyphicon-arrow-right", + error: "glyphicon-warning-sign", + expanderClosed: "glyphicon-menu-right", // glyphicon-plus-sign + expanderLazy: "glyphicon-menu-right", // glyphicon-plus-sign + expanderOpen: "glyphicon-menu-down", // glyphicon-minus-sign + loading: "glyphicon-refresh fancytree-helper-spin", + nodata: "glyphicon-info-sign", + noExpander: "", + radio: "glyphicon-remove-circle", // "glyphicon-unchecked", + radioSelected: "glyphicon-ok-circle", // "glyphicon-check", + // radioUnknown: "glyphicon-ban-circle", + // Default node icons. + // (Use tree.options.icon callback to define custom icons based on node data) + doc: "glyphicon-file", + docOpen: "glyphicon-file", + folder: "glyphicon-folder-close", + folderOpen: "glyphicon-folder-open", + }, + material: { + _addClass: "material-icons", + checkbox: { text: "check_box_outline_blank" }, + checkboxSelected: { text: "check_box" }, + checkboxUnknown: { text: "indeterminate_check_box" }, + dragHelper: { text: "play_arrow" }, + dropMarker: { text: "arrow-forward" }, + error: { text: "warning" }, + expanderClosed: { text: "chevron_right" }, + expanderLazy: { text: "last_page" }, + expanderOpen: { text: "expand_more" }, + loading: { + text: "autorenew", + addClass: "fancytree-helper-spin", + }, + nodata: { text: "info" }, + noExpander: { text: "" }, + radio: { text: "radio_button_unchecked" }, + radioSelected: { text: "radio_button_checked" }, + // Default node icons. + // (Use tree.options.icon callback to define custom icons based on node data) + doc: { text: "insert_drive_file" }, + docOpen: { text: "insert_drive_file" }, + folder: { text: "folder" }, + folderOpen: { text: "folder_open" }, + }, + }; + + function setIcon(node, span, baseClass, opts, type) { + var map = opts.map, + icon = map[type], + $span = $(span), + $counter = $span.find(".fancytree-childcounter"), + setClass = baseClass + " " + (map._addClass || ""); + + // #871 Allow a callback + if (typeof icon === "function") { + icon = icon.call(this, node, span, type); + } + // node.debug( "setIcon(" + baseClass + ", " + type + "): " + "oldIcon" + " -> " + icon ); + // #871: propsed this, but I am not sure how robust this is, e.g. + // the prefix (fas, far) class changes are not considered? + // if (span.tagName === "svg" && opts.preset === "awesome5") { + // // fa5 script converts <i> to <svg> so call a specific handler. + // var oldIcon = "fa-" + $span.data("icon"); + // // node.debug( "setIcon(" + baseClass + ", " + type + "): " + oldIcon + " -> " + icon ); + // if (typeof oldIcon === "string") { + // $span.removeClass(oldIcon); + // } + // if (typeof icon === "string") { + // $span.addClass(icon); + // } + // return; + // } + if (typeof icon === "string") { + // #883: remove inner html that may be added by prev. mode + span.innerHTML = ""; + $span.attr("class", setClass + " " + icon).append($counter); + } else if (icon) { + if (icon.text) { + span.textContent = "" + icon.text; + } else if (icon.html) { + span.innerHTML = icon.html; + } else { + span.innerHTML = ""; + } + $span + .attr("class", setClass + " " + (icon.addClass || "")) + .append($counter); + } + } + + $.ui.fancytree.registerExtension({ + name: "glyph", + version: "2.38.3", + // Default options for this extension. + options: { + preset: null, // 'awesome3', 'awesome4', 'bootstrap3', 'material' + map: {}, + }, + + treeInit: function (ctx) { + var tree = ctx.tree, + opts = ctx.options.glyph; + + if (opts.preset) { + FT.assert( + !!PRESETS[opts.preset], + "Invalid value for `options.glyph.preset`: " + opts.preset + ); + opts.map = $.extend({}, PRESETS[opts.preset], opts.map); + } else { + tree.warn("ext-glyph: missing `preset` option."); + } + this._superApply(arguments); + tree.$container.addClass("fancytree-ext-glyph"); + }, + nodeRenderStatus: function (ctx) { + var checkbox, + icon, + res, + span, + node = ctx.node, + $span = $(node.span), + opts = ctx.options.glyph; + + res = this._super(ctx); + + if (node.isRootNode()) { + return res; + } + span = $span.children(".fancytree-expander").get(0); + if (span) { + // if( node.isLoading() ){ + // icon = "loading"; + if (node.expanded && node.hasChildren()) { + icon = "expanderOpen"; + } else if (node.isUndefined()) { + icon = "expanderLazy"; + } else if (node.hasChildren()) { + icon = "expanderClosed"; + } else { + icon = "noExpander"; + } + // span.className = "fancytree-expander " + map[icon]; + setIcon(node, span, "fancytree-expander", opts, icon); + } + + if (node.tr) { + span = $("td", node.tr).find(".fancytree-checkbox").get(0); + } else { + span = $span.children(".fancytree-checkbox").get(0); + } + if (span) { + checkbox = FT.evalOption("checkbox", node, node, opts, false); + if ( + (node.parent && node.parent.radiogroup) || + checkbox === "radio" + ) { + icon = node.selected ? "radioSelected" : "radio"; + setIcon( + node, + span, + "fancytree-checkbox fancytree-radio", + opts, + icon + ); + } else { + // eslint-disable-next-line no-nested-ternary + icon = node.selected + ? "checkboxSelected" + : node.partsel + ? "checkboxUnknown" + : "checkbox"; + // span.className = "fancytree-checkbox " + map[icon]; + setIcon(node, span, "fancytree-checkbox", opts, icon); + } + } + + // Standard icon (note that this does not match .fancytree-custom-icon, + // that might be set by opts.icon callbacks) + span = $span.children(".fancytree-icon").get(0); + if (span) { + if (node.statusNodeType) { + icon = node.statusNodeType; // loading, error + } else if (node.folder) { + icon = + node.expanded && node.hasChildren() + ? "folderOpen" + : "folder"; + } else { + icon = node.expanded ? "docOpen" : "doc"; + } + setIcon(node, span, "fancytree-icon", opts, icon); + } + return res; + }, + nodeSetStatus: function (ctx, status, message, details) { + var res, + span, + opts = ctx.options.glyph, + node = ctx.node; + + res = this._superApply(arguments); + + if ( + status === "error" || + status === "loading" || + status === "nodata" + ) { + if (node.parent) { + span = $(".fancytree-expander", node.span).get(0); + if (span) { + setIcon(node, span, "fancytree-expander", opts, status); + } + } else { + // + span = $( + ".fancytree-statusnode-" + status, + node[this.nodeContainerAttrName] + ) + .find(".fancytree-icon") + .get(0); + if (span) { + setIcon(node, span, "fancytree-icon", opts, status); + } + } + } + return res; + }, + }); + // Value returned by `require('jquery.fancytree..')` + return $.ui.fancytree; +}); // End of closure + + +/*! Extension 'jquery.fancytree.gridnav.js' *//*! + * jquery.fancytree.gridnav.js + * + * Support keyboard navigation for trees with embedded input controls. + * (Extension module for jquery.fancytree.js: https://github.com/mar10/fancytree/) + * + * Copyright (c) 2008-2023, Martin Wendt (https://wwWendt.de) + * + * Released under the MIT license + * https://github.com/mar10/fancytree/wiki/LicenseInfo + * + * @version 2.38.3 + * @date 2023-02-01T20:52:50Z + */ + +(function (factory) { + if (typeof define === "function" && define.amd) { + // AMD. Register as an anonymous module. + define([ + "jquery", + "./jquery.fancytree", + "./jquery.fancytree.table", + ], factory); + } else if (typeof module === "object" && module.exports) { + // Node/CommonJS + require("./jquery.fancytree.table"); // core + table + module.exports = factory(require("jquery")); + } else { + // Browser globals + factory(jQuery); + } +})(function ($) { + "use strict"; + + /******************************************************************************* + * Private functions and variables + */ + + // Allow these navigation keys even when input controls are focused + + var KC = $.ui.keyCode, + // which keys are *not* handled by embedded control, but passed to tree + // navigation handler: + NAV_KEYS = { + text: [KC.UP, KC.DOWN], + checkbox: [KC.UP, KC.DOWN, KC.LEFT, KC.RIGHT], + link: [KC.UP, KC.DOWN, KC.LEFT, KC.RIGHT], + radiobutton: [KC.UP, KC.DOWN, KC.LEFT, KC.RIGHT], + "select-one": [KC.LEFT, KC.RIGHT], + "select-multiple": [KC.LEFT, KC.RIGHT], + }; + + /* Calculate TD column index (considering colspans).*/ + function getColIdx($tr, $td) { + var colspan, + td = $td.get(0), + idx = 0; + + $tr.children().each(function () { + if (this === td) { + return false; + } + colspan = $(this).prop("colspan"); + idx += colspan ? colspan : 1; + }); + return idx; + } + + /* Find TD at given column index (considering colspans).*/ + function findTdAtColIdx($tr, colIdx) { + var colspan, + res = null, + idx = 0; + + $tr.children().each(function () { + if (idx >= colIdx) { + res = $(this); + return false; + } + colspan = $(this).prop("colspan"); + idx += colspan ? colspan : 1; + }); + return res; + } + + /* Find adjacent cell for a given direction. Skip empty cells and consider merged cells */ + function findNeighbourTd($target, keyCode) { + var $tr, + colIdx, + $td = $target.closest("td"), + $tdNext = null; + + switch (keyCode) { + case KC.LEFT: + $tdNext = $td.prev(); + break; + case KC.RIGHT: + $tdNext = $td.next(); + break; + case KC.UP: + case KC.DOWN: + $tr = $td.parent(); + colIdx = getColIdx($tr, $td); + while (true) { + $tr = keyCode === KC.UP ? $tr.prev() : $tr.next(); + if (!$tr.length) { + break; + } + // Skip hidden rows + if ($tr.is(":hidden")) { + continue; + } + // Find adjacent cell in the same column + $tdNext = findTdAtColIdx($tr, colIdx); + // Skip cells that don't conatain a focusable element + if ($tdNext && $tdNext.find(":input,a").length) { + break; + } + } + break; + } + return $tdNext; + } + + /******************************************************************************* + * Extension code + */ + $.ui.fancytree.registerExtension({ + name: "gridnav", + version: "2.38.3", + // Default options for this extension. + options: { + autofocusInput: false, // Focus first embedded input if node gets activated + handleCursorKeys: true, // Allow UP/DOWN in inputs to move to prev/next node + }, + + treeInit: function (ctx) { + // gridnav requires the table extension to be loaded before itself + this._requireExtension("table", true, true); + this._superApply(arguments); + + this.$container.addClass("fancytree-ext-gridnav"); + + // Activate node if embedded input gets focus (due to a click) + this.$container.on("focusin", function (event) { + var ctx2, + node = $.ui.fancytree.getNode(event.target); + + if (node && !node.isActive()) { + // Call node.setActive(), but also pass the event + ctx2 = ctx.tree._makeHookContext(node, event); + ctx.tree._callHook("nodeSetActive", ctx2, true); + } + }); + }, + nodeSetActive: function (ctx, flag, callOpts) { + var $outer, + opts = ctx.options.gridnav, + node = ctx.node, + event = ctx.originalEvent || {}, + triggeredByInput = $(event.target).is(":input"); + + flag = flag !== false; + + this._superApply(arguments); + + if (flag) { + if (ctx.options.titlesTabbable) { + if (!triggeredByInput) { + $(node.span).find("span.fancytree-title").focus(); + node.setFocus(); + } + // If one node is tabbable, the container no longer needs to be + ctx.tree.$container.attr("tabindex", "-1"); + // ctx.tree.$container.removeAttr("tabindex"); + } else if (opts.autofocusInput && !triggeredByInput) { + // Set focus to input sub input (if node was clicked, but not + // when TAB was pressed ) + $outer = $(node.tr || node.span); + $outer.find(":input:enabled").first().focus(); + } + } + }, + nodeKeydown: function (ctx) { + var inputType, + handleKeys, + $td, + opts = ctx.options.gridnav, + event = ctx.originalEvent, + $target = $(event.target); + + if ($target.is(":input:enabled")) { + inputType = $target.prop("type"); + } else if ($target.is("a")) { + inputType = "link"; + } + // ctx.tree.debug("ext-gridnav nodeKeydown", event, inputType); + + if (inputType && opts.handleCursorKeys) { + handleKeys = NAV_KEYS[inputType]; + if (handleKeys && $.inArray(event.which, handleKeys) >= 0) { + $td = findNeighbourTd($target, event.which); + if ($td && $td.length) { + // ctx.node.debug("ignore keydown in input", event.which, handleKeys); + $td.find(":input:enabled,a").focus(); + // Prevent Fancytree default navigation + return false; + } + } + return true; + } + // ctx.tree.debug("ext-gridnav NOT HANDLED", event, inputType); + return this._superApply(arguments); + }, + }); + // Value returned by `require('jquery.fancytree..')` + return $.ui.fancytree; +}); // End of closure + + +/*! Extension 'jquery.fancytree.multi.js' *//*! + * jquery.fancytree.multi.js + * + * Allow multiple selection of nodes by mouse or keyboard. + * (Extension module for jquery.fancytree.js: https://github.com/mar10/fancytree/) + * + * Copyright (c) 2008-2023, Martin Wendt (https://wwWendt.de) + * + * Released under the MIT license + * https://github.com/mar10/fancytree/wiki/LicenseInfo + * + * @version 2.38.3 + * @date 2023-02-01T20:52:50Z + */ + +(function (factory) { + if (typeof define === "function" && define.amd) { + // AMD. Register as an anonymous module. + define(["jquery", "./jquery.fancytree"], factory); + } else if (typeof module === "object" && module.exports) { + // Node/CommonJS + require("./jquery.fancytree"); + module.exports = factory(require("jquery")); + } else { + // Browser globals + factory(jQuery); + } +})(function ($) { + "use strict"; + + /******************************************************************************* + * Private functions and variables + */ + + // var isMac = /Mac/.test(navigator.platform); + + /******************************************************************************* + * Extension code + */ + $.ui.fancytree.registerExtension({ + name: "multi", + version: "2.38.3", + // Default options for this extension. + options: { + allowNoSelect: false, // + mode: "sameParent", // + // Events: + // beforeSelect: $.noop // Return false to prevent cancel/save (data.input is available) + }, + + treeInit: function (ctx) { + this._superApply(arguments); + this.$container.addClass("fancytree-ext-multi"); + if (ctx.options.selectMode === 1) { + $.error( + "Fancytree ext-multi: selectMode: 1 (single) is not compatible." + ); + } + }, + nodeClick: function (ctx) { + var //pluginOpts = ctx.options.multi, + tree = ctx.tree, + node = ctx.node, + activeNode = tree.getActiveNode() || tree.getFirstChild(), + isCbClick = ctx.targetType === "checkbox", + isExpanderClick = ctx.targetType === "expander", + eventStr = $.ui.fancytree.eventToString(ctx.originalEvent); + + switch (eventStr) { + case "click": + if (isExpanderClick) { + break; + } // Default handler will expand/collapse + if (!isCbClick) { + tree.selectAll(false); + // Select clicked node (radio-button mode) + node.setSelected(); + } + // Default handler will toggle checkbox clicks and activate + break; + case "shift+click": + // node.debug("click") + tree.visitRows( + function (n) { + // n.debug("click2", n===node, node) + n.setSelected(); + if (n === node) { + return false; + } + }, + { + start: activeNode, + reverse: activeNode.isBelowOf(node), + } + ); + break; + case "ctrl+click": + case "meta+click": // Mac: [Command] + node.toggleSelected(); + return; + } + return this._superApply(arguments); + }, + nodeKeydown: function (ctx) { + var tree = ctx.tree, + node = ctx.node, + event = ctx.originalEvent, + eventStr = $.ui.fancytree.eventToString(event); + + switch (eventStr) { + case "up": + case "down": + tree.selectAll(false); + node.navigate(event.which, true); + tree.getActiveNode().setSelected(); + break; + case "shift+up": + case "shift+down": + node.navigate(event.which, true); + tree.getActiveNode().setSelected(); + break; + } + return this._superApply(arguments); + }, + }); + // Value returned by `require('jquery.fancytree..')` + return $.ui.fancytree; +}); // End of closure + + +/*! Extension 'jquery.fancytree.persist.js' *//*! + * jquery.fancytree.persist.js + * + * Persist tree status in cookiesRemove or highlight tree nodes, based on a filter. + * (Extension module for jquery.fancytree.js: https://github.com/mar10/fancytree/) + * + * @depends: js-cookie or jquery-cookie + * + * Copyright (c) 2008-2023, Martin Wendt (https://wwWendt.de) + * + * Released under the MIT license + * https://github.com/mar10/fancytree/wiki/LicenseInfo + * + * @version 2.38.3 + * @date 2023-02-01T20:52:50Z + */ + +(function (factory) { + if (typeof define === "function" && define.amd) { + // AMD. Register as an anonymous module. + define(["jquery", "./jquery.fancytree"], factory); + } else if (typeof module === "object" && module.exports) { + // Node/CommonJS + require("./jquery.fancytree"); + module.exports = factory(require("jquery")); + } else { + // Browser globals + factory(jQuery); + } +})(function ($) { + "use strict"; + /* global Cookies:false */ + + /******************************************************************************* + * Private functions and variables + */ + var cookieStore = null, + localStorageStore = null, + sessionStorageStore = null, + _assert = $.ui.fancytree.assert, + ACTIVE = "active", + EXPANDED = "expanded", + FOCUS = "focus", + SELECTED = "selected"; + + // Accessing window.xxxStorage may raise security exceptions (see #1022) + try { + _assert(window.localStorage && window.localStorage.getItem); + localStorageStore = { + get: function (key) { + return window.localStorage.getItem(key); + }, + set: function (key, value) { + window.localStorage.setItem(key, value); + }, + remove: function (key) { + window.localStorage.removeItem(key); + }, + }; + } catch (e) { + $.ui.fancytree.warn("Could not access window.localStorage", e); + } + + try { + _assert(window.sessionStorage && window.sessionStorage.getItem); + sessionStorageStore = { + get: function (key) { + return window.sessionStorage.getItem(key); + }, + set: function (key, value) { + window.sessionStorage.setItem(key, value); + }, + remove: function (key) { + window.sessionStorage.removeItem(key); + }, + }; + } catch (e) { + $.ui.fancytree.warn("Could not access window.sessionStorage", e); + } + + if (typeof Cookies === "function") { + // Assume https://github.com/js-cookie/js-cookie + cookieStore = { + get: Cookies.get, + set: function (key, value) { + Cookies.set(key, value, this.options.persist.cookie); + }, + remove: Cookies.remove, + }; + } else if ($ && typeof $.cookie === "function") { + // Fall back to https://github.com/carhartl/jquery-cookie + cookieStore = { + get: $.cookie, + set: function (key, value) { + $.cookie(key, value, this.options.persist.cookie); + }, + remove: $.removeCookie, + }; + } + + /* Recursively load lazy nodes + * @param {string} mode 'load', 'expand', false + */ + function _loadLazyNodes(tree, local, keyList, mode, dfd) { + var i, + key, + l, + node, + foundOne = false, + expandOpts = tree.options.persist.expandOpts, + deferredList = [], + missingKeyList = []; + + keyList = keyList || []; + dfd = dfd || $.Deferred(); + + for (i = 0, l = keyList.length; i < l; i++) { + key = keyList[i]; + node = tree.getNodeByKey(key); + if (node) { + if (mode && node.isUndefined()) { + foundOne = true; + tree.debug( + "_loadLazyNodes: " + node + " is lazy: loading..." + ); + if (mode === "expand") { + deferredList.push(node.setExpanded(true, expandOpts)); + } else { + deferredList.push(node.load()); + } + } else { + tree.debug("_loadLazyNodes: " + node + " already loaded."); + node.setExpanded(true, expandOpts); + } + } else { + missingKeyList.push(key); + tree.debug("_loadLazyNodes: " + node + " was not yet found."); + } + } + + $.when.apply($, deferredList).always(function () { + // All lazy-expands have finished + if (foundOne && missingKeyList.length > 0) { + // If we read new nodes from server, try to resolve yet-missing keys + _loadLazyNodes(tree, local, missingKeyList, mode, dfd); + } else { + if (missingKeyList.length) { + tree.warn( + "_loadLazyNodes: could not load those keys: ", + missingKeyList + ); + for (i = 0, l = missingKeyList.length; i < l; i++) { + key = keyList[i]; + local._appendKey(EXPANDED, keyList[i], false); + } + } + dfd.resolve(); + } + }); + return dfd; + } + + /** + * [ext-persist] Remove persistence data of the given type(s). + * Called like + * $.ui.fancytree.getTree("#tree").clearCookies("active expanded focus selected"); + * + * @alias Fancytree#clearPersistData + * @requires jquery.fancytree.persist.js + */ + $.ui.fancytree._FancytreeClass.prototype.clearPersistData = function ( + types + ) { + var local = this.ext.persist, + prefix = local.cookiePrefix; + + types = types || "active expanded focus selected"; + if (types.indexOf(ACTIVE) >= 0) { + local._data(prefix + ACTIVE, null); + } + if (types.indexOf(EXPANDED) >= 0) { + local._data(prefix + EXPANDED, null); + } + if (types.indexOf(FOCUS) >= 0) { + local._data(prefix + FOCUS, null); + } + if (types.indexOf(SELECTED) >= 0) { + local._data(prefix + SELECTED, null); + } + }; + + $.ui.fancytree._FancytreeClass.prototype.clearCookies = function (types) { + this.warn( + "'tree.clearCookies()' is deprecated since v2.27.0: use 'clearPersistData()' instead." + ); + return this.clearPersistData(types); + }; + + /** + * [ext-persist] Return persistence information from cookies + * + * Called like + * $.ui.fancytree.getTree("#tree").getPersistData(); + * + * @alias Fancytree#getPersistData + * @requires jquery.fancytree.persist.js + */ + $.ui.fancytree._FancytreeClass.prototype.getPersistData = function () { + var local = this.ext.persist, + prefix = local.cookiePrefix, + delim = local.cookieDelimiter, + res = {}; + + res[ACTIVE] = local._data(prefix + ACTIVE); + res[EXPANDED] = (local._data(prefix + EXPANDED) || "").split(delim); + res[SELECTED] = (local._data(prefix + SELECTED) || "").split(delim); + res[FOCUS] = local._data(prefix + FOCUS); + return res; + }; + + /****************************************************************************** + * Extension code + */ + $.ui.fancytree.registerExtension({ + name: "persist", + version: "2.38.3", + // Default options for this extension. + options: { + cookieDelimiter: "~", + cookiePrefix: undefined, // 'fancytree-<treeId>-' by default + cookie: { + raw: false, + expires: "", + path: "", + domain: "", + secure: false, + }, + expandLazy: false, // true: recursively expand and load lazy nodes + expandOpts: undefined, // optional `opts` argument passed to setExpanded() + fireActivate: true, // false: suppress `activate` event after active node was restored + overrideSource: true, // true: cookie takes precedence over `source` data attributes. + store: "auto", // 'cookie': force cookie, 'local': force localStore, 'session': force sessionStore + types: "active expanded focus selected", + }, + + /* Generic read/write string data to cookie, sessionStorage or localStorage. */ + _data: function (key, value) { + var store = this._local.store; + + if (value === undefined) { + return store.get.call(this, key); + } else if (value === null) { + store.remove.call(this, key); + } else { + store.set.call(this, key, value); + } + }, + + /* Append `key` to a cookie. */ + _appendKey: function (type, key, flag) { + key = "" + key; // #90 + var local = this._local, + instOpts = this.options.persist, + delim = instOpts.cookieDelimiter, + cookieName = local.cookiePrefix + type, + data = local._data(cookieName), + keyList = data ? data.split(delim) : [], + idx = $.inArray(key, keyList); + // Remove, even if we add a key, so the key is always the last entry + if (idx >= 0) { + keyList.splice(idx, 1); + } + // Append key to cookie + if (flag) { + keyList.push(key); + } + local._data(cookieName, keyList.join(delim)); + }, + + treeInit: function (ctx) { + var tree = ctx.tree, + opts = ctx.options, + local = this._local, + instOpts = this.options.persist; + + // // For 'auto' or 'cookie' mode, the cookie plugin must be available + // _assert((instOpts.store !== "auto" && instOpts.store !== "cookie") || cookieStore, + // "Missing required plugin for 'persist' extension: js.cookie.js or jquery.cookie.js"); + + local.cookiePrefix = + instOpts.cookiePrefix || "fancytree-" + tree._id + "-"; + local.storeActive = instOpts.types.indexOf(ACTIVE) >= 0; + local.storeExpanded = instOpts.types.indexOf(EXPANDED) >= 0; + local.storeSelected = instOpts.types.indexOf(SELECTED) >= 0; + local.storeFocus = instOpts.types.indexOf(FOCUS) >= 0; + local.store = null; + + if (instOpts.store === "auto") { + instOpts.store = localStorageStore ? "local" : "cookie"; + } + if ($.isPlainObject(instOpts.store)) { + local.store = instOpts.store; + } else if (instOpts.store === "cookie") { + local.store = cookieStore; + } else if (instOpts.store === "local") { + local.store = + instOpts.store === "local" + ? localStorageStore + : sessionStorageStore; + } else if (instOpts.store === "session") { + local.store = + instOpts.store === "local" + ? localStorageStore + : sessionStorageStore; + } + _assert(local.store, "Need a valid store."); + + // Bind init-handler to apply cookie state + tree.$div.on("fancytreeinit", function (event) { + if ( + tree._triggerTreeEvent("beforeRestore", null, {}) === false + ) { + return; + } + + var cookie, + dfd, + i, + keyList, + node, + prevFocus = local._data(local.cookiePrefix + FOCUS), // record this before node.setActive() overrides it; + noEvents = instOpts.fireActivate === false; + + // tree.debug("document.cookie:", document.cookie); + + cookie = local._data(local.cookiePrefix + EXPANDED); + keyList = cookie && cookie.split(instOpts.cookieDelimiter); + + if (local.storeExpanded) { + // Recursively load nested lazy nodes if expandLazy is 'expand' or 'load' + // Also remove expand-cookies for unmatched nodes + dfd = _loadLazyNodes( + tree, + local, + keyList, + instOpts.expandLazy ? "expand" : false, + null + ); + } else { + // nothing to do + dfd = new $.Deferred().resolve(); + } + + dfd.done(function () { + if (local.storeSelected) { + cookie = local._data(local.cookiePrefix + SELECTED); + if (cookie) { + keyList = cookie.split(instOpts.cookieDelimiter); + for (i = 0; i < keyList.length; i++) { + node = tree.getNodeByKey(keyList[i]); + if (node) { + if ( + node.selected === undefined || + (instOpts.overrideSource && + node.selected === false) + ) { + // node.setSelected(); + node.selected = true; + node.renderStatus(); + } + } else { + // node is no longer member of the tree: remove from cookie also + local._appendKey( + SELECTED, + keyList[i], + false + ); + } + } + } + // In selectMode 3 we have to fix the child nodes, since we + // only stored the selected *top* nodes + if (tree.options.selectMode === 3) { + tree.visit(function (n) { + if (n.selected) { + n.fixSelection3AfterClick(); + return "skip"; + } + }); + } + } + if (local.storeActive) { + cookie = local._data(local.cookiePrefix + ACTIVE); + if ( + cookie && + (opts.persist.overrideSource || !tree.activeNode) + ) { + node = tree.getNodeByKey(cookie); + if (node) { + node.debug("persist: set active", cookie); + // We only want to set the focus if the container + // had the keyboard focus before + node.setActive(true, { + noFocus: true, + noEvents: noEvents, + }); + } + } + } + if (local.storeFocus && prevFocus) { + node = tree.getNodeByKey(prevFocus); + if (node) { + // node.debug("persist: set focus", cookie); + if (tree.options.titlesTabbable) { + $(node.span).find(".fancytree-title").focus(); + } else { + $(tree.$container).focus(); + } + // node.setFocus(); + } + } + tree._triggerTreeEvent("restore", null, {}); + }); + }); + // Init the tree + return this._superApply(arguments); + }, + nodeSetActive: function (ctx, flag, callOpts) { + var res, + local = this._local; + + flag = flag !== false; + res = this._superApply(arguments); + + if (local.storeActive) { + local._data( + local.cookiePrefix + ACTIVE, + this.activeNode ? this.activeNode.key : null + ); + } + return res; + }, + nodeSetExpanded: function (ctx, flag, callOpts) { + var res, + node = ctx.node, + local = this._local; + + flag = flag !== false; + res = this._superApply(arguments); + + if (local.storeExpanded) { + local._appendKey(EXPANDED, node.key, flag); + } + return res; + }, + nodeSetFocus: function (ctx, flag) { + var res, + local = this._local; + + flag = flag !== false; + res = this._superApply(arguments); + + if (local.storeFocus) { + local._data( + local.cookiePrefix + FOCUS, + this.focusNode ? this.focusNode.key : null + ); + } + return res; + }, + nodeSetSelected: function (ctx, flag, callOpts) { + var res, + selNodes, + tree = ctx.tree, + node = ctx.node, + local = this._local; + + flag = flag !== false; + res = this._superApply(arguments); + + if (local.storeSelected) { + if (tree.options.selectMode === 3) { + // In selectMode 3 we only store the the selected *top* nodes. + // De-selecting a node may also de-select some parents, so we + // calculate the current status again + selNodes = $.map(tree.getSelectedNodes(true), function (n) { + return n.key; + }); + selNodes = selNodes.join( + ctx.options.persist.cookieDelimiter + ); + local._data(local.cookiePrefix + SELECTED, selNodes); + } else { + // beforeSelect can prevent the change - flag doesn't reflect the node.selected state + local._appendKey(SELECTED, node.key, node.selected); + } + } + return res; + }, + }); + // Value returned by `require('jquery.fancytree..')` + return $.ui.fancytree; +}); // End of closure + + +/*! Extension 'jquery.fancytree.table.js' *//*! + * jquery.fancytree.table.js + * + * Render tree as table (aka 'tree grid', 'table tree'). + * (Extension module for jquery.fancytree.js: https://github.com/mar10/fancytree/) + * + * Copyright (c) 2008-2023, Martin Wendt (https://wwWendt.de) + * + * Released under the MIT license + * https://github.com/mar10/fancytree/wiki/LicenseInfo + * + * @version 2.38.3 + * @date 2023-02-01T20:52:50Z + */ + +(function (factory) { + if (typeof define === "function" && define.amd) { + // AMD. Register as an anonymous module. + define(["jquery", "./jquery.fancytree"], factory); + } else if (typeof module === "object" && module.exports) { + // Node/CommonJS + require("./jquery.fancytree"); + module.exports = factory(require("jquery")); + } else { + // Browser globals + factory(jQuery); + } +})(function ($) { + "use strict"; + + /****************************************************************************** + * Private functions and variables + */ + var _assert = $.ui.fancytree.assert; + + function insertFirstChild(referenceNode, newNode) { + referenceNode.insertBefore(newNode, referenceNode.firstChild); + } + + function insertSiblingAfter(referenceNode, newNode) { + referenceNode.parentNode.insertBefore( + newNode, + referenceNode.nextSibling + ); + } + + /* Show/hide all rows that are structural descendants of `parent`. */ + function setChildRowVisibility(parent, flag) { + parent.visit(function (node) { + var tr = node.tr; + // currentFlag = node.hide ? false : flag; // fix for ext-filter + if (tr) { + tr.style.display = node.hide || !flag ? "none" : ""; + } + if (!node.expanded) { + return "skip"; + } + }); + } + + /* Find node that is rendered in previous row. */ + function findPrevRowNode(node) { + var i, + last, + prev, + parent = node.parent, + siblings = parent ? parent.children : null; + + if (siblings && siblings.length > 1 && siblings[0] !== node) { + // use the lowest descendant of the preceeding sibling + i = $.inArray(node, siblings); + prev = siblings[i - 1]; + _assert(prev.tr); + // descend to lowest child (with a <tr> tag) + while (prev.children && prev.children.length) { + last = prev.children[prev.children.length - 1]; + if (!last.tr) { + break; + } + prev = last; + } + } else { + // if there is no preceding sibling, use the direct parent + prev = parent; + } + return prev; + } + + $.ui.fancytree.registerExtension({ + name: "table", + version: "2.38.3", + // Default options for this extension. + options: { + checkboxColumnIdx: null, // render the checkboxes into the this column index (default: nodeColumnIdx) + indentation: 16, // indent every node level by 16px + mergeStatusColumns: true, // display 'nodata', 'loading', 'error' centered in a single, merged TR + nodeColumnIdx: 0, // render node expander, icon, and title to this column (default: #0) + }, + // Overide virtual methods for this extension. + // `this` : is this extension object + // `this._super`: the virtual function that was overriden (member of prev. extension or Fancytree) + treeInit: function (ctx) { + var i, + n, + $row, + $tbody, + tree = ctx.tree, + opts = ctx.options, + tableOpts = opts.table, + $table = tree.widget.element; + + if (tableOpts.customStatus != null) { + if (opts.renderStatusColumns == null) { + tree.warn( + "The 'customStatus' option is deprecated since v2.15.0. Use 'renderStatusColumns' instead." + ); + opts.renderStatusColumns = tableOpts.customStatus; + } else { + $.error( + "The 'customStatus' option is deprecated since v2.15.0. Use 'renderStatusColumns' only instead." + ); + } + } + if (opts.renderStatusColumns) { + if (opts.renderStatusColumns === true) { + opts.renderStatusColumns = opts.renderColumns; + // } else if( opts.renderStatusColumns === "wide" ) { + // opts.renderStatusColumns = _renderStatusNodeWide; + } + } + + $table.addClass("fancytree-container fancytree-ext-table"); + $tbody = $table.find(">tbody"); + if (!$tbody.length) { + // TODO: not sure if we can rely on browsers to insert missing <tbody> before <tr>s: + if ($table.find(">tr").length) { + $.error( + "Expected table > tbody > tr. If you see this please open an issue." + ); + } + $tbody = $("<tbody>").appendTo($table); + } + + tree.tbody = $tbody[0]; + + // Prepare row templates: + // Determine column count from table header if any + tree.columnCount = $("thead >tr", $table) + .last() + .find(">th", $table).length; + // Read TR templates from tbody if any + $row = $tbody.children("tr").first(); + if ($row.length) { + n = $row.children("td").length; + if (tree.columnCount && n !== tree.columnCount) { + tree.warn( + "Column count mismatch between thead (" + + tree.columnCount + + ") and tbody (" + + n + + "): using tbody." + ); + tree.columnCount = n; + } + $row = $row.clone(); + } else { + // Only thead is defined: create default row markup + _assert( + tree.columnCount >= 1, + "Need either <thead> or <tbody> with <td> elements to determine column count." + ); + $row = $("<tr />"); + for (i = 0; i < tree.columnCount; i++) { + $row.append("<td />"); + } + } + $row.find(">td") + .eq(tableOpts.nodeColumnIdx) + .html("<span class='fancytree-node' />"); + if (opts.aria) { + $row.attr("role", "row"); + $row.find("td").attr("role", "gridcell"); + } + tree.rowFragment = document.createDocumentFragment(); + tree.rowFragment.appendChild($row.get(0)); + + // // If tbody contains a second row, use this as status node template + // $row = $tbody.children("tr").eq(1); + // if( $row.length === 0 ) { + // tree.statusRowFragment = tree.rowFragment; + // } else { + // $row = $row.clone(); + // tree.statusRowFragment = document.createDocumentFragment(); + // tree.statusRowFragment.appendChild($row.get(0)); + // } + // + $tbody.empty(); + + // Make sure that status classes are set on the node's <tr> elements + tree.statusClassPropName = "tr"; + tree.ariaPropName = "tr"; + this.nodeContainerAttrName = "tr"; + + // #489: make sure $container is set to <table>, even if ext-dnd is listed before ext-table + tree.$container = $table; + + this._superApply(arguments); + + // standard Fancytree created a root UL + $(tree.rootNode.ul).remove(); + tree.rootNode.ul = null; + + // Add container to the TAB chain + // #577: Allow to set tabindex to "0", "-1" and "" + this.$container.attr("tabindex", opts.tabindex); + // this.$container.attr("tabindex", opts.tabbable ? "0" : "-1"); + if (opts.aria) { + tree.$container + .attr("role", "treegrid") + .attr("aria-readonly", true); + } + }, + nodeRemoveChildMarkup: function (ctx) { + var node = ctx.node; + // node.debug("nodeRemoveChildMarkup()"); + node.visit(function (n) { + if (n.tr) { + $(n.tr).remove(); + n.tr = null; + } + }); + }, + nodeRemoveMarkup: function (ctx) { + var node = ctx.node; + // node.debug("nodeRemoveMarkup()"); + if (node.tr) { + $(node.tr).remove(); + node.tr = null; + } + this.nodeRemoveChildMarkup(ctx); + }, + /* Override standard render. */ + nodeRender: function (ctx, force, deep, collapsed, _recursive) { + var children, + firstTr, + i, + l, + newRow, + prevNode, + prevTr, + subCtx, + tree = ctx.tree, + node = ctx.node, + opts = ctx.options, + isRootNode = !node.parent; + + if (tree._enableUpdate === false) { + // $.ui.fancytree.debug("*** nodeRender _enableUpdate: false"); + return; + } + if (!_recursive) { + ctx.hasCollapsedParents = node.parent && !node.parent.expanded; + } + // $.ui.fancytree.debug("*** nodeRender " + node + ", isRoot=" + isRootNode, "tr=" + node.tr, "hcp=" + ctx.hasCollapsedParents, "parent.tr=" + (node.parent && node.parent.tr)); + if (!isRootNode) { + if (node.tr && force) { + this.nodeRemoveMarkup(ctx); + } + if (node.tr) { + if (force) { + // Set icon, link, and title (normally this is only required on initial render) + this.nodeRenderTitle(ctx); // triggers renderColumns() + } else { + // Update element classes according to node state + this.nodeRenderStatus(ctx); + } + } else { + if (ctx.hasCollapsedParents && !deep) { + // #166: we assume that the parent will be (recursively) rendered + // later anyway. + // node.debug("nodeRender ignored due to unrendered parent"); + return; + } + // Create new <tr> after previous row + // if( node.isStatusNode() ) { + // newRow = tree.statusRowFragment.firstChild.cloneNode(true); + // } else { + newRow = tree.rowFragment.firstChild.cloneNode(true); + // } + prevNode = findPrevRowNode(node); + // $.ui.fancytree.debug("*** nodeRender " + node + ": prev: " + prevNode.key); + _assert(prevNode); + if (collapsed === true && _recursive) { + // hide all child rows, so we can use an animation to show it later + newRow.style.display = "none"; + } else if (deep && ctx.hasCollapsedParents) { + // also hide this row if deep === true but any parent is collapsed + newRow.style.display = "none"; + // newRow.style.color = "red"; + } + if (prevNode.tr) { + insertSiblingAfter(prevNode.tr, newRow); + } else { + _assert( + !prevNode.parent, + "prev. row must have a tr, or be system root" + ); + // tree.tbody.appendChild(newRow); + insertFirstChild(tree.tbody, newRow); // #675 + } + node.tr = newRow; + if (node.key && opts.generateIds) { + node.tr.id = opts.idPrefix + node.key; + } + node.tr.ftnode = node; + // if(opts.aria){ + // $(node.tr).attr("aria-labelledby", "ftal_" + opts.idPrefix + node.key); + // } + node.span = $("span.fancytree-node", node.tr).get(0); + // Set icon, link, and title (normally this is only required on initial render) + this.nodeRenderTitle(ctx); + // Allow tweaking, binding, after node was created for the first time + // tree._triggerNodeEvent("createNode", ctx); + if (opts.createNode) { + opts.createNode.call(tree, { type: "createNode" }, ctx); + } + } + } + // Allow tweaking after node state was rendered + // tree._triggerNodeEvent("renderNode", ctx); + if (opts.renderNode) { + opts.renderNode.call(tree, { type: "renderNode" }, ctx); + } + // Visit child nodes + // Add child markup + children = node.children; + if (children && (isRootNode || deep || node.expanded)) { + for (i = 0, l = children.length; i < l; i++) { + subCtx = $.extend({}, ctx, { node: children[i] }); + subCtx.hasCollapsedParents = + subCtx.hasCollapsedParents || !node.expanded; + this.nodeRender(subCtx, force, deep, collapsed, true); + } + } + // Make sure, that <tr> order matches node.children order. + if (children && !_recursive) { + // we only have to do it once, for the root branch + prevTr = node.tr || null; + firstTr = tree.tbody.firstChild; + // Iterate over all descendants + node.visit(function (n) { + if (n.tr) { + if ( + !n.parent.expanded && + n.tr.style.display !== "none" + ) { + // fix after a node was dropped over a collapsed + n.tr.style.display = "none"; + setChildRowVisibility(n, false); + } + if (n.tr.previousSibling !== prevTr) { + node.debug("_fixOrder: mismatch at node: " + n); + var nextTr = prevTr ? prevTr.nextSibling : firstTr; + tree.tbody.insertBefore(n.tr, nextTr); + } + prevTr = n.tr; + } + }); + } + // Update element classes according to node state + // if(!isRootNode){ + // this.nodeRenderStatus(ctx); + // } + }, + nodeRenderTitle: function (ctx, title) { + var $cb, + res, + tree = ctx.tree, + node = ctx.node, + opts = ctx.options, + isStatusNode = node.isStatusNode(); + + res = this._super(ctx, title); + + if (node.isRootNode()) { + return res; + } + // Move checkbox to custom column + if ( + opts.checkbox && + !isStatusNode && + opts.table.checkboxColumnIdx != null + ) { + $cb = $("span.fancytree-checkbox", node.span); //.detach(); + $(node.tr) + .find("td") + .eq(+opts.table.checkboxColumnIdx) + .html($cb); + } + // Update element classes according to node state + this.nodeRenderStatus(ctx); + + if (isStatusNode) { + if (opts.renderStatusColumns) { + // Let user code write column content + opts.renderStatusColumns.call( + tree, + { type: "renderStatusColumns" }, + ctx + ); + } else if (opts.table.mergeStatusColumns && node.isTopLevel()) { + $(node.tr) + .find(">td") + .eq(0) + .prop("colspan", tree.columnCount) + .text(node.title) + .addClass("fancytree-status-merged") + .nextAll() + .remove(); + } // else: default rendering for status node: leave other cells empty + } else if (opts.renderColumns) { + opts.renderColumns.call(tree, { type: "renderColumns" }, ctx); + } + return res; + }, + nodeRenderStatus: function (ctx) { + var indent, + node = ctx.node, + opts = ctx.options; + + this._super(ctx); + + $(node.tr).removeClass("fancytree-node"); + // indent + indent = (node.getLevel() - 1) * opts.table.indentation; + if (opts.rtl) { + $(node.span).css({ paddingRight: indent + "px" }); + } else { + $(node.span).css({ paddingLeft: indent + "px" }); + } + }, + /* Expand node, return Deferred.promise. */ + nodeSetExpanded: function (ctx, flag, callOpts) { + // flag defaults to true + flag = flag !== false; + + if ((ctx.node.expanded && flag) || (!ctx.node.expanded && !flag)) { + // Expanded state isn't changed - just call base implementation + return this._superApply(arguments); + } + + var dfd = new $.Deferred(), + subOpts = $.extend({}, callOpts, { + noEvents: true, + noAnimation: true, + }); + + callOpts = callOpts || {}; + + function _afterExpand(ok, args) { + // ctx.tree.info("ok:" + ok, args); + if (ok) { + // #1108 minExpandLevel: 2 together with table extension does not work + // don't call when 'ok' is false: + setChildRowVisibility(ctx.node, flag); + if ( + flag && + ctx.options.autoScroll && + !callOpts.noAnimation && + ctx.node.hasChildren() + ) { + // Scroll down to last child, but keep current node visible + ctx.node + .getLastChild() + .scrollIntoView(true, { topNode: ctx.node }) + .always(function () { + if (!callOpts.noEvents) { + ctx.tree._triggerNodeEvent( + flag ? "expand" : "collapse", + ctx + ); + } + dfd.resolveWith(ctx.node); + }); + } else { + if (!callOpts.noEvents) { + ctx.tree._triggerNodeEvent( + flag ? "expand" : "collapse", + ctx + ); + } + dfd.resolveWith(ctx.node); + } + } else { + if (!callOpts.noEvents) { + ctx.tree._triggerNodeEvent( + flag ? "expand" : "collapse", + ctx + ); + } + dfd.rejectWith(ctx.node); + } + } + // Call base-expand with disabled events and animation + this._super(ctx, flag, subOpts) + .done(function () { + _afterExpand(true, arguments); + }) + .fail(function () { + _afterExpand(false, arguments); + }); + return dfd.promise(); + }, + nodeSetStatus: function (ctx, status, message, details) { + if (status === "ok") { + var node = ctx.node, + firstChild = node.children ? node.children[0] : null; + if (firstChild && firstChild.isStatusNode()) { + $(firstChild.tr).remove(); + } + } + return this._superApply(arguments); + }, + treeClear: function (ctx) { + this.nodeRemoveChildMarkup(this._makeHookContext(this.rootNode)); + return this._superApply(arguments); + }, + treeDestroy: function (ctx) { + this.$container.find("tbody").empty(); + if (this.$source) { + this.$source.removeClass("fancytree-helper-hidden"); + } + return this._superApply(arguments); + }, + /*, + treeSetFocus: function(ctx, flag) { +// alert("treeSetFocus" + ctx.tree.$container); + ctx.tree.$container.focus(); + $.ui.fancytree.focusTree = ctx.tree; + }*/ + }); + // Value returned by `require('jquery.fancytree..')` + return $.ui.fancytree; +}); // End of closure + + +/*! Extension 'jquery.fancytree.themeroller.js' *//*! + * jquery.fancytree.themeroller.js + * + * Enable jQuery UI ThemeRoller styles. + * (Extension module for jquery.fancytree.js: https://github.com/mar10/fancytree/) + * + * @see http://jqueryui.com/themeroller/ + * + * Copyright (c) 2008-2023, Martin Wendt (https://wwWendt.de) + * + * Released under the MIT license + * https://github.com/mar10/fancytree/wiki/LicenseInfo + * + * @version 2.38.3 + * @date 2023-02-01T20:52:50Z + */ + +(function (factory) { + if (typeof define === "function" && define.amd) { + // AMD. Register as an anonymous module. + define(["jquery", "./jquery.fancytree"], factory); + } else if (typeof module === "object" && module.exports) { + // Node/CommonJS + require("./jquery.fancytree"); + module.exports = factory(require("jquery")); + } else { + // Browser globals + factory(jQuery); + } +})(function ($) { + "use strict"; + + /******************************************************************************* + * Extension code + */ + $.ui.fancytree.registerExtension({ + name: "themeroller", + version: "2.38.3", + // Default options for this extension. + options: { + activeClass: "ui-state-active", // Class added to active node + // activeClass: "ui-state-highlight", + addClass: "ui-corner-all", // Class added to all nodes + focusClass: "ui-state-focus", // Class added to focused node + hoverClass: "ui-state-hover", // Class added to hovered node + selectedClass: "ui-state-highlight", // Class added to selected nodes + // selectedClass: "ui-state-active" + }, + + treeInit: function (ctx) { + var $el = ctx.widget.element, + opts = ctx.options.themeroller; + + this._superApply(arguments); + + if ($el[0].nodeName === "TABLE") { + $el.addClass("ui-widget ui-corner-all"); + $el.find(">thead tr").addClass("ui-widget-header"); + $el.find(">tbody").addClass("ui-widget-conent"); + } else { + $el.addClass("ui-widget ui-widget-content ui-corner-all"); + } + + $el.on( + "mouseenter mouseleave", + ".fancytree-node", + function (event) { + var node = $.ui.fancytree.getNode(event.target), + flag = event.type === "mouseenter"; + + $(node.tr ? node.tr : node.span).toggleClass( + opts.hoverClass + " " + opts.addClass, + flag + ); + } + ); + }, + treeDestroy: function (ctx) { + this._superApply(arguments); + ctx.widget.element.removeClass( + "ui-widget ui-widget-content ui-corner-all" + ); + }, + nodeRenderStatus: function (ctx) { + var classes = {}, + node = ctx.node, + $el = $(node.tr ? node.tr : node.span), + opts = ctx.options.themeroller; + + this._super(ctx); + /* + .ui-state-highlight: Class to be applied to highlighted or selected elements. Applies "highlight" container styles to an element and its child text, links, and icons. + .ui-state-error: Class to be applied to error messaging container elements. Applies "error" container styles to an element and its child text, links, and icons. + .ui-state-error-text: An additional class that applies just the error text color without background. Can be used on form labels for instance. Also applies error icon color to child icons. + + .ui-state-default: Class to be applied to clickable button-like elements. Applies "clickable default" container styles to an element and its child text, links, and icons. + .ui-state-hover: Class to be applied on mouseover to clickable button-like elements. Applies "clickable hover" container styles to an element and its child text, links, and icons. + .ui-state-focus: Class to be applied on keyboard focus to clickable button-like elements. Applies "clickable hover" container styles to an element and its child text, links, and icons. + .ui-state-active: Class to be applied on mousedown to clickable button-like elements. Applies "clickable active" container styles to an element and its child text, links, and icons. +*/ + // Set ui-state-* class (handle the case that the same class is assigned + // to different states) + classes[opts.activeClass] = false; + classes[opts.focusClass] = false; + classes[opts.selectedClass] = false; + if (node.isActive()) { + classes[opts.activeClass] = true; + } + if (node.hasFocus()) { + classes[opts.focusClass] = true; + } + // activeClass takes precedence before selectedClass: + if (node.isSelected() && !node.isActive()) { + classes[opts.selectedClass] = true; + } + $el.toggleClass(opts.activeClass, classes[opts.activeClass]); + $el.toggleClass(opts.focusClass, classes[opts.focusClass]); + $el.toggleClass(opts.selectedClass, classes[opts.selectedClass]); + // Additional classes (e.g. 'ui-corner-all') + $el.addClass(opts.addClass); + }, + }); + // Value returned by `require('jquery.fancytree..')` + return $.ui.fancytree; +}); // End of closure + + +/*! Extension 'jquery.fancytree.wide.js' *//*! + * jquery.fancytree.wide.js + * Support for 100% wide selection bars. + * (Extension module for jquery.fancytree.js: https://github.com/mar10/fancytree/) + * + * Copyright (c) 2008-2023, Martin Wendt (https://wwWendt.de) + * + * Released under the MIT license + * https://github.com/mar10/fancytree/wiki/LicenseInfo + * + * @version 2.38.3 + * @date 2023-02-01T20:52:50Z + */ + +(function (factory) { + if (typeof define === "function" && define.amd) { + // AMD. Register as an anonymous module. + define(["jquery", "./jquery.fancytree"], factory); + } else if (typeof module === "object" && module.exports) { + // Node/CommonJS + require("./jquery.fancytree"); + module.exports = factory(require("jquery")); + } else { + // Browser globals + factory(jQuery); + } +})(function ($) { + "use strict"; + + var reNumUnit = /^([+-]?(?:\d+|\d*\.\d+))([a-z]*|%)$/; // split "1.5em" to ["1.5", "em"] + + /******************************************************************************* + * Private functions and variables + */ + // var _assert = $.ui.fancytree.assert; + + /* Calculate inner width without scrollbar */ + // function realInnerWidth($el) { + // // http://blog.jquery.com/2012/08/16/jquery-1-8-box-sizing-width-csswidth-and-outerwidth/ + // // inst.contWidth = parseFloat(this.$container.css("width"), 10); + // // 'Client width without scrollbar' - 'padding' + // return $el[0].clientWidth - ($el.innerWidth() - parseFloat($el.css("width"), 10)); + // } + + /* Create a global embedded CSS style for the tree. */ + function defineHeadStyleElement(id, cssText) { + id = "fancytree-style-" + id; + var $headStyle = $("#" + id); + + if (!cssText) { + $headStyle.remove(); + return null; + } + if (!$headStyle.length) { + $headStyle = $("<style />") + .attr("id", id) + .addClass("fancytree-style") + .prop("type", "text/css") + .appendTo("head"); + } + try { + $headStyle.html(cssText); + } catch (e) { + // fix for IE 6-8 + $headStyle[0].styleSheet.cssText = cssText; + } + return $headStyle; + } + + /* Calculate the CSS rules that indent title spans. */ + function renderLevelCss( + containerId, + depth, + levelOfs, + lineOfs, + labelOfs, + measureUnit + ) { + var i, + prefix = "#" + containerId + " span.fancytree-level-", + rules = []; + + for (i = 0; i < depth; i++) { + rules.push( + prefix + + (i + 1) + + " span.fancytree-title { padding-left: " + + (i * levelOfs + lineOfs) + + measureUnit + + "; }" + ); + } + // Some UI animations wrap the UL inside a DIV and set position:relative on both. + // This breaks the left:0 and padding-left:nn settings of the title + rules.push( + "#" + + containerId + + " div.ui-effects-wrapper ul li span.fancytree-title, " + + "#" + + containerId + + " li.fancytree-animating span.fancytree-title " + // #716 + "{ padding-left: " + + labelOfs + + measureUnit + + "; position: static; width: auto; }" + ); + return rules.join("\n"); + } + + // /** + // * [ext-wide] Recalculate the width of the selection bar after the tree container + // * was resized.<br> + // * May be called explicitly on container resize, since there is no resize event + // * for DIV tags. + // * + // * @alias Fancytree#wideUpdate + // * @requires jquery.fancytree.wide.js + // */ + // $.ui.fancytree._FancytreeClass.prototype.wideUpdate = function(){ + // var inst = this.ext.wide, + // prevCw = inst.contWidth, + // prevLo = inst.lineOfs; + + // inst.contWidth = realInnerWidth(this.$container); + // // Each title is precceeded by 2 or 3 icons (16px + 3 margin) + // // + 1px title border and 3px title padding + // // TODO: use code from treeInit() below + // inst.lineOfs = (this.options.checkbox ? 3 : 2) * 19; + // if( prevCw !== inst.contWidth || prevLo !== inst.lineOfs ) { + // this.debug("wideUpdate: " + inst.contWidth); + // this.visit(function(node){ + // node.tree._callHook("nodeRenderTitle", node); + // }); + // } + // }; + + /******************************************************************************* + * Extension code + */ + $.ui.fancytree.registerExtension({ + name: "wide", + version: "2.38.3", + // Default options for this extension. + options: { + iconWidth: null, // Adjust this if @fancy-icon-width != "16px" + iconSpacing: null, // Adjust this if @fancy-icon-spacing != "3px" + labelSpacing: null, // Adjust this if padding between icon and label != "3px" + levelOfs: null, // Adjust this if ul padding != "16px" + }, + + treeCreate: function (ctx) { + this._superApply(arguments); + this.$container.addClass("fancytree-ext-wide"); + + var containerId, + cssText, + iconSpacingUnit, + labelSpacingUnit, + iconWidthUnit, + levelOfsUnit, + instOpts = ctx.options.wide, + // css sniffing + $dummyLI = $( + "<li id='fancytreeTemp'><span class='fancytree-node'><span class='fancytree-icon' /><span class='fancytree-title' /></span><ul />" + ).appendTo(ctx.tree.$container), + $dummyIcon = $dummyLI.find(".fancytree-icon"), + $dummyUL = $dummyLI.find("ul"), + // $dummyTitle = $dummyLI.find(".fancytree-title"), + iconSpacing = + instOpts.iconSpacing || $dummyIcon.css("margin-left"), + iconWidth = instOpts.iconWidth || $dummyIcon.css("width"), + labelSpacing = instOpts.labelSpacing || "3px", + levelOfs = instOpts.levelOfs || $dummyUL.css("padding-left"); + + $dummyLI.remove(); + + iconSpacingUnit = iconSpacing.match(reNumUnit)[2]; + iconSpacing = parseFloat(iconSpacing, 10); + labelSpacingUnit = labelSpacing.match(reNumUnit)[2]; + labelSpacing = parseFloat(labelSpacing, 10); + iconWidthUnit = iconWidth.match(reNumUnit)[2]; + iconWidth = parseFloat(iconWidth, 10); + levelOfsUnit = levelOfs.match(reNumUnit)[2]; + if ( + iconSpacingUnit !== iconWidthUnit || + levelOfsUnit !== iconWidthUnit || + labelSpacingUnit !== iconWidthUnit + ) { + $.error( + "iconWidth, iconSpacing, and levelOfs must have the same css measure unit" + ); + } + this._local.measureUnit = iconWidthUnit; + this._local.levelOfs = parseFloat(levelOfs); + this._local.lineOfs = + (1 + + (ctx.options.checkbox ? 1 : 0) + + (ctx.options.icon === false ? 0 : 1)) * + (iconWidth + iconSpacing) + + iconSpacing; + this._local.labelOfs = labelSpacing; + this._local.maxDepth = 10; + + // Get/Set a unique Id on the container (if not already exists) + containerId = this.$container.uniqueId().attr("id"); + // Generated css rules for some levels (extended on demand) + cssText = renderLevelCss( + containerId, + this._local.maxDepth, + this._local.levelOfs, + this._local.lineOfs, + this._local.labelOfs, + this._local.measureUnit + ); + defineHeadStyleElement(containerId, cssText); + }, + treeDestroy: function (ctx) { + // Remove generated css rules + defineHeadStyleElement(this.$container.attr("id"), null); + return this._superApply(arguments); + }, + nodeRenderStatus: function (ctx) { + var containerId, + cssText, + res, + node = ctx.node, + level = node.getLevel(); + + res = this._super(ctx); + // Generate some more level-n rules if required + if (level > this._local.maxDepth) { + containerId = this.$container.attr("id"); + this._local.maxDepth *= 2; + node.debug( + "Define global ext-wide css up to level " + + this._local.maxDepth + ); + cssText = renderLevelCss( + containerId, + this._local.maxDepth, + this._local.levelOfs, + this._local.lineOfs, + this._local.labelSpacing, + this._local.measureUnit + ); + defineHeadStyleElement(containerId, cssText); + } + // Add level-n class to apply indentation padding. + // (Setting element style would not work, since it cannot easily be + // overriden while animations run) + $(node.span).addClass("fancytree-level-" + level); + return res; + }, + }); + // Value returned by `require('jquery.fancytree..')` + return $.ui.fancytree; +}); // End of closure + +// Value returned by `require('jquery.fancytree')` +return $.ui.fancytree; +})); // End of closure diff --git a/plugins/55/indexmenu/scripts/fancytree/jquery.fancytree-all-deps.min.js b/plugins/55/indexmenu/scripts/fancytree/jquery.fancytree-all-deps.min.js new file mode 100644 index 0000000..c3749d3 --- /dev/null +++ b/plugins/55/indexmenu/scripts/fancytree/jquery.fancytree-all-deps.min.js @@ -0,0 +1,2 @@ +!function(_){_.ui=_.ui||{};_.ui.version="1.13.2";var r,n=0,s=Array.prototype.hasOwnProperty,a=Array.prototype.slice;_.cleanData=(r=_.cleanData,function(e){for(var t,n,i=0;null!=(n=e[i]);i++)(t=_._data(n,"events"))&&t.remove&&_(n).triggerHandler("remove");r(e)}),_.widget=function(e,n,t){var i,r,o,s={},a=e.split(".")[0],l=a+"-"+(e=e.split(".")[1]);return t||(t=n,n=_.Widget),Array.isArray(t)&&(t=_.extend.apply(null,[{}].concat(t))),_.expr.pseudos[l.toLowerCase()]=function(e){return!!_.data(e,l)},_[a]=_[a]||{},i=_[a][e],r=_[a][e]=function(e,t){if(!this||!this._createWidget)return new r(e,t);arguments.length&&this._createWidget(e,t)},_.extend(r,i,{version:t.version,_proto:_.extend({},t),_childConstructors:[]}),(o=new n).options=_.widget.extend({},o.options),_.each(t,function(t,i){function r(){return n.prototype[t].apply(this,arguments)}function o(e){return n.prototype[t].apply(this,e)}s[t]="function"==typeof i?function(){var e,t=this._super,n=this._superApply;return this._super=r,this._superApply=o,e=i.apply(this,arguments),this._super=t,this._superApply=n,e}:i}),r.prototype=_.widget.extend(o,{widgetEventPrefix:i&&o.widgetEventPrefix||e},s,{constructor:r,namespace:a,widgetName:e,widgetFullName:l}),i?(_.each(i._childConstructors,function(e,t){var n=t.prototype;_.widget(n.namespace+"."+n.widgetName,r,t._proto)}),delete i._childConstructors):n._childConstructors.push(r),_.widget.bridge(e,r),r},_.widget.extend=function(e){for(var t,n,i=a.call(arguments,1),r=0,o=i.length;r<o;r++)for(t in i[r])n=i[r][t],s.call(i[r],t)&&void 0!==n&&(_.isPlainObject(n)?e[t]=_.isPlainObject(e[t])?_.widget.extend({},e[t],n):_.widget.extend({},n):e[t]=n);return e},_.widget.bridge=function(o,t){var s=t.prototype.widgetFullName||o;_.fn[o]=function(n){var e="string"==typeof n,i=a.call(arguments,1),r=this;return e?this.length||"instance"!==n?this.each(function(){var e,t=_.data(this,s);return"instance"===n?(r=t,!1):t?"function"!=typeof t[n]||"_"===n.charAt(0)?_.error("no such method '"+n+"' for "+o+" widget instance"):(e=t[n].apply(t,i))!==t&&void 0!==e?(r=e&&e.jquery?r.pushStack(e.get()):e,!1):void 0:_.error("cannot call methods on "+o+" prior to initialization; attempted to call method '"+n+"'")}):r=void 0:(i.length&&(n=_.widget.extend.apply(null,[n].concat(i))),this.each(function(){var e=_.data(this,s);e?(e.option(n||{}),e._init&&e._init()):_.data(this,s,new t(n,this))})),r}},_.Widget=function(){},_.Widget._childConstructors=[],_.Widget.prototype={widgetName:"widget",widgetEventPrefix:"",defaultElement:"<div>",options:{classes:{},disabled:!1,create:null},_createWidget:function(e,t){t=_(t||this.defaultElement||this)[0],this.element=_(t),this.uuid=n++,this.eventNamespace="."+this.widgetName+this.uuid,this.bindings=_(),this.hoverable=_(),this.focusable=_(),this.classesElementLookup={},t!==this&&(_.data(t,this.widgetFullName,this),this._on(!0,this.element,{remove:function(e){e.target===t&&this.destroy()}}),this.document=_(t.style?t.ownerDocument:t.document||t),this.window=_(this.document[0].defaultView||this.document[0].parentWindow)),this.options=_.widget.extend({},this.options,this._getCreateOptions(),e),this._create(),this.options.disabled&&this._setOptionDisabled(this.options.disabled),this._trigger("create",null,this._getCreateEventData()),this._init()},_getCreateOptions:function(){return{}},_getCreateEventData:_.noop,_create:_.noop,_init:_.noop,destroy:function(){var n=this;this._destroy(),_.each(this.classesElementLookup,function(e,t){n._removeClass(t,e)}),this.element.off(this.eventNamespace).removeData(this.widgetFullName),this.widget().off(this.eventNamespace).removeAttr("aria-disabled"),this.bindings.off(this.eventNamespace)},_destroy:_.noop,widget:function(){return this.element},option:function(e,t){var n,i,r,o=e;if(0===arguments.length)return _.widget.extend({},this.options);if("string"==typeof e)if(o={},e=(n=e.split(".")).shift(),n.length){for(i=o[e]=_.widget.extend({},this.options[e]),r=0;r<n.length-1;r++)i[n[r]]=i[n[r]]||{},i=i[n[r]];if(e=n.pop(),1===arguments.length)return void 0===i[e]?null:i[e];i[e]=t}else{if(1===arguments.length)return void 0===this.options[e]?null:this.options[e];o[e]=t}return this._setOptions(o),this},_setOptions:function(e){for(var t in e)this._setOption(t,e[t]);return this},_setOption:function(e,t){return"classes"===e&&this._setOptionClasses(t),this.options[e]=t,"disabled"===e&&this._setOptionDisabled(t),this},_setOptionClasses:function(e){var t,n,i;for(t in e)i=this.classesElementLookup[t],e[t]!==this.options.classes[t]&&i&&i.length&&(n=_(i.get()),this._removeClass(i,t),n.addClass(this._classes({element:n,keys:t,classes:e,add:!0})))},_setOptionDisabled:function(e){this._toggleClass(this.widget(),this.widgetFullName+"-disabled",null,!!e),e&&(this._removeClass(this.hoverable,null,"ui-state-hover"),this._removeClass(this.focusable,null,"ui-state-focus"))},enable:function(){return this._setOptions({disabled:!1})},disable:function(){return this._setOptions({disabled:!0})},_classes:function(r){var o=[],s=this;function e(e,t){for(var n,i=0;i<e.length;i++)n=s.classesElementLookup[e[i]]||_(),n=r.add?(function(){var n=[];r.element.each(function(e,t){_.map(s.classesElementLookup,function(e){return e}).some(function(e){return e.is(t)})||n.push(t)}),s._on(_(n),{remove:"_untrackClassesElement"})}(),_(_.uniqueSort(n.get().concat(r.element.get())))):_(n.not(r.element).get()),s.classesElementLookup[e[i]]=n,o.push(e[i]),t&&r.classes[e[i]]&&o.push(r.classes[e[i]])}return(r=_.extend({element:this.element,classes:this.options.classes||{}},r)).keys&&e(r.keys.match(/\S+/g)||[],!0),r.extra&&e(r.extra.match(/\S+/g)||[]),o.join(" ")},_untrackClassesElement:function(n){var i=this;_.each(i.classesElementLookup,function(e,t){-1!==_.inArray(n.target,t)&&(i.classesElementLookup[e]=_(t.not(n.target).get()))}),this._off(_(n.target))},_removeClass:function(e,t,n){return this._toggleClass(e,t,n,!1)},_addClass:function(e,t,n){return this._toggleClass(e,t,n,!0)},_toggleClass:function(e,t,n,i){var r="string"==typeof e||null===e,n={extra:r?t:n,keys:r?e:t,element:r?this.element:e,add:i="boolean"==typeof i?i:n};return n.element.toggleClass(this._classes(n),i),this},_on:function(r,o,e){var s,a=this;"boolean"!=typeof r&&(e=o,o=r,r=!1),e?(o=s=_(o),this.bindings=this.bindings.add(o)):(e=o,o=this.element,s=this.widget()),_.each(e,function(e,t){function n(){if(r||!0!==a.options.disabled&&!_(this).hasClass("ui-state-disabled"))return("string"==typeof t?a[t]:t).apply(a,arguments)}"string"!=typeof t&&(n.guid=t.guid=t.guid||n.guid||_.guid++);var i=e.match(/^([\w:-]*)\s*(.*)$/),e=i[1]+a.eventNamespace,i=i[2];i?s.on(e,i,n):o.on(e,n)})},_off:function(e,t){t=(t||"").split(" ").join(this.eventNamespace+" ")+this.eventNamespace,e.off(t),this.bindings=_(this.bindings.not(e).get()),this.focusable=_(this.focusable.not(e).get()),this.hoverable=_(this.hoverable.not(e).get())},_delay:function(e,t){var n=this;return setTimeout(function(){return("string"==typeof e?n[e]:e).apply(n,arguments)},t||0)},_hoverable:function(e){this.hoverable=this.hoverable.add(e),this._on(e,{mouseenter:function(e){this._addClass(_(e.currentTarget),null,"ui-state-hover")},mouseleave:function(e){this._removeClass(_(e.currentTarget),null,"ui-state-hover")}})},_focusable:function(e){this.focusable=this.focusable.add(e),this._on(e,{focusin:function(e){this._addClass(_(e.currentTarget),null,"ui-state-focus")},focusout:function(e){this._removeClass(_(e.currentTarget),null,"ui-state-focus")}})},_trigger:function(e,t,n){var i,r,o=this.options[e];if(n=n||{},(t=_.Event(t)).type=(e===this.widgetEventPrefix?e:this.widgetEventPrefix+e).toLowerCase(),t.target=this.element[0],r=t.originalEvent)for(i in r)i in t||(t[i]=r[i]);return this.element.trigger(t,n),!("function"==typeof o&&!1===o.apply(this.element[0],[t].concat(n))||t.isDefaultPrevented())}},_.each({show:"fadeIn",hide:"fadeOut"},function(o,s){_.Widget.prototype["_"+o]=function(t,e,n){var i,r=(e="string"==typeof e?{effect:e}:e)?!0!==e&&"number"!=typeof e&&e.effect||s:o;"number"==typeof(e=e||{})?e={duration:e}:!0===e&&(e={}),i=!_.isEmptyObject(e),e.complete=n,e.delay&&t.delay(e.delay),i&&_.effects&&_.effects.effect[r]?t[o](e):r!==o&&t[r]?t[r](e.duration,e.easing,n):t.queue(function(e){_(this)[o](),n&&n.call(t[0]),e()})}});var i,k,w,o,l,d,c,u,N;_.widget;function S(e,t,n){return[parseFloat(e[0])*(u.test(e[0])?t/100:1),parseFloat(e[1])*(u.test(e[1])?n/100:1)]}function E(e,t){return parseInt(_.css(e,t),10)||0}function T(e){return null!=e&&e===e.window}k=Math.max,w=Math.abs,o=/left|center|right/,l=/top|center|bottom/,d=/[\+\-]\d+(\.[\d]+)?%?/,c=/^\w+/,u=/%$/,N=_.fn.position,_.position={scrollbarWidth:function(){if(void 0!==i)return i;var e,t=_("<div style='display:block;position:absolute;width:200px;height:200px;overflow:hidden;'><div style='height:300px;width:auto;'></div></div>"),n=t.children()[0];return _("body").append(t),e=n.offsetWidth,t.css("overflow","scroll"),e===(n=n.offsetWidth)&&(n=t[0].clientWidth),t.remove(),i=e-n},getScrollInfo:function(e){var t=e.isWindow||e.isDocument?"":e.element.css("overflow-x"),n=e.isWindow||e.isDocument?"":e.element.css("overflow-y"),t="scroll"===t||"auto"===t&&e.width<e.element[0].scrollWidth;return{width:"scroll"===n||"auto"===n&&e.height<e.element[0].scrollHeight?_.position.scrollbarWidth():0,height:t?_.position.scrollbarWidth():0}},getWithinInfo:function(e){var t=_(e||window),n=T(t[0]),i=!!t[0]&&9===t[0].nodeType;return{element:t,isWindow:n,isDocument:i,offset:!n&&!i?_(e).offset():{left:0,top:0},scrollLeft:t.scrollLeft(),scrollTop:t.scrollTop(),width:t.outerWidth(),height:t.outerHeight()}}},_.fn.position=function(u){if(!u||!u.of)return N.apply(this,arguments);var h,f,p,g,y,e,v="string"==typeof(u=_.extend({},u)).of?_(document).find(u.of):_(u.of),m=_.position.getWithinInfo(u.within),b=_.position.getScrollInfo(m),x=(u.collision||"flip").split(" "),C={},t=9===(e=(t=v)[0]).nodeType?{width:t.width(),height:t.height(),offset:{top:0,left:0}}:T(e)?{width:t.width(),height:t.height(),offset:{top:t.scrollTop(),left:t.scrollLeft()}}:e.preventDefault?{width:0,height:0,offset:{top:e.pageY,left:e.pageX}}:{width:t.outerWidth(),height:t.outerHeight(),offset:t.offset()};return v[0].preventDefault&&(u.at="left top"),f=t.width,p=t.height,y=_.extend({},g=t.offset),_.each(["my","at"],function(){var e,t,n=(u[this]||"").split(" ");(n=1===n.length?o.test(n[0])?n.concat(["center"]):l.test(n[0])?["center"].concat(n):["center","center"]:n)[0]=o.test(n[0])?n[0]:"center",n[1]=l.test(n[1])?n[1]:"center",e=d.exec(n[0]),t=d.exec(n[1]),C[this]=[e?e[0]:0,t?t[0]:0],u[this]=[c.exec(n[0])[0],c.exec(n[1])[0]]}),1===x.length&&(x[1]=x[0]),"right"===u.at[0]?y.left+=f:"center"===u.at[0]&&(y.left+=f/2),"bottom"===u.at[1]?y.top+=p:"center"===u.at[1]&&(y.top+=p/2),h=S(C.at,f,p),y.left+=h[0],y.top+=h[1],this.each(function(){var n,e,s=_(this),a=s.outerWidth(),l=s.outerHeight(),t=E(this,"marginLeft"),i=E(this,"marginTop"),r=a+t+E(this,"marginRight")+b.width,o=l+i+E(this,"marginBottom")+b.height,d=_.extend({},y),c=S(C.my,s.outerWidth(),s.outerHeight());"right"===u.my[0]?d.left-=a:"center"===u.my[0]&&(d.left-=a/2),"bottom"===u.my[1]?d.top-=l:"center"===u.my[1]&&(d.top-=l/2),d.left+=c[0],d.top+=c[1],n={marginLeft:t,marginTop:i},_.each(["left","top"],function(e,t){_.ui.position[x[e]]&&_.ui.position[x[e]][t](d,{targetWidth:f,targetHeight:p,elemWidth:a,elemHeight:l,collisionPosition:n,collisionWidth:r,collisionHeight:o,offset:[h[0]+c[0],h[1]+c[1]],my:u.my,at:u.at,within:m,elem:s})}),u.using&&(e=function(e){var t=g.left-d.left,n=t+f-a,i=g.top-d.top,r=i+p-l,o={target:{element:v,left:g.left,top:g.top,width:f,height:p},element:{element:s,left:d.left,top:d.top,width:a,height:l},horizontal:n<0?"left":0<t?"right":"center",vertical:r<0?"top":0<i?"bottom":"middle"};f<a&&w(t+n)<f&&(o.horizontal="center"),p<l&&w(i+r)<p&&(o.vertical="middle"),k(w(t),w(n))>k(w(i),w(r))?o.important="horizontal":o.important="vertical",u.using.call(this,e,o)}),s.offset(_.extend(d,{using:e}))})},_.ui.position={fit:{left:function(e,t){var n=t.within,i=n.isWindow?n.scrollLeft:n.offset.left,r=n.width,o=e.left-t.collisionPosition.marginLeft,s=i-o,a=o+t.collisionWidth-r-i;t.collisionWidth>r?0<s&&a<=0?(n=e.left+s+t.collisionWidth-r-i,e.left+=s-n):e.left=!(0<a&&s<=0)&&a<s?i+r-t.collisionWidth:i:0<s?e.left+=s:0<a?e.left-=a:e.left=k(e.left-o,e.left)},top:function(e,t){var n=t.within,i=n.isWindow?n.scrollTop:n.offset.top,r=t.within.height,o=e.top-t.collisionPosition.marginTop,s=i-o,a=o+t.collisionHeight-r-i;t.collisionHeight>r?0<s&&a<=0?(n=e.top+s+t.collisionHeight-r-i,e.top+=s-n):e.top=!(0<a&&s<=0)&&a<s?i+r-t.collisionHeight:i:0<s?e.top+=s:0<a?e.top-=a:e.top=k(e.top-o,e.top)}},flip:{left:function(e,t){var n=t.within,i=n.offset.left+n.scrollLeft,r=n.width,o=n.isWindow?n.scrollLeft:n.offset.left,s=e.left-t.collisionPosition.marginLeft,a=s-o,l=s+t.collisionWidth-r-o,d="left"===t.my[0]?-t.elemWidth:"right"===t.my[0]?t.elemWidth:0,n="left"===t.at[0]?t.targetWidth:"right"===t.at[0]?-t.targetWidth:0,s=-2*t.offset[0];a<0?((i=e.left+d+n+s+t.collisionWidth-r-i)<0||i<w(a))&&(e.left+=d+n+s):0<l&&(0<(o=e.left-t.collisionPosition.marginLeft+d+n+s-o)||w(o)<l)&&(e.left+=d+n+s)},top:function(e,t){var n=t.within,i=n.offset.top+n.scrollTop,r=n.height,o=n.isWindow?n.scrollTop:n.offset.top,s=e.top-t.collisionPosition.marginTop,a=s-o,l=s+t.collisionHeight-r-o,d="top"===t.my[1]?-t.elemHeight:"bottom"===t.my[1]?t.elemHeight:0,n="top"===t.at[1]?t.targetHeight:"bottom"===t.at[1]?-t.targetHeight:0,s=-2*t.offset[1];a<0?((i=e.top+d+n+s+t.collisionHeight-r-i)<0||i<w(a))&&(e.top+=d+n+s):0<l&&(0<(o=e.top-t.collisionPosition.marginTop+d+n+s-o)||w(o)<l)&&(e.top+=d+n+s)}},flipfit:{left:function(){_.ui.position.flip.left.apply(this,arguments),_.ui.position.fit.left.apply(this,arguments)},top:function(){_.ui.position.flip.top.apply(this,arguments),_.ui.position.fit.top.apply(this,arguments)}}};var t,h;_.ui.position;_.expr.pseudos||(_.expr.pseudos=_.expr[":"]),_.uniqueSort||(_.uniqueSort=_.unique),_.escapeSelector||(t=/([\0-\x1f\x7f]|^-?\d)|^-$|[^\x80-\uFFFF\w-]/g,h=function(e,t){return t?"\0"===e?"\ufffd":e.slice(0,-1)+"\\"+e.charCodeAt(e.length-1).toString(16)+" ":"\\"+e},_.escapeSelector=function(e){return(e+"").replace(t,h)}),_.fn.even&&_.fn.odd||_.fn.extend({even:function(){return this.filter(function(e){return e%2==0})},odd:function(){return this.filter(function(e){return e%2==1})}});var e;_.ui.keyCode={BACKSPACE:8,COMMA:188,DELETE:46,DOWN:40,END:35,ENTER:13,ESCAPE:27,HOME:36,LEFT:37,PAGE_DOWN:34,PAGE_UP:33,PERIOD:190,RIGHT:39,SPACE:32,TAB:9,UP:38},_.fn.scrollParent=function(e){var t=this.css("position"),n="absolute"===t,i=e?/(auto|scroll|hidden)/:/(auto|scroll)/,e=this.parents().filter(function(){var e=_(this);return(!n||"static"!==e.css("position"))&&i.test(e.css("overflow")+e.css("overflow-y")+e.css("overflow-x"))}).eq(0);return"fixed"!==t&&e.length?e:_(this[0].ownerDocument||document)},_.fn.extend({uniqueId:(e=0,function(){return this.each(function(){this.id||(this.id="ui-id-"+ ++e)})}),removeUniqueId:function(){return this.each(function(){/^ui-id-\d+$/.test(this.id)&&_(this).removeAttr("id")})}})}(jQuery),function(e){"function"==typeof define&&define.amd?define(["jquery"],e):"object"==typeof module&&module.exports?module.exports=e(require("jquery")):e(jQuery)}(function(e){var t;return t=function(C){"use strict";if(!C.ui||!C.ui.fancytree){for(var e,h=null,c=new RegExp(/\.|\//),t=/[&<>"'/]/g,n=/[<>"'/]/g,f="$recursive_request",p="$request_target_invalid",i={"&":"&","<":"<",">":">",'"':""","'":"'","/":"/"},r={16:!0,17:!0,18:!0},u={8:"backspace",9:"tab",10:"return",13:"return",19:"pause",20:"capslock",27:"esc",32:"space",33:"pageup",34:"pagedown",35:"end",36:"home",37:"left",38:"up",39:"right",40:"down",45:"insert",46:"del",59:";",61:"=",96:"0",97:"1",98:"2",99:"3",100:"4",101:"5",102:"6",103:"7",104:"8",105:"9",106:"*",107:"+",109:"-",110:".",111:"/",112:"f1",113:"f2",114:"f3",115:"f4",116:"f5",117:"f6",118:"f7",119:"f8",120:"f9",121:"f10",122:"f11",123:"f12",144:"numlock",145:"scroll",173:"-",186:";",187:"=",188:",",189:"-",190:".",191:"/",192:"`",219:"[",220:"\\",221:"]",222:"'"},g={16:"shift",17:"ctrl",18:"alt",91:"meta",93:"meta"},o={0:"",1:"left",2:"middle",3:"right"},y="active expanded focus folder lazy radiogroup selected unselectable unselectableIgnore".split(" "),v={},m="columns types".split(" "),b="checkbox expanded extraClasses folder icon iconTooltip key lazy partsel radiogroup refKey selected statusNodeType title tooltip type unselectable unselectableIgnore unselectableStatus".split(" "),s={},x={},a={active:!0,children:!0,data:!0,focus:!0},l=0;l<y.length;l++)v[y[l]]=!0;for(l=0;l<b.length;l++)e=b[l],s[e]=!0,e!==e.toLowerCase()&&(x[e.toLowerCase()]=e);var _=Array.isArray;return k(C.ui,"Fancytree requires jQuery UI (http://jqueryui.com)"),Date.now||(Date.now=function(){return(new Date).getTime()}),j.prototype={_findDirectChild:function(e){var t,n,i=this.children;if(i)if("string"==typeof e){for(t=0,n=i.length;t<n;t++)if(i[t].key===e)return i[t]}else{if("number"==typeof e)return this.children[e];if(e.parent===this)return e}return null},_setChildren:function(e){k(e&&(!this.children||0===this.children.length),"only init supported"),this.children=[];for(var t=0,n=e.length;t<n;t++)this.children.push(new j(this,e[t]));this.tree._callHook("treeStructureChanged",this.tree,"setChildren")},addChildren:function(e,t){var n,i,r,o,s=this.getFirstChild(),a=this.getLastChild(),l=[];for(C.isPlainObject(e)&&(e=[e]),this.children||(this.children=[]),n=0,i=e.length;n<i;n++)l.push(new j(this,e[n]));if(o=l[0],null==t?this.children=this.children.concat(l):(t=this._findDirectChild(t),k(0<=(r=C.inArray(t,this.children)),"insertBefore must be an existing child"),this.children.splice.apply(this.children,[r,0].concat(l))),s&&!t){for(n=0,i=l.length;n<i;n++)l[n].render();s!==this.getFirstChild()&&s.renderStatus(),a!==this.getLastChild()&&a.renderStatus()}else this.parent&&!this.parent.ul&&!this.tr||this.render();return 3===this.tree.options.selectMode&&this.fixSelection3FromEndNodes(),this.triggerModifyChild("add",1===l.length?l[0]:null),o},addClass:function(e){return this.toggleClass(e,!0)},addNode:function(e,t){switch(t=void 0===t||"over"===t?"child":t){case"after":return this.getParent().addChildren(e,this.getNextSibling());case"before":return this.getParent().addChildren(e,this);case"firstChild":var n=this.children?this.children[0]:null;return this.addChildren(e,n);case"child":case"over":return this.addChildren(e)}k(!1,"Invalid mode: "+t)},addPagingNode:function(e,t){var n,i;if(t=t||"child",!1!==e)return e=C.extend({title:this.tree.options.strings.moreData,statusNodeType:"paging",icon:!1},e),this.partload=!0,this.addNode(e,t);for(n=this.children.length-1;0<=n;n--)"paging"===(i=this.children[n]).statusNodeType&&this.removeChild(i);this.partload=!1},appendSibling:function(e){return this.addNode(e,"after")},applyCommand:function(e,t){return this.tree.applyCommand(e,this,t)},applyPatch:function(e){if(null===e)return this.remove(),T(this);var t,n,i={children:!0,expanded:!0,parent:!0};for(t in e)w(e,t)&&(n=e[t],i[t]||N(n)||(s[t]?this[t]=n:this.data[t]=n));return w(e,"children")&&(this.removeChildren(),e.children&&this._setChildren(e.children)),this.isVisible()&&(this.renderTitle(),this.renderStatus()),w(e,"expanded")?this.setExpanded(e.expanded):T(this)},collapseSiblings:function(){return this.tree._callHook("nodeCollapseSiblings",this)},copyTo:function(e,t,n){return e.addNode(this.toDict(!0,n),t)},countChildren:function(e){var t,n,i,r=this.children;if(!r)return 0;if(i=r.length,!1!==e)for(t=0,n=i;t<n;t++)i+=r[t].countChildren();return i},debug:function(e){4<=this.tree.options.debugLevel&&(Array.prototype.unshift.call(arguments,this.toString()),d("log",arguments))},discard:function(){return this.warn("FancytreeNode.discard() is deprecated since 2014-02-16. Use .resetLazy() instead."),this.resetLazy()},discardMarkup:function(e){this.tree._callHook(e?"nodeRemoveMarkup":"nodeRemoveChildMarkup",this)},error:function(e){1<=this.tree.options.debugLevel&&(Array.prototype.unshift.call(arguments,this.toString()),d("error",arguments))},findAll:function(t){t=N(t)?t:L(t);var n=[];return this.visit(function(e){t(e)&&n.push(e)}),n},findFirst:function(t){t=N(t)?t:L(t);var n=null;return this.visit(function(e){if(t(e))return n=e,!1}),n},findRelatedNode:function(e,t){return this.tree.findRelatedNode(this,e,t)},_changeSelectStatusAttrs:function(e){var t=!1,n=this.tree.options,i=h.evalOption("unselectable",this,this,n,!1),n=h.evalOption("unselectableStatus",this,this,n,void 0);switch(e=i&&null!=n?n:e){case!1:t=this.selected||this.partsel,this.selected=!1,this.partsel=!1;break;case!0:t=!this.selected||!this.partsel,this.selected=!0,this.partsel=!0;break;case void 0:t=this.selected||!this.partsel,this.selected=!1,this.partsel=!0;break;default:k(!1,"invalid state: "+e)}return t&&this.renderStatus(),t},fixSelection3AfterClick:function(e){var t=this.isSelected();this.visit(function(e){if(e._changeSelectStatusAttrs(t),e.radiogroup)return"skip"}),this.fixSelection3FromEndNodes(e)},fixSelection3FromEndNodes:function(e){var u=this.tree.options;k(3===u.selectMode,"expected selectMode 3"),function e(t){var n,i,r,o,s,a,l,d,c=t.children;if(c&&c.length){for(l=!(a=!0),n=0,i=c.length;n<i;n++)o=e(r=c[n]),h.evalOption("unselectableIgnore",r,r,u,!1)||(!1!==o&&(l=!0),!0!==o&&(a=!1));s=!!a||!!l&&void 0}else s=null==(d=h.evalOption("unselectableStatus",t,t,u,void 0))?!!t.selected:!!d;return t.partsel&&!t.selected&&t.lazy&&null==t.children&&(s=void 0),t._changeSelectStatusAttrs(s),s}(this),this.visitParents(function(e){for(var t,n,i,r=e.children,o=!0,s=!1,a=0,l=r.length;a<l;a++)t=r[a],h.evalOption("unselectableIgnore",t,t,u,!1)||(((n=null==(i=h.evalOption("unselectableStatus",t,t,u,void 0))?!!t.selected:!!i)||t.partsel)&&(s=!0),n||(o=!1));e._changeSelectStatusAttrs(n=!!o||!!s&&void 0)})},fromDict:function(e){for(var t in e)s[t]?this[t]=e[t]:"data"===t?C.extend(this.data,e.data):N(e[t])||a[t]||(this.data[t]=e[t]);e.children&&(this.removeChildren(),this.addChildren(e.children)),this.renderTitle()},getChildren:function(){if(void 0!==this.hasChildren())return this.children},getFirstChild:function(){return this.children?this.children[0]:null},getIndex:function(){return C.inArray(this,this.parent.children)},getIndexHier:function(e,n){e=e||".";var i,r=[];return C.each(this.getParentList(!1,!0),function(e,t){i=""+(t.getIndex()+1),n&&(i=("0000000"+i).substr(-n)),r.push(i)}),r.join(e)},getKeyPath:function(e){var t=this.tree.options.keyPathSeparator;return t+this.getPath(!e,"key",t)},getLastChild:function(){return this.children?this.children[this.children.length-1]:null},getLevel:function(){for(var e=0,t=this.parent;t;)e++,t=t.parent;return e},getNextSibling:function(){if(this.parent)for(var e=this.parent.children,t=0,n=e.length-1;t<n;t++)if(e[t]===this)return e[t+1];return null},getParent:function(){return this.parent},getParentList:function(e,t){for(var n=[],i=t?this:this.parent;i;)(e||i.parent)&&n.unshift(i),i=i.parent;return n},getPath:function(e,t,n){n=n||"/";var i,r=[],o=N(t=t||"title");return this.visitParents(function(e){e.parent&&(i=o?t(e):e[t],r.unshift(i))},e=!1!==e),r.join(n)},getPrevSibling:function(){if(this.parent)for(var e=this.parent.children,t=1,n=e.length;t<n;t++)if(e[t]===this)return e[t-1];return null},getSelectedNodes:function(t){var n=[];return this.visit(function(e){if(e.selected&&(n.push(e),!0===t))return"skip"}),n},hasChildren:function(){return this.lazy?null==this.children?void 0:0!==this.children.length&&(1!==this.children.length||!this.children[0].isStatusNode()||void 0):!(!this.children||!this.children.length)},hasClass:function(e){return 0<=(" "+(this.extraClasses||"")+" ").indexOf(" "+e+" ")},hasFocus:function(){return this.tree.hasFocus()&&this.tree.focusNode===this},info:function(e){3<=this.tree.options.debugLevel&&(Array.prototype.unshift.call(arguments,this.toString()),d("info",arguments))},isActive:function(){return this.tree.activeNode===this},isBelowOf:function(e){return this.getIndexHier(".",5)>e.getIndexHier(".",5)},isChildOf:function(e){return this.parent&&this.parent===e},isDescendantOf:function(e){if(!e||e.tree!==this.tree)return!1;for(var t=this.parent;t;){if(t===e)return!0;t===t.parent&&C.error("Recursive parent link: "+t),t=t.parent}return!1},isExpanded:function(){return!!this.expanded},isFirstSibling:function(){var e=this.parent;return!e||e.children[0]===this},isFolder:function(){return!!this.folder},isLastSibling:function(){var e=this.parent;return!e||e.children[e.children.length-1]===this},isLazy:function(){return!!this.lazy},isLoaded:function(){return!this.lazy||void 0!==this.hasChildren()},isLoading:function(){return!!this._isLoading},isRoot:function(){return this.isRootNode()},isPartsel:function(){return!this.selected&&!!this.partsel},isPartload:function(){return!!this.partload},isRootNode:function(){return this.tree.rootNode===this},isSelected:function(){return!!this.selected},isStatusNode:function(){return!!this.statusNodeType},isPagingNode:function(){return"paging"===this.statusNodeType},isTopLevel:function(){return this.tree.rootNode===this.parent},isUndefined:function(){return void 0===this.hasChildren()},isVisible:function(){var e,t,n=this.tree.enableFilter,i=this.getParentList(!1,!1);if(n&&!this.match&&!this.subMatchCount)return!1;for(e=0,t=i.length;e<t;e++)if(!i[e].expanded)return!1;return!0},lazyLoad:function(e){C.error("FancytreeNode.lazyLoad() is deprecated since 2014-02-16. Use .load() instead.")},load:function(e){var t=this,n=this.isExpanded();return k(this.isLazy(),"load() requires a lazy node"),e||this.isUndefined()?(this.isLoaded()&&this.resetLazy(),!1===(e=this.tree._triggerNodeEvent("lazyLoad",this))?T(this):(k("boolean"!=typeof e,"lazyLoad event must return source in data.result"),e=this.tree._callHook("nodeLoadChildren",this,e),n?(this.expanded=!0,e.always(function(){t.render()})):e.always(function(){t.renderStatus()}),e)):T(this)},makeVisible:function(e){for(var t=this,n=[],i=new C.Deferred,r=this.getParentList(!1,!1),o=r.length,s=!(e&&!0===e.noAnimation),a=!(e&&!1===e.scrollIntoView),l=o-1;0<=l;l--)n.push(r[l].setExpanded(!0,e));return C.when.apply(C,n).done(function(){a?t.scrollIntoView(s).done(function(){i.resolve()}):i.resolve()}),i.promise()},moveTo:function(t,e,n){void 0===e||"over"===e?e="child":"firstChild"===e&&(t.children&&t.children.length?(e="before",t=t.children[0]):e="child");var i,r=this.tree,o=this.parent,s="child"===e?t:t.parent;if(this!==t){if(this.parent?s.isDescendantOf(this)&&C.error("Cannot move a node to its own descendant"):C.error("Cannot move system root"),s!==o&&o.triggerModifyChild("remove",this),1===this.parent.children.length){if(this.parent===s)return;this.parent.children=this.parent.lazy?[]:null,this.parent.expanded=!1}else k(0<=(i=C.inArray(this,this.parent.children)),"invalid source parent"),this.parent.children.splice(i,1);if((this.parent=s).hasChildren())switch(e){case"child":s.children.push(this);break;case"before":k(0<=(i=C.inArray(t,s.children)),"invalid target parent"),s.children.splice(i,0,this);break;case"after":k(0<=(i=C.inArray(t,s.children)),"invalid target parent"),s.children.splice(i+1,0,this);break;default:C.error("Invalid mode "+e)}else s.children=[this];n&&t.visit(n,!0),s===o?s.triggerModifyChild("move",this):s.triggerModifyChild("add",this),r!==t.tree&&(this.warn("Cross-tree moveTo is experimental!"),this.visit(function(e){e.tree=t.tree},!0)),r._callHook("treeStructureChanged",r,"moveTo"),o.isDescendantOf(s)||o.render(),s.isDescendantOf(o)||s===o||s.render()}},navigate:function(e,t){var n=C.ui.keyCode;switch(e){case"left":case n.LEFT:if(this.expanded)return this.setExpanded(!1);break;case"right":case n.RIGHT:if(!this.expanded&&(this.children||this.lazy))return this.setExpanded()}if(n=this.findRelatedNode(e)){try{n.makeVisible({scrollIntoView:!1})}catch(e){}return!1===t?(n.setFocus(),T()):n.setActive()}return this.warn("Could not find related node '"+e+"'."),T()},remove:function(){return this.parent.removeChild(this)},removeChild:function(e){return this.tree._callHook("nodeRemoveChild",this,e)},removeChildren:function(){return this.tree._callHook("nodeRemoveChildren",this)},removeClass:function(e){return this.toggleClass(e,!1)},render:function(e,t){return this.tree._callHook("nodeRender",this,e,t)},renderTitle:function(){return this.tree._callHook("nodeRenderTitle",this)},renderStatus:function(){return this.tree._callHook("nodeRenderStatus",this)},replaceWith:function(e){var n=this.parent,i=C.inArray(this,n.children),r=this;return k(this.isPagingNode(),"replaceWith() currently requires a paging status node"),(e=this.tree._callHook("nodeLoadChildren",this,e)).done(function(e){var t=r.children;for(l=0;l<t.length;l++)t[l].parent=n;n.children.splice.apply(n.children,[i+1,0].concat(t)),r.children=null,r.remove(),n.render()}).fail(function(){r.setExpanded()}),e},resetLazy:function(){this.removeChildren(),this.expanded=!1,this.lazy=!0,this.children=void 0,this.renderStatus()},scheduleAction:function(e,t){this.tree.timer&&(clearTimeout(this.tree.timer),this.tree.debug("clearTimeout(%o)",this.tree.timer)),this.tree.timer=null;var n=this;switch(e){case"cancel":break;case"expand":this.tree.timer=setTimeout(function(){n.tree.debug("setTimeout: trigger expand"),n.setExpanded(!0)},t);break;case"activate":this.tree.timer=setTimeout(function(){n.tree.debug("setTimeout: trigger activate"),n.setActive(!0)},t);break;default:C.error("Invalid mode "+e)}},scrollIntoView:function(e,t){if(void 0!==t&&((p=t).tree&&void 0!==p.statusNodeType))throw Error("scrollIntoView() with 'topNode' option is deprecated since 2014-05-08. Use 'options.topNode' instead.");var n=C.extend({effects:!0===e?{duration:200,queue:!1}:e,scrollOfs:this.tree.options.scrollOfs,scrollParent:this.tree.options.scrollParent,topNode:null},t),i=n.scrollParent,r=this.tree.$container,o=r.css("overflow-y");i?i.jquery||(i=C(i)):i=!this.tree.tbody&&("scroll"===o||"auto"===o)?r:r.scrollParent(),i[0]!==document&&i[0]!==document.body||(this.debug("scrollIntoView(): normalizing scrollParent to 'window':",i[0]),i=C(window));var s,a,l=new C.Deferred,d=this,c=C(this.span).height(),u=n.scrollOfs.top||0,h=n.scrollOfs.bottom||0,f=i.height(),p=i.scrollTop(),e=i,t=i[0]===window,o=n.topNode||null,r=null;return this.isRootNode()||!this.isVisible()?(this.info("scrollIntoView(): node is invisible."),T()):(t?(a=C(this.span).offset().top,s=o&&o.span?C(o.span).offset().top:0,e=C("html,body")):(k(i[0]!==document&&i[0]!==document.body,"scrollParent should be a simple element or `window`, not document or body."),t=i.offset().top,a=C(this.span).offset().top-t+p,s=o?C(o.span).offset().top-t+p:0,f-=Math.max(0,i.innerHeight()-i[0].clientHeight)),a<p+u?r=a-u:p+f-h<a+c&&(r=a+c-f+h,o&&(k(o.isRootNode()||o.isVisible(),"topNode must be visible"),s<r&&(r=s-u))),null===r?l.resolveWith(this):n.effects?(n.effects.complete=function(){l.resolveWith(d)},e.stop(!0).animate({scrollTop:r},n.effects)):(e[0].scrollTop=r,l.resolveWith(this)),l.promise())},setActive:function(e,t){return this.tree._callHook("nodeSetActive",this,e,t)},setExpanded:function(e,t){return this.tree._callHook("nodeSetExpanded",this,e,t)},setFocus:function(e){return this.tree._callHook("nodeSetFocus",this,e)},setSelected:function(e,t){return this.tree._callHook("nodeSetSelected",this,e,t)},setStatus:function(e,t,n){return this.tree._callHook("nodeSetStatus",this,e,t,n)},setTitle:function(e){this.title=e,this.renderTitle(),this.triggerModify("rename")},sortChildren:function(e,t){var n,i,r=this.children;if(r){if(r.sort(e=e||function(e,t){e=e.title.toLowerCase(),t=t.title.toLowerCase();return e===t?0:t<e?1:-1}),t)for(n=0,i=r.length;n<i;n++)r[n].children&&r[n].sortChildren(e,"$norender$");"$norender$"!==t&&this.render(),this.triggerModifyChild("sort")}},toDict:function(e,t){var n,i,r,o,s={},a=this;if(C.each(b,function(e,t){!a[t]&&!1!==a[t]||(s[t]=a[t])}),C.isEmptyObject(this.data)||(s.data=C.extend({},this.data),C.isEmptyObject(s.data)&&delete s.data),t){if(!1===(o=t(s,a)))return!1;"skip"===o&&(e=!1)}if(e&&_(this.children))for(s.children=[],n=0,i=this.children.length;n<i;n++)(r=this.children[n]).isStatusNode()||!1!==(o=r.toDict(!0,t))&&s.children.push(o);return s},toggleClass:function(e,t){var n,i,r=e.match(/\S+/g)||[],o=0,s=!1,a=this[this.tree.statusClassPropName],l=" "+(this.extraClasses||"")+" ";for(a&&C(a).toggleClass(e,t);n=r[o++];)if(i=0<=l.indexOf(" "+n+" "),t=void 0===t?!i:!!t)i||(l+=n+" ",s=!0);else for(;-1<l.indexOf(" "+n+" ");)l=l.replace(" "+n+" "," ");return this.extraClasses=S(l),s},toggleExpanded:function(){return this.tree._callHook("nodeToggleExpanded",this)},toggleSelected:function(){return this.tree._callHook("nodeToggleSelected",this)},toString:function(){return"FancytreeNode@"+this.key+"[title='"+this.title+"']"},triggerModifyChild:function(e,t,n){var i=this.tree.options.modifyChild;i&&(t&&t.parent!==this&&C.error("childNode "+t+" is not a child of "+this),t={node:this,tree:this.tree,operation:e,childNode:t||null},n&&C.extend(t,n),i({type:"modifyChild"},t))},triggerModify:function(e,t){this.parent.triggerModifyChild(e,this,t)},visit:function(e,t){var n,i,r=!0,o=this.children;if(!0===t&&(!1===(r=e(this))||"skip"===r))return r;if(o)for(n=0,i=o.length;n<i&&!1!==(r=o[n].visit(e,!0));n++);return r},visitAndLoad:function(n,e,t){var i,r,o,s=this;return!n||!0!==e||!1!==(r=n(s))&&"skip"!==r?s.children||s.lazy?(i=new C.Deferred,o=[],s.load().done(function(){for(var e=0,t=s.children.length;e<t;e++){if(!1===(r=s.children[e].visitAndLoad(n,!0,!0))){i.reject();break}"skip"!==r&&o.push(r)}C.when.apply(this,o).then(function(){i.resolve()})}),i.promise()):T():t?r:T()},visitParents:function(e,t){if(t&&!1===e(this))return!1;for(var n=this.parent;n;){if(!1===e(n))return!1;n=n.parent}return!0},visitSiblings:function(e,t){for(var n,i=this.parent.children,r=0,o=i.length;r<o;r++)if(n=i[r],(t||n!==this)&&!1===e(n))return!1;return!0},warn:function(e){2<=this.tree.options.debugLevel&&(Array.prototype.unshift.call(arguments,this.toString()),d("warn",arguments))}},F.prototype={_makeHookContext:function(e,t,n){var i,r;return void 0!==e.node?(t&&e.originalEvent!==t&&C.error("invalid args"),i=e):e.tree?i={node:e,tree:r=e.tree,widget:r.widget,options:r.widget.options,originalEvent:t,typeInfo:r.types[e.type]||{}}:e.widget?i={node:null,tree:e,widget:e.widget,options:e.widget.options,originalEvent:t}:C.error("invalid args"),n&&C.extend(i,n),i},_callHook:function(e,t,n){var i=this._makeHookContext(t),r=this[e],t=Array.prototype.slice.call(arguments,2);return N(r)||C.error("_callHook('"+e+"') is not a function"),t.unshift(i),r.apply(this,t)},_setExpiringValue:function(e,t,n){this._tempCache[e]={value:t,expire:Date.now()+(+n||50)}},_getExpiringValue:function(e){var t=this._tempCache[e];return t&&t.expire>Date.now()?t.value:(delete this._tempCache[e],null)},_usesExtension:function(e){return 0<=C.inArray(e,this.options.extensions)},_requireExtension:function(e,t,n,i){null!=n&&(n=!!n);var r=this._local.name,o=this.options.extensions,s=C.inArray(e,o)<C.inArray(r,o),o=t&&null==this.ext[e],s=!o&&null!=n&&n!==s;return k(r&&r!==e,"invalid or same name '"+r+"' (require yourself?)"),!o&&!s||(i||(o||t?(i="'"+r+"' extension requires '"+e+"'",s&&(i+=" to be registered "+(n?"before":"after")+" itself")):i="If used together, `"+e+"` must be registered "+(n?"before":"after")+" `"+r+"`"),C.error(i),!1)},activateKey:function(e,t){e=this.getNodeByKey(e);return e?e.setActive(!0,t):this.activeNode&&this.activeNode.setActive(!1,t),e},addPagingNode:function(e,t){return this.rootNode.addPagingNode(e,t)},applyCommand:function(e,t,n){var i;switch(t=t||this.getActiveNode(),e){case"moveUp":(i=t.getPrevSibling())&&(t.moveTo(i,"before"),t.setActive());break;case"moveDown":(i=t.getNextSibling())&&(t.moveTo(i,"after"),t.setActive());break;case"indent":(i=t.getPrevSibling())&&(t.moveTo(i,"child"),i.setExpanded(),t.setActive());break;case"outdent":t.isTopLevel()||(t.moveTo(t.getParent(),"after"),t.setActive());break;case"remove":i=t.getPrevSibling()||t.getParent(),t.remove(),i&&i.setActive();break;case"addChild":t.editCreateNode("child","");break;case"addSibling":t.editCreateNode("after","");break;case"rename":t.editStart();break;case"down":case"first":case"last":case"left":case"parent":case"right":case"up":return t.navigate(e);default:C.error("Unhandled command: '"+e+"'")}},applyPatch:function(e){for(var t,n,i,r,o=e.length,s=[],a=0;a<o;a++)k(2===(t=e[a]).length,"patchList must be an array of length-2-arrays"),n=t[0],i=t[1],(r=null===n?this.rootNode:this.getNodeByKey(n))?(t=new C.Deferred,s.push(t),r.applyPatch(i).always(O(t,r))):this.warn("could not find node with key '"+n+"'");return C.when.apply(C,s).promise()},clear:function(e){this._callHook("treeClear",this)},count:function(){return this.rootNode.countChildren()},debug:function(e){4<=this.options.debugLevel&&(Array.prototype.unshift.call(arguments,this.toString()),d("log",arguments))},destroy:function(){this.widget.destroy()},enable:function(e){!1===e?this.widget.disable():this.widget.enable()},enableUpdate:function(e){return!!this._enableUpdate==!!(e=!1!==e)?e:((this._enableUpdate=e)?(this.debug("enableUpdate(true): redraw "),this._callHook("treeStructureChanged",this,"enableUpdate"),this.render()):this.debug("enableUpdate(false)..."),!e)},error:function(e){1<=this.options.debugLevel&&(Array.prototype.unshift.call(arguments,this.toString()),d("error",arguments))},expandAll:function(t,n){var e=this.enableUpdate(!1);t=!1!==t,this.visit(function(e){!1!==e.hasChildren()&&e.isExpanded()!==t&&e.setExpanded(t,n)}),this.enableUpdate(e)},findAll:function(e){return this.rootNode.findAll(e)},findFirst:function(e){return this.rootNode.findFirst(e)},findNextNode:function(t,n){var i,r=null,e=this.getFirstChild();function o(e){if((r=t(e)?e:r)||e===n)return!1}return t="string"==typeof t?(i=new RegExp("^"+t,"i"),function(e){return i.test(e.title)}):t,this.visitRows(o,{start:n=n||e,includeSelf:!1}),r||n===e||this.visitRows(o,{start:e,includeSelf:!0}),r},findRelatedNode:function(e,t,n){var i=null,r=C.ui.keyCode;switch(t){case"parent":case r.BACKSPACE:e.parent&&e.parent.parent&&(i=e.parent);break;case"first":case r.HOME:this.visit(function(e){if(e.isVisible())return i=e,!1});break;case"last":case r.END:this.visit(function(e){e.isVisible()&&(i=e)});break;case"left":case r.LEFT:e.expanded?e.setExpanded(!1):e.parent&&e.parent.parent&&(i=e.parent);break;case"right":case r.RIGHT:e.expanded||!e.children&&!e.lazy?e.children&&e.children.length&&(i=e.children[0]):(e.setExpanded(),i=e);break;case"up":case r.UP:this.visitRows(function(e){return i=e,!1},{start:e,reverse:!0,includeSelf:!1});break;case"down":case r.DOWN:this.visitRows(function(e){return i=e,!1},{start:e,includeSelf:!1});break;default:this.tree.warn("Unknown relation '"+t+"'.")}return i},generateFormElements:function(e,t,n){n=n||{};var i="string"==typeof e?e:"ft_"+this._id+"[]",r="string"==typeof t?t:"ft_"+this._id+"_active",o="fancytree_result_"+this._id,s=C("#"+o),a=3===this.options.selectMode&&!1!==n.stopOnParents;function l(e){s.append(C("<input>",{type:"checkbox",name:i,value:e.key,checked:!0}))}s.length?s.empty():s=C("<div>",{id:o}).hide().insertAfter(this.$container),!1!==t&&this.activeNode&&s.append(C("<input>",{type:"radio",name:r,value:this.activeNode.key,checked:!0})),n.filter?this.visit(function(e){var t=n.filter(e);if("skip"===t)return t;!1!==t&&l(e)}):!1!==e&&(a=this.getSelectedNodes(a),C.each(a,function(e,t){l(t)}))},getActiveNode:function(){return this.activeNode},getFirstChild:function(){return this.rootNode.getFirstChild()},getFocusNode:function(){return this.focusNode},getOption:function(e){return this.widget.option(e)},getNodeByKey:function(t,e){var n,i;return!e&&(n=document.getElementById(this.options.idPrefix+t))?n.ftnode||null:(e=e||this.rootNode,t=""+t,e.visit(function(e){if(e.key===t)return i=e,!1},!(i=null)),i)},getRootNode:function(){return this.rootNode},getSelectedNodes:function(e){return this.rootNode.getSelectedNodes(e)},hasFocus:function(){return!!this._hasFocus},info:function(e){3<=this.options.debugLevel&&(Array.prototype.unshift.call(arguments,this.toString()),d("info",arguments))},isLoading:function(){var t=!1;return this.rootNode.visit(function(e){if(e._isLoading||e._requestId)return!(t=!0)},!0),t},loadKeyPath:function(e,t){var i,n,r,o=this,s=new C.Deferred,a=this.getRootNode(),l=this.options.keyPathSeparator,d=[],c=C.extend({},t);for("function"==typeof t?i=t:t&&t.callback&&(i=t.callback),c.callback=function(e,t,n){i&&i.call(e,t,n),s.notifyWith(e,[{node:t,status:n}])},null==c.matchKey&&(c.matchKey=function(e,t){return e.key===t}),_(e)||(e=[e]),n=0;n<e.length;n++)(r=e[n]).charAt(0)===l&&(r=r.substr(1)),d.push(r.split(l));return setTimeout(function(){o._loadKeyPathImpl(s,c,a,d).done(function(){s.resolve()})},0),s.promise()},_loadKeyPathImpl:function(e,o,t,n){var i,r,s,a,l,d,c,u,h,f,p=this;for(c={},r=0;r<n.length;r++)for(h=n[r],u=t;h.length;){if(s=h.shift(),!(a=function(e,t){var n,i,r=e.children;if(r)for(n=0,i=r.length;n<i;n++)if(o.matchKey(r[n],t))return r[n];return null}(u,s))){this.warn("loadKeyPath: key not found: "+s+" (parent: "+u+")"),o.callback(this,s,"error");break}if(0===h.length){o.callback(this,a,"ok");break}if(a.lazy&&void 0===a.hasChildren()){o.callback(this,a,"loaded"),c[s=a.key]?c[s].pathSegList.push(h):c[s]={parent:a,pathSegList:[h]};break}o.callback(this,a,"loaded"),u=a}for(l in i=[],c)w(c,l)&&(d=c[l],f=new C.Deferred,i.push(f),function(t,n,e){o.callback(p,n,"loading"),n.load().done(function(){p._loadKeyPathImpl.call(p,t,o,n,e).always(O(t,p))}).fail(function(e){p.warn("loadKeyPath: error loading lazy "+n),o.callback(p,a,"error"),t.rejectWith(p)})}(f,d.parent,d.pathSegList));return C.when.apply(C,i).promise()},reactivate:function(e){var t,n=this.activeNode;return n?(this.activeNode=null,t=n.setActive(!0,{noFocus:!0}),e&&n.setFocus(),t):T()},reload:function(e){return this._callHook("treeClear",this),this._callHook("treeLoad",this,e)},render:function(e,t){return this.rootNode.render(e,t)},selectAll:function(t){this.visit(function(e){e.setSelected(t)})},setFocus:function(e){return this._callHook("treeSetFocus",this,e)},setOption:function(e,t){return this.widget.option(e,t)},debugTime:function(e){4<=this.options.debugLevel&&window.console.time(this+" - "+e)},debugTimeEnd:function(e){4<=this.options.debugLevel&&window.console.timeEnd(this+" - "+e)},toDict:function(e,t){t=this.rootNode.toDict(!0,t);return e?t:t.children},toString:function(){return"Fancytree@"+this._id},_triggerNodeEvent:function(e,t,n,i){i=this._makeHookContext(t,n,i),n=this.widget._trigger(e,n,i);return!1!==n&&void 0!==i.result?i.result:n},_triggerTreeEvent:function(e,t,n){n=this._makeHookContext(this,t,n),t=this.widget._trigger(e,t,n);return!1!==t&&void 0!==n.result?n.result:t},visit:function(e){return this.rootNode.visit(e,!1)},visitRows:function(t,e){if(!this.rootNode.hasChildren())return!1;if(e&&e.reverse)return delete e.reverse,this._visitRowsUp(t,e);for(var n,i,r,o=0,s=!1===(e=e||{}).includeSelf,a=!!e.includeHidden,l=!a&&this.enableFilter,d=e.start||this.rootNode.children[0],c=d.parent;c;){for(k(0<=(i=(r=c.children).indexOf(d)+o),"Could not find "+d+" in parent's children: "+c),n=i;n<r.length;n++)if(d=r[n],!l||d.match||d.subMatchCount){if(!s&&!1===t(d))return!1;if(s=!1,d.children&&d.children.length&&(a||d.expanded)&&!1===d.visit(function(e){return!l||e.match||e.subMatchCount?!1!==t(e)&&(a||!e.children||e.expanded?void 0:"skip"):"skip"},!1))return!1}c=(d=c).parent,o=1}return!0},_visitRowsUp:function(e,t){for(var n,i,r,o=!!t.includeHidden,s=t.start||this.rootNode.children[0];;){if((n=(r=s.parent).children)[0]===s){if(!(s=r).parent)break;n=r.children}else for(i=n.indexOf(s),s=n[i-1];(o||s.expanded)&&s.children&&s.children.length;)s=(n=(r=s).children)[n.length-1];if((o||s.isVisible())&&!1===e(s))return!1}},warn:function(e){2<=this.options.debugLevel&&(Array.prototype.unshift.call(arguments,this.toString()),d("warn",arguments))}},C.extend(F.prototype,{nodeClick:function(e){var t,n,i=e.targetType,r=e.node;if("expander"===i)r.isLoading()?r.debug("Got 2nd click while loading: ignored"):this._callHook("nodeToggleExpanded",e);else if("checkbox"===i)this._callHook("nodeToggleSelected",e),e.options.focusOnSelect&&this._callHook("nodeSetFocus",e,!0);else{if(t=!(n=!1),r.folder)switch(e.options.clickFolderMode){case 2:t=!(n=!0);break;case 3:n=t=!0}t&&(this.nodeSetFocus(e),this._callHook("nodeSetActive",e,!0)),n&&this._callHook("nodeToggleExpanded",e)}},nodeCollapseSiblings:function(e,t){var n,i,r,o=e.node;if(o.parent)for(i=0,r=(n=o.parent.children).length;i<r;i++)n[i]!==o&&n[i].expanded&&this._callHook("nodeSetExpanded",n[i],!1,t)},nodeDblclick:function(e){"title"===e.targetType&&4===e.options.clickFolderMode&&this._callHook("nodeToggleExpanded",e),"title"===e.targetType&&e.originalEvent.preventDefault()},nodeKeydown:function(e){var t=e.originalEvent,n=e.node,i=e.tree,r=e.options,o=t.which,s=t.key||String.fromCharCode(o),a=!!(t.altKey||t.ctrlKey||t.metaKey),l=!g[o]&&!u[o]&&!a,o=C(t.target),d=!0,c=!(t.ctrlKey||!r.autoActivate);if(n||(a=this.getActiveNode()||this.getFirstChild())&&(a.setFocus(),(n=e.node=this.focusNode).debug("Keydown force focus on active node")),r.quicksearch&&l&&!o.is(":input:enabled"))return 500<(o=Date.now())-i.lastQuicksearchTime&&(i.lastQuicksearchTerm=""),i.lastQuicksearchTime=o,i.lastQuicksearchTerm+=s,(s=i.findNextNode(i.lastQuicksearchTerm,i.getActiveNode()))&&s.setActive(),void t.preventDefault();switch(h.eventToString(t)){case"+":case"=":i.nodeSetExpanded(e,!0);break;case"-":i.nodeSetExpanded(e,!1);break;case"space":n.isPagingNode()?i._triggerNodeEvent("clickPaging",e,t):h.evalOption("checkbox",n,n,r,!1)?i.nodeToggleSelected(e):i.nodeSetActive(e,!0);break;case"return":i.nodeSetActive(e,!0);break;case"home":case"end":case"backspace":case"left":case"right":case"up":case"down":n.navigate(t.which,c);break;default:d=!1}d&&t.preventDefault()},nodeLoadChildren:function(o,s){var t,n,a,e=null,i=!0,l=o.tree,d=o.node,c=d.parent,r="nodeLoadChildren",u=Date.now();return N(s)&&k(!N(s=s.call(l,{type:"source"},o)),"source callback must not return another function"),N(s.then)?e=s:s.url?e=(t=C.extend({},o.options.ajax,s)).debugDelay?(n=t.debugDelay,delete t.debugDelay,_(n)&&(n=n[0]+Math.random()*(n[1]-n[0])),d.warn("nodeLoadChildren waiting debugDelay "+Math.round(n)+" ms ..."),C.Deferred(function(e){setTimeout(function(){C.ajax(t).done(function(){e.resolveWith(this,arguments)}).fail(function(){e.rejectWith(this,arguments)})},n)})):C.ajax(t):C.isPlainObject(s)||_(s)?i=!(e={then:function(e,t){e(s,null,null)}}):C.error("Invalid source type: "+s),d._requestId&&(d.warn("Recursive load request #"+u+" while #"+d._requestId+" is pending."),d._requestId=u),i&&(l.debugTime(r),l.nodeSetStatus(o,"loading")),a=new C.Deferred,e.then(function(e,t,n){var i,r;if("json"!==s.dataType&&"jsonp"!==s.dataType||"string"!=typeof e||C.error("Ajax request returned a string (did you get the JSON dataType wrong?)."),d._requestId&&d._requestId>u)a.rejectWith(this,[f]);else if(null!==d.parent||null===c){if(o.options.postProcess){try{(r=l._triggerNodeEvent("postProcess",o,o.originalEvent,{response:e,error:null,dataType:s.dataType})).error&&l.warn("postProcess returned error:",r)}catch(e){r={error:e,message:""+e,details:"postProcess failed"}}if(r.error)return i=C.isPlainObject(r.error)?r.error:{message:r.error},i=l._makeHookContext(d,null,i),void a.rejectWith(this,[i]);(_(r)||C.isPlainObject(r)&&_(r.children))&&(e=r)}else e&&w(e,"d")&&o.options.enableAspx&&(42===o.options.enableAspx&&l.warn("The default for enableAspx will change to `false` in the fututure. Pass `enableAspx: true` or implement postProcess to silence this warning."),e="string"==typeof e.d?C.parseJSON(e.d):e.d);a.resolveWith(this,[e])}else a.rejectWith(this,[p])},function(e,t,n){n=l._makeHookContext(d,null,{error:e,args:Array.prototype.slice.call(arguments),message:n,details:e.status+": "+n});a.rejectWith(this,[n])}),a.done(function(e){var t,n,i;l.nodeSetStatus(o,"ok"),C.isPlainObject(e)?(k(d.isRootNode(),"source may only be an object for root nodes (expecting an array of child objects otherwise)"),k(_(e.children),"if an object is passed as source, it must contain a 'children' array (all other properties are added to 'tree.data')"),t=(n=e).children,delete n.children,C.each(m,function(e,t){void 0!==n[t]&&(l[t]=n[t],delete n[t])}),C.extend(l.data,n)):t=e,k(_(t),"expected array of children"),d._setChildren(t),l.options.nodata&&0===t.length&&(N(l.options.nodata)?i=l.options.nodata.call(l,{type:"nodata"},o):!0===l.options.nodata&&d.isRootNode()?i=l.options.strings.noData:"string"==typeof l.options.nodata&&d.isRootNode()&&(i=l.options.nodata),i&&d.setStatus("nodata",i)),l._triggerNodeEvent("loadChildren",d)}).fail(function(e){var t;e!==f?e!==p?(e.node&&e.error&&e.message?t=e:"[object Object]"===(t=l._makeHookContext(d,null,{error:e,args:Array.prototype.slice.call(arguments),message:e?e.message||e.toString():""})).message&&(t.message=""),d.warn("Load children failed ("+t.message+")",t),!1!==l._triggerNodeEvent("loadError",t,null)&&l.nodeSetStatus(o,"error",t.message,t.details)):d.warn("Lazy parent node was removed while loading: discarding response."):d.warn("Ignored response for obsolete load request #"+u+" (expected #"+d._requestId+")")}).always(function(){d._requestId=null,i&&l.debugTimeEnd(r)}),a.promise()},nodeLoadKeyPath:function(e,t){},nodeRemoveChild:function(e,t){var n=e.node,i=C.extend({},e,{node:t}),r=n.children;if(1===r.length)return k(t===r[0],"invalid single child"),this.nodeRemoveChildren(e);this.activeNode&&(t===this.activeNode||this.activeNode.isDescendantOf(t))&&this.activeNode.setActive(!1),this.focusNode&&(t===this.focusNode||this.focusNode.isDescendantOf(t))&&(this.focusNode=null),this.nodeRemoveMarkup(i),this.nodeRemoveChildren(i),k(0<=(i=C.inArray(t,r)),"invalid child"),n.triggerModifyChild("remove",t),t.visit(function(e){e.parent=null},!0),this._callHook("treeRegisterNode",this,!1,t),r.splice(i,1)},nodeRemoveChildMarkup:function(e){e=e.node;e.ul&&(e.isRootNode()?C(e.ul).empty():(C(e.ul).remove(),e.ul=null),e.visit(function(e){e.li=e.ul=null}))},nodeRemoveChildren:function(e){var t=e.tree,n=e.node;n.children&&(this.activeNode&&this.activeNode.isDescendantOf(n)&&this.activeNode.setActive(!1),this.focusNode&&this.focusNode.isDescendantOf(n)&&(this.focusNode=null),this.nodeRemoveChildMarkup(e),n.triggerModifyChild("remove",null),n.visit(function(e){e.parent=null,t._callHook("treeRegisterNode",t,!1,e)}),n.lazy?n.children=[]:n.children=null,n.isRootNode()||(n.expanded=!1),this.nodeRenderStatus(e))},nodeRemoveMarkup:function(e){var t=e.node;t.li&&(C(t.li).remove(),t.li=null),this.nodeRemoveChildMarkup(e)},nodeRender:function(e,t,n,i,r){var o,s,a,l,d,c,u,h=e.node,f=e.tree,p=e.options,g=p.aria,y=!1,v=h.parent,m=!v,b=h.children,x=null;if(!1!==f._enableUpdate&&(m||v.ul)){if(k(m||v.ul,"parent UL must exist"),m||(h.li&&(t||h.li.parentNode!==h.parent.ul)&&(h.li.parentNode===h.parent.ul?x=h.li.nextSibling:this.debug("Unlinking "+h+" (must be child of "+h.parent+")"),this.nodeRemoveMarkup(e)),h.li?this.nodeRenderStatus(e):(y=!0,h.li=document.createElement("li"),(h.li.ftnode=h).key&&p.generateIds&&(h.li.id=p.idPrefix+h.key),h.span=document.createElement("span"),h.span.className="fancytree-node",g&&!h.tr&&C(h.li).attr("role","treeitem"),h.li.appendChild(h.span),this.nodeRenderTitle(e),p.createNode&&p.createNode.call(f,{type:"createNode"},e)),p.renderNode&&p.renderNode.call(f,{type:"renderNode"},e)),b){if(m||h.expanded||!0===n){for(h.ul||(h.ul=document.createElement("ul"),(!0!==i||r)&&h.expanded||(h.ul.style.display="none"),g&&C(h.ul).attr("role","group"),h.li?h.li.appendChild(h.ul):h.tree.$div.append(h.ul)),l=0,d=b.length;l<d;l++)u=C.extend({},e,{node:b[l]}),this.nodeRender(u,t,n,!1,!0);for(o=h.ul.firstChild;o;)o=(a=o.ftnode)&&a.parent!==h?(h.debug("_fixParent: remove missing "+a,o),c=o.nextSibling,o.parentNode.removeChild(o),c):o.nextSibling;for(o=h.ul.firstChild,l=0,d=b.length-1;l<d;l++)(s=b[l])===(a=o.ftnode)?o=o.nextSibling:h.ul.insertBefore(s.li,a.li)}}else h.ul&&(this.warn("remove child markup for "+h),this.nodeRemoveChildMarkup(e));m||y&&v.ul.insertBefore(h.li,x)}},nodeRenderTitle:function(e,t){var n,i,r=e.node,o=e.tree,s=e.options,a=s.aria,l=r.getLevel(),d=[];void 0!==t&&(r.title=t),r.span&&!1!==o._enableUpdate&&(t=a&&!1!==r.hasChildren()?" role='button'":"",l<s.minExpandLevel?(r.lazy||(r.expanded=!0),1<l&&d.push("<span "+t+" class='fancytree-expander fancytree-expander-fixed'></span>")):d.push("<span "+t+" class='fancytree-expander'></span>"),(l=h.evalOption("checkbox",r,r,s,!1))&&!r.isStatusNode()&&(n="fancytree-checkbox",("radio"===l||r.parent&&r.parent.radiogroup)&&(n+=" fancytree-radio"),d.push("<span "+(t=a?" role='checkbox'":"")+" class='"+n+"'></span>")),void 0!==r.data.iconClass&&(r.icon?C.error("'iconClass' node option is deprecated since v2.14.0: use 'icon' only instead"):(r.warn("'iconClass' node option is deprecated since v2.14.0: use 'icon' instead"),r.icon=r.data.iconClass)),!1!==(n=h.evalOption("icon",r,r,s,!0))&&(t=a?" role='presentation'":"",i=(i=h.evalOption("iconTooltip",r,r,s,null))?" title='"+D(i)+"'":"","string"==typeof n?c.test(n)?(n="/"===n.charAt(0)?n:(s.imagePath||"")+n,d.push("<img src='"+n+"' class='fancytree-icon'"+i+" alt='' />")):d.push("<span "+t+" class='fancytree-custom-icon "+n+"'"+i+"></span>"):n.text?d.push("<span "+t+" class='fancytree-custom-icon "+(n.addClass||"")+"'"+i+">"+h.escapeHtml(n.text)+"</span>"):n.html?d.push("<span "+t+" class='fancytree-custom-icon "+(n.addClass||"")+"'"+i+">"+n.html+"</span>"):d.push("<span "+t+" class='fancytree-icon'"+i+"></span>")),t="",t=(t=s.renderTitle?s.renderTitle.call(o,{type:"renderTitle"},e)||"":t)||"<span class='fancytree-title'"+(i=(i=!0===(i=h.evalOption("tooltip",r,r,s,null))?r.title:i)?" title='"+D(i)+"'":"")+(s.titlesTabbable?" tabindex='0'":"")+">"+(s.escapeTitles?h.escapeHtml(r.title):r.title)+"</span>",d.push(t),r.span.innerHTML=d.join(""),this.nodeRenderStatus(e),s.enhanceTitle&&(e.$title=C(">span.fancytree-title",r.span),t=s.enhanceTitle.call(o,{type:"enhanceTitle"},e)||""))},nodeRenderStatus:function(e){var t,n=e.node,i=e.tree,r=e.options,o=n.hasChildren(),s=n.isLastSibling(),a=r.aria,l=r._classNames,d=[],e=n[i.statusClassPropName];e&&!1!==i._enableUpdate&&(a&&(t=C(n.tr||n.li)),d.push(l.node),i.activeNode===n&&d.push(l.active),i.focusNode===n&&d.push(l.focused),n.expanded&&d.push(l.expanded),a&&(!1===o?t.removeAttr("aria-expanded"):t.attr("aria-expanded",Boolean(n.expanded))),n.folder&&d.push(l.folder),!1!==o&&d.push(l.hasChildren),s&&d.push(l.lastsib),n.lazy&&null==n.children&&d.push(l.lazy),n.partload&&d.push(l.partload),n.partsel&&d.push(l.partsel),h.evalOption("unselectable",n,n,r,!1)&&d.push(l.unselectable),n._isLoading&&d.push(l.loading),n._error&&d.push(l.error),n.statusNodeType&&d.push(l.statusNodePrefix+n.statusNodeType),n.selected?(d.push(l.selected),a&&t.attr("aria-selected",!0)):a&&t.attr("aria-selected",!1),n.extraClasses&&d.push(n.extraClasses),!1===o?d.push(l.combinedExpanderPrefix+"n"+(s?"l":"")):d.push(l.combinedExpanderPrefix+(n.expanded?"e":"c")+(n.lazy&&null==n.children?"d":"")+(s?"l":"")),d.push(l.combinedIconPrefix+(n.expanded?"e":"c")+(n.folder?"f":"")),e.className=d.join(" "),n.li&&C(n.li).toggleClass(l.lastsib,s))},nodeSetActive:function(e,t,n){var i=e.node,r=e.tree,o=e.options,s=!0===(n=n||{}).noEvents,a=!0===n.noFocus,n=!1!==n.scrollIntoView;return i===r.activeNode===(t=!1!==t)?T(i):(n&&e.originalEvent&&C(e.originalEvent.target).is("a,:checkbox")&&(i.info("Not scrolling while clicking an embedded link."),n=!1),t&&!s&&!1===this._triggerNodeEvent("beforeActivate",i,e.originalEvent)?A(i,["rejected"]):(t?(r.activeNode&&(k(r.activeNode!==i,"node was active (inconsistency)"),t=C.extend({},e,{node:r.activeNode}),r.nodeSetActive(t,!1),k(null===r.activeNode,"deactivate was out of sync?")),o.activeVisible&&i.makeVisible({scrollIntoView:n}),r.activeNode=i,r.nodeRenderStatus(e),a||r.nodeSetFocus(e),s||r._triggerNodeEvent("activate",i,e.originalEvent)):(k(r.activeNode===i,"node was not active (inconsistency)"),r.activeNode=null,this.nodeRenderStatus(e),s||e.tree._triggerNodeEvent("deactivate",i,e.originalEvent)),T(i)))},nodeSetExpanded:function(i,r,e){var t,n,o,s,a,l,d=i.node,c=i.tree,u=i.options,h=!0===(e=e||{}).noAnimation,f=!0===e.noEvents;if(r=!1!==r,C(d.li).hasClass(u._classNames.animating))return d.warn("setExpanded("+r+") while animating: ignored."),A(d,["recursion"]);if(d.expanded&&r||!d.expanded&&!r)return T(d);if(r&&!d.lazy&&!d.hasChildren())return T(d);if(!r&&d.getLevel()<u.minExpandLevel)return A(d,["locked"]);if(!f&&!1===this._triggerNodeEvent("beforeExpand",d,i.originalEvent))return A(d,["rejected"]);if(h||d.isVisible()||(h=e.noAnimation=!0),n=new C.Deferred,r&&!d.expanded&&u.autoCollapse){a=d.getParentList(!1,!0),l=u.autoCollapse;try{for(u.autoCollapse=!1,o=0,s=a.length;o<s;o++)this._callHook("nodeCollapseSiblings",a[o],e)}finally{u.autoCollapse=l}}return n.done(function(){var e=d.getLastChild();r&&u.autoScroll&&!h&&e&&c._enableUpdate?e.scrollIntoView(!0,{topNode:d}).always(function(){f||i.tree._triggerNodeEvent(r?"expand":"collapse",i)}):f||i.tree._triggerNodeEvent(r?"expand":"collapse",i)}),t=function(e){var t=u._classNames,n=u.toggleEffect;if(d.expanded=r,c._callHook("treeStructureChanged",i,r?"expand":"collapse"),c._callHook("nodeRender",i,!1,!1,!0),d.ul)if("none"!==d.ul.style.display==!!d.expanded)d.warn("nodeSetExpanded: UL.style.display already set");else{if(n&&!h)return C(d.li).addClass(t.animating),void(N(C(d.ul)[n.effect])?C(d.ul)[n.effect]({duration:n.duration,always:function(){C(this).removeClass(t.animating),C(d.li).removeClass(t.animating),e()}}):(C(d.ul).stop(!0,!0),C(d.ul).parent().find(".ui-effects-placeholder").remove(),C(d.ul).toggle(n.effect,n.options,n.duration,function(){C(this).removeClass(t.animating),C(d.li).removeClass(t.animating),e()})));d.ul.style.display=d.expanded||!parent?"":"none"}e()},r&&d.lazy&&void 0===d.hasChildren()?d.load().done(function(){n.notifyWith&&n.notifyWith(d,["loaded"]),t(function(){n.resolveWith(d)})}).fail(function(e){t(function(){n.rejectWith(d,["load failed ("+e+")"])})}):t(function(){n.resolveWith(d)}),n.promise()},nodeSetFocus:function(e,t){var n,i=e.tree,r=e.node,o=i.options,s=!!e.originalEvent&&C(e.originalEvent.target).is(":input");if(t=!1!==t,i.focusNode){if(i.focusNode===r&&t)return;n=C.extend({},e,{node:i.focusNode}),i.focusNode=null,this._triggerNodeEvent("blur",n),this._callHook("nodeRenderStatus",n)}t&&(this.hasFocus()||(r.debug("nodeSetFocus: forcing container focus"),this._callHook("treeSetFocus",e,!0,{calledByNode:!0})),r.makeVisible({scrollIntoView:!1}),i.focusNode=r,o.titlesTabbable&&(s||C(r.span).find(".fancytree-title").focus()),o.aria&&C(i.$container).attr("aria-activedescendant",C(r.tr||r.li).uniqueId().attr("id")),this._triggerNodeEvent("focus",e),document.activeElement===i.$container.get(0)||1<=C(document.activeElement,i.$container).length||C(i.$container).focus(),o.autoScroll&&r.scrollIntoView(),this._callHook("nodeRenderStatus",e))},nodeSetSelected:function(e,t,n){var i=e.node,r=e.tree,o=e.options,s=!0===(n=n||{}).noEvents,a=i.parent;if(t=!1!==t,!h.evalOption("unselectable",i,i,o,!1))return i._lastSelectIntent=t,!!i.selected!==t||3===o.selectMode&&i.partsel&&!t?s||!1!==this._triggerNodeEvent("beforeSelect",i,e.originalEvent)?(t&&1===o.selectMode?(r.lastSelectedNode&&r.lastSelectedNode.setSelected(!1),i.selected=t):3!==o.selectMode||!a||a.radiogroup||i.radiogroup?a&&a.radiogroup?i.visitSiblings(function(e){e._changeSelectStatusAttrs(t&&e===i)},!0):i.selected=t:(i.selected=t,i.fixSelection3AfterClick(n)),this.nodeRenderStatus(e),r.lastSelectedNode=t?i:null,void(s||r._triggerNodeEvent("select",e))):!!i.selected:t},nodeSetStatus:function(i,e,t,n){var r=i.node,o=i.tree;function s(e,t){var n=r.children?r.children[0]:null;return n&&n.isStatusNode()?(C.extend(n,e),n.statusNodeType=t,o._callHook("nodeRenderTitle",n)):(r._setChildren([e]),o._callHook("treeStructureChanged",i,"setStatusNode"),r.children[0].statusNodeType=t,o.render()),r.children[0]}switch(e){case"ok":!function(){var e=r.children?r.children[0]:null;if(e&&e.isStatusNode()){try{r.ul&&(r.ul.removeChild(e.li),e.li=null)}catch(e){}1===r.children.length?r.children=[]:r.children.shift(),o._callHook("treeStructureChanged",i,"clearStatusNode")}}(),r._isLoading=!1,r._error=null,r.renderStatus();break;case"loading":r.parent||s({title:o.options.strings.loading+(t?" ("+t+")":""),checkbox:!1,tooltip:n},e),r._isLoading=!0,r._error=null,r.renderStatus();break;case"error":s({title:o.options.strings.loadError+(t?" ("+t+")":""),checkbox:!1,tooltip:n},e),r._isLoading=!1,r._error={message:t,details:n},r.renderStatus();break;case"nodata":s({title:t||o.options.strings.noData,checkbox:!1,tooltip:n},e),r._isLoading=!1,r._error=null,r.renderStatus();break;default:C.error("invalid node status "+e)}},nodeToggleExpanded:function(e){return this.nodeSetExpanded(e,!e.node.expanded)},nodeToggleSelected:function(e){var t=e.node,n=!t.selected;return t.partsel&&!t.selected&&!0===t._lastSelectIntent&&(t.selected=!(n=!1)),t._lastSelectIntent=n,this.nodeSetSelected(e,n)},treeClear:function(e){var t=e.tree;t.activeNode=null,t.focusNode=null,t.$div.find(">ul.fancytree-container").empty(),t.rootNode.children=null,t._callHook("treeStructureChanged",e,"clear")},treeCreate:function(e){},treeDestroy:function(e){this.$div.find(">ul.fancytree-container").remove(),this.$source&&this.$source.removeClass("fancytree-helper-hidden")},treeInit:function(e){var n=e.tree,i=n.options;n.$container.attr("tabindex",i.tabindex),C.each(m,function(e,t){void 0!==i[t]&&(n.info("Move option "+t+" to tree"),n[t]=i[t],delete i[t])}),i.checkboxAutoHide&&n.$container.addClass("fancytree-checkbox-auto-hide"),i.rtl?n.$container.attr("DIR","RTL").addClass("fancytree-rtl"):n.$container.removeAttr("DIR").removeClass("fancytree-rtl"),i.aria&&(n.$container.attr("role","tree"),1!==i.selectMode&&n.$container.attr("aria-multiselectable",!0)),this.treeLoad(e)},treeLoad:function(e,t){var n,i,r,o=e.tree,s=e.widget.element,a=C.extend({},e,{node:this.rootNode});if(o.rootNode.children&&this.treeClear(e),t=t||this.options.source)"string"==typeof t&&C.error("Not implemented");else switch(i=s.data("type")||"html"){case"html":(r=s.find(">ul").not(".fancytree-container").first()).length?(r.addClass("ui-fancytree-source fancytree-helper-hidden"),t=C.ui.fancytree.parseHtml(r),this.data=C.extend(this.data,P(r))):(h.warn("No `source` option was passed and container does not contain `<ul>`: assuming `source: []`."),t=[]);break;case"json":t=C.parseJSON(s.text()),s.contents().filter(function(){return 3===this.nodeType}).remove(),C.isPlainObject(t)&&(k(_(t.children),"if an object is passed as source, it must contain a 'children' array (all other properties are added to 'tree.data')"),t=(n=t).children,delete n.children,C.each(m,function(e,t){void 0!==n[t]&&(o[t]=n[t],delete n[t])}),C.extend(o.data,n));break;default:C.error("Invalid data-type: "+i)}return o._triggerTreeEvent("preInit",null),this.nodeLoadChildren(a,t).done(function(){o._callHook("treeStructureChanged",e,"loadChildren"),o.render(),3===e.options.selectMode&&o.rootNode.fixSelection3FromEndNodes(),o.activeNode&&o.options.activeVisible&&o.activeNode.makeVisible(),o._triggerTreeEvent("init",null,{status:!0})}).fail(function(){o.render(),o._triggerTreeEvent("init",null,{status:!1})})},treeRegisterNode:function(e,t,n){e.tree._callHook("treeStructureChanged",e,t?"addNode":"removeNode")},treeSetFocus:function(e,t,n){var i;(t=!1!==t)!==this.hasFocus()&&(!(this._hasFocus=t)&&this.focusNode?this.focusNode.setFocus(!1):!t||n&&n.calledByNode||C(this.$container).focus(),this.$container.toggleClass("fancytree-treefocus",t),this._triggerTreeEvent(t?"focusTree":"blurTree"),t&&!this.activeNode&&(i=this._lastMousedownNode||this.getFirstChild())&&i.setFocus())},treeSetOption:function(e,t,n){var i=e.tree,r=!0,o=!1,s=!1;switch(t){case"aria":case"checkbox":case"icon":case"minExpandLevel":case"tabindex":s=o=!0;break;case"checkboxAutoHide":i.$container.toggleClass("fancytree-checkbox-auto-hide",!!n);break;case"escapeTitles":case"tooltip":s=!0;break;case"rtl":!1===n?i.$container.removeAttr("DIR").removeClass("fancytree-rtl"):i.$container.attr("DIR","RTL").addClass("fancytree-rtl"),s=!0;break;case"source":r=!1,i._callHook("treeLoad",i,n),s=!0}i.debug("set option "+t+"="+n+" <"+typeof n+">"),r&&(this.widget._super||C.Widget.prototype._setOption).call(this.widget,t,n),o&&i._callHook("treeCreate",i),s&&i.render(!0,!1)},treeStructureChanged:function(e,t){}}),C.widget("ui.fancytree",{options:{activeVisible:!0,ajax:{type:"GET",cache:!1,dataType:"json"},aria:!0,autoActivate:!0,autoCollapse:!1,autoScroll:!1,checkbox:!1,clickFolderMode:4,copyFunctionsToData:!1,debugLevel:null,disabled:!1,enableAspx:42,escapeTitles:!1,extensions:[],focusOnSelect:!1,generateIds:!1,icon:!0,idPrefix:"ft_",keyboard:!0,keyPathSeparator:"/",minExpandLevel:1,nodata:!0,quicksearch:!1,rtl:!1,scrollOfs:{top:0,bottom:0},scrollParent:null,selectMode:2,strings:{loading:"Loading...",loadError:"Load error!",moreData:"More...",noData:"No data."},tabindex:"0",titlesTabbable:!1,toggleEffect:{effect:"slideToggle",duration:200},tooltip:!1,treeId:null,_classNames:{active:"fancytree-active",animating:"fancytree-animating",combinedExpanderPrefix:"fancytree-exp-",combinedIconPrefix:"fancytree-ico-",error:"fancytree-error",expanded:"fancytree-expanded",focused:"fancytree-focused",folder:"fancytree-folder",hasChildren:"fancytree-has-children",lastsib:"fancytree-lastsib",lazy:"fancytree-lazy",loading:"fancytree-loading",node:"fancytree-node",partload:"fancytree-partload",partsel:"fancytree-partsel",radio:"fancytree-radio",selected:"fancytree-selected",statusNodePrefix:"fancytree-statusnode-",unselectable:"fancytree-unselectable"},lazyLoad:null,postProcess:null},_deprecationWarning:function(e){var t=this.tree;t&&3<=t.options.debugLevel&&t.warn("$().fancytree('"+e+"') is deprecated (see https://wwwendt.de/tech/fancytree/doc/jsdoc/Fancytree_Widget.html")},_create:function(){this.tree=new F(this),this.$source=this.source||"json"===this.element.data("type")?this.element:this.element.find(">ul").first();for(var e,t,n=this.options,i=n.extensions,r=(this.tree,0);r<i.length;r++)t=i[r],(e=C.ui.fancytree._extensions[t])||C.error("Could not apply extension '"+t+"' (it is not registered, did you forget to include it?)"),this.tree.options[t]=function e(t){var n,i,r,o,s=t||{},a=1,l=arguments.length;if("object"==typeof s||N(s)||(s={}),a===l)throw Error("need at least two args");for(;a<l;a++)if(null!=(n=arguments[a]))for(i in n)w(n,i)&&(o=s[i],s!==(r=n[i])&&(r&&C.isPlainObject(r)?(o=o&&C.isPlainObject(o)?o:{},s[i]=e(o,r)):void 0!==r&&(s[i]=r)));return s}({},e.options,this.tree.options[t]),k(void 0===this.tree.ext[t],"Extension name must not exist as Fancytree.ext attribute: '"+t+"'"),this.tree.ext[t]={},function(e,t,n){for(var i in t)"function"==typeof t[i]?"function"==typeof e[i]?e[i]=E(i,e,0,t,n):"_"===i.charAt(0)?e.ext[n][i]=E(i,e,0,t,n):C.error("Could not override tree."+i+". Use prefix '_' to create tree."+n+"._"+i):"options"!==i&&(e.ext[n][i]=t[i])}(this.tree,e,t),0;void 0!==n.icons&&(!0===n.icon?(this.tree.warn("'icons' tree option is deprecated since v2.14.0: use 'icon' instead"),n.icon=n.icons):C.error("'icons' tree option is deprecated since v2.14.0: use 'icon' only instead")),void 0!==n.iconClass&&(n.icon?C.error("'iconClass' tree option is deprecated since v2.14.0: use 'icon' only instead"):(this.tree.warn("'iconClass' tree option is deprecated since v2.14.0: use 'icon' instead"),n.icon=n.iconClass)),void 0!==n.tabbable&&(n.tabindex=n.tabbable?"0":"-1",this.tree.warn("'tabbable' tree option is deprecated since v2.17.0: use 'tabindex='"+n.tabindex+"' instead")),this.tree._callHook("treeCreate",this.tree)},_init:function(){this.tree._callHook("treeInit",this.tree),this._bind()},_setOption:function(e,t){return this.tree._callHook("treeSetOption",this.tree,e,t)},_destroy:function(){this._unbind(),this.tree._callHook("treeDestroy",this.tree)},_unbind:function(){var e=this.tree._ns;this.element.off(e),this.tree.$container.off(e),C(document).off(e)},_bind:function(){var s=this,a=this.options,o=this.tree,e=o._ns;this._unbind(),o.$container.on("focusin"+e+" focusout"+e,function(e){var t=h.getNode(e),n="focusin"===e.type;if(!n&&t&&C(e.target).is("a"))t.debug("Ignored focusout on embedded <a> element.");else{if(n){if(o._getExpiringValue("focusin"))return void o.debug("Ignored double focusin.");o._setExpiringValue("focusin",!0,50),t||(t=o._getExpiringValue("mouseDownNode"))&&o.debug("Reconstruct mouse target for focusin from recent event.")}t?o._callHook("nodeSetFocus",o._makeHookContext(t,e),n):o.tbody&&C(e.target).parents("table.fancytree-container > thead").length?o.debug("Ignore focus event outside table body.",e):o._callHook("treeSetFocus",o,n)}}).on("selectstart"+e,"span.fancytree-title",function(e){e.preventDefault()}).on("keydown"+e,function(e){if(a.disabled||!1===a.keyboard)return!0;var t,n=o.focusNode,i=o._makeHookContext(n||o,e),r=o.phase;try{return o.phase="userEvent","preventNav"===(t=n?o._triggerNodeEvent("keydown",n,e):o._triggerTreeEvent("keydown",e))?t=!0:!1!==t&&(t=o._callHook("nodeKeydown",i)),t}finally{o.phase=r}}).on("mousedown"+e,function(e){e=h.getEventTarget(e);o._lastMousedownNode=e?e.node:null,o._setExpiringValue("mouseDownNode",o._lastMousedownNode)}).on("click"+e+" dblclick"+e,function(e){if(a.disabled)return!0;var t,n=h.getEventTarget(e),i=n.node,r=s.tree,o=r.phase;if(!i)return!0;t=r._makeHookContext(i,e);try{switch(r.phase="userEvent",e.type){case"click":return t.targetType=n.type,i.isPagingNode()?!0===r._triggerNodeEvent("clickPaging",t,e):!1!==r._triggerNodeEvent("click",t,e)&&r._callHook("nodeClick",t);case"dblclick":return t.targetType=n.type,!1!==r._triggerNodeEvent("dblclick",t,e)&&r._callHook("nodeDblclick",t)}}finally{r.phase=o}})},getActiveNode:function(){return this._deprecationWarning("getActiveNode"),this.tree.activeNode},getNodeByKey:function(e){return this._deprecationWarning("getNodeByKey"),this.tree.getNodeByKey(e)},getRootNode:function(){return this._deprecationWarning("getRootNode"),this.tree.rootNode},getTree:function(){return this._deprecationWarning("getTree"),this.tree}}),h=C.ui.fancytree,C.extend(C.ui.fancytree,{version:"2.38.3",buildType: "production",debugLevel: 3,_nextId:1,_nextNodeKey:1,_extensions:{},_FancytreeClass:F,_FancytreeNodeClass:j,jquerySupports:{positionMyOfs:function(e){for(var t,n,i=C.map(S(e).split("."),function(e){return parseInt(e,10)}),r=C.map(Array.prototype.slice.call(arguments,1),function(e){return parseInt(e,10)}),o=0;o<r.length;o++)if((t=i[o]||0)!==(n=r[o]||0))return n<t;return!0}(C.ui.version,1,9)},assert:k,createTree:function(e,t){t=C(e).fancytree(t);return h.getTree(t)},debounce:function(t,n,i,r){var o;return 3===arguments.length&&"boolean"!=typeof i&&(r=i,i=!1),function(){var e=arguments;r=r||this,i&&!o&&n.apply(r,e),clearTimeout(o),o=setTimeout(function(){i||n.apply(r,e),o=null},t)}},debug:function(e){4<=C.ui.fancytree.debugLevel&&d("log",arguments)},error:function(e){1<=C.ui.fancytree.debugLevel&&d("error",arguments)},escapeHtml:function(e){return(""+e).replace(t,function(e){return i[e]})},fixPositionOptions:function(e){var t,n,i,r;return(e.offset||0<=(""+e.my+e.at).indexOf("%"))&&C.error("expected new position syntax (but '%' is not supported)"),C.ui.fancytree.jquerySupports.positionMyOfs||(t=/(\w+)([+-]?\d+)?\s+(\w+)([+-]?\d+)?/.exec(e.my),n=/(\w+)([+-]?\d+)?\s+(\w+)([+-]?\d+)?/.exec(e.at),i=(t[2]?+t[2]:0)+(n[2]?+n[2]:0),r=(t[4]?+t[4]:0)+(n[4]?+n[4]:0),e=C.extend({},e,{my:t[1]+" "+t[3],at:n[1]+" "+n[3]}),(i||r)&&(e.offset=i+" "+r)),e},getEventTarget:function(e){var t=e&&e.target?e.target.className:"",n={node:this.getNode(e.target),type:void 0};return/\bfancytree-title\b/.test(t)?n.type="title":/\bfancytree-expander\b/.test(t)?n.type=!1===n.node.hasChildren()?"prefix":"expander":/\bfancytree-checkbox\b/.test(t)?n.type="checkbox":/\bfancytree(-custom)?-icon\b/.test(t)?n.type="icon":/\bfancytree-node\b/.test(t)?n.type="title":e&&e.target&&((e=C(e.target)).is("ul[role=group]")?((n.node&&n.node.tree||h).debug("Ignoring click on outer UL."),n.node=null):e.closest(".fancytree-title").length?n.type="title":e.closest(".fancytree-checkbox").length?n.type="checkbox":e.closest(".fancytree-expander").length&&(n.type="expander")),n},getEventTargetType:function(e){return this.getEventTarget(e).type},getNode:function(e){if(e instanceof j)return e;for(e instanceof C?e=e[0]:void 0!==e.originalEvent&&(e=e.target);e;){if(e.ftnode)return e.ftnode;e=e.parentNode}return null},getTree:function(e){var t=e;return e instanceof F?e:("number"==typeof(e=void 0===e?0:e)?e=C(".fancytree-container").eq(e):"string"==typeof e?(e=C("#ft-id-"+t).eq(0)).length||(e=C(t).eq(0)):e instanceof Element||e instanceof HTMLDocument?e=C(e):e instanceof C?e=e.eq(0):void 0!==e.originalEvent&&(e=C(e.target)),(e=(e=e.closest(":ui-fancytree")).data("ui-fancytree")||e.data("fancytree"))?e.tree:null)},evalOption:function(e,t,n,i,r){var o,s=t.tree,i=i[e],n=n[e];return N(i)?(o={node:t,tree:s,widget:s.widget,options:s.widget.options,typeInfo:s.types[t.type]||{}},null==(o=i.call(s,{type:e},o))&&(o=n)):o=null==n?i:n,o=null==o?r:o},setSpanIcon:function(e,t,n){var i=C(e);"string"==typeof n?i.attr("class",t+" "+n):(n.text?i.text(""+n.text):n.html&&(e.innerHTML=n.html),i.attr("class",t+" "+(n.addClass||"")))},eventToString:function(e){var t=e.which,n=e.type,i=[];return e.altKey&&i.push("alt"),e.ctrlKey&&i.push("ctrl"),e.metaKey&&i.push("meta"),e.shiftKey&&i.push("shift"),"click"===n||"dblclick"===n?i.push(o[e.button]+n):"wheel"===n?i.push(n):r[t]||i.push(u[t]||String.fromCharCode(t).toLowerCase()),i.join("+")},info:function(e){3<=C.ui.fancytree.debugLevel&&d("info",arguments)},keyEventToString:function(e){return this.warn("keyEventToString() is deprecated: use eventToString()"),this.eventToString(e)},overrideMethod:function(e,t,n,i){var r,o=e[t]||C.noop;e[t]=function(){var e=i||this;try{return r=e._super,e._super=o,n.apply(e,arguments)}finally{e._super=r}}},parseHtml:function(s){var a,l,d,c,u,h,f,p,e=s.find(">li"),g=[];return e.each(function(){var e,t,n=C(this),i=n.find(">span",this).first(),r=i.length?null:n.find(">a").first(),o={tooltip:null,data:{}};for(i.length?o.title=i.html():r&&r.length?(o.title=r.html(),o.data.href=r.attr("href"),o.data.target=r.attr("target"),o.tooltip=r.attr("title")):(o.title=n.html(),0<=(u=o.title.search(/<ul/i))&&(o.title=o.title.substring(0,u))),o.title=S(o.title),c=0,h=y.length;c<h;c++)o[y[c]]=void 0;for(a=this.className.split(" "),d=[],c=0,h=a.length;c<h;c++)l=a[c],v[l]?o[l]=!0:d.push(l);if(o.extraClasses=d.join(" "),(f=n.attr("title"))&&(o.tooltip=f),(f=n.attr("id"))&&(o.key=f),n.attr("hideCheckbox")&&(o.checkbox=!1),(e=P(n))&&!C.isEmptyObject(e)){for(t in x)w(e,t)&&(e[x[t]]=e[t],delete e[t]);for(c=0,h=b.length;c<h;c++)f=b[c],null!=(p=e[f])&&(delete e[f],o[f]=p);C.extend(o.data,e)}(s=n.find(">ul").first()).length?o.children=C.ui.fancytree.parseHtml(s):o.children=o.lazy?void 0:null,g.push(o)}),g},registerExtension:function(e){k(null!=e.name,"extensions must have a `name` property."),k(null!=e.version,"extensions must have a `version` property."),C.ui.fancytree._extensions[e.name]=e},trim:S,unescapeHtml:function(e){var t=document.createElement("div");return t.innerHTML=e,0===t.childNodes.length?"":t.childNodes[0].nodeValue},warn:function(e){2<=C.ui.fancytree.debugLevel&&d("warn",arguments)}}),C.ui.fancytree}function k(e,t){e||(C.ui.fancytree.error(t="Fancytree assertion failed"+(t=t?": "+t:"")),C.error(t))}function w(e,t){return Object.prototype.hasOwnProperty.call(e,t)}function N(e){return"function"==typeof e}function S(e){return null==e?"":e.trim()}function d(t,n){var i,r,t=window.console?window.console[t]:null;if(t)try{t.apply(window.console,n)}catch(e){for(r="",i=0;i<n.length;i++)r+=n[i];t(r)}}function E(e,i,t,n,r){var o,s,a;function l(){return o.apply(i,arguments)}function d(e){return o.apply(i,e)}return o=i[e],s=n[e],a=i.ext[r],function(){var e=i._local,t=i._super,n=i._superApply;try{return i._local=a,i._super=l,i._superApply=d,s.apply(i,arguments)}finally{i._local=e,i._super=t,i._superApply=n}}}function T(e,t){return(void 0===e?C.Deferred(function(){this.resolve()}):C.Deferred(function(){this.resolveWith(e,t)})).promise()}function A(e,t){return(void 0===e?C.Deferred(function(){this.reject()}):C.Deferred(function(){this.rejectWith(e,t)})).promise()}function O(e,t){return function(){e.resolveWith(t)}}function P(e){var t=C.extend({},e.data()),e=t.json;return delete t.fancytree,delete t.uiFancytree,e&&(delete t.json,t=C.extend(t,e)),t}function D(e){return(""+e).replace(n,function(e){return i[e]})}function L(t){return t=t.toLowerCase(),function(e){return 0<=e.title.toLowerCase().indexOf(t)}}function j(e,t){var n,i,r;for(this.parent=e,this.tree=e.tree,this.ul=null,this.li=null,this.statusNodeType=null,this._isLoading=!1,this._error=null,this.data={},n=0,i=b.length;n<i;n++)this[r=b[n]]=t[r];for(r in null==this.unselectableIgnore&&null==this.unselectableStatus||(this.unselectable=!0),t.hideCheckbox&&C.error("'hideCheckbox' node option was removed in v2.23.0: use 'checkbox: false'"),t.data&&C.extend(this.data,t.data),t)s[r]||!this.tree.options.copyFunctionsToData&&N(t[r])||a[r]||(this.data[r]=t[r]);null==this.key?this.tree.options.defaultKey?(this.key=""+this.tree.options.defaultKey(this),k(this.key,"defaultKey() must return a unique key")):this.key="_"+h._nextNodeKey++:this.key=""+this.key,t.active&&(k(null===this.tree.activeNode,"only one active node allowed"),this.tree.activeNode=this),t.selected&&(this.tree.lastSelectedNode=this),(e=t.children)?e.length?this._setChildren(e):this.children=this.lazy?[]:null:this.children=null,this.tree._callHook("treeRegisterNode",this.tree,!0,this)}function F(e){this.widget=e,this.$div=e.element,this.options=e.options,this.options&&(void 0!==this.options.lazyload&&C.error("The 'lazyload' event is deprecated since 2014-02-25. Use 'lazyLoad' (with uppercase L) instead."),void 0!==this.options.loaderror&&C.error("The 'loaderror' event was renamed since 2014-07-03. Use 'loadError' (with uppercase E) instead."),void 0!==this.options.fx&&C.error("The 'fx' option was replaced by 'toggleEffect' since 2014-11-30."),void 0!==this.options.removeNode&&C.error("The 'removeNode' event was replaced by 'modifyChild' since 2.20 (2016-09-10).")),this.ext={},this.types={},this.columns={},this.data=P(this.$div),this._id=""+(this.options.treeId||C.ui.fancytree._nextId++),this._ns=".fancytree-"+this._id,this.activeNode=null,this.focusNode=null,this._hasFocus=null,this._tempCache={},this._lastMousedownNode=null,this._enableUpdate=!0,this.lastSelectedNode=null,this.systemFocusElement=null,this.lastQuicksearchTerm="",this.lastQuicksearchTime=0,this.viewport=null,this.statusClassPropName="span",this.ariaPropName="li",this.nodeContainerAttrName="li",this.$div.find(">ul.fancytree-container").remove(),this.rootNode=new j({tree:this},{title:"root",key:"root_"+this._id,children:null,expanded:!0}),this.rootNode.parent=null,e=C("<ul>",{id:"ft-id-"+this._id,class:"ui-fancytree fancytree-container fancytree-plain"}).appendTo(this.$div),this.$container=e,this.rootNode.ul=e[0],null==this.options.debugLevel&&(this.options.debugLevel=h.debugLevel)}C.ui.fancytree.warn("Fancytree: ignored duplicate include")},"function"==typeof define&&define.amd?define(["jquery","./jquery.fancytree.ui-deps"],t):"object"==typeof module&&module.exports?(require("./jquery.fancytree.ui-deps"),module.exports=t(require("jquery"))):t(jQuery),t=function(o){"use strict";return o.ui.fancytree._FancytreeClass.prototype.countSelected=function(e){this.options;return this.getSelectedNodes(e).length},o.ui.fancytree._FancytreeNodeClass.prototype.updateCounters=function(){var e=this,t=o("span.fancytree-childcounter",e.span),n=e.tree.options.childcounter,i=e.countChildren(n.deep);!(e.data.childCounter=i)&&n.hideZeros||e.isExpanded()&&n.hideExpanded?t.remove():(t=!t.length?o("<span class='fancytree-childcounter'/>").appendTo(o("span.fancytree-icon,span.fancytree-custom-icon",e.span)):t).text(i),!n.deep||e.isTopLevel()||e.isRootNode()||e.parent.updateCounters()},o.ui.fancytree.prototype.widgetMethod1=function(e){this.tree;return e},o.ui.fancytree.registerExtension({name:"childcounter",version:"2.38.3",options:{deep:!0,hideZeros:!0,hideExpanded:!1},foo:42,_appendCounter:function(e){},treeInit:function(e){e.options,e.options.childcounter;this._superApply(arguments),this.$container.addClass("fancytree-ext-childcounter")},treeDestroy:function(e){this._superApply(arguments)},nodeRenderTitle:function(e,t){var n=e.node,i=e.options.childcounter,r=null==n.data.childCounter?n.countChildren(i.deep):+n.data.childCounter;this._super(e,t),!r&&i.hideZeros||n.isExpanded()&&i.hideExpanded||o("span.fancytree-icon,span.fancytree-custom-icon",n.span).append(o("<span class='fancytree-childcounter'/>").text(r))},nodeSetExpanded:function(e,t,n){var i=e.tree;e.node;return this._superApply(arguments).always(function(){i.nodeRenderTitle(e)})}}),o.ui.fancytree},"function"==typeof define&&define.amd?define(["jquery","./jquery.fancytree"],t):"object"==typeof module&&module.exports?(require("./jquery.fancytree"),module.exports=t(require("jquery"))):t(jQuery),t=function(c){"use strict";var u=c.ui.fancytree.assert;function n(e,t,n){for(var i,r,o=3&e.length,s=e.length-o,a=n,l=3432918353,d=461845907,c=0;c<s;)r=255&e.charCodeAt(c)|(255&e.charCodeAt(++c))<<8|(255&e.charCodeAt(++c))<<16|(255&e.charCodeAt(++c))<<24,++c,a=27492+(65535&(i=5*(65535&(a=(a^=r=(65535&(r=(r=(65535&r)*l+(((r>>>16)*l&65535)<<16)&4294967295)<<15|r>>>17))*d+(((r>>>16)*d&65535)<<16)&4294967295)<<13|a>>>19))+((5*(a>>>16)&65535)<<16)&4294967295))+((58964+(i>>>16)&65535)<<16);switch(r=0,o){case 3:r^=(255&e.charCodeAt(c+2))<<16;case 2:r^=(255&e.charCodeAt(c+1))<<8;case 1:a^=r=(65535&(r=(r=(65535&(r^=255&e.charCodeAt(c)))*l+(((r>>>16)*l&65535)<<16)&4294967295)<<15|r>>>17))*d+(((r>>>16)*d&65535)<<16)&4294967295}return a^=e.length,a=2246822507*(65535&(a^=a>>>16))+((2246822507*(a>>>16)&65535)<<16)&4294967295,a=3266489909*(65535&(a^=a>>>13))+((3266489909*(a>>>16)&65535)<<16)&4294967295,a^=a>>>16,t?("0000000"+(a>>>0).toString(16)).substr(-8):a>>>0}return c.ui.fancytree._FancytreeNodeClass.prototype.getCloneList=function(e){var t,n=this.tree,i=n.refMap[this.refKey]||null,r=n.keyMap;return i&&(t=this.key,e?i=c.map(i,function(e){return r[e]}):(i=c.map(i,function(e){return e===t?null:r[e]})).length<1&&(i=null)),i},c.ui.fancytree._FancytreeNodeClass.prototype.isClone=function(){var e=this.refKey||null,e=e&&this.tree.refMap[e]||null;return!!(e&&1<e.length)},c.ui.fancytree._FancytreeNodeClass.prototype.reRegister=function(t,e){e=null==e?null:""+e;var n=this.tree,i=this.key,r=this.refKey,o=n.keyMap,s=n.refMap,a=s[r]||null,n=!1;return null!=(t=null==t?null:""+t)&&t!==this.key&&(o[t]&&c.error("[ext-clones] reRegister("+t+"): already exists: "+this),delete o[i],o[t]=this,a&&(s[r]=c.map(a,function(e){return e===i?t:e})),this.key=t,n=!0),null!=e&&e!==this.refKey&&(a&&(1===a.length?delete s[r]:s[r]=c.map(a,function(e){return e===i?null:e})),s[e]?s[e].append(t):s[e]=[this.key],this.refKey=e,n=!0),n},c.ui.fancytree._FancytreeNodeClass.prototype.setRefKey=function(e){return this.reRegister(null,e)},c.ui.fancytree._FancytreeClass.prototype.getNodesByRef=function(e,t){var n=this.keyMap,e=this.refMap[e]||null;return e=e&&(e=t?c.map(e,function(e){e=n[e];return e.isDescendantOf(t)?e:null}):c.map(e,function(e){return n[e]})).length<1?null:e},c.ui.fancytree._FancytreeClass.prototype.changeRefKey=function(e,t){var n,i=this.keyMap,r=this.refMap[e]||null;if(r){for(n=0;n<r.length;n++)i[r[n]].refKey=t;delete this.refMap[e],this.refMap[t]=r}},c.ui.fancytree.registerExtension({name:"clones",version:"2.38.3",options:{highlightActiveClones:!0,highlightClones:!1},treeCreate:function(e){this._superApply(arguments),e.tree.refMap={},e.tree.keyMap={}},treeInit:function(e){this.$container.addClass("fancytree-ext-clones"),u(null==e.options.defaultKey),e.options.defaultKey=function(e){return t=e,"id_"+(t=n(e=(e=c.map(e.getParentList(!1,!0),function(e){return e.refKey||e.key})).join("/"),!0))+n(t+e,!0);var t},this._superApply(arguments)},treeClear:function(e){return e.tree.refMap={},e.tree.keyMap={},this._superApply(arguments)},treeRegisterNode:function(e,t,n){var i,r,o=e.tree,s=o.keyMap,a=o.refMap,l=n.key,d=n&&null!=n.refKey?""+n.refKey:null;return n.isStatusNode()||(t?(null!=s[n.key]&&(r=s[n.key],r="clones.treeRegisterNode: duplicate key '"+n.key+"': /"+n.getPath(!0)+" => "+r.getPath(!0),o.error(r),c.error(r)),s[l]=n,d&&((i=a[d])?(i.push(l),2===i.length&&e.options.clones.highlightClones&&s[i[0]].renderStatus()):a[d]=[l])):(null==s[l]&&c.error("clones.treeRegisterNode: node.key not registered: "+n.key),delete s[l],d&&(i=a[d])&&((r=i.length)<=1?(u(1===r),u(i[0]===l),delete a[d]):(function(e,t){for(var n=e.length-1;0<=n;n--)if(e[n]===t)return e.splice(n,1)}(i,l),2===r&&e.options.clones.highlightClones&&s[i[0]].renderStatus())))),this._super(e,t,n)},nodeRenderStatus:function(e){var t,n=e.node,i=this._super(e);return e.options.clones.highlightClones&&(t=c(n[e.tree.statusClassPropName])).length&&n.isClone()&&t.addClass("fancytree-clone"),i},nodeSetActive:function(e,n,t){var i=e.tree.statusClassPropName,r=e.node,o=this._superApply(arguments);return e.options.clones.highlightActiveClones&&r.isClone()&&c.each(r.getCloneList(!0),function(e,t){c(t[i]).toggleClass("fancytree-active-clone",!1!==n)}),o}}),c.ui.fancytree},"function"==typeof define&&define.amd?define(["jquery","./jquery.fancytree"],t):"object"==typeof module&&module.exports?(require("./jquery.fancytree"),module.exports=t(require("jquery"))):t(jQuery),t=function(f){"use strict";var a,l,p=f.ui.fancytree,o=/Mac/.test(navigator.platform),d="fancytree-drag-source",c="fancytree-drag-remove",g="fancytree-drop-accept",y="fancytree-drop-after",v="fancytree-drop-before",m="fancytree-drop-over",b="fancytree-drop-reject",x="fancytree-drop-target",u="application/x-fancytree-node",C=null,h=null,_=null,k=null,w=null,s=null,N=null,S=null,E=null,T=null;function A(){_=h=s=S=N=T=w=null,k&&k.removeClass(d+" "+c),k=null,C&&C.hide(),l&&(l.remove(),l=null)}function O(e){return 0===e?"":0<e?"+"+e:""+e}function P(e,t){var n,i=t.tree,r=t.dataTransfer;"dragstart"===e.type?(t.effectAllowed=i.options.dnd5.effectAllowed,t.dropEffect=i.options.dnd5.dropEffectDefault):(t.effectAllowed=S,t.dropEffect=N),t.dropEffectSuggested=(n=e,i=(e=i).options.dnd5.dropEffectDefault,o?n.metaKey&&n.altKey||n.ctrlKey?i="link":n.metaKey?i="move":n.altKey&&(i="copy"):n.ctrlKey?i="copy":n.shiftKey?i="move":n.altKey&&(i="link"),i!==s&&e.info("evalEffectModifiers: "+n.type+" - evalEffectModifiers(): "+s+" -> "+i),s=i),t.isMove="move"===t.dropEffect,t.files=r.files||[]}function D(e,t,n){var i=t.tree,r=t.dataTransfer;return"dragstart"!==e.type&&S!==t.effectAllowed&&i.warn("effectAllowed should only be changed in dragstart event: "+e.type+": data.effectAllowed changed from "+S+" -> "+t.effectAllowed),!1===n&&(i.info("applyDropEffectCallback: allowDrop === false"),t.effectAllowed="none",t.dropEffect="none"),t.isMove="move"===t.dropEffect,"dragstart"===e.type&&(S=t.effectAllowed,N=t.dropEffect),r.effectAllowed=S,r.dropEffect=N}function L(e,t){if(t.options.dnd5.scroll&&(h=t.tree,s=e,r=h.options.dnd5,o=h.$scrollParent[0],l=r.scrollSensitivity,u=r.scrollSpeed,i=0,o!==document&&"HTML"!==o.tagName?(r=h.$scrollParent.offset(),d=o.scrollTop,r.top+o.offsetHeight-s.pageY<l?0<o.scrollHeight-h.$scrollParent.innerHeight()-d&&(o.scrollTop=i=d+u):0<d&&s.pageY-r.top<l&&(o.scrollTop=i=d-u)):0<(d=f(document).scrollTop())&&s.pageY-d<l?(i=d-u,f(document).scrollTop(i)):f(window).height()-(s.pageY-d)<l&&(i=d+u,f(document).scrollTop(i)),i&&h.debug("autoScroll: "+i+"px")),!t.node)return t.tree.warn("Ignored dragover for non-node"),E;var n,i,r=null,o=t.tree,s=o.options,a=s.dnd5,l=t.node,d=t.otherNode,c="center",u=f(l.span),h=u.find("span.fancytree-title");if(!1===w)return o.debug("Ignored dragover, since dragenter returned false."),!1;if("string"==typeof w&&f.error("assert failed: dragenter returned string"),i=u.offset(),u=(e.pageY-i.top)/u.height(),void 0===e.pageY&&o.warn("event.pageY is undefined: see issue #1013."),w.after&&.75<u||!w.over&&w.after&&.5<u?r="after":w.before&&u<=.25||!w.over&&w.before&&u<=.5?r="before":w.over&&(r="over"),a.preventVoidMoves&&"move"===t.dropEffect&&(l===d?(l.debug("Drop over source node prevented."),r=null):"before"===r&&d&&l===d.getNextSibling()?(l.debug("Drop after source node prevented."),r=null):"after"===r&&d&&l===d.getPrevSibling()?(l.debug("Drop before source node prevented."),r=null):"over"===r&&d&&d.parent===l&&d.isLastSibling()&&(l.debug("Drop last child over own parent prevented."),r=null)),(t.hitMode=r)&&a.dragOver&&(P(e,t),a.dragOver(l,t),D(e,t,!!r),r=t.hitMode),"after"===(E=r)||"before"===r||"over"===r){switch(n=a.dropMarkerOffsetX||0,r){case"before":c="top",n+=a.dropMarkerInsertOffsetX||0;break;case"after":c="bottom",n+=a.dropMarkerInsertOffsetX||0}h={my:"left"+O(n)+" center",at:"left "+c,of:h},s.rtl&&(h.my="right"+O(-n)+" center",h.at="right "+c),C.toggleClass(y,"after"===r).toggleClass(m,"over"===r).toggleClass(v,"before"===r).show().position(p.fixPositionOptions(h))}else C.hide();return f(l.span).toggleClass(x,"after"===r||"before"===r||"over"===r).toggleClass(y,"after"===r).toggleClass(v,"before"===r).toggleClass(g,"over"===r).toggleClass(b,!1===r),r}function j(e){var t,n=this,i=n.options.dnd5,r=null,o=p.getNode(e),s=e.dataTransfer||e.originalEvent.dataTransfer,a={tree:n,node:o,options:n.options,originalEvent:e.originalEvent,widget:n.widget,hitMode:w,dataTransfer:s,otherNode:h||null,otherNodeList:_||null,otherNodeData:null,useDefaultImage:!0,dropEffect:void 0,dropEffectSuggested:void 0,effectAllowed:void 0,files:null,isCancelled:void 0,isMove:void 0};switch(e.type){case"dragenter":if(T=null,!o){n.debug("Ignore non-node "+e.type+": "+e.target.tagName+"."+e.target.className),w=!1;break}if(f(o.span).addClass(m).removeClass(g+" "+b),t=0<=f.inArray(u,s.types),i.preventNonNodes&&!t){o.debug("Reject dropping a non-node."),w=!1;break}if(i.preventForeignNodes&&(!h||h.tree!==o.tree)){o.debug("Reject dropping a foreign node."),w=!1;break}if(i.preventSameParent&&a.otherNode&&a.otherNode.tree===o.tree&&o.parent===a.otherNode.parent){o.debug("Reject dropping as sibling (same parent)."),w=!1;break}if(i.preventRecursion&&a.otherNode&&a.otherNode.tree===o.tree&&o.isDescendantOf(a.otherNode)){o.debug("Reject dropping below own ancestor."),w=!1;break}if(i.preventLazyParents&&!o.isLoaded()){o.warn("Drop over unloaded target node prevented."),w=!1;break}C.show(),P(e,a),t=i.dragEnter(o,a),t=!!(t=t)&&(t=f.isPlainObject(t)?{over:!!t.over,before:!!t.before,after:!!t.after}:Array.isArray(t)?{over:0<=f.inArray("over",t),before:0<=f.inArray("before",t),after:0<=f.inArray("after",t)}:{over:!0===t||"over"===t,before:!0===t||"before"===t,after:!0===t||"after"===t},0!==Object.keys(t).length&&t),D(e,a,r=(w=t)&&(t.over||t.before||t.after));break;case"dragover":if(!o){n.debug("Ignore non-node "+e.type+": "+e.target.tagName+"."+e.target.className);break}P(e,a),r=!!(E=L(e,a)),("over"===E||!1===E)&&!o.expanded&&!1!==o.hasChildren()?T?!(i.autoExpandMS&&Date.now()-T>i.autoExpandMS)||o.isLoading()||i.dragExpand&&!1===i.dragExpand(o,a)||o.setExpanded():T=Date.now():T=null;break;case"dragleave":if(!o){n.debug("Ignore non-node "+e.type+": "+e.target.tagName+"."+e.target.className);break}if(!f(o.span).hasClass(m)){o.debug("Ignore dragleave (multi).");break}f(o.span).removeClass(m+" "+g+" "+b),o.scheduleAction("cancel"),i.dragLeave(o,a),C.hide();break;case"drop":if(0<=f.inArray(u,s.types)&&(d=s.getData(u),n.info(e.type+": getData('application/x-fancytree-node'): '"+d+"'")),d||(d=s.getData("text"),n.info(e.type+": getData('text'): '"+d+"'")),d)try{void 0!==(l=JSON.parse(d)).title&&(a.otherNodeData=l)}catch(e){}n.debug(e.type+": nodeData: '"+d+"', otherNodeData: ",a.otherNodeData),f(o.span).removeClass(m+" "+g+" "+b),a.hitMode=E,P(e,a),a.isCancelled=!E;var l=h&&h.span,d=h&&h.tree;i.dragDrop(o,a),e.preventDefault(),l&&!document.body.contains(l)&&(d===n?(n.debug("Drop handler removed source element: generating dragEnd."),i.dragEnd(h,a)):n.warn("Drop handler removed source element: dragend event may be lost.")),A()}if(r)return e.preventDefault(),!1}return f.ui.fancytree.getDragNodeList=function(){return _||[]},f.ui.fancytree.getDragNode=function(){return h},f.ui.fancytree.registerExtension({name:"dnd5",version:"2.38.3",options:{autoExpandMS:1500,dropMarkerInsertOffsetX:-16,dropMarkerOffsetX:-24,dropMarkerParent:"body",multiSource:!1,effectAllowed:"all",dropEffectDefault:"move",preventForeignNodes:!1,preventLazyParents:!0,preventNonNodes:!1,preventRecursion:!0,preventSameParent:!1,preventVoidMoves:!0,scroll:!0,scrollSensitivity:20,scrollSpeed:5,setTextTypeJson:!1,sourceCopyHook:null,dragStart:null,dragDrag:f.noop,dragEnd:f.noop,dragEnter:null,dragOver:f.noop,dragExpand:f.noop,dragDrop:f.noop,dragLeave:f.noop},treeInit:function(e){var t=e.tree,n=e.options,i=n.glyph||null,r=n.dnd5;0<=f.inArray("dnd",n.extensions)&&f.error("Extensions 'dnd' and 'dnd5' are mutually exclusive."),r.dragStop&&f.error("dragStop is not used by ext-dnd5. Use dragEnd instead."),null!=r.preventRecursiveMoves&&f.error("preventRecursiveMoves was renamed to preventRecursion."),r.dragStart&&p.overrideMethod(e.options,"createNode",function(e,t){this._super.apply(this,arguments),t.node.span?t.node.span.draggable=!0:t.node.warn("Cannot add `draggable`: no span tag")}),this._superApply(arguments),this.$container.addClass("fancytree-ext-dnd5"),e=f("<span>").appendTo(this.$container),this.$scrollParent=e.scrollParent(),e.remove(),(C=f("#fancytree-drop-marker")).length||(C=f("<div id='fancytree-drop-marker'></div>").hide().css({"z-index":1e3,"pointer-events":"none"}).prependTo(r.dropMarkerParent),i&&p.setSpanIcon(C[0],i.map._addClass,i.map.dropMarker)),C.toggleClass("fancytree-rtl",!!n.rtl),r.dragStart&&t.$container.on("dragstart drag dragend",function(e){var t=this,n=t.options.dnd5,i=p.getNode(e),r=e.dataTransfer||e.originalEvent.dataTransfer,o={tree:t,node:i,options:t.options,originalEvent:e.originalEvent,widget:t.widget,dataTransfer:r,useDefaultImage:!0,dropEffect:void 0,dropEffectSuggested:void 0,effectAllowed:void 0,files:void 0,isCancelled:void 0,isMove:void 0};switch(e.type){case"dragstart":if(!i)return t.info("Ignored dragstart on a non-node."),!1;h=i,_=!1===n.multiSource?[i]:!0===n.multiSource?i.isSelected()?t.getSelectedNodes():[i]:n.multiSource(i,o),(k=f(f.map(_,function(e){return e.span}))).addClass(d);var s=i.toDict(!0,n.sourceCopyHook);s.treeId=i.tree._id,s=JSON.stringify(s);try{r.setData(u,s),r.setData("text/html",f(i.span).html()),r.setData("text/plain",i.title)}catch(e){t.warn("Could not set data (IE only accepts 'text') - "+e)}return(n.setTextTypeJson?r.setData("text",s):r.setData("text",i.title),P(e,o),!1===n.dragStart(i,o))?(A(),!1):(D(e,o),l=null,o.useDefaultImage&&(a=f(i.span).find(".fancytree-title"),_&&1<_.length&&(l=f("<span class='fancytree-childcounter'/>").text("+"+(_.length-1)).appendTo(a)),r.setDragImage&&r.setDragImage(a[0],-10,-10)),!0);case"drag":P(e,o),n.dragDrag(i,o),D(e,o),k.toggleClass(c,o.isMove);break;case"dragend":P(e,o),A(),o.isCancelled=!E,n.dragEnd(i,o,!E)}}.bind(t)),r.dragEnter&&t.$container.on("dragenter dragover dragleave drop",j.bind(t))}}),f.ui.fancytree},"function"==typeof define&&define.amd?define(["jquery","./jquery.fancytree"],t):"object"==typeof module&&module.exports?(require("./jquery.fancytree"),module.exports=t(require("jquery"))):t(jQuery),t=function(d){"use strict";var t=/Mac/.test(navigator.platform),c=d.ui.fancytree.escapeHtml,u=d.ui.fancytree.trim,a=d.ui.fancytree.unescapeHtml;return d.ui.fancytree._FancytreeNodeClass.prototype.editStart=function(){var t,n=this,e=this.tree,i=e.ext.edit,r=e.options.edit,o=d(".fancytree-title",n.span),s={node:n,tree:e,options:e.options,isNew:d(n[e.statusClassPropName]).hasClass("fancytree-edit-new"),orgTitle:n.title,input:null,dirty:!1};if(!1===r.beforeEdit.call(n,{type:"beforeEdit"},s))return!1;d.ui.fancytree.assert(!i.currentNode,"recursive edit"),i.currentNode=this,i.eventData=s,e.widget._unbind(),i.lastDraggableAttrValue=n.span.draggable,i.lastDraggableAttrValue&&(n.span.draggable=!1),d(document).on("mousedown.fancytree-edit",function(e){d(e.target).hasClass("fancytree-edit-input")||n.editEnd(!0,e)}),t=d("<input />",{class:"fancytree-edit-input",type:"text",value:e.options.escapeTitles?s.orgTitle:a(s.orgTitle)}),i.eventData.input=t,null!=r.adjustWidthOfs&&t.width(o.width()+r.adjustWidthOfs),null!=r.inputCss&&t.css(r.inputCss),o.html(t),t.focus().change(function(e){t.addClass("fancytree-edit-dirty")}).on("keydown",function(e){switch(e.which){case d.ui.keyCode.ESCAPE:n.editEnd(!1,e);break;case d.ui.keyCode.ENTER:return n.editEnd(!0,e),!1}e.stopPropagation()}).blur(function(e){return n.editEnd(!0,e)}),r.edit.call(n,{type:"edit"},s)},d.ui.fancytree._FancytreeNodeClass.prototype.editEnd=function(e,t){var n,i=this,r=this.tree,o=r.ext.edit,s=o.eventData,a=r.options.edit,l=d(".fancytree-title",i.span).find("input.fancytree-edit-input");return a.trim&&l.val(u(l.val())),n=l.val(),s.dirty=n!==i.title,s.originalEvent=t,!1===e?s.save=!1:s.isNew?s.save=""!==n:s.save=s.dirty&&""!==n,!1!==a.beforeClose.call(i,{type:"beforeClose"},s)&&((!s.save||!1!==a.save.call(i,{type:"save"},s))&&(l.removeClass("fancytree-edit-dirty").off(),d(document).off(".fancytree-edit"),s.save?(i.setTitle(r.options.escapeTitles?n:c(n)),i.setFocus()):s.isNew?(i.remove(),i=s.node=null,o.relatedNode.setFocus()):(i.renderTitle(),i.setFocus()),o.eventData=null,o.currentNode=null,o.relatedNode=null,r.widget._bind(),i&&o.lastDraggableAttrValue&&(i.span.draggable=!0),r.$container.get(0).focus({preventScroll:!0}),s.input=null,a.close.call(i,{type:"close"},s),!0))},d.ui.fancytree._FancytreeNodeClass.prototype.editCreateNode=function(e,t){var n,i=this.tree,r=this;e=e||"child",null==t?t={title:""}:"string"==typeof t?t={title:t}:d.ui.fancytree.assert(d.isPlainObject(t)),"child"!==e||this.isExpanded()||!1===this.hasChildren()?((n=this.addNode(t,e)).match=!0,d(n[i.statusClassPropName]).removeClass("fancytree-hide").addClass("fancytree-match"),n.makeVisible().done(function(){d(n[i.statusClassPropName]).addClass("fancytree-edit-new"),r.tree.ext.edit.relatedNode=r,n.editStart()})):this.setExpanded().done(function(){r.editCreateNode(e,t)})},d.ui.fancytree._FancytreeClass.prototype.isEditing=function(){return this.ext.edit?this.ext.edit.currentNode:null},d.ui.fancytree._FancytreeNodeClass.prototype.isEditing=function(){return!!this.tree.ext.edit&&this.tree.ext.edit.currentNode===this},d.ui.fancytree.registerExtension({name:"edit",version:"2.38.3",options:{adjustWidthOfs:4,allowEmpty:!1,inputCss:{minWidth:"3em"},triggerStart:["f2","mac+enter","shift+click"],trim:!0,beforeClose:d.noop,beforeEdit:d.noop,close:d.noop,edit:d.noop,save:d.noop},currentNode:null,treeInit:function(e){var i=e.tree;this._superApply(arguments),this.$container.addClass("fancytree-ext-edit").on("fancytreebeforeupdateviewport",function(e,t){var n=i.isEditing();n&&(n.info("Cancel edit due to scroll event."),n.editEnd(!1,e))})},nodeClick:function(e){var t=d.ui.fancytree.eventToString(e.originalEvent),n=e.options.edit.triggerStart;return"shift+click"===t&&0<=d.inArray("shift+click",n)&&e.originalEvent.shiftKey||"click"===t&&0<=d.inArray("clickActive",n)&&e.node.isActive()&&!e.node.isEditing()&&d(e.originalEvent.target).hasClass("fancytree-title")?(e.node.editStart(),!1):this._superApply(arguments)},nodeDblclick:function(e){return 0<=d.inArray("dblclick",e.options.edit.triggerStart)?(e.node.editStart(),!1):this._superApply(arguments)},nodeKeydown:function(e){switch(e.originalEvent.which){case 113:if(0<=d.inArray("f2",e.options.edit.triggerStart))return e.node.editStart(),!1;break;case d.ui.keyCode.ENTER:if(0<=d.inArray("mac+enter",e.options.edit.triggerStart)&&t)return e.node.editStart(),!1}return this._superApply(arguments)}}),d.ui.fancytree},"function"==typeof define&&define.amd?define(["jquery","./jquery.fancytree"],t):"object"==typeof module&&module.exports?(require("./jquery.fancytree"),module.exports=t(require("jquery"))):t(jQuery),t=function(y){"use strict";var v="__not_found__",m=y.ui.fancytree.escapeHtml;function b(e){return(e+"").replace(/([.?*+^$[\]\\(){}|-])/g,"\\$1")}function x(e,t,n){for(var i=[],r=1;r<t.length;r++){var o=t[r].length+(1===r?0:1)+(i[i.length-1]||0);i.push(o)}var s=e.split("");return n?i.forEach(function(e){s[e]="\ufff7"+s[e]+"\ufff8"}):i.forEach(function(e){s[e]="<mark>"+s[e]+"</mark>"}),s.join("")}return y.ui.fancytree._FancytreeClass.prototype._applyFilterImpl=function(i,r,e){var t,o,s,a,l,d,c=0,n=this.options,u=n.escapeTitles,h=n.autoCollapse,f=y.extend({},n.filter,e),p="hide"===f.mode,g=!!f.leavesOnly&&!r;if("string"==typeof i){if(""===i)return this.warn("Fancytree passing an empty string as a filter is handled as clearFilter()."),void this.clearFilter();t=f.fuzzy?i.split("").map(b).reduce(function(e,t){return e+"([^"+t+"]*)"+t},""):b(i),o=new RegExp(t,"i"),s=new RegExp(b(i),"gi"),u&&(a=new RegExp(b("\ufff7"),"g"),l=new RegExp(b("\ufff8"),"g")),i=function(e){if(!e.title)return!1;var t,n=u?e.title:0<=(t=e.title).indexOf(">")?y("<div/>").html(t).text():t,t=n.match(o);return t&&f.highlight&&(u?(d=f.fuzzy?x(n,t,u):n.replace(s,function(e){return"\ufff7"+e+"\ufff8"}),e.titleWithHighlight=m(d).replace(a,"<mark>").replace(l,"</mark>")):f.fuzzy?e.titleWithHighlight=x(n,t):e.titleWithHighlight=n.replace(s,function(e){return"<mark>"+e+"</mark>"})),!!t}}return this.enableFilter=!0,this.lastFilterArgs=arguments,e=this.enableUpdate(!1),this.$div.addClass("fancytree-ext-filter"),p?this.$div.addClass("fancytree-ext-filter-hide"):this.$div.addClass("fancytree-ext-filter-dimm"),this.$div.toggleClass("fancytree-ext-filter-hide-expanders",!!f.hideExpanders),this.rootNode.subMatchCount=0,this.visit(function(e){delete e.match,delete e.titleWithHighlight,e.subMatchCount=0}),(t=this.getRootNode()._findDirectChild(v))&&t.remove(),n.autoCollapse=!1,this.visit(function(t){if(!g||null==t.children){var e=i(t),n=!1;if("skip"===e)return t.visit(function(e){e.match=!1},!0),"skip";e||!r&&"branch"!==e||!t.parent.match||(n=e=!0),e&&(c++,t.match=!0,t.visitParents(function(e){e!==t&&(e.subMatchCount+=1),!f.autoExpand||n||e.expanded||(e.setExpanded(!0,{noAnimation:!0,noEvents:!0,scrollIntoView:!1}),e._filterAutoExpanded=!0)},!0))}}),n.autoCollapse=h,0===c&&f.nodata&&p&&(!0===(t="function"==typeof(t=f.nodata)?t():t)?t={}:"string"==typeof t&&(t={title:t}),t=y.extend({statusNodeType:"nodata",key:v,title:this.options.strings.noData},t),this.getRootNode().addNode(t).match=!0),this._callHook("treeStructureChanged",this,"applyFilter"),this.enableUpdate(e),c},y.ui.fancytree._FancytreeClass.prototype.filterNodes=function(e,t){return"boolean"==typeof t&&(t={leavesOnly:t},this.warn("Fancytree.filterNodes() leavesOnly option is deprecated since 2.9.0 / 2015-04-19. Use opts.leavesOnly instead.")),this._applyFilterImpl(e,!1,t)},y.ui.fancytree._FancytreeClass.prototype.filterBranches=function(e,t){return this._applyFilterImpl(e,!0,t)},y.ui.fancytree._FancytreeClass.prototype.updateFilter=function(){this.enableFilter&&this.lastFilterArgs&&this.options.filter.autoApply?this._applyFilterImpl.apply(this,this.lastFilterArgs):this.warn("updateFilter(): no filter active.")},y.ui.fancytree._FancytreeClass.prototype.clearFilter=function(){var t,e=this.getRootNode()._findDirectChild(v),n=this.options.escapeTitles,i=this.options.enhanceTitle,r=this.enableUpdate(!1);e&&e.remove(),delete this.rootNode.match,delete this.rootNode.subMatchCount,this.visit(function(e){e.match&&e.span&&(t=y(e.span).find(">span.fancytree-title"),n?t.text(e.title):t.html(e.title),i&&i({type:"enhanceTitle"},{node:e,$title:t})),delete e.match,delete e.subMatchCount,delete e.titleWithHighlight,e.$subMatchBadge&&(e.$subMatchBadge.remove(),delete e.$subMatchBadge),e._filterAutoExpanded&&e.expanded&&e.setExpanded(!1,{noAnimation:!0,noEvents:!0,scrollIntoView:!1}),delete e._filterAutoExpanded}),this.enableFilter=!1,this.lastFilterArgs=null,this.$div.removeClass("fancytree-ext-filter fancytree-ext-filter-dimm fancytree-ext-filter-hide"),this._callHook("treeStructureChanged",this,"clearFilter"),this.enableUpdate(r)},y.ui.fancytree._FancytreeClass.prototype.isFilterActive=function(){return!!this.enableFilter},y.ui.fancytree._FancytreeNodeClass.prototype.isMatched=function(){return!(this.tree.enableFilter&&!this.match)},y.ui.fancytree.registerExtension({name:"filter",version:"2.38.3",options:{autoApply:!0,autoExpand:!1,counter:!0,fuzzy:!1,hideExpandedCounter:!0,hideExpanders:!1,highlight:!0,leavesOnly:!1,nodata:!0,mode:"dimm"},nodeLoadChildren:function(e,t){var n=e.tree;return this._superApply(arguments).done(function(){n.enableFilter&&n.lastFilterArgs&&e.options.filter.autoApply&&n._applyFilterImpl.apply(n,n.lastFilterArgs)})},nodeSetExpanded:function(e,t,n){var i=e.node;return delete i._filterAutoExpanded,!t&&e.options.filter.hideExpandedCounter&&i.$subMatchBadge&&i.$subMatchBadge.show(),this._superApply(arguments)},nodeRenderStatus:function(e){var t=e.node,n=e.tree,i=e.options.filter,r=y(t.span).find("span.fancytree-title"),o=y(t[n.statusClassPropName]),s=e.options.enhanceTitle,a=e.options.escapeTitles,e=this._super(e);return o.length&&n.enableFilter&&(o.toggleClass("fancytree-match",!!t.match).toggleClass("fancytree-submatch",!!t.subMatchCount).toggleClass("fancytree-hide",!(t.match||t.subMatchCount)),!i.counter||!t.subMatchCount||t.isExpanded()&&i.hideExpandedCounter?t.$subMatchBadge&&t.$subMatchBadge.hide():(t.$subMatchBadge||(t.$subMatchBadge=y("<span class='fancytree-childcounter'/>"),y("span.fancytree-icon, span.fancytree-custom-icon",t.span).append(t.$subMatchBadge)),t.$subMatchBadge.show().text(t.subMatchCount)),!t.span||t.isEditing&&t.isEditing.call(t)||(t.titleWithHighlight?r.html(t.titleWithHighlight):a?r.text(t.title):r.html(t.title),s&&s({type:"enhanceTitle"},{node:t,$title:r}))),e}}),y.ui.fancytree},"function"==typeof define&&define.amd?define(["jquery","./jquery.fancytree"],t):"object"==typeof module&&module.exports?(require("./jquery.fancytree"),module.exports=t(require("jquery"))):t(jQuery),t=function(l){"use strict";var a=l.ui.fancytree,n={awesome3:{_addClass:"",checkbox:"icon-check-empty",checkboxSelected:"icon-check",checkboxUnknown:"icon-check icon-muted",dragHelper:"icon-caret-right",dropMarker:"icon-caret-right",error:"icon-exclamation-sign",expanderClosed:"icon-caret-right",expanderLazy:"icon-angle-right",expanderOpen:"icon-caret-down",loading:"icon-refresh icon-spin",nodata:"icon-meh",noExpander:"",radio:"icon-circle-blank",radioSelected:"icon-circle",doc:"icon-file-alt",docOpen:"icon-file-alt",folder:"icon-folder-close-alt",folderOpen:"icon-folder-open-alt"},awesome4:{_addClass:"fa",checkbox:"fa-square-o",checkboxSelected:"fa-check-square-o",checkboxUnknown:"fa-square fancytree-helper-indeterminate-cb",dragHelper:"fa-arrow-right",dropMarker:"fa-long-arrow-right",error:"fa-warning",expanderClosed:"fa-caret-right",expanderLazy:"fa-angle-right",expanderOpen:"fa-caret-down",loading:{html:"<span class='fa fa-spinner fa-pulse' />"},nodata:"fa-meh-o",noExpander:"",radio:"fa-circle-thin",radioSelected:"fa-circle",doc:"fa-file-o",docOpen:"fa-file-o",folder:"fa-folder-o",folderOpen:"fa-folder-open-o"},awesome5:{_addClass:"",checkbox:"far fa-square",checkboxSelected:"far fa-check-square",checkboxUnknown:"fas fa-square fancytree-helper-indeterminate-cb",radio:"far fa-circle",radioSelected:"fas fa-circle",radioUnknown:"far fa-dot-circle",dragHelper:"fas fa-arrow-right",dropMarker:"fas fa-long-arrow-alt-right",error:"fas fa-exclamation-triangle",expanderClosed:"fas fa-caret-right",expanderLazy:"fas fa-angle-right",expanderOpen:"fas fa-caret-down",loading:"fas fa-spinner fa-pulse",nodata:"far fa-meh",noExpander:"",doc:"far fa-file",docOpen:"far fa-file",folder:"far fa-folder",folderOpen:"far fa-folder-open"},bootstrap3:{_addClass:"glyphicon",checkbox:"glyphicon-unchecked",checkboxSelected:"glyphicon-check",checkboxUnknown:"glyphicon-expand fancytree-helper-indeterminate-cb",dragHelper:"glyphicon-play",dropMarker:"glyphicon-arrow-right",error:"glyphicon-warning-sign",expanderClosed:"glyphicon-menu-right",expanderLazy:"glyphicon-menu-right",expanderOpen:"glyphicon-menu-down",loading:"glyphicon-refresh fancytree-helper-spin",nodata:"glyphicon-info-sign",noExpander:"",radio:"glyphicon-remove-circle",radioSelected:"glyphicon-ok-circle",doc:"glyphicon-file",docOpen:"glyphicon-file",folder:"glyphicon-folder-close",folderOpen:"glyphicon-folder-open"},material:{_addClass:"material-icons",checkbox:{text:"check_box_outline_blank"},checkboxSelected:{text:"check_box"},checkboxUnknown:{text:"indeterminate_check_box"},dragHelper:{text:"play_arrow"},dropMarker:{text:"arrow-forward"},error:{text:"warning"},expanderClosed:{text:"chevron_right"},expanderLazy:{text:"last_page"},expanderOpen:{text:"expand_more"},loading:{text:"autorenew",addClass:"fancytree-helper-spin"},nodata:{text:"info"},noExpander:{text:""},radio:{text:"radio_button_unchecked"},radioSelected:{text:"radio_button_checked"},doc:{text:"insert_drive_file"},docOpen:{text:"insert_drive_file"},folder:{text:"folder"},folderOpen:{text:"folder_open"}}};function d(e,t,n,i,r){var o=i.map,s=o[r],a=l(t),i=a.find(".fancytree-childcounter"),o=n+" "+(o._addClass||"");"string"==typeof(s="function"==typeof s?s.call(this,e,t,r):s)?(t.innerHTML="",a.attr("class",o+" "+s).append(i)):s&&(s.text?t.textContent=""+s.text:s.html?t.innerHTML=s.html:t.innerHTML="",a.attr("class",o+" "+(s.addClass||"")).append(i))}return l.ui.fancytree.registerExtension({name:"glyph",version:"2.38.3",options:{preset:null,map:{}},treeInit:function(e){var t=e.tree,e=e.options.glyph;e.preset?(a.assert(!!n[e.preset],"Invalid value for `options.glyph.preset`: "+e.preset),e.map=l.extend({},n[e.preset],e.map)):t.warn("ext-glyph: missing `preset` option."),this._superApply(arguments),t.$container.addClass("fancytree-ext-glyph")},nodeRenderStatus:function(e){var t,n,i=e.node,r=l(i.span),o=e.options.glyph,s=this._super(e);return i.isRootNode()||((n=r.children(".fancytree-expander").get(0))&&(t=i.expanded&&i.hasChildren()?"expanderOpen":i.isUndefined()?"expanderLazy":i.hasChildren()?"expanderClosed":"noExpander",d(i,n,"fancytree-expander",o,t)),(n=(i.tr?l("td",i.tr).find(".fancytree-checkbox"):r.children(".fancytree-checkbox")).get(0))&&(e=a.evalOption("checkbox",i,i,o,!1),i.parent&&i.parent.radiogroup||"radio"===e?d(i,n,"fancytree-checkbox fancytree-radio",o,t=i.selected?"radioSelected":"radio"):d(i,n,"fancytree-checkbox",o,t=i.selected?"checkboxSelected":i.partsel?"checkboxUnknown":"checkbox")),(n=r.children(".fancytree-icon").get(0))&&(t=i.statusNodeType||(i.folder?i.expanded&&i.hasChildren()?"folderOpen":"folder":i.expanded?"docOpen":"doc"),d(i,n,"fancytree-icon",o,t))),s},nodeSetStatus:function(e,t,n,i){var r,o=e.options.glyph,s=e.node,e=this._superApply(arguments);return"error"!==t&&"loading"!==t&&"nodata"!==t||(s.parent?(r=l(".fancytree-expander",s.span).get(0))&&d(s,r,"fancytree-expander",o,t):(r=l(".fancytree-statusnode-"+t,s[this.nodeContainerAttrName]).find(".fancytree-icon").get(0))&&d(s,r,"fancytree-icon",o,t)),e}}),l.ui.fancytree},"function"==typeof define&&define.amd?define(["jquery","./jquery.fancytree"],t):"object"==typeof module&&module.exports?(require("./jquery.fancytree"),module.exports=t(require("jquery"))):t(jQuery),t=function(c){"use strict";var u=c.ui.keyCode,o={text:[u.UP,u.DOWN],checkbox:[u.UP,u.DOWN,u.LEFT,u.RIGHT],link:[u.UP,u.DOWN,u.LEFT,u.RIGHT],radiobutton:[u.UP,u.DOWN,u.LEFT,u.RIGHT],"select-one":[u.LEFT,u.RIGHT],"select-multiple":[u.LEFT,u.RIGHT]};function s(e,t){var n,i,r,o,s,a,l=e.closest("td"),d=null;switch(t){case u.LEFT:d=l.prev();break;case u.RIGHT:d=l.next();break;case u.UP:case u.DOWN:for(n=l.parent(),r=n,s=l.get(0),a=0,r.children().each(function(){return this!==s&&(o=c(this).prop("colspan"),void(a+=o||1))}),i=a;(n=t===u.UP?n.prev():n.next()).length&&(n.is(":hidden")||!(d=function(e,t){var n,i=null,r=0;return e.children().each(function(){return t<=r?(i=c(this),!1):(n=c(this).prop("colspan"),void(r+=n||1))}),i}(n,i))||!d.find(":input,a").length););}return d}return c.ui.fancytree.registerExtension({name:"gridnav",version:"2.38.3",options:{autofocusInput:!1,handleCursorKeys:!0},treeInit:function(n){this._requireExtension("table",!0,!0),this._superApply(arguments),this.$container.addClass("fancytree-ext-gridnav"),this.$container.on("focusin",function(e){var t=c.ui.fancytree.getNode(e.target);t&&!t.isActive()&&(e=n.tree._makeHookContext(t,e),n.tree._callHook("nodeSetActive",e,!0))})},nodeSetActive:function(e,t,n){var i=e.options.gridnav,r=e.node,o=e.originalEvent||{},o=c(o.target).is(":input");t=!1!==t,this._superApply(arguments),t&&(e.options.titlesTabbable?(o||(c(r.span).find("span.fancytree-title").focus(),r.setFocus()),e.tree.$container.attr("tabindex","-1")):i.autofocusInput&&!o&&c(r.tr||r.span).find(":input:enabled").first().focus())},nodeKeydown:function(e){var t,n,i=e.options.gridnav,r=e.originalEvent,e=c(r.target);return e.is(":input:enabled")?t=e.prop("type"):e.is("a")&&(t="link"),t&&i.handleCursorKeys?!((t=o[t])&&0<=c.inArray(r.which,t)&&(n=s(e,r.which))&&n.length)||(n.find(":input:enabled,a").focus(),!1):this._superApply(arguments)}}),c.ui.fancytree},"function"==typeof define&&define.amd?define(["jquery","./jquery.fancytree","./jquery.fancytree.table"],t):"object"==typeof module&&module.exports?(require("./jquery.fancytree.table"),module.exports=t(require("jquery"))):t(jQuery),t=function(s){"use strict";return s.ui.fancytree.registerExtension({name:"multi",version:"2.38.3",options:{allowNoSelect:!1,mode:"sameParent"},treeInit:function(e){this._superApply(arguments),this.$container.addClass("fancytree-ext-multi"),1===e.options.selectMode&&s.error("Fancytree ext-multi: selectMode: 1 (single) is not compatible.")},nodeClick:function(e){var t=e.tree,n=e.node,i=t.getActiveNode()||t.getFirstChild(),r="checkbox"===e.targetType,o="expander"===e.targetType;switch(s.ui.fancytree.eventToString(e.originalEvent)){case"click":if(o)break;r||(t.selectAll(!1),n.setSelected());break;case"shift+click":t.visitRows(function(e){if(e.setSelected(),e===n)return!1},{start:i,reverse:i.isBelowOf(n)});break;case"ctrl+click":case"meta+click":return void n.toggleSelected()}return this._superApply(arguments)},nodeKeydown:function(e){var t=e.tree,n=e.node,i=e.originalEvent;switch(s.ui.fancytree.eventToString(i)){case"up":case"down":t.selectAll(!1),n.navigate(i.which,!0),t.getActiveNode().setSelected();break;case"shift+up":case"shift+down":n.navigate(i.which,!0),t.getActiveNode().setSelected()}return this._superApply(arguments)}}),s.ui.fancytree},"function"==typeof define&&define.amd?define(["jquery","./jquery.fancytree"],t):"object"==typeof module&&module.exports?(require("./jquery.fancytree"),module.exports=t(require("jquery"))):t(jQuery),t=function(p){"use strict";var t=null,n=null,i=null,r=p.ui.fancytree.assert,u="active",g="expanded",h="focus",f="selected";try{r(window.localStorage&&window.localStorage.getItem),n={get:function(e){return window.localStorage.getItem(e)},set:function(e,t){window.localStorage.setItem(e,t)},remove:function(e){window.localStorage.removeItem(e)}}}catch(e){p.ui.fancytree.warn("Could not access window.localStorage",e)}try{r(window.sessionStorage&&window.sessionStorage.getItem),i={get:function(e){return window.sessionStorage.getItem(e)},set:function(e,t){window.sessionStorage.setItem(e,t)},remove:function(e){window.sessionStorage.removeItem(e)}}}catch(e){p.ui.fancytree.warn("Could not access window.sessionStorage",e)}return"function"==typeof Cookies?t={get:Cookies.get,set:function(e,t){Cookies.set(e,t,this.options.persist.cookie)},remove:Cookies.remove}:p&&"function"==typeof p.cookie&&(t={get:p.cookie,set:function(e,t){p.cookie(e,t,this.options.persist.cookie)},remove:p.removeCookie}),p.ui.fancytree._FancytreeClass.prototype.clearPersistData=function(e){var t=this.ext.persist,n=t.cookiePrefix;0<=(e=e||"active expanded focus selected").indexOf(u)&&t._data(n+u,null),0<=e.indexOf(g)&&t._data(n+g,null),0<=e.indexOf(h)&&t._data(n+h,null),0<=e.indexOf(f)&&t._data(n+f,null)},p.ui.fancytree._FancytreeClass.prototype.clearCookies=function(e){return this.warn("'tree.clearCookies()' is deprecated since v2.27.0: use 'clearPersistData()' instead."),this.clearPersistData(e)},p.ui.fancytree._FancytreeClass.prototype.getPersistData=function(){var e=this.ext.persist,t=e.cookiePrefix,n=e.cookieDelimiter,i={};return i[u]=e._data(t+u),i[g]=(e._data(t+g)||"").split(n),i[f]=(e._data(t+f)||"").split(n),i[h]=e._data(t+h),i},p.ui.fancytree.registerExtension({name:"persist",version:"2.38.3",options:{cookieDelimiter:"~",cookiePrefix:void 0,cookie:{raw:!1,expires:"",path:"",domain:"",secure:!1},expandLazy:!1,expandOpts:void 0,fireActivate:!0,overrideSource:!0,store:"auto",types:"active expanded focus selected"},_data:function(e,t){var n=this._local.store;if(void 0===t)return n.get.call(this,e);null===t?n.remove.call(this,e):n.set.call(this,e,t)},_appendKey:function(e,t,n){t=""+t;var i=this._local,r=this.options.persist.cookieDelimiter,o=i.cookiePrefix+e,s=i._data(o),e=s?s.split(r):[],s=p.inArray(t,e);0<=s&&e.splice(s,1),n&&e.push(t),i._data(o,e.join(r))},treeInit:function(e){var a=e.tree,l=e.options,d=this._local,c=this.options.persist;return d.cookiePrefix=c.cookiePrefix||"fancytree-"+a._id+"-",d.storeActive=0<=c.types.indexOf(u),d.storeExpanded=0<=c.types.indexOf(g),d.storeSelected=0<=c.types.indexOf(f),d.storeFocus=0<=c.types.indexOf(h),d.store=null,"auto"===c.store&&(c.store=n?"local":"cookie"),p.isPlainObject(c.store)?d.store=c.store:"cookie"===c.store?d.store=t:"local"!==c.store&&"session"!==c.store||(d.store="local"===c.store?n:i),r(d.store,"Need a valid store."),a.$div.on("fancytreeinit",function(e){var t,n,i,r,o,s;!1!==a._triggerTreeEvent("beforeRestore",null,{})&&(i=d._data(d.cookiePrefix+h),r=!1===c.fireActivate,o=d._data(d.cookiePrefix+g),s=o&&o.split(c.cookieDelimiter),(d.storeExpanded?function e(t,n,i,r,o){var s,a,l,d,c=!1,u=t.options.persist.expandOpts,h=[],f=[];for(i=i||[],o=o||p.Deferred(),s=0,l=i.length;s<l;s++)a=i[s],(d=t.getNodeByKey(a))?r&&d.isUndefined()?(c=!0,t.debug("_loadLazyNodes: "+d+" is lazy: loading..."),"expand"===r?h.push(d.setExpanded(!0,u)):h.push(d.load())):(t.debug("_loadLazyNodes: "+d+" already loaded."),d.setExpanded(!0,u)):(f.push(a),t.debug("_loadLazyNodes: "+d+" was not yet found."));return p.when.apply(p,h).always(function(){if(c&&0<f.length)e(t,n,f,r,o);else{if(f.length)for(t.warn("_loadLazyNodes: could not load those keys: ",f),s=0,l=f.length;s<l;s++)a=i[s],n._appendKey(g,i[s],!1);o.resolve()}}),o}(a,d,s,!!c.expandLazy&&"expand",null):(new p.Deferred).resolve()).done(function(){if(d.storeSelected){if(o=d._data(d.cookiePrefix+f))for(s=o.split(c.cookieDelimiter),t=0;t<s.length;t++)(n=a.getNodeByKey(s[t]))?(void 0===n.selected||c.overrideSource&&!1===n.selected)&&(n.selected=!0,n.renderStatus()):d._appendKey(f,s[t],!1);3===a.options.selectMode&&a.visit(function(e){if(e.selected)return e.fixSelection3AfterClick(),"skip"})}d.storeActive&&(!(o=d._data(d.cookiePrefix+u))||!l.persist.overrideSource&&a.activeNode||(n=a.getNodeByKey(o))&&(n.debug("persist: set active",o),n.setActive(!0,{noFocus:!0,noEvents:r}))),d.storeFocus&&i&&(n=a.getNodeByKey(i))&&(a.options.titlesTabbable?p(n.span).find(".fancytree-title"):p(a.$container)).focus(),a._triggerTreeEvent("restore",null,{})}))}),this._superApply(arguments)},nodeSetActive:function(e,t,n){var i=this._local;return t=!1!==t,t=this._superApply(arguments),i.storeActive&&i._data(i.cookiePrefix+u,this.activeNode?this.activeNode.key:null),t},nodeSetExpanded:function(e,t,n){var i=e.node,r=this._local;return t=!1!==t,e=this._superApply(arguments),r.storeExpanded&&r._appendKey(g,i.key,t),e},nodeSetFocus:function(e,t){var n=this._local;return t=!1!==t,t=this._superApply(arguments),n.storeFocus&&n._data(n.cookiePrefix+h,this.focusNode?this.focusNode.key:null),t},nodeSetSelected:function(e,t,n){var i=e.tree,r=e.node,o=this._local;return t=!1!==t,t=this._superApply(arguments),o.storeSelected&&(3===i.options.selectMode?(i=(i=p.map(i.getSelectedNodes(!0),function(e){return e.key})).join(e.options.persist.cookieDelimiter),o._data(o.cookiePrefix+f,i)):o._appendKey(f,r.key,r.selected)),t}}),p.ui.fancytree},"function"==typeof define&&define.amd?define(["jquery","./jquery.fancytree"],t):"object"==typeof module&&module.exports?(require("./jquery.fancytree"),module.exports=t(require("jquery"))):t(jQuery),t=function(m){"use strict";var b=m.ui.fancytree.assert;function x(e,n){e.visit(function(e){var t=e.tr;if(t&&(t.style.display=e.hide||!n?"none":""),!e.expanded)return"skip"})}return m.ui.fancytree.registerExtension({name:"table",version:"2.38.3",options:{checkboxColumnIdx:null,indentation:16,mergeStatusColumns:!0,nodeColumnIdx:0},treeInit:function(e){var t,n,i,r=e.tree,o=e.options,s=o.table,a=r.widget.element;if(null!=s.customStatus&&(null==o.renderStatusColumns?(r.warn("The 'customStatus' option is deprecated since v2.15.0. Use 'renderStatusColumns' instead."),o.renderStatusColumns=s.customStatus):m.error("The 'customStatus' option is deprecated since v2.15.0. Use 'renderStatusColumns' only instead.")),o.renderStatusColumns&&!0===o.renderStatusColumns&&(o.renderStatusColumns=o.renderColumns),a.addClass("fancytree-container fancytree-ext-table"),(i=a.find(">tbody")).length||(a.find(">tr").length&&m.error("Expected table > tbody > tr. If you see this please open an issue."),i=m("<tbody>").appendTo(a)),r.tbody=i[0],r.columnCount=m("thead >tr",a).last().find(">th",a).length,(n=i.children("tr").first()).length)e=n.children("td").length,r.columnCount&&e!==r.columnCount&&(r.warn("Column count mismatch between thead ("+r.columnCount+") and tbody ("+e+"): using tbody."),r.columnCount=e),n=n.clone();else for(b(1<=r.columnCount,"Need either <thead> or <tbody> with <td> elements to determine column count."),n=m("<tr />"),t=0;t<r.columnCount;t++)n.append("<td />");n.find(">td").eq(s.nodeColumnIdx).html("<span class='fancytree-node' />"),o.aria&&(n.attr("role","row"),n.find("td").attr("role","gridcell")),r.rowFragment=document.createDocumentFragment(),r.rowFragment.appendChild(n.get(0)),i.empty(),r.statusClassPropName="tr",r.ariaPropName="tr",this.nodeContainerAttrName="tr",r.$container=a,this._superApply(arguments),m(r.rootNode.ul).remove(),r.rootNode.ul=null,this.$container.attr("tabindex",o.tabindex),o.aria&&r.$container.attr("role","treegrid").attr("aria-readonly",!0)},nodeRemoveChildMarkup:function(e){e.node.visit(function(e){e.tr&&(m(e.tr).remove(),e.tr=null)})},nodeRemoveMarkup:function(e){var t=e.node;t.tr&&(m(t.tr).remove(),t.tr=null),this.nodeRemoveChildMarkup(e)},nodeRender:function(e,t,n,i,r){var o,s,a,l,d,c,u,h,f,p=e.tree,g=e.node,y=e.options,v=!g.parent;if(!1!==p._enableUpdate){if(r||(e.hasCollapsedParents=g.parent&&!g.parent.expanded),!v)if(g.tr&&t&&this.nodeRemoveMarkup(e),g.tr)t?this.nodeRenderTitle(e):this.nodeRenderStatus(e);else{if(e.hasCollapsedParents&&!n)return;d=p.rowFragment.firstChild.cloneNode(!0),h=function(e){var t,n,i=e.parent,r=i?i.children:null;if(r&&1<r.length&&r[0]!==e)for(n=r[m.inArray(e,r)-1],b(n.tr);n.children&&n.children.length&&(t=n.children[n.children.length-1]).tr;)n=t;else n=i;return n}(g),b(h),(!0===i&&r||n&&e.hasCollapsedParents)&&(d.style.display="none"),h.tr?(f=h.tr).parentNode.insertBefore(d,f.nextSibling):(b(!h.parent,"prev. row must have a tr, or be system root"),(h=p.tbody).insertBefore(d,h.firstChild)),g.tr=d,g.key&&y.generateIds&&(g.tr.id=y.idPrefix+g.key),(g.tr.ftnode=g).span=m("span.fancytree-node",g.tr).get(0),this.nodeRenderTitle(e),y.createNode&&y.createNode.call(p,{type:"createNode"},e)}if(y.renderNode&&y.renderNode.call(p,{type:"renderNode"},e),(o=g.children)&&(v||n||g.expanded))for(a=0,l=o.length;a<l;a++)(u=m.extend({},e,{node:o[a]})).hasCollapsedParents=u.hasCollapsedParents||!g.expanded,this.nodeRender(u,t,n,i,!0);o&&!r&&(c=g.tr||null,s=p.tbody.firstChild,g.visit(function(e){var t;e.tr&&(e.parent.expanded||"none"===e.tr.style.display||(e.tr.style.display="none",x(e,!1)),e.tr.previousSibling!==c&&(g.debug("_fixOrder: mismatch at node: "+e),t=c?c.nextSibling:s,p.tbody.insertBefore(e.tr,t)),c=e.tr)}))}},nodeRenderTitle:function(e,t){var n=e.tree,i=e.node,r=e.options,o=i.isStatusNode(),s=this._super(e,t);return i.isRootNode()||(r.checkbox&&!o&&null!=r.table.checkboxColumnIdx&&(t=m("span.fancytree-checkbox",i.span),m(i.tr).find("td").eq(+r.table.checkboxColumnIdx).html(t)),this.nodeRenderStatus(e),o?r.renderStatusColumns?r.renderStatusColumns.call(n,{type:"renderStatusColumns"},e):r.table.mergeStatusColumns&&i.isTopLevel()&&m(i.tr).find(">td").eq(0).prop("colspan",n.columnCount).text(i.title).addClass("fancytree-status-merged").nextAll().remove():r.renderColumns&&r.renderColumns.call(n,{type:"renderColumns"},e)),s},nodeRenderStatus:function(e){var t=e.node,n=e.options;this._super(e),m(t.tr).removeClass("fancytree-node"),e=(t.getLevel()-1)*n.table.indentation,n.rtl?m(t.span).css({paddingRight:e+"px"}):m(t.span).css({paddingLeft:e+"px"})},nodeSetExpanded:function(t,n,i){if(n=!1!==n,t.node.expanded&&n||!t.node.expanded&&!n)return this._superApply(arguments);var r=new m.Deferred,e=m.extend({},i,{noEvents:!0,noAnimation:!0});function o(e){e?(x(t.node,n),n&&t.options.autoScroll&&!i.noAnimation&&t.node.hasChildren()?t.node.getLastChild().scrollIntoView(!0,{topNode:t.node}).always(function(){i.noEvents||t.tree._triggerNodeEvent(n?"expand":"collapse",t),r.resolveWith(t.node)}):(i.noEvents||t.tree._triggerNodeEvent(n?"expand":"collapse",t),r.resolveWith(t.node))):(i.noEvents||t.tree._triggerNodeEvent(n?"expand":"collapse",t),r.rejectWith(t.node))}return i=i||{},this._super(t,n,e).done(function(){o(!0)}).fail(function(){o(!1)}),r.promise()},nodeSetStatus:function(e,t,n,i){return"ok"!==t||(e=(e=e.node).children?e.children[0]:null)&&e.isStatusNode()&&m(e.tr).remove(),this._superApply(arguments)},treeClear:function(e){return this.nodeRemoveChildMarkup(this._makeHookContext(this.rootNode)),this._superApply(arguments)},treeDestroy:function(e){return this.$container.find("tbody").empty(),this.$source&&this.$source.removeClass("fancytree-helper-hidden"),this._superApply(arguments)}}),m.ui.fancytree},"function"==typeof define&&define.amd?define(["jquery","./jquery.fancytree"],t):"object"==typeof module&&module.exports?(require("./jquery.fancytree"),module.exports=t(require("jquery"))):t(jQuery),t=function(o){"use strict";return o.ui.fancytree.registerExtension({name:"themeroller",version:"2.38.3",options:{activeClass:"ui-state-active",addClass:"ui-corner-all",focusClass:"ui-state-focus",hoverClass:"ui-state-hover",selectedClass:"ui-state-highlight"},treeInit:function(e){var t=e.widget.element,n=e.options.themeroller;this._superApply(arguments),"TABLE"===t[0].nodeName?(t.addClass("ui-widget ui-corner-all"),t.find(">thead tr").addClass("ui-widget-header"),t.find(">tbody").addClass("ui-widget-conent")):t.addClass("ui-widget ui-widget-content ui-corner-all"),t.on("mouseenter mouseleave",".fancytree-node",function(e){var t=o.ui.fancytree.getNode(e.target),e="mouseenter"===e.type;o(t.tr||t.span).toggleClass(n.hoverClass+" "+n.addClass,e)})},treeDestroy:function(e){this._superApply(arguments),e.widget.element.removeClass("ui-widget ui-widget-content ui-corner-all")},nodeRenderStatus:function(e){var t={},n=e.node,i=o(n.tr||n.span),r=e.options.themeroller;this._super(e),t[r.activeClass]=!1,t[r.focusClass]=!1,t[r.selectedClass]=!1,n.isActive()&&(t[r.activeClass]=!0),n.hasFocus()&&(t[r.focusClass]=!0),n.isSelected()&&!n.isActive()&&(t[r.selectedClass]=!0),i.toggleClass(r.activeClass,t[r.activeClass]),i.toggleClass(r.focusClass,t[r.focusClass]),i.toggleClass(r.selectedClass,t[r.selectedClass]),i.addClass(r.addClass)}}),o.ui.fancytree},"function"==typeof define&&define.amd?define(["jquery","./jquery.fancytree"],t):"object"==typeof module&&module.exports?(require("./jquery.fancytree"),module.exports=t(require("jquery"))):t(jQuery),t=function(d){"use strict";var c=/^([+-]?(?:\d+|\d*\.\d+))([a-z]*|%)$/;function u(e,t){var n=d("#"+(e="fancytree-style-"+e));if(t){n.length||(n=d("<style />").attr("id",e).addClass("fancytree-style").prop("type","text/css").appendTo("head"));try{n.html(t)}catch(e){n[0].styleSheet.cssText=t}return n}n.remove()}function h(e,t,n,i,r,o){for(var s="#"+e+" span.fancytree-level-",a=[],l=0;l<t;l++)a.push(s+(l+1)+" span.fancytree-title { padding-left: "+(l*n+i)+o+"; }");return a.push("#"+e+" div.ui-effects-wrapper ul li span.fancytree-title, #"+e+" li.fancytree-animating span.fancytree-title { padding-left: "+r+o+"; position: static; width: auto; }"),a.join("\n")}return d.ui.fancytree.registerExtension({name:"wide",version:"2.38.3",options:{iconWidth:null,iconSpacing:null,labelSpacing:null,levelOfs:null},treeCreate:function(e){this._superApply(arguments),this.$container.addClass("fancytree-ext-wide");var t=e.options.wide,n=d("<li id='fancytreeTemp'><span class='fancytree-node'><span class='fancytree-icon' /><span class='fancytree-title' /></span><ul />").appendTo(e.tree.$container),i=n.find(".fancytree-icon"),r=n.find("ul"),o=t.iconSpacing||i.css("margin-left"),s=t.iconWidth||i.css("width"),a=t.labelSpacing||"3px",l=t.levelOfs||r.css("padding-left");n.remove(),i=o.match(c)[2],o=parseFloat(o,10),t=a.match(c)[2],a=parseFloat(a,10),r=s.match(c)[2],s=parseFloat(s,10),n=l.match(c)[2],i===r&&n===r&&t===r||d.error("iconWidth, iconSpacing, and levelOfs must have the same css measure unit"),this._local.measureUnit=r,this._local.levelOfs=parseFloat(l),this._local.lineOfs=(1+(e.options.checkbox?1:0)+(!1===e.options.icon?0:1))*(s+o)+o,this._local.labelOfs=a,this._local.maxDepth=10,u(a=this.$container.uniqueId().attr("id"),h(a,this._local.maxDepth,this._local.levelOfs,this._local.lineOfs,this._local.labelOfs,this._local.measureUnit))},treeDestroy:function(e){return u(this.$container.attr("id"),null),this._superApply(arguments)},nodeRenderStatus:function(e){var t=e.node,n=t.getLevel(),i=this._super(e);return n>this._local.maxDepth&&(e=this.$container.attr("id"),this._local.maxDepth*=2,t.debug("Define global ext-wide css up to level "+this._local.maxDepth),u(e,h(e,this._local.maxDepth,this._local.levelOfs,this._local.lineOfs,this._local.labelSpacing,this._local.measureUnit))),d(t.span).addClass("fancytree-level-"+n),i}}),d.ui.fancytree},"function"==typeof define&&define.amd?define(["jquery","./jquery.fancytree"],t):"object"==typeof module&&module.exports?(require("./jquery.fancytree"),module.exports=t(require("jquery"))):t(jQuery),e.ui.fancytree}); +//# sourceMappingURL=jquery.fancytree-all-deps.min.js.map
\ No newline at end of file diff --git a/plugins/55/indexmenu/scripts/fancytree/jquery.fancytree-all-deps.min.js.map b/plugins/55/indexmenu/scripts/fancytree/jquery.fancytree-all-deps.min.js.map new file mode 100644 index 0000000..9cadd5b --- /dev/null +++ b/plugins/55/indexmenu/scripts/fancytree/jquery.fancytree-all-deps.min.js.map @@ -0,0 +1 @@ +{"version":3,"file":"jquery.fancytree-all-deps.min.js","sources":["jquery.fancytree-all-deps.js"],"names":["$","ui","version","orig","widgetUuid","widgetHasOwnProperty","Array","prototype","hasOwnProperty","widgetSlice","slice","cleanData","elems","events","elem","i","_data","remove","triggerHandler","widget","name","base","existingConstructor","constructor","basePrototype","proxiedPrototype","namespace","split","fullName","Widget","isArray","extend","apply","concat","expr","pseudos","toLowerCase","data","options","element","this","_createWidget","arguments","length","_proto","_childConstructors","each","prop","value","_super","_superApply","args","returnValue","__super","__superApply","widgetEventPrefix","widgetName","widgetFullName","child","childPrototype","push","bridge","target","key","input","call","inputIndex","inputLength","undefined","isPlainObject","object","fn","isMethodCall","methodValue","instance","charAt","error","jquery","pushStack","get","option","_init","defaultElement","classes","disabled","create","uuid","eventNamespace","bindings","hoverable","focusable","classesElementLookup","_on","event","destroy","document","style","ownerDocument","window","defaultView","parentWindow","_getCreateOptions","_create","_setOptionDisabled","_trigger","_getCreateEventData","noop","that","_destroy","_removeClass","off","removeData","removeAttr","parts","curOption","shift","pop","_setOptions","_setOption","_setOptionClasses","classKey","elements","currentElements","addClass","_classes","keys","add","_toggleClass","enable","disable","full","processClassString","checkOption","current","nodesToBind","_","map","some","is","bindRemoveEvent","uniqueSort","not","match","extra","join","_untrackClassesElement","inArray","_off","_addClass","toggleClass","suppressDisabledCheck","handlers","delegateElement","handler","handlerProxy","hasClass","guid","eventName","selector","on","_delay","delay","setTimeout","_hoverable","mouseenter","currentTarget","mouseleave","_focusable","focusin","focusout","type","callback","Event","originalEvent","trigger","isDefaultPrevented","show","hide","method","defaultEffect","hasOptions","effectName","effect","duration","isEmptyObject","complete","effects","easing","queue","next","cachedScrollbarWidth","max","abs","rhorizontal","rvertical","roffset","rposition","rpercent","_position","getOffsets","offsets","width","height","parseFloat","test","parseCss","property","parseInt","css","isWindow","obj","Math","position","scrollbarWidth","w1","div","innerDiv","children","append","offsetWidth","w2","clientWidth","getScrollInfo","within","overflowX","isDocument","overflowY","hasOverflowX","scrollWidth","scrollHeight","getWithinInfo","withinElement","isElemWindow","nodeType","offset","left","top","scrollLeft","scrollTop","outerWidth","outerHeight","of","atOffset","targetWidth","targetHeight","targetOffset","basePosition","raw","find","scrollInfo","collision","dimensions","preventDefault","pageY","pageX","at","horizontalOffset","verticalOffset","pos","exec","collisionPosition","using","elemWidth","elemHeight","marginLeft","marginTop","collisionWidth","collisionHeight","myOffset","my","dir","props","right","bottom","feedback","horizontal","vertical","important","fit","withinOffset","collisionPosLeft","overLeft","overRight","newOverRight","collisionPosTop","overTop","overBottom","newOverBottom","flip","offsetLeft","newOverLeft","offsetTop","newOverTop","flipfit","rcssescape","fcssescape","unique","escapeSelector","ch","asCodePoint","charCodeAt","toString","sel","replace","even","odd","filter","keyCode","BACKSPACE","COMMA","DELETE","DOWN","END","ENTER","ESCAPE","HOME","LEFT","PAGE_DOWN","PAGE_UP","PERIOD","RIGHT","SPACE","TAB","UP","scrollParent","includeHidden","excludeStaticParent","overflowRegex","parents","parent","eq","uniqueId","id","removeUniqueId","jQuery","factory","define","amd","module","exports","require","fancytree","attr","FT","TEST_IMG","RegExp","REX_HTML","REX_TOOLTIP","RECURSIVE_REQUEST_ERROR","INVALID_REQUEST_TARGET_ERROR","ENTITY_MAP","&","<",">","\"","'","/","IGNORE_KEYCODES","16","17","18","SPECIAL_KEYCODES","8","9","10","13","19","20","27","32","33","34","35","36","37","38","39","40","45","46","59","61","96","97","98","99","100","101","102","103","104","105","106","107","109","110","111","112","113","114","115","116","117","118","119","120","121","122","123","144","145","173","186","187","188","189","190","191","192","219","220","221","222","MODIFIERS","91","93","MOUSE_BUTTONS","0","1","2","3","CLASS_ATTRS","CLASS_ATTR_MAP","TREE_ATTRS","NODE_ATTRS","NODE_ATTR_MAP","NODE_ATTR_LOWERCASE_MAP","NONE_NODE_DATA_MAP","active","focus","_isArray","_assert","Date","now","getTime","FancytreeNode","_findDirectChild","ptr","l","cl","_setChildren","tree","_callHook","addChildren","insertBefore","firstNode","origFirstChild","getFirstChild","origLastChild","getLastChild","nodeList","splice","render","renderStatus","ul","tr","selectMode","fixSelection3FromEndNodes","triggerModifyChild","className","addNode","node","mode","getParent","getNextSibling","addPagingNode","n","title","strings","moreData","statusNodeType","icon","partload","removeChild","appendSibling","applyCommand","cmd","opts","applyPatch","patch","_getResolvedPromise","v","IGNORE_MAP","expanded","_hasProp","_isFunction","removeChildren","isVisible","renderTitle","setExpanded","collapseSiblings","copyTo","toDict","countChildren","deep","debug","msg","debugLevel","unshift","consoleApply","discard","warn","resetLazy","discardMarkup","includeSelf","findAll","_makeNodeTitleMatcher","res","visit","findFirst","findRelatedNode","where","_changeSelectStatusAttrs","state","changed","unselectable","evalOption","unselectableStatus","selected","partsel","fixSelection3AfterClick","callOpts","flag","isSelected","radiogroup","_walk","s","allSelected","someSelected","unselState","lazy","visitParents","fromDict","dict","getChildren","hasChildren","getIndex","getIndexHier","separator","digits","getParentList","o","substr","getKeyPath","excludeSelf","sep","keyPathSeparator","getPath","getLevel","level","dtn","ac","includeRoot","part","val","path","isFunc","getPrevSibling","getSelectedNodes","stopOnParents","isStatusNode","extraClasses","indexOf","hasFocus","focusNode","info","isActive","activeNode","isBelowOf","otherNode","isChildOf","isDescendantOf","p","isExpanded","isFirstSibling","isFolder","folder","isLastSibling","isLazy","isLoaded","isLoading","_isLoading","isRoot","isRootNode","isPartsel","isPartload","rootNode","isPagingNode","isTopLevel","isUndefined","hasFilter","enableFilter","subMatchCount","lazyLoad","load","forceReload","self","wasExpanded","source","_triggerNodeEvent","always","makeVisible","deferreds","dfd","Deferred","len","noAnimation","scroll","scrollIntoView","when","done","resolve","promise","moveTo","targetNode","prevParent","targetParent","navigate","activate","KC","e","setFocus","setActive","childNode","removeClass","force","replaceWith","fail","scheduleAction","ms","timer","clearTimeout","x","Error","scrollOfs","topNode","$scrollParent","$container","tbody","body","topNodeY","nodeY","nodeHeight","span","topOfs","bottomOfs","containerHeight","$animateTarget","isParentWindow","newScrollTop","containerOffsetTop","innerHeight","clientHeight","resolveWith","stop","animate","setSelected","setStatus","status","message","details","setTitle","triggerModify","sortChildren","cmp","sort","a","b","y","recursive","classNames","wasAdded","statusElem","statusClassPropName","curClasses","_trim","toggleExpanded","toggleSelected","operation","modifyChild","visitAndLoad","_recursion","loaders","reject","then","visitSiblings","Fancytree","_makeHookContext","ctx","typeInfo","types","funcName","contextObject","_extraArgs","_setExpiringValue","_tempCache","expire","_getExpiringValue","entry","_usesExtension","extensions","_requireExtension","required","before","thisName","_local","extList","isBefore","isMissing","ext","badOrder","activateKey","getNodeByKey","opts_","refNode","getActiveNode","editCreateNode","editStart","patchList","p2","patchCount","deferredList","_makeResolveFunc","clear","count","enableUpdate","_enableUpdate","expandAll","prev","findNextNode","startNode","reMatch","_checkNode","visitRows","start","reverse","generateFormElements","selectedName","_id","activeName","$result","_appender","checked","empty","insertAfter","idx","getFocusNode","getOption","optionName","searchRoot","el","getElementById","idPrefix","ftnode","getRootNode","_hasFocus","_requestId","loadKeyPath","keyPathList","optsOrCallback","pathSegList","notifyWith","matchKey","_loadKeyPathImpl","nodeKey","remain","remainMap","tmpParent","segList","subDfd","__findChild","errMsg","rejectWith","__lazyload","reactivate","noFocus","reload","selectAll","setOption","debugTime","label","console","time","debugTimeEnd","timeEnd","result","_triggerTreeEvent","_visitRowsUp","nextIdx","siblings","siblingOfs","skipFirstNode","checkFilter","nodeClick","expand","targetType","focusOnSelect","clickFolderMode","nodeSetFocus","nodeCollapseSiblings","nodeDblclick","nodeKeydown","which","String","fromCharCode","specialModifiers","altKey","ctrlKey","metaKey","isAlnum","$target","handled","autoActivate","quicksearch","stamp","lastQuicksearchTime","lastQuicksearchTerm","matchNode","eventToString","nodeSetExpanded","nodeToggleSelected","nodeSetActive","nodeLoadChildren","ajax","resultDfd","ajaxDfd","isAsync","nodePrevParent","tag","requestId","url","debugDelay","random","round","nodeSetStatus","textStatus","jqXHR","errorObj","dataType","postProcess","response","enableAspx","d","parseJSON","errorThrown","metaData","noDataRes","nodata","noData","ctxErr","nodeLoadKeyPath","nodeRemoveChild","subCtx","nodeRemoveChildren","nodeRemoveMarkup","nodeRemoveChildMarkup","li","nodeRenderStatus","nodeRender","collapsed","_recursive","childLI","childNode1","childNode2","aria","firstTime","successorLi","parentNode","nextSibling","createElement","generateIds","appendChild","nodeRenderTitle","createNode","renderNode","display","$div","firstChild","iconTooltip","ares","role","minExpandLevel","checkbox","iconClass","_escapeTooltip","imagePath","text","escapeHtml","html","nodeTitle","tooltip","titlesTabbable","escapeTitles","innerHTML","enhanceTitle","$title","$ariaElem","isLastSib","cn","_classNames","cnList","focused","Boolean","lastsib","loading","_error","statusNodePrefix","combinedExpanderPrefix","combinedIconPrefix","noEvents","_getRejectedPromise","activeVisible","_afterLoad","prevAC","animating","autoCollapse","lastChild","autoScroll","toggleEffect","toggle","ctx2","isInput","calledByNode","activeElement","nodeSetSelected","_lastSelectIntent","lastSelectedNode","_setStatusNode","_clearStatusNode","loadError","nodeToggleExpanded","treeClear","treeCreate","treeDestroy","$source","treeInit","tabindex","checkboxAutoHide","rtl","treeLoad","$ul","rootCtx","first","parseHtml","_getElementDataAsDict","contents","treeRegisterNode","treeSetFocus","_lastMousedownNode","treeSetOption","callDefault","callCreate","callRender","treeStructureChanged","cache","copyFunctionsToData","keyboard","treeId","radio","_deprecationWarning","extension","extName","_extensions","_simpleDeepMerge","copy","clone","src","attrName","_makeVirtualFunction","_subclassObject","icons","tabbable","_bind","_unbind","ns","_ns","getNode","prevPhase","phase","et","getEventTarget","getTree","buildType","_nextId","_nextNodeKey","_FancytreeClass","_FancytreeNodeClass","jquerySupports","positionMyOfs","dottedVersion","t","verParts","testParts","isVersionAtLeast","assert","createTree","$tree","debounce","timeout","invokeAsap","fixPositionOptions","myParts","atParts","dx","dy","tcn","closest","getEventTargetType","orgEl","Element","HTMLDocument","nodeObject","treeOptions","defaultValue","treeOpt","nodeOpt","setSpanIcon","baseClass","$span","shiftKey","button","keyEventToString","overrideMethod","methodName","context","prevSuper","iPos","tmp","tmp2","$children","allData","lowerCaseAttr","$li","$liSpan","$liA","href","search","substring","registerExtension","definition","trim","unescapeHtml","childNodes","nodeValue","cond","Object","prevFunc","baseFunc","prevLocal","prevSuperApply","argArray","deferred","$el","json","uiFancytree","unselectableIgnore","hideCheckbox","defaultKey","lazyload","loaderror","fx","removeNode","columns","systemFocusElement","viewport","ariaPropName","nodeContainerAttrName","class","appendTo","countSelected","topOnly","updateCounters","$badge","extOpts","childcounter","childCounter","hideZeros","hideExpanded","widgetMethod1","arg1","foo","_appendCounter","bar","hashMurmur3","asString","seed","h1b","k1","remainder","bytes","h1","c1","c2","getCloneList","refList","refMap","refKey","keyMap","isClone","reRegister","prevKey","prevRefKey","modified","setRefKey","getNodesByRef","changeRefKey","oldRefKey","newRefKey","highlightActiveClones","highlightClones","other","clones","arr","_removeArrayMember","scpn","$dragImage","$extraHelper","isMac","navigator","platform","classDragSource","classDragRemove","classDropAccept","classDropAfter","classDropBefore","classDropOver","classDropReject","classDropTarget","nodeMimeType","$dropMarker","SOURCE_NODE","SOURCE_NODE_LIST","$sourceList","DRAG_ENTER_RESPONSE","SUGGESTED_DROP_EFFECT","REQUESTED_DROP_EFFECT","REQUESTED_EFFECT_ALLOWED","LAST_HIT_MODE","DRAG_OVER_STAMP","_clearGlobals","offsetString","prepareDropEffectCallback","dataTransfer","effectAllowed","dnd5","dropEffect","dropEffectDefault","dropEffectSuggested","effectDefault","isMove","files","applyDropEffectCallback","allowDrop","handleDragOver","dndOpts","sp","sensitivity","scrollSensitivity","speed","scrollSpeed","scrolled","tagName","spOfs","offsetHeight","markerOffsetX","nodeOfs","hitMode","sourceNode","markerAt","$targetTitle","relPosY","after","over","preventVoidMoves","dragOver","dropMarkerOffsetX","dropMarkerInsertOffsetX","onDropEvent","r","otherNodeList","otherNodeData","useDefaultImage","isCancelled","isSourceFtNode","preventNonNodes","preventForeignNodes","preventSameParent","preventRecursion","preventLazyParents","dragEnter","autoExpandMS","dragExpand","dragLeave","nodeData","getData","JSON","parse","ex","orgSourceElem","orgSourceTree","dragDrop","contains","dragEnd","getDragNodeList","getDragNode","dropMarkerParent","multiSource","setTextTypeJson","sourceCopyHook","dragStart","dragDrag","glyph","dragStop","preventRecursiveMoves","draggable","$temp","z-index","pointer-events","prependTo","dropMarker","stringify","setData","setDragImage","bind","$input","local","edit","instOpts","eventData","isNew","orgTitle","dirty","beforeEdit","currentNode","lastDraggableAttrValue","editEnd","adjustWidthOfs","inputCss","change","stopPropagation","blur","applyChanges","_event","newVal","save","beforeClose","relatedNode","preventScroll","close","init","newNode","isEditing","allowEmpty","minWidth","triggerStart","editNode","eventStr","KeyNoData","_escapeRegex","str","_markFuzzyMatchedChars","regexMatchArray","matchingIndices","_matchingArrIdx","_mIdx","textPoses","forEach","_applyFilterImpl","branchMode","_opts","statusNode","re","reHighlight","reExoticStartChar","reExoticEndChar","temp","treeOpts","prevAutoCollapse","hideMode","leavesOnly","clearFilter","fuzzy","reduce","highlight","titleWithHighlight","lastFilterArgs","prevEnableUpdate","hideExpanders","matchedByBranch","c","autoExpand","_filterAutoExpanded","filterNodes","filterBranches","updateFilter","autoApply","$subMatchBadge","isFilterActive","isMatched","counter","hideExpandedCounter","PRESETS","awesome3","checkboxSelected","checkboxUnknown","dragHelper","expanderClosed","expanderLazy","expanderOpen","noExpander","radioSelected","doc","docOpen","folderOpen","awesome4","awesome5","radioUnknown","bootstrap3","material","setIcon","$counter","setClass","textContent","preset","NAV_KEYS","link","radiobutton","select-one","select-multiple","findNeighbourTd","$tr","colIdx","colspan","td","$td","$tdNext","findTdAtColIdx","autofocusInput","handleCursorKeys","gridnav","triggeredByInput","handleKeys","inputType","allowNoSelect","isCbClick","isExpanderClick","cookieStore","localStorageStore","sessionStorageStore","ACTIVE","EXPANDED","FOCUS","SELECTED","localStorage","getItem","set","setItem","removeItem","sessionStorage","Cookies","persist","cookie","removeCookie","clearPersistData","prefix","cookiePrefix","clearCookies","getPersistData","delim","cookieDelimiter","expires","domain","secure","expandLazy","expandOpts","fireActivate","overrideSource","store","_appendKey","cookieName","keyList","storeActive","storeExpanded","storeSelected","storeFocus","prevFocus","_loadLazyNodes","foundOne","missingKeyList","selNodes","setChildRowVisibility","checkboxColumnIdx","indentation","mergeStatusColumns","nodeColumnIdx","$row","$tbody","tableOpts","table","$table","customStatus","renderStatusColumns","renderColumns","columnCount","last","rowFragment","createDocumentFragment","firstTr","newRow","prevTr","referenceNode","hasCollapsedParents","cloneNode","prevNode","findPrevRowNode","nextTr","previousSibling","$cb","nextAll","indent","paddingRight","paddingLeft","subOpts","_afterExpand","ok","activeClass","focusClass","hoverClass","selectedClass","themeroller","nodeName","reNumUnit","defineHeadStyleElement","cssText","$headStyle","styleSheet","renderLevelCss","containerId","depth","levelOfs","lineOfs","labelOfs","measureUnit","rules","iconWidth","iconSpacing","labelSpacing","wide","$dummyLI","$dummyIcon","$dummyUL","iconSpacingUnit","labelSpacingUnit","iconWidthUnit","levelOfsUnit","maxDepth"],"mappings":"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"}
\ No newline at end of file diff --git a/plugins/55/indexmenu/scripts/fancytree/jquery.fancytree-all.js b/plugins/55/indexmenu/scripts/fancytree/jquery.fancytree-all.js new file mode 100644 index 0000000..44e0267 --- /dev/null +++ b/plugins/55/indexmenu/scripts/fancytree/jquery.fancytree-all.js @@ -0,0 +1,13178 @@ +/*! + * jquery.fancytree.js + * Tree view control with support for lazy loading and much more. + * https://github.com/mar10/fancytree/ + * + * Copyright (c) 2008-2023, Martin Wendt (https://wwWendt.de) + * Released under the MIT license + * https://github.com/mar10/fancytree/wiki/LicenseInfo + * + * @version 2.38.3 + * @date 2023-02-01T20:52:50Z + */ + +/** Core Fancytree module. + */ + +// UMD wrapper for the Fancytree core module +(function (factory) { + if (typeof define === "function" && define.amd) { + // AMD. Register as an anonymous module. + define(["jquery", "./jquery.fancytree.ui-deps"], factory); + } else if (typeof module === "object" && module.exports) { + // Node/CommonJS + require("./jquery.fancytree.ui-deps"); + module.exports = factory(require("jquery")); + } else { + // Browser globals + factory(jQuery); + } +})(function ($) { + "use strict"; + + // prevent duplicate loading + if ($.ui && $.ui.fancytree) { + $.ui.fancytree.warn("Fancytree: ignored duplicate include"); + return; + } + + /****************************************************************************** + * Private functions and variables + */ + + var i, + attr, + FT = null, // initialized below + TEST_IMG = new RegExp(/\.|\//), // strings are considered image urls if they contain '.' or '/' + REX_HTML = /[&<>"'/]/g, // Escape those characters + REX_TOOLTIP = /[<>"'/]/g, // Don't escape `&` in tooltips + RECURSIVE_REQUEST_ERROR = "$recursive_request", + INVALID_REQUEST_TARGET_ERROR = "$request_target_invalid", + ENTITY_MAP = { + "&": "&", + "<": "<", + ">": ">", + '"': """, + "'": "'", + "/": "/", + }, + IGNORE_KEYCODES = { 16: true, 17: true, 18: true }, + SPECIAL_KEYCODES = { + 8: "backspace", + 9: "tab", + 10: "return", + 13: "return", + // 16: null, 17: null, 18: null, // ignore shift, ctrl, alt + 19: "pause", + 20: "capslock", + 27: "esc", + 32: "space", + 33: "pageup", + 34: "pagedown", + 35: "end", + 36: "home", + 37: "left", + 38: "up", + 39: "right", + 40: "down", + 45: "insert", + 46: "del", + 59: ";", + 61: "=", + // 91: null, 93: null, // ignore left and right meta + 96: "0", + 97: "1", + 98: "2", + 99: "3", + 100: "4", + 101: "5", + 102: "6", + 103: "7", + 104: "8", + 105: "9", + 106: "*", + 107: "+", + 109: "-", + 110: ".", + 111: "/", + 112: "f1", + 113: "f2", + 114: "f3", + 115: "f4", + 116: "f5", + 117: "f6", + 118: "f7", + 119: "f8", + 120: "f9", + 121: "f10", + 122: "f11", + 123: "f12", + 144: "numlock", + 145: "scroll", + 173: "-", + 186: ";", + 187: "=", + 188: ",", + 189: "-", + 190: ".", + 191: "/", + 192: "`", + 219: "[", + 220: "\\", + 221: "]", + 222: "'", + }, + MODIFIERS = { + 16: "shift", + 17: "ctrl", + 18: "alt", + 91: "meta", + 93: "meta", + }, + MOUSE_BUTTONS = { 0: "", 1: "left", 2: "middle", 3: "right" }, + // Boolean attributes that can be set with equivalent class names in the LI tags + // Note: v2.23: checkbox and hideCheckbox are *not* in this list + CLASS_ATTRS = + "active expanded focus folder lazy radiogroup selected unselectable unselectableIgnore".split( + " " + ), + CLASS_ATTR_MAP = {}, + // Top-level Fancytree attributes, that can be set by dict + TREE_ATTRS = "columns types".split(" "), + // TREE_ATTR_MAP = {}, + // Top-level FancytreeNode attributes, that can be set by dict + NODE_ATTRS = + "checkbox expanded extraClasses folder icon iconTooltip key lazy partsel radiogroup refKey selected statusNodeType title tooltip type unselectable unselectableIgnore unselectableStatus".split( + " " + ), + NODE_ATTR_MAP = {}, + // Mapping of lowercase -> real name (because HTML5 data-... attribute only supports lowercase) + NODE_ATTR_LOWERCASE_MAP = {}, + // Attribute names that should NOT be added to node.data + NONE_NODE_DATA_MAP = { + active: true, + children: true, + data: true, + focus: true, + }; + + for (i = 0; i < CLASS_ATTRS.length; i++) { + CLASS_ATTR_MAP[CLASS_ATTRS[i]] = true; + } + for (i = 0; i < NODE_ATTRS.length; i++) { + attr = NODE_ATTRS[i]; + NODE_ATTR_MAP[attr] = true; + if (attr !== attr.toLowerCase()) { + NODE_ATTR_LOWERCASE_MAP[attr.toLowerCase()] = attr; + } + } + // for(i=0; i<TREE_ATTRS.length; i++) { + // TREE_ATTR_MAP[TREE_ATTRS[i]] = true; + // } + + function _assert(cond, msg) { + // TODO: see qunit.js extractStacktrace() + if (!cond) { + msg = msg ? ": " + msg : ""; + msg = "Fancytree assertion failed" + msg; + + // consoleApply("assert", [!!cond, msg]); + + // #1041: Raised exceptions may not be visible in the browser + // console if inside promise chains, so we also print directly: + $.ui.fancytree.error(msg); + + // Throw exception: + $.error(msg); + } + } + + function _hasProp(object, property) { + return Object.prototype.hasOwnProperty.call(object, property); + } + + /* Replacement for the deprecated `jQuery.isFunction()`. */ + function _isFunction(obj) { + return typeof obj === "function"; + } + + /* Replacement for the deprecated `jQuery.trim()`. */ + function _trim(text) { + return text == null ? "" : text.trim(); + } + + /* Replacement for the deprecated `jQuery.isArray()`. */ + var _isArray = Array.isArray; + + _assert($.ui, "Fancytree requires jQuery UI (http://jqueryui.com)"); + + function consoleApply(method, args) { + var i, + s, + fn = window.console ? window.console[method] : null; + + if (fn) { + try { + fn.apply(window.console, args); + } catch (e) { + // IE 8? + s = ""; + for (i = 0; i < args.length; i++) { + s += args[i]; + } + fn(s); + } + } + } + + /* support: IE8 Polyfil for Date.now() */ + if (!Date.now) { + Date.now = function now() { + return new Date().getTime(); + }; + } + + /*Return true if x is a FancytreeNode.*/ + function _isNode(x) { + return !!(x.tree && x.statusNodeType !== undefined); + } + + /** Return true if dotted version string is equal or higher than requested version. + * + * See http://jsfiddle.net/mar10/FjSAN/ + */ + function isVersionAtLeast(dottedVersion, major, minor, patch) { + var i, + v, + t, + verParts = $.map(_trim(dottedVersion).split("."), function (e) { + return parseInt(e, 10); + }), + testParts = $.map( + Array.prototype.slice.call(arguments, 1), + function (e) { + return parseInt(e, 10); + } + ); + + for (i = 0; i < testParts.length; i++) { + v = verParts[i] || 0; + t = testParts[i] || 0; + if (v !== t) { + return v > t; + } + } + return true; + } + + /** + * Deep-merge a list of objects (but replace array-type options). + * + * jQuery's $.extend(true, ...) method does a deep merge, that also merges Arrays. + * This variant is used to merge extension defaults with user options, and should + * merge objects, but override arrays (for example the `triggerStart: [...]` option + * of ext-edit). Also `null` values are copied over and not skipped. + * + * See issue #876 + * + * Example: + * _simpleDeepMerge({}, o1, o2); + */ + function _simpleDeepMerge() { + var options, + name, + src, + copy, + clone, + target = arguments[0] || {}, + i = 1, + length = arguments.length; + + // Handle case when target is a string or something (possible in deep copy) + if (typeof target !== "object" && !_isFunction(target)) { + target = {}; + } + if (i === length) { + throw Error("need at least two args"); + } + for (; i < length; i++) { + // Only deal with non-null/undefined values + if ((options = arguments[i]) != null) { + // Extend the base object + for (name in options) { + if (_hasProp(options, name)) { + src = target[name]; + copy = options[name]; + // Prevent never-ending loop + if (target === copy) { + continue; + } + // Recurse if we're merging plain objects + // (NOTE: unlike $.extend, we don't merge arrays, but replace them) + if (copy && $.isPlainObject(copy)) { + clone = src && $.isPlainObject(src) ? src : {}; + // Never move original objects, clone them + target[name] = _simpleDeepMerge(clone, copy); + // Don't bring in undefined values + } else if (copy !== undefined) { + target[name] = copy; + } + } + } + } + } + // Return the modified object + return target; + } + + /** Return a wrapper that calls sub.methodName() and exposes + * this : tree + * this._local : tree.ext.EXTNAME + * this._super : base.methodName.call() + * this._superApply : base.methodName.apply() + */ + function _makeVirtualFunction(methodName, tree, base, extension, extName) { + // $.ui.fancytree.debug("_makeVirtualFunction", methodName, tree, base, extension, extName); + // if(rexTestSuper && !rexTestSuper.test(func)){ + // // extension.methodName() doesn't call _super(), so no wrapper required + // return func; + // } + // Use an immediate function as closure + var proxy = (function () { + var prevFunc = tree[methodName], // org. tree method or prev. proxy + baseFunc = extension[methodName], // + _local = tree.ext[extName], + _super = function () { + return prevFunc.apply(tree, arguments); + }, + _superApply = function (args) { + return prevFunc.apply(tree, args); + }; + + // Return the wrapper function + return function () { + var prevLocal = tree._local, + prevSuper = tree._super, + prevSuperApply = tree._superApply; + + try { + tree._local = _local; + tree._super = _super; + tree._superApply = _superApply; + return baseFunc.apply(tree, arguments); + } finally { + tree._local = prevLocal; + tree._super = prevSuper; + tree._superApply = prevSuperApply; + } + }; + })(); // end of Immediate Function + return proxy; + } + + /** + * Subclass `base` by creating proxy functions + */ + function _subclassObject(tree, base, extension, extName) { + // $.ui.fancytree.debug("_subclassObject", tree, base, extension, extName); + for (var attrName in extension) { + if (typeof extension[attrName] === "function") { + if (typeof tree[attrName] === "function") { + // override existing method + tree[attrName] = _makeVirtualFunction( + attrName, + tree, + base, + extension, + extName + ); + } else if (attrName.charAt(0) === "_") { + // Create private methods in tree.ext.EXTENSION namespace + tree.ext[extName][attrName] = _makeVirtualFunction( + attrName, + tree, + base, + extension, + extName + ); + } else { + $.error( + "Could not override tree." + + attrName + + ". Use prefix '_' to create tree." + + extName + + "._" + + attrName + ); + } + } else { + // Create member variables in tree.ext.EXTENSION namespace + if (attrName !== "options") { + tree.ext[extName][attrName] = extension[attrName]; + } + } + } + } + + function _getResolvedPromise(context, argArray) { + if (context === undefined) { + return $.Deferred(function () { + this.resolve(); + }).promise(); + } + return $.Deferred(function () { + this.resolveWith(context, argArray); + }).promise(); + } + + function _getRejectedPromise(context, argArray) { + if (context === undefined) { + return $.Deferred(function () { + this.reject(); + }).promise(); + } + return $.Deferred(function () { + this.rejectWith(context, argArray); + }).promise(); + } + + function _makeResolveFunc(deferred, context) { + return function () { + deferred.resolveWith(context); + }; + } + + function _getElementDataAsDict($el) { + // Evaluate 'data-NAME' attributes with special treatment for 'data-json'. + var d = $.extend({}, $el.data()), + json = d.json; + + delete d.fancytree; // added to container by widget factory (old jQuery UI) + delete d.uiFancytree; // added to container by widget factory + + if (json) { + delete d.json; + // <li data-json='...'> is already returned as object (http://api.jquery.com/data/#data-html5) + d = $.extend(d, json); + } + return d; + } + + function _escapeTooltip(s) { + return ("" + s).replace(REX_TOOLTIP, function (s) { + return ENTITY_MAP[s]; + }); + } + + // TODO: use currying + function _makeNodeTitleMatcher(s) { + s = s.toLowerCase(); + return function (node) { + return node.title.toLowerCase().indexOf(s) >= 0; + }; + } + + function _makeNodeTitleStartMatcher(s) { + var reMatch = new RegExp("^" + s, "i"); + return function (node) { + return reMatch.test(node.title); + }; + } + + /****************************************************************************** + * FancytreeNode + */ + + /** + * Creates a new FancytreeNode + * + * @class FancytreeNode + * @classdesc A FancytreeNode represents the hierarchical data model and operations. + * + * @param {FancytreeNode} parent + * @param {NodeData} obj + * + * @property {Fancytree} tree The tree instance + * @property {FancytreeNode} parent The parent node + * @property {string} key Node id (must be unique inside the tree) + * @property {string} title Display name (may contain HTML) + * @property {object} data Contains all extra data that was passed on node creation + * @property {FancytreeNode[] | null | undefined} children Array of child nodes.<br> + * For lazy nodes, null or undefined means 'not yet loaded'. Use an empty array + * to define a node that has no children. + * @property {boolean} expanded Use isExpanded(), setExpanded() to access this property. + * @property {string} extraClasses Additional CSS classes, added to the node's `<span>`.<br> + * Note: use `node.add/remove/toggleClass()` to modify. + * @property {boolean} folder Folder nodes have different default icons and click behavior.<br> + * Note: Also non-folders may have children. + * @property {string} statusNodeType null for standard nodes. Otherwise type of special system node: 'error', 'loading', 'nodata', or 'paging'. + * @property {boolean} lazy True if this node is loaded on demand, i.e. on first expansion. + * @property {boolean} selected Use isSelected(), setSelected() to access this property. + * @property {string} tooltip Alternative description used as hover popup + * @property {string} iconTooltip Description used as hover popup for icon. @since 2.27 + * @property {string} type Node type, used with tree.types map. @since 2.27 + */ + function FancytreeNode(parent, obj) { + var i, l, name, cl; + + this.parent = parent; + this.tree = parent.tree; + this.ul = null; + this.li = null; // <li id='key' ftnode=this> tag + this.statusNodeType = null; // if this is a temp. node to display the status of its parent + this._isLoading = false; // if this node itself is loading + this._error = null; // {message: '...'} if a load error occurred + this.data = {}; + + // TODO: merge this code with node.toDict() + // copy attributes from obj object + for (i = 0, l = NODE_ATTRS.length; i < l; i++) { + name = NODE_ATTRS[i]; + this[name] = obj[name]; + } + // unselectableIgnore and unselectableStatus imply unselectable + if ( + this.unselectableIgnore != null || + this.unselectableStatus != null + ) { + this.unselectable = true; + } + if (obj.hideCheckbox) { + $.error( + "'hideCheckbox' node option was removed in v2.23.0: use 'checkbox: false'" + ); + } + // node.data += obj.data + if (obj.data) { + $.extend(this.data, obj.data); + } + // Copy all other attributes to this.data.NAME + for (name in obj) { + if ( + !NODE_ATTR_MAP[name] && + (this.tree.options.copyFunctionsToData || + !_isFunction(obj[name])) && + !NONE_NODE_DATA_MAP[name] + ) { + // node.data.NAME = obj.NAME + this.data[name] = obj[name]; + } + } + + // Fix missing key + if (this.key == null) { + // test for null OR undefined + if (this.tree.options.defaultKey) { + this.key = "" + this.tree.options.defaultKey(this); + _assert(this.key, "defaultKey() must return a unique key"); + } else { + this.key = "_" + FT._nextNodeKey++; + } + } else { + this.key = "" + this.key; // Convert to string (#217) + } + + // Fix tree.activeNode + // TODO: not elegant: we use obj.active as marker to set tree.activeNode + // when loading from a dictionary. + if (obj.active) { + _assert( + this.tree.activeNode === null, + "only one active node allowed" + ); + this.tree.activeNode = this; + } + if (obj.selected) { + // #186 + this.tree.lastSelectedNode = this; + } + // TODO: handle obj.focus = true + + // Create child nodes + cl = obj.children; + if (cl) { + if (cl.length) { + this._setChildren(cl); + } else { + // if an empty array was passed for a lazy node, keep it, in order to mark it 'loaded' + this.children = this.lazy ? [] : null; + } + } else { + this.children = null; + } + // Add to key/ref map (except for root node) + // if( parent ) { + this.tree._callHook("treeRegisterNode", this.tree, true, this); + // } + } + + FancytreeNode.prototype = /** @lends FancytreeNode# */ { + /* Return the direct child FancytreeNode with a given key, index. */ + _findDirectChild: function (ptr) { + var i, + l, + cl = this.children; + + if (cl) { + if (typeof ptr === "string") { + for (i = 0, l = cl.length; i < l; i++) { + if (cl[i].key === ptr) { + return cl[i]; + } + } + } else if (typeof ptr === "number") { + return this.children[ptr]; + } else if (ptr.parent === this) { + return ptr; + } + } + return null; + }, + // TODO: activate() + // TODO: activateSilently() + /* Internal helper called in recursive addChildren sequence.*/ + _setChildren: function (children) { + _assert( + children && (!this.children || this.children.length === 0), + "only init supported" + ); + this.children = []; + for (var i = 0, l = children.length; i < l; i++) { + this.children.push(new FancytreeNode(this, children[i])); + } + this.tree._callHook( + "treeStructureChanged", + this.tree, + "setChildren" + ); + }, + /** + * Append (or insert) a list of child nodes. + * + * @param {NodeData[]} children array of child node definitions (also single child accepted) + * @param {FancytreeNode | string | Integer} [insertBefore] child node (or key or index of such). + * If omitted, the new children are appended. + * @returns {FancytreeNode} first child added + * + * @see FancytreeNode#applyPatch + */ + addChildren: function (children, insertBefore) { + var i, + l, + pos, + origFirstChild = this.getFirstChild(), + origLastChild = this.getLastChild(), + firstNode = null, + nodeList = []; + + if ($.isPlainObject(children)) { + children = [children]; + } + if (!this.children) { + this.children = []; + } + for (i = 0, l = children.length; i < l; i++) { + nodeList.push(new FancytreeNode(this, children[i])); + } + firstNode = nodeList[0]; + if (insertBefore == null) { + this.children = this.children.concat(nodeList); + } else { + // Returns null if insertBefore is not a direct child: + insertBefore = this._findDirectChild(insertBefore); + pos = $.inArray(insertBefore, this.children); + _assert(pos >= 0, "insertBefore must be an existing child"); + // insert nodeList after children[pos] + this.children.splice.apply( + this.children, + [pos, 0].concat(nodeList) + ); + } + if (origFirstChild && !insertBefore) { + // #708: Fast path -- don't render every child of root, just the new ones! + // #723, #729: but only if it's appended to an existing child list + for (i = 0, l = nodeList.length; i < l; i++) { + nodeList[i].render(); // New nodes were never rendered before + } + // Adjust classes where status may have changed + // Has a first child + if (origFirstChild !== this.getFirstChild()) { + // Different first child -- recompute classes + origFirstChild.renderStatus(); + } + if (origLastChild !== this.getLastChild()) { + // Different last child -- recompute classes + origLastChild.renderStatus(); + } + } else if (!this.parent || this.parent.ul || this.tr) { + // render if the parent was rendered (or this is a root node) + this.render(); + } + if (this.tree.options.selectMode === 3) { + this.fixSelection3FromEndNodes(); + } + this.triggerModifyChild( + "add", + nodeList.length === 1 ? nodeList[0] : null + ); + return firstNode; + }, + /** + * Add class to node's span tag and to .extraClasses. + * + * @param {string} className class name + * + * @since 2.17 + */ + addClass: function (className) { + return this.toggleClass(className, true); + }, + /** + * Append or prepend a node, or append a child node. + * + * This a convenience function that calls addChildren() + * + * @param {NodeData} node node definition + * @param {string} [mode=child] 'before', 'after', 'firstChild', or 'child' ('over' is a synonym for 'child') + * @returns {FancytreeNode} new node + */ + addNode: function (node, mode) { + if (mode === undefined || mode === "over") { + mode = "child"; + } + switch (mode) { + case "after": + return this.getParent().addChildren( + node, + this.getNextSibling() + ); + case "before": + return this.getParent().addChildren(node, this); + case "firstChild": + // Insert before the first child if any + var insertBefore = this.children ? this.children[0] : null; + return this.addChildren(node, insertBefore); + case "child": + case "over": + return this.addChildren(node); + } + _assert(false, "Invalid mode: " + mode); + }, + /**Add child status nodes that indicate 'More...', etc. + * + * This also maintains the node's `partload` property. + * @param {boolean|object} node optional node definition. Pass `false` to remove all paging nodes. + * @param {string} [mode='child'] 'child'|firstChild' + * @since 2.15 + */ + addPagingNode: function (node, mode) { + var i, n; + + mode = mode || "child"; + if (node === false) { + for (i = this.children.length - 1; i >= 0; i--) { + n = this.children[i]; + if (n.statusNodeType === "paging") { + this.removeChild(n); + } + } + this.partload = false; + return; + } + node = $.extend( + { + title: this.tree.options.strings.moreData, + statusNodeType: "paging", + icon: false, + }, + node + ); + this.partload = true; + return this.addNode(node, mode); + }, + /** + * Append new node after this. + * + * This a convenience function that calls addNode(node, 'after') + * + * @param {NodeData} node node definition + * @returns {FancytreeNode} new node + */ + appendSibling: function (node) { + return this.addNode(node, "after"); + }, + /** + * (experimental) Apply a modification (or navigation) operation. + * + * @param {string} cmd + * @param {object} [opts] + * @see Fancytree#applyCommand + * @since 2.32 + */ + applyCommand: function (cmd, opts) { + return this.tree.applyCommand(cmd, this, opts); + }, + /** + * Modify existing child nodes. + * + * @param {NodePatch} patch + * @returns {$.Promise} + * @see FancytreeNode#addChildren + */ + applyPatch: function (patch) { + // patch [key, null] means 'remove' + if (patch === null) { + this.remove(); + return _getResolvedPromise(this); + } + // TODO: make sure that root node is not collapsed or modified + // copy (most) attributes to node.ATTR or node.data.ATTR + var name, + promise, + v, + IGNORE_MAP = { children: true, expanded: true, parent: true }; // TODO: should be global + + for (name in patch) { + if (_hasProp(patch, name)) { + v = patch[name]; + if (!IGNORE_MAP[name] && !_isFunction(v)) { + if (NODE_ATTR_MAP[name]) { + this[name] = v; + } else { + this.data[name] = v; + } + } + } + } + // Remove and/or create children + if (_hasProp(patch, "children")) { + this.removeChildren(); + if (patch.children) { + // only if not null and not empty list + // TODO: addChildren instead? + this._setChildren(patch.children); + } + // TODO: how can we APPEND or INSERT child nodes? + } + if (this.isVisible()) { + this.renderTitle(); + this.renderStatus(); + } + // Expand collapse (final step, since this may be async) + if (_hasProp(patch, "expanded")) { + promise = this.setExpanded(patch.expanded); + } else { + promise = _getResolvedPromise(this); + } + return promise; + }, + /** Collapse all sibling nodes. + * @returns {$.Promise} + */ + collapseSiblings: function () { + return this.tree._callHook("nodeCollapseSiblings", this); + }, + /** Copy this node as sibling or child of `node`. + * + * @param {FancytreeNode} node source node + * @param {string} [mode=child] 'before' | 'after' | 'child' + * @param {Function} [map] callback function(NodeData, FancytreeNode) that could modify the new node + * @returns {FancytreeNode} new + */ + copyTo: function (node, mode, map) { + return node.addNode(this.toDict(true, map), mode); + }, + /** Count direct and indirect children. + * + * @param {boolean} [deep=true] pass 'false' to only count direct children + * @returns {int} number of child nodes + */ + countChildren: function (deep) { + var cl = this.children, + i, + l, + n; + if (!cl) { + return 0; + } + n = cl.length; + if (deep !== false) { + for (i = 0, l = n; i < l; i++) { + n += cl[i].countChildren(); + } + } + return n; + }, + // TODO: deactivate() + /** Write to browser console if debugLevel >= 4 (prepending node info) + * + * @param {*} msg string or object or array of such + */ + debug: function (msg) { + if (this.tree.options.debugLevel >= 4) { + Array.prototype.unshift.call(arguments, this.toString()); + consoleApply("log", arguments); + } + }, + /** Deprecated. + * @deprecated since 2014-02-16. Use resetLazy() instead. + */ + discard: function () { + this.warn( + "FancytreeNode.discard() is deprecated since 2014-02-16. Use .resetLazy() instead." + ); + return this.resetLazy(); + }, + /** Remove DOM elements for all descendents. May be called on .collapse event + * to keep the DOM small. + * @param {boolean} [includeSelf=false] + */ + discardMarkup: function (includeSelf) { + var fn = includeSelf ? "nodeRemoveMarkup" : "nodeRemoveChildMarkup"; + this.tree._callHook(fn, this); + }, + /** Write error to browser console if debugLevel >= 1 (prepending tree info) + * + * @param {*} msg string or object or array of such + */ + error: function (msg) { + if (this.tree.options.debugLevel >= 1) { + Array.prototype.unshift.call(arguments, this.toString()); + consoleApply("error", arguments); + } + }, + /**Find all nodes that match condition (excluding self). + * + * @param {string | function(node)} match title string to search for, or a + * callback function that returns `true` if a node is matched. + * @returns {FancytreeNode[]} array of nodes (may be empty) + */ + findAll: function (match) { + match = _isFunction(match) ? match : _makeNodeTitleMatcher(match); + var res = []; + this.visit(function (n) { + if (match(n)) { + res.push(n); + } + }); + return res; + }, + /**Find first node that matches condition (excluding self). + * + * @param {string | function(node)} match title string to search for, or a + * callback function that returns `true` if a node is matched. + * @returns {FancytreeNode} matching node or null + * @see FancytreeNode#findAll + */ + findFirst: function (match) { + match = _isFunction(match) ? match : _makeNodeTitleMatcher(match); + var res = null; + this.visit(function (n) { + if (match(n)) { + res = n; + return false; + } + }); + return res; + }, + /** Find a node relative to self. + * + * @param {number|string} where The keyCode that would normally trigger this move, + * or a keyword ('down', 'first', 'last', 'left', 'parent', 'right', 'up'). + * @returns {FancytreeNode} + * @since v2.31 + */ + findRelatedNode: function (where, includeHidden) { + return this.tree.findRelatedNode(this, where, includeHidden); + }, + /* Apply selection state (internal use only) */ + _changeSelectStatusAttrs: function (state) { + var changed = false, + opts = this.tree.options, + unselectable = FT.evalOption( + "unselectable", + this, + this, + opts, + false + ), + unselectableStatus = FT.evalOption( + "unselectableStatus", + this, + this, + opts, + undefined + ); + + if (unselectable && unselectableStatus != null) { + state = unselectableStatus; + } + switch (state) { + case false: + changed = this.selected || this.partsel; + this.selected = false; + this.partsel = false; + break; + case true: + changed = !this.selected || !this.partsel; + this.selected = true; + this.partsel = true; + break; + case undefined: + changed = this.selected || !this.partsel; + this.selected = false; + this.partsel = true; + break; + default: + _assert(false, "invalid state: " + state); + } + // this.debug("fixSelection3AfterLoad() _changeSelectStatusAttrs()", state, changed); + if (changed) { + this.renderStatus(); + } + return changed; + }, + /** + * Fix selection status, after this node was (de)selected in multi-hier mode. + * This includes (de)selecting all children. + */ + fixSelection3AfterClick: function (callOpts) { + var flag = this.isSelected(); + + // this.debug("fixSelection3AfterClick()"); + + this.visit(function (node) { + node._changeSelectStatusAttrs(flag); + if (node.radiogroup) { + // #931: don't (de)select this branch + return "skip"; + } + }); + this.fixSelection3FromEndNodes(callOpts); + }, + /** + * Fix selection status for multi-hier mode. + * Only end-nodes are considered to update the descendants branch and parents. + * Should be called after this node has loaded new children or after + * children have been modified using the API. + */ + fixSelection3FromEndNodes: function (callOpts) { + var opts = this.tree.options; + + // this.debug("fixSelection3FromEndNodes()"); + _assert(opts.selectMode === 3, "expected selectMode 3"); + + // Visit all end nodes and adjust their parent's `selected` and `partsel` + // attributes. Return selection state true, false, or undefined. + function _walk(node) { + var i, + l, + child, + s, + state, + allSelected, + someSelected, + unselIgnore, + unselState, + children = node.children; + + if (children && children.length) { + // check all children recursively + allSelected = true; + someSelected = false; + + for (i = 0, l = children.length; i < l; i++) { + child = children[i]; + // the selection state of a node is not relevant; we need the end-nodes + s = _walk(child); + // if( !child.unselectableIgnore ) { + unselIgnore = FT.evalOption( + "unselectableIgnore", + child, + child, + opts, + false + ); + if (!unselIgnore) { + if (s !== false) { + someSelected = true; + } + if (s !== true) { + allSelected = false; + } + } + } + // eslint-disable-next-line no-nested-ternary + state = allSelected + ? true + : someSelected + ? undefined + : false; + } else { + // This is an end-node: simply report the status + unselState = FT.evalOption( + "unselectableStatus", + node, + node, + opts, + undefined + ); + state = unselState == null ? !!node.selected : !!unselState; + } + // #939: Keep a `partsel` flag that was explicitly set on a lazy node + if ( + node.partsel && + !node.selected && + node.lazy && + node.children == null + ) { + state = undefined; + } + node._changeSelectStatusAttrs(state); + return state; + } + _walk(this); + + // Update parent's state + this.visitParents(function (node) { + var i, + l, + child, + state, + unselIgnore, + unselState, + children = node.children, + allSelected = true, + someSelected = false; + + for (i = 0, l = children.length; i < l; i++) { + child = children[i]; + unselIgnore = FT.evalOption( + "unselectableIgnore", + child, + child, + opts, + false + ); + if (!unselIgnore) { + unselState = FT.evalOption( + "unselectableStatus", + child, + child, + opts, + undefined + ); + state = + unselState == null + ? !!child.selected + : !!unselState; + // When fixing the parents, we trust the sibling status (i.e. + // we don't recurse) + if (state || child.partsel) { + someSelected = true; + } + if (!state) { + allSelected = false; + } + } + } + // eslint-disable-next-line no-nested-ternary + state = allSelected ? true : someSelected ? undefined : false; + node._changeSelectStatusAttrs(state); + }); + }, + // TODO: focus() + /** + * Update node data. If dict contains 'children', then also replace + * the hole sub tree. + * @param {NodeData} dict + * + * @see FancytreeNode#addChildren + * @see FancytreeNode#applyPatch + */ + fromDict: function (dict) { + // copy all other attributes to this.data.xxx + for (var name in dict) { + if (NODE_ATTR_MAP[name]) { + // node.NAME = dict.NAME + this[name] = dict[name]; + } else if (name === "data") { + // node.data += dict.data + $.extend(this.data, dict.data); + } else if ( + !_isFunction(dict[name]) && + !NONE_NODE_DATA_MAP[name] + ) { + // node.data.NAME = dict.NAME + this.data[name] = dict[name]; + } + } + if (dict.children) { + // recursively set children and render + this.removeChildren(); + this.addChildren(dict.children); + } + this.renderTitle(); + /* + var children = dict.children; + if(children === undefined){ + this.data = $.extend(this.data, dict); + this.render(); + return; + } + dict = $.extend({}, dict); + dict.children = undefined; + this.data = $.extend(this.data, dict); + this.removeChildren(); + this.addChild(children); + */ + }, + /** Return the list of child nodes (undefined for unexpanded lazy nodes). + * @returns {FancytreeNode[] | undefined} + */ + getChildren: function () { + if (this.hasChildren() === undefined) { + // TODO: only required for lazy nodes? + return undefined; // Lazy node: unloaded, currently loading, or load error + } + return this.children; + }, + /** Return the first child node or null. + * @returns {FancytreeNode | null} + */ + getFirstChild: function () { + return this.children ? this.children[0] : null; + }, + /** Return the 0-based child index. + * @returns {int} + */ + getIndex: function () { + // return this.parent.children.indexOf(this); + return $.inArray(this, this.parent.children); // indexOf doesn't work in IE7 + }, + /** Return the hierarchical child index (1-based, e.g. '3.2.4'). + * @param {string} [separator="."] + * @param {int} [digits=1] + * @returns {string} + */ + getIndexHier: function (separator, digits) { + separator = separator || "."; + var s, + res = []; + $.each(this.getParentList(false, true), function (i, o) { + s = "" + (o.getIndex() + 1); + if (digits) { + // prepend leading zeroes + s = ("0000000" + s).substr(-digits); + } + res.push(s); + }); + return res.join(separator); + }, + /** Return the parent keys separated by options.keyPathSeparator, e.g. "/id_1/id_17/id_32". + * + * (Unlike `node.getPath()`, this method prepends a "/" and inverts the first argument.) + * + * @see FancytreeNode#getPath + * @param {boolean} [excludeSelf=false] + * @returns {string} + */ + getKeyPath: function (excludeSelf) { + var sep = this.tree.options.keyPathSeparator; + + return sep + this.getPath(!excludeSelf, "key", sep); + }, + /** Return the last child of this node or null. + * @returns {FancytreeNode | null} + */ + getLastChild: function () { + return this.children + ? this.children[this.children.length - 1] + : null; + }, + /** Return node depth. 0: System root node, 1: visible top-level node, 2: first sub-level, ... . + * @returns {int} + */ + getLevel: function () { + var level = 0, + dtn = this.parent; + while (dtn) { + level++; + dtn = dtn.parent; + } + return level; + }, + /** Return the successor node (under the same parent) or null. + * @returns {FancytreeNode | null} + */ + getNextSibling: function () { + // TODO: use indexOf, if available: (not in IE6) + if (this.parent) { + var i, + l, + ac = this.parent.children; + + for (i = 0, l = ac.length - 1; i < l; i++) { + // up to length-2, so next(last) = null + if (ac[i] === this) { + return ac[i + 1]; + } + } + } + return null; + }, + /** Return the parent node (null for the system root node). + * @returns {FancytreeNode | null} + */ + getParent: function () { + // TODO: return null for top-level nodes? + return this.parent; + }, + /** Return an array of all parent nodes (top-down). + * @param {boolean} [includeRoot=false] Include the invisible system root node. + * @param {boolean} [includeSelf=false] Include the node itself. + * @returns {FancytreeNode[]} + */ + getParentList: function (includeRoot, includeSelf) { + var l = [], + dtn = includeSelf ? this : this.parent; + while (dtn) { + if (includeRoot || dtn.parent) { + l.unshift(dtn); + } + dtn = dtn.parent; + } + return l; + }, + /** Return a string representing the hierachical node path, e.g. "a/b/c". + * @param {boolean} [includeSelf=true] + * @param {string | function} [part="title"] node property name or callback + * @param {string} [separator="/"] + * @returns {string} + * @since v2.31 + */ + getPath: function (includeSelf, part, separator) { + includeSelf = includeSelf !== false; + part = part || "title"; + separator = separator || "/"; + + var val, + path = [], + isFunc = _isFunction(part); + + this.visitParents(function (n) { + if (n.parent) { + val = isFunc ? part(n) : n[part]; + path.unshift(val); + } + }, includeSelf); + return path.join(separator); + }, + /** Return the predecessor node (under the same parent) or null. + * @returns {FancytreeNode | null} + */ + getPrevSibling: function () { + if (this.parent) { + var i, + l, + ac = this.parent.children; + + for (i = 1, l = ac.length; i < l; i++) { + // start with 1, so prev(first) = null + if (ac[i] === this) { + return ac[i - 1]; + } + } + } + return null; + }, + /** + * Return an array of selected descendant nodes. + * @param {boolean} [stopOnParents=false] only return the topmost selected + * node (useful with selectMode 3) + * @returns {FancytreeNode[]} + */ + getSelectedNodes: function (stopOnParents) { + var nodeList = []; + this.visit(function (node) { + if (node.selected) { + nodeList.push(node); + if (stopOnParents === true) { + return "skip"; // stop processing this branch + } + } + }); + return nodeList; + }, + /** Return true if node has children. Return undefined if not sure, i.e. the node is lazy and not yet loaded). + * @returns {boolean | undefined} + */ + hasChildren: function () { + if (this.lazy) { + if (this.children == null) { + // null or undefined: Not yet loaded + return undefined; + } else if (this.children.length === 0) { + // Loaded, but response was empty + return false; + } else if ( + this.children.length === 1 && + this.children[0].isStatusNode() + ) { + // Currently loading or load error + return undefined; + } + return true; + } + return !!(this.children && this.children.length); + }, + /** + * Return true if node has `className` defined in .extraClasses. + * + * @param {string} className class name (separate multiple classes by space) + * @returns {boolean} + * + * @since 2.32 + */ + hasClass: function (className) { + return ( + (" " + (this.extraClasses || "") + " ").indexOf( + " " + className + " " + ) >= 0 + ); + }, + /** Return true if node has keyboard focus. + * @returns {boolean} + */ + hasFocus: function () { + return this.tree.hasFocus() && this.tree.focusNode === this; + }, + /** Write to browser console if debugLevel >= 3 (prepending node info) + * + * @param {*} msg string or object or array of such + */ + info: function (msg) { + if (this.tree.options.debugLevel >= 3) { + Array.prototype.unshift.call(arguments, this.toString()); + consoleApply("info", arguments); + } + }, + /** Return true if node is active (see also FancytreeNode#isSelected). + * @returns {boolean} + */ + isActive: function () { + return this.tree.activeNode === this; + }, + /** Return true if node is vertically below `otherNode`, i.e. rendered in a subsequent row. + * @param {FancytreeNode} otherNode + * @returns {boolean} + * @since 2.28 + */ + isBelowOf: function (otherNode) { + return this.getIndexHier(".", 5) > otherNode.getIndexHier(".", 5); + }, + /** Return true if node is a direct child of otherNode. + * @param {FancytreeNode} otherNode + * @returns {boolean} + */ + isChildOf: function (otherNode) { + return this.parent && this.parent === otherNode; + }, + /** Return true, if node is a direct or indirect sub node of otherNode. + * @param {FancytreeNode} otherNode + * @returns {boolean} + */ + isDescendantOf: function (otherNode) { + if (!otherNode || otherNode.tree !== this.tree) { + return false; + } + var p = this.parent; + while (p) { + if (p === otherNode) { + return true; + } + if (p === p.parent) { + $.error("Recursive parent link: " + p); + } + p = p.parent; + } + return false; + }, + /** Return true if node is expanded. + * @returns {boolean} + */ + isExpanded: function () { + return !!this.expanded; + }, + /** Return true if node is the first node of its parent's children. + * @returns {boolean} + */ + isFirstSibling: function () { + var p = this.parent; + return !p || p.children[0] === this; + }, + /** Return true if node is a folder, i.e. has the node.folder attribute set. + * @returns {boolean} + */ + isFolder: function () { + return !!this.folder; + }, + /** Return true if node is the last node of its parent's children. + * @returns {boolean} + */ + isLastSibling: function () { + var p = this.parent; + return !p || p.children[p.children.length - 1] === this; + }, + /** Return true if node is lazy (even if data was already loaded) + * @returns {boolean} + */ + isLazy: function () { + return !!this.lazy; + }, + /** Return true if node is lazy and loaded. For non-lazy nodes always return true. + * @returns {boolean} + */ + isLoaded: function () { + return !this.lazy || this.hasChildren() !== undefined; // Also checks if the only child is a status node + }, + /** Return true if children are currently beeing loaded, i.e. a Ajax request is pending. + * @returns {boolean} + */ + isLoading: function () { + return !!this._isLoading; + }, + /* + * @deprecated since v2.4.0: Use isRootNode() instead + */ + isRoot: function () { + return this.isRootNode(); + }, + /** Return true if node is partially selected (tri-state). + * @returns {boolean} + * @since 2.23 + */ + isPartsel: function () { + return !this.selected && !!this.partsel; + }, + /** (experimental) Return true if this is partially loaded. + * @returns {boolean} + * @since 2.15 + */ + isPartload: function () { + return !!this.partload; + }, + /** Return true if this is the (invisible) system root node. + * @returns {boolean} + * @since 2.4 + */ + isRootNode: function () { + return this.tree.rootNode === this; + }, + /** Return true if node is selected, i.e. has a checkmark set (see also FancytreeNode#isActive). + * @returns {boolean} + */ + isSelected: function () { + return !!this.selected; + }, + /** Return true if this node is a temporarily generated system node like + * 'loading', 'paging', or 'error' (node.statusNodeType contains the type). + * @returns {boolean} + */ + isStatusNode: function () { + return !!this.statusNodeType; + }, + /** Return true if this node is a status node of type 'paging'. + * @returns {boolean} + * @since 2.15 + */ + isPagingNode: function () { + return this.statusNodeType === "paging"; + }, + /** Return true if this a top level node, i.e. a direct child of the (invisible) system root node. + * @returns {boolean} + * @since 2.4 + */ + isTopLevel: function () { + return this.tree.rootNode === this.parent; + }, + /** Return true if node is lazy and not yet loaded. For non-lazy nodes always return false. + * @returns {boolean} + */ + isUndefined: function () { + return this.hasChildren() === undefined; // also checks if the only child is a status node + }, + /** Return true if all parent nodes are expanded. Note: this does not check + * whether the node is scrolled into the visible part of the screen. + * @returns {boolean} + */ + isVisible: function () { + var i, + l, + n, + hasFilter = this.tree.enableFilter, + parents = this.getParentList(false, false); + + // TODO: check $(n.span).is(":visible") + // i.e. return false for nodes (but not parents) that are hidden + // by a filter + if (hasFilter && !this.match && !this.subMatchCount) { + // this.debug( "isVisible: HIDDEN (" + hasFilter + ", " + this.match + ", " + this.match + ")" ); + return false; + } + + for (i = 0, l = parents.length; i < l; i++) { + n = parents[i]; + + if (!n.expanded) { + // this.debug("isVisible: HIDDEN (parent collapsed)"); + return false; + } + // if (hasFilter && !n.match && !n.subMatchCount) { + // this.debug("isVisible: HIDDEN (" + hasFilter + ", " + this.match + ", " + this.match + ")"); + // return false; + // } + } + // this.debug("isVisible: VISIBLE"); + return true; + }, + /** Deprecated. + * @deprecated since 2014-02-16: use load() instead. + */ + lazyLoad: function (discard) { + $.error( + "FancytreeNode.lazyLoad() is deprecated since 2014-02-16. Use .load() instead." + ); + }, + /** + * Load all children of a lazy node if neccessary. The <i>expanded</i> state is maintained. + * @param {boolean} [forceReload=false] Pass true to discard any existing nodes before. Otherwise this method does nothing if the node was already loaded. + * @returns {$.Promise} + */ + load: function (forceReload) { + var res, + source, + self = this, + wasExpanded = this.isExpanded(); + + _assert(this.isLazy(), "load() requires a lazy node"); + // _assert( forceReload || this.isUndefined(), "Pass forceReload=true to re-load a lazy node" ); + if (!forceReload && !this.isUndefined()) { + return _getResolvedPromise(this); + } + if (this.isLoaded()) { + this.resetLazy(); // also collapses + } + // This method is also called by setExpanded() and loadKeyPath(), so we + // have to avoid recursion. + source = this.tree._triggerNodeEvent("lazyLoad", this); + if (source === false) { + // #69 + return _getResolvedPromise(this); + } + _assert( + typeof source !== "boolean", + "lazyLoad event must return source in data.result" + ); + res = this.tree._callHook("nodeLoadChildren", this, source); + if (wasExpanded) { + this.expanded = true; + res.always(function () { + self.render(); + }); + } else { + res.always(function () { + self.renderStatus(); // fix expander icon to 'loaded' + }); + } + return res; + }, + /** Expand all parents and optionally scroll into visible area as neccessary. + * Promise is resolved, when lazy loading and animations are done. + * @param {object} [opts] passed to `setExpanded()`. + * Defaults to {noAnimation: false, noEvents: false, scrollIntoView: true} + * @returns {$.Promise} + */ + makeVisible: function (opts) { + var i, + self = this, + deferreds = [], + dfd = new $.Deferred(), + parents = this.getParentList(false, false), + len = parents.length, + effects = !(opts && opts.noAnimation === true), + scroll = !(opts && opts.scrollIntoView === false); + + // Expand bottom-up, so only the top node is animated + for (i = len - 1; i >= 0; i--) { + // self.debug("pushexpand" + parents[i]); + deferreds.push(parents[i].setExpanded(true, opts)); + } + $.when.apply($, deferreds).done(function () { + // All expands have finished + // self.debug("expand DONE", scroll); + if (scroll) { + self.scrollIntoView(effects).done(function () { + // self.debug("scroll DONE"); + dfd.resolve(); + }); + } else { + dfd.resolve(); + } + }); + return dfd.promise(); + }, + /** Move this node to targetNode. + * @param {FancytreeNode} targetNode + * @param {string} mode <pre> + * 'child': append this node as last child of targetNode. + * This is the default. To be compatble with the D'n'd + * hitMode, we also accept 'over'. + * 'firstChild': add this node as first child of targetNode. + * 'before': add this node as sibling before targetNode. + * 'after': add this node as sibling after targetNode.</pre> + * @param {function} [map] optional callback(FancytreeNode) to allow modifcations + */ + moveTo: function (targetNode, mode, map) { + if (mode === undefined || mode === "over") { + mode = "child"; + } else if (mode === "firstChild") { + if (targetNode.children && targetNode.children.length) { + mode = "before"; + targetNode = targetNode.children[0]; + } else { + mode = "child"; + } + } + var pos, + tree = this.tree, + prevParent = this.parent, + targetParent = + mode === "child" ? targetNode : targetNode.parent; + + if (this === targetNode) { + return; + } else if (!this.parent) { + $.error("Cannot move system root"); + } else if (targetParent.isDescendantOf(this)) { + $.error("Cannot move a node to its own descendant"); + } + if (targetParent !== prevParent) { + prevParent.triggerModifyChild("remove", this); + } + // Unlink this node from current parent + if (this.parent.children.length === 1) { + if (this.parent === targetParent) { + return; // #258 + } + this.parent.children = this.parent.lazy ? [] : null; + this.parent.expanded = false; + } else { + pos = $.inArray(this, this.parent.children); + _assert(pos >= 0, "invalid source parent"); + this.parent.children.splice(pos, 1); + } + // Remove from source DOM parent + // if(this.parent.ul){ + // this.parent.ul.removeChild(this.li); + // } + + // Insert this node to target parent's child list + this.parent = targetParent; + if (targetParent.hasChildren()) { + switch (mode) { + case "child": + // Append to existing target children + targetParent.children.push(this); + break; + case "before": + // Insert this node before target node + pos = $.inArray(targetNode, targetParent.children); + _assert(pos >= 0, "invalid target parent"); + targetParent.children.splice(pos, 0, this); + break; + case "after": + // Insert this node after target node + pos = $.inArray(targetNode, targetParent.children); + _assert(pos >= 0, "invalid target parent"); + targetParent.children.splice(pos + 1, 0, this); + break; + default: + $.error("Invalid mode " + mode); + } + } else { + targetParent.children = [this]; + } + // Parent has no <ul> tag yet: + // if( !targetParent.ul ) { + // // This is the parent's first child: create UL tag + // // (Hidden, because it will be + // targetParent.ul = document.createElement("ul"); + // targetParent.ul.style.display = "none"; + // targetParent.li.appendChild(targetParent.ul); + // } + // // Issue 319: Add to target DOM parent (only if node was already rendered(expanded)) + // if(this.li){ + // targetParent.ul.appendChild(this.li); + // } + + // Let caller modify the nodes + if (map) { + targetNode.visit(map, true); + } + if (targetParent === prevParent) { + targetParent.triggerModifyChild("move", this); + } else { + // prevParent.triggerModifyChild("remove", this); + targetParent.triggerModifyChild("add", this); + } + // Handle cross-tree moves + if (tree !== targetNode.tree) { + // Fix node.tree for all source nodes + // _assert(false, "Cross-tree move is not yet implemented."); + this.warn("Cross-tree moveTo is experimental!"); + this.visit(function (n) { + // TODO: fix selection state and activation, ... + n.tree = targetNode.tree; + }, true); + } + + // A collaposed node won't re-render children, so we have to remove it manually + // if( !targetParent.expanded ){ + // prevParent.ul.removeChild(this.li); + // } + tree._callHook("treeStructureChanged", tree, "moveTo"); + + // Update HTML markup + if (!prevParent.isDescendantOf(targetParent)) { + prevParent.render(); + } + if ( + !targetParent.isDescendantOf(prevParent) && + targetParent !== prevParent + ) { + targetParent.render(); + } + // TODO: fix selection state + // TODO: fix active state + + /* + var tree = this.tree; + var opts = tree.options; + var pers = tree.persistence; + + // Always expand, if it's below minExpandLevel + // tree.logDebug ("%s._addChildNode(%o), l=%o", this, ftnode, ftnode.getLevel()); + if ( opts.minExpandLevel >= ftnode.getLevel() ) { + // tree.logDebug ("Force expand for %o", ftnode); + this.bExpanded = true; + } + + // In multi-hier mode, update the parents selection state + // DT issue #82: only if not initializing, because the children may not exist yet + // if( !ftnode.data.isStatusNode() && opts.selectMode==3 && !isInitializing ) + // ftnode._fixSelectionState(); + + // In multi-hier mode, update the parents selection state + if( ftnode.bSelected && opts.selectMode==3 ) { + var p = this; + while( p ) { + if( !p.hasSubSel ) + p._setSubSel(true); + p = p.parent; + } + } + // render this node and the new child + if ( tree.bEnableUpdate ) + this.render(); + return ftnode; + */ + }, + /** Set focus relative to this node and optionally activate. + * + * 'left' collapses the node if it is expanded, or move to the parent + * otherwise. + * 'right' expands the node if it is collapsed, or move to the first + * child otherwise. + * + * @param {string|number} where 'down', 'first', 'last', 'left', 'parent', 'right', or 'up'. + * (Alternatively the keyCode that would normally trigger this move, + * e.g. `$.ui.keyCode.LEFT` = 'left'. + * @param {boolean} [activate=true] + * @returns {$.Promise} + */ + navigate: function (where, activate) { + var node, + KC = $.ui.keyCode; + + // Handle optional expand/collapse action for LEFT/RIGHT + switch (where) { + case "left": + case KC.LEFT: + if (this.expanded) { + return this.setExpanded(false); + } + break; + case "right": + case KC.RIGHT: + if (!this.expanded && (this.children || this.lazy)) { + return this.setExpanded(); + } + break; + } + // Otherwise activate or focus the related node + node = this.findRelatedNode(where); + if (node) { + // setFocus/setActive will scroll later (if autoScroll is specified) + try { + node.makeVisible({ scrollIntoView: false }); + } catch (e) {} // #272 + if (activate === false) { + node.setFocus(); + return _getResolvedPromise(); + } + return node.setActive(); + } + this.warn("Could not find related node '" + where + "'."); + return _getResolvedPromise(); + }, + /** + * Remove this node (not allowed for system root). + */ + remove: function () { + return this.parent.removeChild(this); + }, + /** + * Remove childNode from list of direct children. + * @param {FancytreeNode} childNode + */ + removeChild: function (childNode) { + return this.tree._callHook("nodeRemoveChild", this, childNode); + }, + /** + * Remove all child nodes and descendents. This converts the node into a leaf.<br> + * If this was a lazy node, it is still considered 'loaded'; call node.resetLazy() + * in order to trigger lazyLoad on next expand. + */ + removeChildren: function () { + return this.tree._callHook("nodeRemoveChildren", this); + }, + /** + * Remove class from node's span tag and .extraClasses. + * + * @param {string} className class name + * + * @since 2.17 + */ + removeClass: function (className) { + return this.toggleClass(className, false); + }, + /** + * This method renders and updates all HTML markup that is required + * to display this node in its current state.<br> + * Note: + * <ul> + * <li>It should only be neccessary to call this method after the node object + * was modified by direct access to its properties, because the common + * API methods (node.setTitle(), moveTo(), addChildren(), remove(), ...) + * already handle this. + * <li> {@link FancytreeNode#renderTitle} and {@link FancytreeNode#renderStatus} + * are implied. If changes are more local, calling only renderTitle() or + * renderStatus() may be sufficient and faster. + * </ul> + * + * @param {boolean} [force=false] re-render, even if html markup was already created + * @param {boolean} [deep=false] also render all descendants, even if parent is collapsed + */ + render: function (force, deep) { + return this.tree._callHook("nodeRender", this, force, deep); + }, + /** Create HTML markup for the node's outer `<span>` (expander, checkbox, icon, and title). + * Implies {@link FancytreeNode#renderStatus}. + * @see Fancytree_Hooks#nodeRenderTitle + */ + renderTitle: function () { + return this.tree._callHook("nodeRenderTitle", this); + }, + /** Update element's CSS classes according to node state. + * @see Fancytree_Hooks#nodeRenderStatus + */ + renderStatus: function () { + return this.tree._callHook("nodeRenderStatus", this); + }, + /** + * (experimental) Replace this node with `source`. + * (Currently only available for paging nodes.) + * @param {NodeData[]} source List of child node definitions + * @since 2.15 + */ + replaceWith: function (source) { + var res, + parent = this.parent, + pos = $.inArray(this, parent.children), + self = this; + + _assert( + this.isPagingNode(), + "replaceWith() currently requires a paging status node" + ); + + res = this.tree._callHook("nodeLoadChildren", this, source); + res.done(function (data) { + // New nodes are currently children of `this`. + var children = self.children; + // Prepend newly loaded child nodes to `this` + // Move new children after self + for (i = 0; i < children.length; i++) { + children[i].parent = parent; + } + parent.children.splice.apply( + parent.children, + [pos + 1, 0].concat(children) + ); + + // Remove self + self.children = null; + self.remove(); + // Redraw new nodes + parent.render(); + // TODO: set node.partload = false if this was tha last paging node? + // parent.addPagingNode(false); + }).fail(function () { + self.setExpanded(); + }); + return res; + // $.error("Not implemented: replaceWith()"); + }, + /** + * Remove all children, collapse, and set the lazy-flag, so that the lazyLoad + * event is triggered on next expand. + */ + resetLazy: function () { + this.removeChildren(); + this.expanded = false; + this.lazy = true; + this.children = undefined; + this.renderStatus(); + }, + /** Schedule activity for delayed execution (cancel any pending request). + * scheduleAction('cancel') will only cancel a pending request (if any). + * @param {string} mode + * @param {number} ms + */ + scheduleAction: function (mode, ms) { + if (this.tree.timer) { + clearTimeout(this.tree.timer); + this.tree.debug("clearTimeout(%o)", this.tree.timer); + } + this.tree.timer = null; + var self = this; // required for closures + switch (mode) { + case "cancel": + // Simply made sure that timer was cleared + break; + case "expand": + this.tree.timer = setTimeout(function () { + self.tree.debug("setTimeout: trigger expand"); + self.setExpanded(true); + }, ms); + break; + case "activate": + this.tree.timer = setTimeout(function () { + self.tree.debug("setTimeout: trigger activate"); + self.setActive(true); + }, ms); + break; + default: + $.error("Invalid mode " + mode); + } + // this.tree.debug("setTimeout(%s, %s): %s", mode, ms, this.tree.timer); + }, + /** + * + * @param {boolean | PlainObject} [effects=false] animation options. + * @param {object} [options=null] {topNode: null, effects: ..., parent: ...} this node will remain visible in + * any case, even if `this` is outside the scroll pane. + * @returns {$.Promise} + */ + scrollIntoView: function (effects, options) { + if (options !== undefined && _isNode(options)) { + throw Error( + "scrollIntoView() with 'topNode' option is deprecated since 2014-05-08. Use 'options.topNode' instead." + ); + } + // The scroll parent is typically the plain tree's <UL> container. + // For ext-table, we choose the nearest parent that has `position: relative` + // and `overflow` set. + // (This default can be overridden by the local or global `scrollParent` option.) + var opts = $.extend( + { + effects: + effects === true + ? { duration: 200, queue: false } + : effects, + scrollOfs: this.tree.options.scrollOfs, + scrollParent: this.tree.options.scrollParent, + topNode: null, + }, + options + ), + $scrollParent = opts.scrollParent, + $container = this.tree.$container, + overflowY = $container.css("overflow-y"); + + if (!$scrollParent) { + if (this.tree.tbody) { + $scrollParent = $container.scrollParent(); + } else if (overflowY === "scroll" || overflowY === "auto") { + $scrollParent = $container; + } else { + // #922 plain tree in a non-fixed-sized UL scrolls inside its parent + $scrollParent = $container.scrollParent(); + } + } else if (!$scrollParent.jquery) { + // Make sure we have a jQuery object + $scrollParent = $($scrollParent); + } + if ( + $scrollParent[0] === document || + $scrollParent[0] === document.body + ) { + // `document` may be returned by $().scrollParent(), if nothing is found, + // but would not work: (see #894) + this.debug( + "scrollIntoView(): normalizing scrollParent to 'window':", + $scrollParent[0] + ); + $scrollParent = $(window); + } + // eslint-disable-next-line one-var + var topNodeY, + nodeY, + horzScrollbarHeight, + containerOffsetTop, + dfd = new $.Deferred(), + self = this, + nodeHeight = $(this.span).height(), + topOfs = opts.scrollOfs.top || 0, + bottomOfs = opts.scrollOfs.bottom || 0, + containerHeight = $scrollParent.height(), + scrollTop = $scrollParent.scrollTop(), + $animateTarget = $scrollParent, + isParentWindow = $scrollParent[0] === window, + topNode = opts.topNode || null, + newScrollTop = null; + + // this.debug("scrollIntoView(), scrollTop=" + scrollTop, opts.scrollOfs); + // _assert($(this.span).is(":visible"), "scrollIntoView node is invisible"); // otherwise we cannot calc offsets + if (this.isRootNode() || !this.isVisible()) { + // We cannot calc offsets for hidden elements + this.info("scrollIntoView(): node is invisible."); + return _getResolvedPromise(); + } + if (isParentWindow) { + nodeY = $(this.span).offset().top; + topNodeY = + topNode && topNode.span ? $(topNode.span).offset().top : 0; + $animateTarget = $("html,body"); + } else { + _assert( + $scrollParent[0] !== document && + $scrollParent[0] !== document.body, + "scrollParent should be a simple element or `window`, not document or body." + ); + + containerOffsetTop = $scrollParent.offset().top; + nodeY = + $(this.span).offset().top - containerOffsetTop + scrollTop; // relative to scroll parent + topNodeY = topNode + ? $(topNode.span).offset().top - + containerOffsetTop + + scrollTop + : 0; + horzScrollbarHeight = Math.max( + 0, + $scrollParent.innerHeight() - $scrollParent[0].clientHeight + ); + containerHeight -= horzScrollbarHeight; + } + + // this.debug(" scrollIntoView(), nodeY=" + nodeY + ", containerHeight=" + containerHeight); + if (nodeY < scrollTop + topOfs) { + // Node is above visible container area + newScrollTop = nodeY - topOfs; + // this.debug(" scrollIntoView(), UPPER newScrollTop=" + newScrollTop); + } else if ( + nodeY + nodeHeight > + scrollTop + containerHeight - bottomOfs + ) { + newScrollTop = nodeY + nodeHeight - containerHeight + bottomOfs; + // this.debug(" scrollIntoView(), LOWER newScrollTop=" + newScrollTop); + // If a topNode was passed, make sure that it is never scrolled + // outside the upper border + if (topNode) { + _assert( + topNode.isRootNode() || topNode.isVisible(), + "topNode must be visible" + ); + if (topNodeY < newScrollTop) { + newScrollTop = topNodeY - topOfs; + // this.debug(" scrollIntoView(), TOP newScrollTop=" + newScrollTop); + } + } + } + + if (newScrollTop === null) { + dfd.resolveWith(this); + } else { + // this.debug(" scrollIntoView(), SET newScrollTop=" + newScrollTop); + if (opts.effects) { + opts.effects.complete = function () { + dfd.resolveWith(self); + }; + $animateTarget.stop(true).animate( + { + scrollTop: newScrollTop, + }, + opts.effects + ); + } else { + $animateTarget[0].scrollTop = newScrollTop; + dfd.resolveWith(this); + } + } + return dfd.promise(); + }, + + /**Activate this node. + * + * The `cell` option requires the ext-table and ext-ariagrid extensions. + * + * @param {boolean} [flag=true] pass false to deactivate + * @param {object} [opts] additional options. Defaults to {noEvents: false, noFocus: false, cell: null} + * @returns {$.Promise} + */ + setActive: function (flag, opts) { + return this.tree._callHook("nodeSetActive", this, flag, opts); + }, + /**Expand or collapse this node. Promise is resolved, when lazy loading and animations are done. + * @param {boolean} [flag=true] pass false to collapse + * @param {object} [opts] additional options. Defaults to {noAnimation: false, noEvents: false} + * @returns {$.Promise} + */ + setExpanded: function (flag, opts) { + return this.tree._callHook("nodeSetExpanded", this, flag, opts); + }, + /**Set keyboard focus to this node. + * @param {boolean} [flag=true] pass false to blur + * @see Fancytree#setFocus + */ + setFocus: function (flag) { + return this.tree._callHook("nodeSetFocus", this, flag); + }, + /**Select this node, i.e. check the checkbox. + * @param {boolean} [flag=true] pass false to deselect + * @param {object} [opts] additional options. Defaults to {noEvents: false, p + * propagateDown: null, propagateUp: null, callback: null } + */ + setSelected: function (flag, opts) { + return this.tree._callHook("nodeSetSelected", this, flag, opts); + }, + /**Mark a lazy node as 'error', 'loading', 'nodata', or 'ok'. + * @param {string} status 'error'|'loading'|'nodata'|'ok' + * @param {string} [message] + * @param {string} [details] + */ + setStatus: function (status, message, details) { + return this.tree._callHook( + "nodeSetStatus", + this, + status, + message, + details + ); + }, + /**Rename this node. + * @param {string} title + */ + setTitle: function (title) { + this.title = title; + this.renderTitle(); + this.triggerModify("rename"); + }, + /**Sort child list by title. + * @param {function} [cmp] custom compare function(a, b) that returns -1, 0, or 1 (defaults to sort by title). + * @param {boolean} [deep=false] pass true to sort all descendant nodes + */ + sortChildren: function (cmp, deep) { + var i, + l, + cl = this.children; + + if (!cl) { + return; + } + cmp = + cmp || + function (a, b) { + var x = a.title.toLowerCase(), + y = b.title.toLowerCase(); + + // eslint-disable-next-line no-nested-ternary + return x === y ? 0 : x > y ? 1 : -1; + }; + cl.sort(cmp); + if (deep) { + for (i = 0, l = cl.length; i < l; i++) { + if (cl[i].children) { + cl[i].sortChildren(cmp, "$norender$"); + } + } + } + if (deep !== "$norender$") { + this.render(); + } + this.triggerModifyChild("sort"); + }, + /** Convert node (or whole branch) into a plain object. + * + * The result is compatible with node.addChildren(). + * + * @param {boolean} [recursive=false] include child nodes + * @param {function} [callback] callback(dict, node) is called for every node, in order to allow modifications. + * Return `false` to ignore this node or `"skip"` to include this node without its children. + * @returns {NodeData} + */ + toDict: function (recursive, callback) { + var i, + l, + node, + res, + dict = {}, + self = this; + + $.each(NODE_ATTRS, function (i, a) { + if (self[a] || self[a] === false) { + dict[a] = self[a]; + } + }); + if (!$.isEmptyObject(this.data)) { + dict.data = $.extend({}, this.data); + if ($.isEmptyObject(dict.data)) { + delete dict.data; + } + } + if (callback) { + res = callback(dict, self); + if (res === false) { + return false; // Don't include this node nor its children + } + if (res === "skip") { + recursive = false; // Include this node, but not the children + } + } + if (recursive) { + if (_isArray(this.children)) { + dict.children = []; + for (i = 0, l = this.children.length; i < l; i++) { + node = this.children[i]; + if (!node.isStatusNode()) { + res = node.toDict(true, callback); + if (res !== false) { + dict.children.push(res); + } + } + } + } + } + return dict; + }, + /** + * Set, clear, or toggle class of node's span tag and .extraClasses. + * + * @param {string} className class name (separate multiple classes by space) + * @param {boolean} [flag] true/false to add/remove class. If omitted, class is toggled. + * @returns {boolean} true if a class was added + * + * @since 2.17 + */ + toggleClass: function (value, flag) { + var className, + hasClass, + rnotwhite = /\S+/g, + classNames = value.match(rnotwhite) || [], + i = 0, + wasAdded = false, + statusElem = this[this.tree.statusClassPropName], + curClasses = " " + (this.extraClasses || "") + " "; + + // this.info("toggleClass('" + value + "', " + flag + ")", curClasses); + // Modify DOM element directly if it already exists + if (statusElem) { + $(statusElem).toggleClass(value, flag); + } + // Modify node.extraClasses to make this change persistent + // Toggle if flag was not passed + while ((className = classNames[i++])) { + hasClass = curClasses.indexOf(" " + className + " ") >= 0; + flag = flag === undefined ? !hasClass : !!flag; + if (flag) { + if (!hasClass) { + curClasses += className + " "; + wasAdded = true; + } + } else { + while (curClasses.indexOf(" " + className + " ") > -1) { + curClasses = curClasses.replace( + " " + className + " ", + " " + ); + } + } + } + this.extraClasses = _trim(curClasses); + // this.info("-> toggleClass('" + value + "', " + flag + "): '" + this.extraClasses + "'"); + return wasAdded; + }, + /** Flip expanded status. */ + toggleExpanded: function () { + return this.tree._callHook("nodeToggleExpanded", this); + }, + /** Flip selection status. */ + toggleSelected: function () { + return this.tree._callHook("nodeToggleSelected", this); + }, + toString: function () { + return "FancytreeNode@" + this.key + "[title='" + this.title + "']"; + // return "<FancytreeNode(#" + this.key + ", '" + this.title + "')>"; + }, + /** + * Trigger `modifyChild` event on a parent to signal that a child was modified. + * @param {string} operation Type of change: 'add', 'remove', 'rename', 'move', 'data', ... + * @param {FancytreeNode} [childNode] + * @param {object} [extra] + */ + triggerModifyChild: function (operation, childNode, extra) { + var data, + modifyChild = this.tree.options.modifyChild; + + if (modifyChild) { + if (childNode && childNode.parent !== this) { + $.error( + "childNode " + childNode + " is not a child of " + this + ); + } + data = { + node: this, + tree: this.tree, + operation: operation, + childNode: childNode || null, + }; + if (extra) { + $.extend(data, extra); + } + modifyChild({ type: "modifyChild" }, data); + } + }, + /** + * Trigger `modifyChild` event on node.parent(!). + * @param {string} operation Type of change: 'add', 'remove', 'rename', 'move', 'data', ... + * @param {object} [extra] + */ + triggerModify: function (operation, extra) { + this.parent.triggerModifyChild(operation, this, extra); + }, + /** Call fn(node) for all child nodes in hierarchical order (depth-first).<br> + * Stop iteration, if fn() returns false. Skip current branch, if fn() returns "skip".<br> + * Return false if iteration was stopped. + * + * @param {function} fn the callback function. + * Return false to stop iteration, return "skip" to skip this node and + * its children only. + * @param {boolean} [includeSelf=false] + * @returns {boolean} + */ + visit: function (fn, includeSelf) { + var i, + l, + res = true, + children = this.children; + + if (includeSelf === true) { + res = fn(this); + if (res === false || res === "skip") { + return res; + } + } + if (children) { + for (i = 0, l = children.length; i < l; i++) { + res = children[i].visit(fn, true); + if (res === false) { + break; + } + } + } + return res; + }, + /** Call fn(node) for all child nodes and recursively load lazy children.<br> + * <b>Note:</b> If you need this method, you probably should consider to review + * your architecture! Recursivley loading nodes is a perfect way for lazy + * programmers to flood the server with requests ;-) + * + * @param {function} [fn] optional callback function. + * Return false to stop iteration, return "skip" to skip this node and + * its children only. + * @param {boolean} [includeSelf=false] + * @returns {$.Promise} + * @since 2.4 + */ + visitAndLoad: function (fn, includeSelf, _recursion) { + var dfd, + res, + loaders, + node = this; + + // node.debug("visitAndLoad"); + if (fn && includeSelf === true) { + res = fn(node); + if (res === false || res === "skip") { + return _recursion ? res : _getResolvedPromise(); + } + } + if (!node.children && !node.lazy) { + return _getResolvedPromise(); + } + dfd = new $.Deferred(); + loaders = []; + // node.debug("load()..."); + node.load().done(function () { + // node.debug("load()... done."); + for (var i = 0, l = node.children.length; i < l; i++) { + res = node.children[i].visitAndLoad(fn, true, true); + if (res === false) { + dfd.reject(); + break; + } else if (res !== "skip") { + loaders.push(res); // Add promise to the list + } + } + $.when.apply(this, loaders).then(function () { + dfd.resolve(); + }); + }); + return dfd.promise(); + }, + /** Call fn(node) for all parent nodes, bottom-up, including invisible system root.<br> + * Stop iteration, if fn() returns false.<br> + * Return false if iteration was stopped. + * + * @param {function} fn the callback function. + * Return false to stop iteration, return "skip" to skip this node and children only. + * @param {boolean} [includeSelf=false] + * @returns {boolean} + */ + visitParents: function (fn, includeSelf) { + // Visit parent nodes (bottom up) + if (includeSelf && fn(this) === false) { + return false; + } + var p = this.parent; + while (p) { + if (fn(p) === false) { + return false; + } + p = p.parent; + } + return true; + }, + /** Call fn(node) for all sibling nodes.<br> + * Stop iteration, if fn() returns false.<br> + * Return false if iteration was stopped. + * + * @param {function} fn the callback function. + * Return false to stop iteration. + * @param {boolean} [includeSelf=false] + * @returns {boolean} + */ + visitSiblings: function (fn, includeSelf) { + var i, + l, + n, + ac = this.parent.children; + + for (i = 0, l = ac.length; i < l; i++) { + n = ac[i]; + if (includeSelf || n !== this) { + if (fn(n) === false) { + return false; + } + } + } + return true; + }, + /** Write warning to browser console if debugLevel >= 2 (prepending node info) + * + * @param {*} msg string or object or array of such + */ + warn: function (msg) { + if (this.tree.options.debugLevel >= 2) { + Array.prototype.unshift.call(arguments, this.toString()); + consoleApply("warn", arguments); + } + }, + }; + + /****************************************************************************** + * Fancytree + */ + /** + * Construct a new tree object. + * + * @class Fancytree + * @classdesc The controller behind a fancytree. + * This class also contains 'hook methods': see {@link Fancytree_Hooks}. + * + * @param {Widget} widget + * + * @property {string} _id Automatically generated unique tree instance ID, e.g. "1". + * @property {string} _ns Automatically generated unique tree namespace, e.g. ".fancytree-1". + * @property {FancytreeNode} activeNode Currently active node or null. + * @property {string} ariaPropName Property name of FancytreeNode that contains the element which will receive the aria attributes. + * Typically "li", but "tr" for table extension. + * @property {jQueryObject} $container Outer `<ul>` element (or `<table>` element for ext-table). + * @property {jQueryObject} $div A jQuery object containing the element used to instantiate the tree widget (`widget.element`) + * @property {object|array} columns Recommended place to store shared column meta data. @since 2.27 + * @property {object} data Metadata, i.e. properties that may be passed to `source` in addition to a children array. + * @property {object} ext Hash of all active plugin instances. + * @property {FancytreeNode} focusNode Currently focused node or null. + * @property {FancytreeNode} lastSelectedNode Used to implement selectMode 1 (single select) + * @property {string} nodeContainerAttrName Property name of FancytreeNode that contains the outer element of single nodes. + * Typically "li", but "tr" for table extension. + * @property {FancytreeOptions} options Current options, i.e. default options + options passed to constructor. + * @property {FancytreeNode} rootNode Invisible system root node. + * @property {string} statusClassPropName Property name of FancytreeNode that contains the element which will receive the status classes. + * Typically "span", but "tr" for table extension. + * @property {object} types Map for shared type specific meta data, used with node.type attribute. @since 2.27 + * @property {object} viewport See ext-vieport. @since v2.31 + * @property {object} widget Base widget instance. + */ + function Fancytree(widget) { + this.widget = widget; + this.$div = widget.element; + this.options = widget.options; + if (this.options) { + if (this.options.lazyload !== undefined) { + $.error( + "The 'lazyload' event is deprecated since 2014-02-25. Use 'lazyLoad' (with uppercase L) instead." + ); + } + if (this.options.loaderror !== undefined) { + $.error( + "The 'loaderror' event was renamed since 2014-07-03. Use 'loadError' (with uppercase E) instead." + ); + } + if (this.options.fx !== undefined) { + $.error( + "The 'fx' option was replaced by 'toggleEffect' since 2014-11-30." + ); + } + if (this.options.removeNode !== undefined) { + $.error( + "The 'removeNode' event was replaced by 'modifyChild' since 2.20 (2016-09-10)." + ); + } + } + this.ext = {}; // Active extension instances + this.types = {}; + this.columns = {}; + // allow to init tree.data.foo from <div data-foo=''> + this.data = _getElementDataAsDict(this.$div); + // TODO: use widget.uuid instead? + this._id = "" + (this.options.treeId || $.ui.fancytree._nextId++); + // TODO: use widget.eventNamespace instead? + this._ns = ".fancytree-" + this._id; // append for namespaced events + this.activeNode = null; + this.focusNode = null; + this._hasFocus = null; + this._tempCache = {}; + this._lastMousedownNode = null; + this._enableUpdate = true; + this.lastSelectedNode = null; + this.systemFocusElement = null; + this.lastQuicksearchTerm = ""; + this.lastQuicksearchTime = 0; + this.viewport = null; // ext-grid + + this.statusClassPropName = "span"; + this.ariaPropName = "li"; + this.nodeContainerAttrName = "li"; + + // Remove previous markup if any + this.$div.find(">ul.fancytree-container").remove(); + + // Create a node without parent. + var fakeParent = { tree: this }, + $ul; + this.rootNode = new FancytreeNode(fakeParent, { + title: "root", + key: "root_" + this._id, + children: null, + expanded: true, + }); + this.rootNode.parent = null; + + // Create root markup + $ul = $("<ul>", { + id: "ft-id-" + this._id, + class: "ui-fancytree fancytree-container fancytree-plain", + }).appendTo(this.$div); + this.$container = $ul; + this.rootNode.ul = $ul[0]; + + if (this.options.debugLevel == null) { + this.options.debugLevel = FT.debugLevel; + } + // // Add container to the TAB chain + // // See http://www.w3.org/TR/wai-aria-practices/#focus_activedescendant + // // #577: Allow to set tabindex to "0", "-1" and "" + // this.$container.attr("tabindex", this.options.tabindex); + + // if( this.options.rtl ) { + // this.$container.attr("DIR", "RTL").addClass("fancytree-rtl"); + // // }else{ + // // this.$container.attr("DIR", null).removeClass("fancytree-rtl"); + // } + // if(this.options.aria){ + // this.$container.attr("role", "tree"); + // if( this.options.selectMode !== 1 ) { + // this.$container.attr("aria-multiselectable", true); + // } + // } + } + + Fancytree.prototype = /** @lends Fancytree# */ { + /* Return a context object that can be re-used for _callHook(). + * @param {Fancytree | FancytreeNode | EventData} obj + * @param {Event} originalEvent + * @param {Object} extra + * @returns {EventData} + */ + _makeHookContext: function (obj, originalEvent, extra) { + var ctx, tree; + if (obj.node !== undefined) { + // obj is already a context object + if (originalEvent && obj.originalEvent !== originalEvent) { + $.error("invalid args"); + } + ctx = obj; + } else if (obj.tree) { + // obj is a FancytreeNode + tree = obj.tree; + ctx = { + node: obj, + tree: tree, + widget: tree.widget, + options: tree.widget.options, + originalEvent: originalEvent, + typeInfo: tree.types[obj.type] || {}, + }; + } else if (obj.widget) { + // obj is a Fancytree + ctx = { + node: null, + tree: obj, + widget: obj.widget, + options: obj.widget.options, + originalEvent: originalEvent, + }; + } else { + $.error("invalid args"); + } + if (extra) { + $.extend(ctx, extra); + } + return ctx; + }, + /* Trigger a hook function: funcName(ctx, [...]). + * + * @param {string} funcName + * @param {Fancytree|FancytreeNode|EventData} contextObject + * @param {any} [_extraArgs] optional additional arguments + * @returns {any} + */ + _callHook: function (funcName, contextObject, _extraArgs) { + var ctx = this._makeHookContext(contextObject), + fn = this[funcName], + args = Array.prototype.slice.call(arguments, 2); + if (!_isFunction(fn)) { + $.error("_callHook('" + funcName + "') is not a function"); + } + args.unshift(ctx); + // this.debug("_hook", funcName, ctx.node && ctx.node.toString() || ctx.tree.toString(), args); + return fn.apply(this, args); + }, + _setExpiringValue: function (key, value, ms) { + this._tempCache[key] = { + value: value, + expire: Date.now() + (+ms || 50), + }; + }, + _getExpiringValue: function (key) { + var entry = this._tempCache[key]; + if (entry && entry.expire > Date.now()) { + return entry.value; + } + delete this._tempCache[key]; + return null; + }, + /* Check if this tree has extension `name` enabled. + * + * @param {string} name name of the required extension + */ + _usesExtension: function (name) { + return $.inArray(name, this.options.extensions) >= 0; + }, + /* Check if current extensions dependencies are met and throw an error if not. + * + * This method may be called inside the `treeInit` hook for custom extensions. + * + * @param {string} name name of the required extension + * @param {boolean} [required=true] pass `false` if the extension is optional, but we want to check for order if it is present + * @param {boolean} [before] `true` if `name` must be included before this, `false` otherwise (use `null` if order doesn't matter) + * @param {string} [message] optional error message (defaults to a descriptve error message) + */ + _requireExtension: function (name, required, before, message) { + if (before != null) { + before = !!before; + } + var thisName = this._local.name, + extList = this.options.extensions, + isBefore = + $.inArray(name, extList) < $.inArray(thisName, extList), + isMissing = required && this.ext[name] == null, + badOrder = !isMissing && before != null && before !== isBefore; + + _assert( + thisName && thisName !== name, + "invalid or same name '" + thisName + "' (require yourself?)" + ); + + if (isMissing || badOrder) { + if (!message) { + if (isMissing || required) { + message = + "'" + + thisName + + "' extension requires '" + + name + + "'"; + if (badOrder) { + message += + " to be registered " + + (before ? "before" : "after") + + " itself"; + } + } else { + message = + "If used together, `" + + name + + "` must be registered " + + (before ? "before" : "after") + + " `" + + thisName + + "`"; + } + } + $.error(message); + return false; + } + return true; + }, + /** Activate node with a given key and fire focus and activate events. + * + * A previously activated node will be deactivated. + * If activeVisible option is set, all parents will be expanded as necessary. + * Pass key = false, to deactivate the current node only. + * @param {string} key + * @param {object} [opts] additional options. Defaults to {noEvents: false, noFocus: false} + * @returns {FancytreeNode} activated node (null, if not found) + */ + activateKey: function (key, opts) { + var node = this.getNodeByKey(key); + if (node) { + node.setActive(true, opts); + } else if (this.activeNode) { + this.activeNode.setActive(false, opts); + } + return node; + }, + /** (experimental) Add child status nodes that indicate 'More...', .... + * @param {boolean|object} node optional node definition. Pass `false` to remove all paging nodes. + * @param {string} [mode='append'] 'child'|firstChild' + * @since 2.15 + */ + addPagingNode: function (node, mode) { + return this.rootNode.addPagingNode(node, mode); + }, + /** + * (experimental) Apply a modification (or navigation) operation. + * + * Valid commands: + * - 'moveUp', 'moveDown' + * - 'indent', 'outdent' + * - 'remove' + * - 'edit', 'addChild', 'addSibling': (reqires ext-edit extension) + * - 'cut', 'copy', 'paste': (use an internal singleton 'clipboard') + * - 'down', 'first', 'last', 'left', 'parent', 'right', 'up': navigate + * + * @param {string} cmd + * @param {FancytreeNode} [node=active_node] + * @param {object} [opts] Currently unused + * + * @since 2.32 + */ + applyCommand: function (cmd, node, opts_) { + var // clipboard, + refNode; + // opts = $.extend( + // { setActive: true, clipboard: CLIPBOARD }, + // opts_ + // ); + + node = node || this.getActiveNode(); + // clipboard = opts.clipboard; + + switch (cmd) { + // Sorting and indentation: + case "moveUp": + refNode = node.getPrevSibling(); + if (refNode) { + node.moveTo(refNode, "before"); + node.setActive(); + } + break; + case "moveDown": + refNode = node.getNextSibling(); + if (refNode) { + node.moveTo(refNode, "after"); + node.setActive(); + } + break; + case "indent": + refNode = node.getPrevSibling(); + if (refNode) { + node.moveTo(refNode, "child"); + refNode.setExpanded(); + node.setActive(); + } + break; + case "outdent": + if (!node.isTopLevel()) { + node.moveTo(node.getParent(), "after"); + node.setActive(); + } + break; + // Remove: + case "remove": + refNode = node.getPrevSibling() || node.getParent(); + node.remove(); + if (refNode) { + refNode.setActive(); + } + break; + // Add, edit (requires ext-edit): + case "addChild": + node.editCreateNode("child", ""); + break; + case "addSibling": + node.editCreateNode("after", ""); + break; + case "rename": + node.editStart(); + break; + // Simple clipboard simulation: + // case "cut": + // clipboard = { mode: cmd, data: node }; + // break; + // case "copy": + // clipboard = { + // mode: cmd, + // data: node.toDict(function(d, n) { + // delete d.key; + // }), + // }; + // break; + // case "clear": + // clipboard = null; + // break; + // case "paste": + // if (clipboard.mode === "cut") { + // // refNode = node.getPrevSibling(); + // clipboard.data.moveTo(node, "child"); + // clipboard.data.setActive(); + // } else if (clipboard.mode === "copy") { + // node.addChildren(clipboard.data).setActive(); + // } + // break; + // Navigation commands: + case "down": + case "first": + case "last": + case "left": + case "parent": + case "right": + case "up": + return node.navigate(cmd); + default: + $.error("Unhandled command: '" + cmd + "'"); + } + }, + /** (experimental) Modify existing data model. + * + * @param {Array} patchList array of [key, NodePatch] arrays + * @returns {$.Promise} resolved, when all patches have been applied + * @see TreePatch + */ + applyPatch: function (patchList) { + var dfd, + i, + p2, + key, + patch, + node, + patchCount = patchList.length, + deferredList = []; + + for (i = 0; i < patchCount; i++) { + p2 = patchList[i]; + _assert( + p2.length === 2, + "patchList must be an array of length-2-arrays" + ); + key = p2[0]; + patch = p2[1]; + node = key === null ? this.rootNode : this.getNodeByKey(key); + if (node) { + dfd = new $.Deferred(); + deferredList.push(dfd); + node.applyPatch(patch).always(_makeResolveFunc(dfd, node)); + } else { + this.warn("could not find node with key '" + key + "'"); + } + } + // Return a promise that is resolved, when ALL patches were applied + return $.when.apply($, deferredList).promise(); + }, + /* TODO: implement in dnd extension + cancelDrag: function() { + var dd = $.ui.ddmanager.current; + if(dd){ + dd.cancel(); + } + }, + */ + /** Remove all nodes. + * @since 2.14 + */ + clear: function (source) { + this._callHook("treeClear", this); + }, + /** Return the number of nodes. + * @returns {integer} + */ + count: function () { + return this.rootNode.countChildren(); + }, + /** Write to browser console if debugLevel >= 4 (prepending tree name) + * + * @param {*} msg string or object or array of such + */ + debug: function (msg) { + if (this.options.debugLevel >= 4) { + Array.prototype.unshift.call(arguments, this.toString()); + consoleApply("log", arguments); + } + }, + /** Destroy this widget, restore previous markup and cleanup resources. + * + * @since 2.34 + */ + destroy: function () { + this.widget.destroy(); + }, + /** Enable (or disable) the tree control. + * + * @param {boolean} [flag=true] pass false to disable + * @since 2.30 + */ + enable: function (flag) { + if (flag === false) { + this.widget.disable(); + } else { + this.widget.enable(); + } + }, + /** Temporarily suppress rendering to improve performance on bulk-updates. + * + * @param {boolean} flag + * @returns {boolean} previous status + * @since 2.19 + */ + enableUpdate: function (flag) { + flag = flag !== false; + if (!!this._enableUpdate === !!flag) { + return flag; + } + this._enableUpdate = flag; + if (flag) { + this.debug("enableUpdate(true): redraw "); //, this._dirtyRoots); + this._callHook("treeStructureChanged", this, "enableUpdate"); + this.render(); + } else { + // this._dirtyRoots = null; + this.debug("enableUpdate(false)..."); + } + return !flag; // return previous value + }, + /** Write error to browser console if debugLevel >= 1 (prepending tree info) + * + * @param {*} msg string or object or array of such + */ + error: function (msg) { + if (this.options.debugLevel >= 1) { + Array.prototype.unshift.call(arguments, this.toString()); + consoleApply("error", arguments); + } + }, + /** Expand (or collapse) all parent nodes. + * + * This convenience method uses `tree.visit()` and `tree.setExpanded()` + * internally. + * + * @param {boolean} [flag=true] pass false to collapse + * @param {object} [opts] passed to setExpanded() + * @since 2.30 + */ + expandAll: function (flag, opts) { + var prev = this.enableUpdate(false); + + flag = flag !== false; + this.visit(function (node) { + if ( + node.hasChildren() !== false && + node.isExpanded() !== flag + ) { + node.setExpanded(flag, opts); + } + }); + this.enableUpdate(prev); + }, + /**Find all nodes that matches condition. + * + * @param {string | function(node)} match title string to search for, or a + * callback function that returns `true` if a node is matched. + * @returns {FancytreeNode[]} array of nodes (may be empty) + * @see FancytreeNode#findAll + * @since 2.12 + */ + findAll: function (match) { + return this.rootNode.findAll(match); + }, + /**Find first node that matches condition. + * + * @param {string | function(node)} match title string to search for, or a + * callback function that returns `true` if a node is matched. + * @returns {FancytreeNode} matching node or null + * @see FancytreeNode#findFirst + * @since 2.12 + */ + findFirst: function (match) { + return this.rootNode.findFirst(match); + }, + /** Find the next visible node that starts with `match`, starting at `startNode` + * and wrap-around at the end. + * + * @param {string|function} match + * @param {FancytreeNode} [startNode] defaults to first node + * @returns {FancytreeNode} matching node or null + */ + findNextNode: function (match, startNode) { + //, visibleOnly) { + var res = null, + firstNode = this.getFirstChild(); + + match = + typeof match === "string" + ? _makeNodeTitleStartMatcher(match) + : match; + startNode = startNode || firstNode; + + function _checkNode(n) { + // console.log("_check " + n) + if (match(n)) { + res = n; + } + if (res || n === startNode) { + return false; + } + } + this.visitRows(_checkNode, { + start: startNode, + includeSelf: false, + }); + // Wrap around search + if (!res && startNode !== firstNode) { + this.visitRows(_checkNode, { + start: firstNode, + includeSelf: true, + }); + } + return res; + }, + /** Find a node relative to another node. + * + * @param {FancytreeNode} node + * @param {string|number} where 'down', 'first', 'last', 'left', 'parent', 'right', or 'up'. + * (Alternatively the keyCode that would normally trigger this move, + * e.g. `$.ui.keyCode.LEFT` = 'left'. + * @param {boolean} [includeHidden=false] Not yet implemented + * @returns {FancytreeNode|null} + * @since v2.31 + */ + findRelatedNode: function (node, where, includeHidden) { + var res = null, + KC = $.ui.keyCode; + + switch (where) { + case "parent": + case KC.BACKSPACE: + if (node.parent && node.parent.parent) { + res = node.parent; + } + break; + case "first": + case KC.HOME: + // First visible node + this.visit(function (n) { + if (n.isVisible()) { + res = n; + return false; + } + }); + break; + case "last": + case KC.END: + this.visit(function (n) { + // last visible node + if (n.isVisible()) { + res = n; + } + }); + break; + case "left": + case KC.LEFT: + if (node.expanded) { + node.setExpanded(false); + } else if (node.parent && node.parent.parent) { + res = node.parent; + } + break; + case "right": + case KC.RIGHT: + if (!node.expanded && (node.children || node.lazy)) { + node.setExpanded(); + res = node; + } else if (node.children && node.children.length) { + res = node.children[0]; + } + break; + case "up": + case KC.UP: + this.visitRows( + function (n) { + res = n; + return false; + }, + { start: node, reverse: true, includeSelf: false } + ); + break; + case "down": + case KC.DOWN: + this.visitRows( + function (n) { + res = n; + return false; + }, + { start: node, includeSelf: false } + ); + break; + default: + this.tree.warn("Unknown relation '" + where + "'."); + } + return res; + }, + // TODO: fromDict + /** + * Generate INPUT elements that can be submitted with html forms. + * + * In selectMode 3 only the topmost selected nodes are considered, unless + * `opts.stopOnParents: false` is passed. + * + * @example + * // Generate input elements for active and selected nodes + * tree.generateFormElements(); + * // Generate input elements selected nodes, using a custom `name` attribute + * tree.generateFormElements("cust_sel", false); + * // Generate input elements using a custom filter + * tree.generateFormElements(true, true, { filter: function(node) { + * return node.isSelected() && node.data.yes; + * }}); + * + * @param {boolean | string} [selected=true] Pass false to disable, pass a string to override the field name (default: 'ft_ID[]') + * @param {boolean | string} [active=true] Pass false to disable, pass a string to override the field name (default: 'ft_ID_active') + * @param {object} [opts] default { filter: null, stopOnParents: true } + */ + generateFormElements: function (selected, active, opts) { + opts = opts || {}; + + var nodeList, + selectedName = + typeof selected === "string" + ? selected + : "ft_" + this._id + "[]", + activeName = + typeof active === "string" + ? active + : "ft_" + this._id + "_active", + id = "fancytree_result_" + this._id, + $result = $("#" + id), + stopOnParents = + this.options.selectMode === 3 && + opts.stopOnParents !== false; + + if ($result.length) { + $result.empty(); + } else { + $result = $("<div>", { + id: id, + }) + .hide() + .insertAfter(this.$container); + } + if (active !== false && this.activeNode) { + $result.append( + $("<input>", { + type: "radio", + name: activeName, + value: this.activeNode.key, + checked: true, + }) + ); + } + function _appender(node) { + $result.append( + $("<input>", { + type: "checkbox", + name: selectedName, + value: node.key, + checked: true, + }) + ); + } + if (opts.filter) { + this.visit(function (node) { + var res = opts.filter(node); + if (res === "skip") { + return res; + } + if (res !== false) { + _appender(node); + } + }); + } else if (selected !== false) { + nodeList = this.getSelectedNodes(stopOnParents); + $.each(nodeList, function (idx, node) { + _appender(node); + }); + } + }, + /** + * Return the currently active node or null. + * @returns {FancytreeNode} + */ + getActiveNode: function () { + return this.activeNode; + }, + /** Return the first top level node if any (not the invisible root node). + * @returns {FancytreeNode | null} + */ + getFirstChild: function () { + return this.rootNode.getFirstChild(); + }, + /** + * Return node that has keyboard focus or null. + * @returns {FancytreeNode} + */ + getFocusNode: function () { + return this.focusNode; + }, + /** + * Return current option value. + * (Note: this is the preferred variant of `$().fancytree("option", "KEY")`) + * + * @param {string} name option name (may contain '.') + * @returns {any} + */ + getOption: function (optionName) { + return this.widget.option(optionName); + }, + /** + * Return node with a given key or null if not found. + * + * @param {string} key + * @param {FancytreeNode} [searchRoot] only search below this node + * @returns {FancytreeNode | null} + */ + getNodeByKey: function (key, searchRoot) { + // Search the DOM by element ID (assuming this is faster than traversing all nodes). + var el, match; + // TODO: use tree.keyMap if available + // TODO: check opts.generateIds === true + if (!searchRoot) { + el = document.getElementById(this.options.idPrefix + key); + if (el) { + return el.ftnode ? el.ftnode : null; + } + } + // Not found in the DOM, but still may be in an unrendered part of tree + searchRoot = searchRoot || this.rootNode; + match = null; + key = "" + key; // Convert to string (#1005) + searchRoot.visit(function (node) { + if (node.key === key) { + match = node; + return false; // Stop iteration + } + }, true); + return match; + }, + /** Return the invisible system root node. + * @returns {FancytreeNode} + */ + getRootNode: function () { + return this.rootNode; + }, + /** + * Return an array of selected nodes. + * + * Note: you cannot send this result via Ajax directly. Instead the + * node object need to be converted to plain objects, for example + * by using `$.map()` and `node.toDict()`. + * @param {boolean} [stopOnParents=false] only return the topmost selected + * node (useful with selectMode 3) + * @returns {FancytreeNode[]} + */ + getSelectedNodes: function (stopOnParents) { + return this.rootNode.getSelectedNodes(stopOnParents); + }, + /** Return true if the tree control has keyboard focus + * @returns {boolean} + */ + hasFocus: function () { + // var ae = document.activeElement, + // hasFocus = !!( + // ae && $(ae).closest(".fancytree-container").length + // ); + + // if (hasFocus !== !!this._hasFocus) { + // this.warn( + // "hasFocus(): fix inconsistent container state, now: " + + // hasFocus + // ); + // this._hasFocus = hasFocus; + // this.$container.toggleClass("fancytree-treefocus", hasFocus); + // } + // return hasFocus; + return !!this._hasFocus; + }, + /** Write to browser console if debugLevel >= 3 (prepending tree name) + * @param {*} msg string or object or array of such + */ + info: function (msg) { + if (this.options.debugLevel >= 3) { + Array.prototype.unshift.call(arguments, this.toString()); + consoleApply("info", arguments); + } + }, + /** Return true if any node is currently beeing loaded, i.e. a Ajax request is pending. + * @returns {boolean} + * @since 2.32 + */ + isLoading: function () { + var res = false; + + this.rootNode.visit(function (n) { + // also visit rootNode + if (n._isLoading || n._requestId) { + res = true; + return false; + } + }, true); + return res; + }, + /* + TODO: isInitializing: function() { + return ( this.phase=="init" || this.phase=="postInit" ); + }, + TODO: isReloading: function() { + return ( this.phase=="init" || this.phase=="postInit" ) && this.options.persist && this.persistence.cookiesFound; + }, + TODO: isUserEvent: function() { + return ( this.phase=="userEvent" ); + }, + */ + + /** + * Make sure that a node with a given ID is loaded, by traversing - and + * loading - its parents. This method is meant for lazy hierarchies. + * A callback is executed for every node as we go. + * @example + * // Resolve using node.key: + * tree.loadKeyPath("/_3/_23/_26/_27", function(node, status){ + * if(status === "loaded") { + * console.log("loaded intermediate node " + node); + * }else if(status === "ok") { + * node.activate(); + * } + * }); + * // Use deferred promise: + * tree.loadKeyPath("/_3/_23/_26/_27").progress(function(data){ + * if(data.status === "loaded") { + * console.log("loaded intermediate node " + data.node); + * }else if(data.status === "ok") { + * node.activate(); + * } + * }).done(function(){ + * ... + * }); + * // Custom path segment resolver: + * tree.loadKeyPath("/321/431/21/2", { + * matchKey: function(node, key){ + * return node.data.refKey === key; + * }, + * callback: function(node, status){ + * if(status === "loaded") { + * console.log("loaded intermediate node " + node); + * }else if(status === "ok") { + * node.activate(); + * } + * } + * }); + * @param {string | string[]} keyPathList one or more key paths (e.g. '/3/2_1/7') + * @param {function | object} optsOrCallback callback(node, status) is called for every visited node ('loading', 'loaded', 'ok', 'error'). + * Pass an object to define custom key matchers for the path segments: {callback: function, matchKey: function}. + * @returns {$.Promise} + */ + loadKeyPath: function (keyPathList, optsOrCallback) { + var callback, + i, + path, + self = this, + dfd = new $.Deferred(), + parent = this.getRootNode(), + sep = this.options.keyPathSeparator, + pathSegList = [], + opts = $.extend({}, optsOrCallback); + + // Prepare options + if (typeof optsOrCallback === "function") { + callback = optsOrCallback; + } else if (optsOrCallback && optsOrCallback.callback) { + callback = optsOrCallback.callback; + } + opts.callback = function (ctx, node, status) { + if (callback) { + callback.call(ctx, node, status); + } + dfd.notifyWith(ctx, [{ node: node, status: status }]); + }; + if (opts.matchKey == null) { + opts.matchKey = function (node, key) { + return node.key === key; + }; + } + // Convert array of path strings to array of segment arrays + if (!_isArray(keyPathList)) { + keyPathList = [keyPathList]; + } + for (i = 0; i < keyPathList.length; i++) { + path = keyPathList[i]; + // strip leading slash + if (path.charAt(0) === sep) { + path = path.substr(1); + } + // segListMap[path] = { parent: parent, segList: path.split(sep) }; + pathSegList.push(path.split(sep)); + // targetList.push({ parent: parent, segList: path.split(sep)/* , path: path*/}); + } + // The timeout forces async behavior always (even if nodes are all loaded) + // This way a potential progress() event will fire. + setTimeout(function () { + self._loadKeyPathImpl(dfd, opts, parent, pathSegList).done( + function () { + dfd.resolve(); + } + ); + }, 0); + return dfd.promise(); + }, + /* + * Resolve a list of paths, relative to one parent node. + */ + _loadKeyPathImpl: function (dfd, opts, parent, pathSegList) { + var deferredList, + i, + key, + node, + nodeKey, + remain, + remainMap, + tmpParent, + segList, + subDfd, + self = this; + + function __findChild(parent, key) { + // console.log("__findChild", key, parent); + var i, + l, + cl = parent.children; + + if (cl) { + for (i = 0, l = cl.length; i < l; i++) { + if (opts.matchKey(cl[i], key)) { + return cl[i]; + } + } + } + return null; + } + + // console.log("_loadKeyPathImpl, parent=", parent, ", pathSegList=", pathSegList); + + // Pass 1: + // Handle all path segments for nodes that are already loaded. + // Collect distinct top-most lazy nodes in a map. + // Note that we can use node.key to de-dupe entries, even if a custom matcher would + // look for other node attributes. + // map[node.key] => {node: node, pathList: [list of remaining rest-paths]} + remainMap = {}; + + for (i = 0; i < pathSegList.length; i++) { + segList = pathSegList[i]; + // target = targetList[i]; + + // Traverse and pop path segments (i.e. keys), until we hit a lazy, unloaded node + tmpParent = parent; + while (segList.length) { + key = segList.shift(); + node = __findChild(tmpParent, key); + if (!node) { + this.warn( + "loadKeyPath: key not found: " + + key + + " (parent: " + + tmpParent + + ")" + ); + opts.callback(this, key, "error"); + break; + } else if (segList.length === 0) { + opts.callback(this, node, "ok"); + break; + } else if (!node.lazy || node.hasChildren() !== undefined) { + opts.callback(this, node, "loaded"); + tmpParent = node; + } else { + opts.callback(this, node, "loaded"); + key = node.key; //target.segList.join(sep); + if (remainMap[key]) { + remainMap[key].pathSegList.push(segList); + } else { + remainMap[key] = { + parent: node, + pathSegList: [segList], + }; + } + break; + } + } + } + // console.log("_loadKeyPathImpl AFTER pass 1, remainMap=", remainMap); + + // Now load all lazy nodes and continue iteration for remaining paths + deferredList = []; + + // Avoid jshint warning 'Don't make functions within a loop.': + function __lazyload(dfd, parent, pathSegList) { + // console.log("__lazyload", parent, "pathSegList=", pathSegList); + opts.callback(self, parent, "loading"); + parent + .load() + .done(function () { + self._loadKeyPathImpl + .call(self, dfd, opts, parent, pathSegList) + .always(_makeResolveFunc(dfd, self)); + }) + .fail(function (errMsg) { + self.warn("loadKeyPath: error loading lazy " + parent); + opts.callback(self, node, "error"); + dfd.rejectWith(self); + }); + } + // remainMap contains parent nodes, each with a list of relative sub-paths. + // We start loading all of them now, and pass the the list to each loader. + for (nodeKey in remainMap) { + if (_hasProp(remainMap, nodeKey)) { + remain = remainMap[nodeKey]; + // console.log("for(): remain=", remain, "remainMap=", remainMap); + // key = remain.segList.shift(); + // node = __findChild(remain.parent, key); + // if (node == null) { // #576 + // // Issue #576, refactored for v2.27: + // // The root cause was, that sometimes the wrong parent was used here + // // to find the next segment. + // // Falling back to getNodeByKey() was a hack that no longer works if a custom + // // matcher is used, because we cannot assume that a single segment-key is unique + // // throughout the tree. + // self.error("loadKeyPath: error loading child by key '" + key + "' (parent: " + target.parent + ")", target); + // // node = self.getNodeByKey(key); + // continue; + // } + subDfd = new $.Deferred(); + deferredList.push(subDfd); + __lazyload(subDfd, remain.parent, remain.pathSegList); + } + } + // Return a promise that is resolved, when ALL paths were loaded + return $.when.apply($, deferredList).promise(); + }, + /** Re-fire beforeActivate, activate, and (optional) focus events. + * Calling this method in the `init` event, will activate the node that + * was marked 'active' in the source data, and optionally set the keyboard + * focus. + * @param [setFocus=false] + */ + reactivate: function (setFocus) { + var res, + node = this.activeNode; + + if (!node) { + return _getResolvedPromise(); + } + this.activeNode = null; // Force re-activating + res = node.setActive(true, { noFocus: true }); + if (setFocus) { + node.setFocus(); + } + return res; + }, + /** Reload tree from source and return a promise. + * @param [source] optional new source (defaults to initial source data) + * @returns {$.Promise} + */ + reload: function (source) { + this._callHook("treeClear", this); + return this._callHook("treeLoad", this, source); + }, + /**Render tree (i.e. create DOM elements for all top-level nodes). + * @param {boolean} [force=false] create DOM elemnts, even if parent is collapsed + * @param {boolean} [deep=false] + */ + render: function (force, deep) { + return this.rootNode.render(force, deep); + }, + /**(De)select all nodes. + * @param {boolean} [flag=true] + * @since 2.28 + */ + selectAll: function (flag) { + this.visit(function (node) { + node.setSelected(flag); + }); + }, + // TODO: selectKey: function(key, select) + // TODO: serializeArray: function(stopOnParents) + /** + * @param {boolean} [flag=true] + */ + setFocus: function (flag) { + return this._callHook("treeSetFocus", this, flag); + }, + /** + * Set current option value. + * (Note: this is the preferred variant of `$().fancytree("option", "KEY", VALUE)`) + * @param {string} name option name (may contain '.') + * @param {any} new value + */ + setOption: function (optionName, value) { + return this.widget.option(optionName, value); + }, + /** + * Call console.time() when in debug mode (verbose >= 4). + * + * @param {string} label + */ + debugTime: function (label) { + if (this.options.debugLevel >= 4) { + window.console.time(this + " - " + label); + } + }, + /** + * Call console.timeEnd() when in debug mode (verbose >= 4). + * + * @param {string} label + */ + debugTimeEnd: function (label) { + if (this.options.debugLevel >= 4) { + window.console.timeEnd(this + " - " + label); + } + }, + /** + * Return all nodes as nested list of {@link NodeData}. + * + * @param {boolean} [includeRoot=false] Returns the hidden system root node (and its children) + * @param {function} [callback] callback(dict, node) is called for every node, in order to allow modifications. + * Return `false` to ignore this node or "skip" to include this node without its children. + * @returns {Array | object} + * @see FancytreeNode#toDict + */ + toDict: function (includeRoot, callback) { + var res = this.rootNode.toDict(true, callback); + return includeRoot ? res : res.children; + }, + /* Implicitly called for string conversions. + * @returns {string} + */ + toString: function () { + return "Fancytree@" + this._id; + // return "<Fancytree(#" + this._id + ")>"; + }, + /* _trigger a widget event with additional node ctx. + * @see EventData + */ + _triggerNodeEvent: function (type, node, originalEvent, extra) { + // this.debug("_trigger(" + type + "): '" + ctx.node.title + "'", ctx); + var ctx = this._makeHookContext(node, originalEvent, extra), + res = this.widget._trigger(type, originalEvent, ctx); + if (res !== false && ctx.result !== undefined) { + return ctx.result; + } + return res; + }, + /* _trigger a widget event with additional tree data. */ + _triggerTreeEvent: function (type, originalEvent, extra) { + // this.debug("_trigger(" + type + ")", ctx); + var ctx = this._makeHookContext(this, originalEvent, extra), + res = this.widget._trigger(type, originalEvent, ctx); + + if (res !== false && ctx.result !== undefined) { + return ctx.result; + } + return res; + }, + /** Call fn(node) for all nodes in hierarchical order (depth-first). + * + * @param {function} fn the callback function. + * Return false to stop iteration, return "skip" to skip this node and children only. + * @returns {boolean} false, if the iterator was stopped. + */ + visit: function (fn) { + return this.rootNode.visit(fn, false); + }, + /** Call fn(node) for all nodes in vertical order, top down (or bottom up).<br> + * Stop iteration, if fn() returns false.<br> + * Return false if iteration was stopped. + * + * @param {function} fn the callback function. + * Return false to stop iteration, return "skip" to skip this node and children only. + * @param {object} [options] + * Defaults: + * {start: First top node, reverse: false, includeSelf: true, includeHidden: false} + * @returns {boolean} false if iteration was cancelled + * @since 2.28 + */ + visitRows: function (fn, opts) { + if (!this.rootNode.hasChildren()) { + return false; + } + if (opts && opts.reverse) { + delete opts.reverse; + return this._visitRowsUp(fn, opts); + } + opts = opts || {}; + + var i, + nextIdx, + parent, + res, + siblings, + siblingOfs = 0, + skipFirstNode = opts.includeSelf === false, + includeHidden = !!opts.includeHidden, + checkFilter = !includeHidden && this.enableFilter, + node = opts.start || this.rootNode.children[0]; + + parent = node.parent; + while (parent) { + // visit siblings + siblings = parent.children; + nextIdx = siblings.indexOf(node) + siblingOfs; + _assert( + nextIdx >= 0, + "Could not find " + + node + + " in parent's children: " + + parent + ); + + for (i = nextIdx; i < siblings.length; i++) { + node = siblings[i]; + if (checkFilter && !node.match && !node.subMatchCount) { + continue; + } + if (!skipFirstNode && fn(node) === false) { + return false; + } + skipFirstNode = false; + // Dive into node's child nodes + if ( + node.children && + node.children.length && + (includeHidden || node.expanded) + ) { + // Disable warning: Functions declared within loops referencing an outer + // scoped variable may lead to confusing semantics: + /*jshint -W083 */ + res = node.visit(function (n) { + if (checkFilter && !n.match && !n.subMatchCount) { + return "skip"; + } + if (fn(n) === false) { + return false; + } + if (!includeHidden && n.children && !n.expanded) { + return "skip"; + } + }, false); + /*jshint +W083 */ + if (res === false) { + return false; + } + } + } + // Visit parent nodes (bottom up) + node = parent; + parent = parent.parent; + siblingOfs = 1; // + } + return true; + }, + /* Call fn(node) for all nodes in vertical order, bottom up. + */ + _visitRowsUp: function (fn, opts) { + var children, + idx, + parent, + includeHidden = !!opts.includeHidden, + node = opts.start || this.rootNode.children[0]; + + while (true) { + parent = node.parent; + children = parent.children; + + if (children[0] === node) { + // If this is already the first sibling, goto parent + node = parent; + if (!node.parent) { + break; // first node of the tree + } + children = parent.children; + } else { + // Otherwise, goto prev. sibling + idx = children.indexOf(node); + node = children[idx - 1]; + // If the prev. sibling has children, follow down to last descendant + while ( + // See: https://github.com/eslint/eslint/issues/11302 + // eslint-disable-next-line no-unmodified-loop-condition + (includeHidden || node.expanded) && + node.children && + node.children.length + ) { + children = node.children; + parent = node; + node = children[children.length - 1]; + } + } + // Skip invisible + if (!includeHidden && !node.isVisible()) { + continue; + } + if (fn(node) === false) { + return false; + } + } + }, + /** Write warning to browser console if debugLevel >= 2 (prepending tree info) + * + * @param {*} msg string or object or array of such + */ + warn: function (msg) { + if (this.options.debugLevel >= 2) { + Array.prototype.unshift.call(arguments, this.toString()); + consoleApply("warn", arguments); + } + }, + }; + + /** + * These additional methods of the {@link Fancytree} class are 'hook functions' + * that can be used and overloaded by extensions. + * + * @see [writing extensions](https://github.com/mar10/fancytree/wiki/TutorialExtensions) + * @mixin Fancytree_Hooks + */ + $.extend( + Fancytree.prototype, + /** @lends Fancytree_Hooks# */ + { + /** Default handling for mouse click events. + * + * @param {EventData} ctx + */ + nodeClick: function (ctx) { + var activate, + expand, + // event = ctx.originalEvent, + targetType = ctx.targetType, + node = ctx.node; + + // this.debug("ftnode.onClick(" + event.type + "): ftnode:" + this + ", button:" + event.button + ", which: " + event.which, ctx); + // TODO: use switch + // TODO: make sure clicks on embedded <input> doesn't steal focus (see table sample) + if (targetType === "expander") { + if (node.isLoading()) { + // #495: we probably got a click event while a lazy load is pending. + // The 'expanded' state is not yet set, so 'toggle' would expand + // and trigger lazyLoad again. + // It would be better to allow to collapse/expand the status node + // while loading (instead of ignoring), but that would require some + // more work. + node.debug("Got 2nd click while loading: ignored"); + return; + } + // Clicking the expander icon always expands/collapses + this._callHook("nodeToggleExpanded", ctx); + } else if (targetType === "checkbox") { + // Clicking the checkbox always (de)selects + this._callHook("nodeToggleSelected", ctx); + if (ctx.options.focusOnSelect) { + // #358 + this._callHook("nodeSetFocus", ctx, true); + } + } else { + // Honor `clickFolderMode` for + expand = false; + activate = true; + if (node.folder) { + switch (ctx.options.clickFolderMode) { + case 2: // expand only + expand = true; + activate = false; + break; + case 3: // expand and activate + activate = true; + expand = true; //!node.isExpanded(); + break; + // else 1 or 4: just activate + } + } + if (activate) { + this.nodeSetFocus(ctx); + this._callHook("nodeSetActive", ctx, true); + } + if (expand) { + if (!activate) { + // this._callHook("nodeSetFocus", ctx); + } + // this._callHook("nodeSetExpanded", ctx, true); + this._callHook("nodeToggleExpanded", ctx); + } + } + // Make sure that clicks stop, otherwise <a href='#'> jumps to the top + // if(event.target.localName === "a" && event.target.className === "fancytree-title"){ + // event.preventDefault(); + // } + // TODO: return promise? + }, + /** Collapse all other children of same parent. + * + * @param {EventData} ctx + * @param {object} callOpts + */ + nodeCollapseSiblings: function (ctx, callOpts) { + // TODO: return promise? + var ac, + i, + l, + node = ctx.node; + + if (node.parent) { + ac = node.parent.children; + for (i = 0, l = ac.length; i < l; i++) { + if (ac[i] !== node && ac[i].expanded) { + this._callHook( + "nodeSetExpanded", + ac[i], + false, + callOpts + ); + } + } + } + }, + /** Default handling for mouse douleclick events. + * @param {EventData} ctx + */ + nodeDblclick: function (ctx) { + // TODO: return promise? + if ( + ctx.targetType === "title" && + ctx.options.clickFolderMode === 4 + ) { + // this.nodeSetFocus(ctx); + // this._callHook("nodeSetActive", ctx, true); + this._callHook("nodeToggleExpanded", ctx); + } + // TODO: prevent text selection on dblclicks + if (ctx.targetType === "title") { + ctx.originalEvent.preventDefault(); + } + }, + /** Default handling for mouse keydown events. + * + * NOTE: this may be called with node == null if tree (but no node) has focus. + * @param {EventData} ctx + */ + nodeKeydown: function (ctx) { + // TODO: return promise? + var matchNode, + stamp, + _res, + focusNode, + event = ctx.originalEvent, + node = ctx.node, + tree = ctx.tree, + opts = ctx.options, + which = event.which, + // #909: Use event.key, to get unicode characters. + // We can't use `/\w/.test(key)`, because that would + // only detect plain ascii alpha-numerics. But we still need + // to ignore modifier-only, whitespace, cursor-keys, etc. + key = event.key || String.fromCharCode(which), + specialModifiers = !!( + event.altKey || + event.ctrlKey || + event.metaKey + ), + isAlnum = + !MODIFIERS[which] && + !SPECIAL_KEYCODES[which] && + !specialModifiers, + $target = $(event.target), + handled = true, + activate = !(event.ctrlKey || !opts.autoActivate); + + // (node || FT).debug("ftnode.nodeKeydown(" + event.type + "): ftnode:" + this + ", charCode:" + event.charCode + ", keyCode: " + event.keyCode + ", which: " + event.which); + // FT.debug( "eventToString(): " + FT.eventToString(event) + ", key='" + key + "', isAlnum: " + isAlnum ); + + // Set focus to active (or first node) if no other node has the focus yet + if (!node) { + focusNode = this.getActiveNode() || this.getFirstChild(); + if (focusNode) { + focusNode.setFocus(); + node = ctx.node = this.focusNode; + node.debug("Keydown force focus on active node"); + } + } + + if ( + opts.quicksearch && + isAlnum && + !$target.is(":input:enabled") + ) { + // Allow to search for longer streaks if typed in quickly + stamp = Date.now(); + if (stamp - tree.lastQuicksearchTime > 500) { + tree.lastQuicksearchTerm = ""; + } + tree.lastQuicksearchTime = stamp; + tree.lastQuicksearchTerm += key; + // tree.debug("quicksearch find", tree.lastQuicksearchTerm); + matchNode = tree.findNextNode( + tree.lastQuicksearchTerm, + tree.getActiveNode() + ); + if (matchNode) { + matchNode.setActive(); + } + event.preventDefault(); + return; + } + switch (FT.eventToString(event)) { + case "+": + case "=": // 187: '+' @ Chrome, Safari + tree.nodeSetExpanded(ctx, true); + break; + case "-": + tree.nodeSetExpanded(ctx, false); + break; + case "space": + if (node.isPagingNode()) { + tree._triggerNodeEvent("clickPaging", ctx, event); + } else if ( + FT.evalOption("checkbox", node, node, opts, false) + ) { + // #768 + tree.nodeToggleSelected(ctx); + } else { + tree.nodeSetActive(ctx, true); + } + break; + case "return": + tree.nodeSetActive(ctx, true); + break; + case "home": + case "end": + case "backspace": + case "left": + case "right": + case "up": + case "down": + _res = node.navigate(event.which, activate); + break; + default: + handled = false; + } + if (handled) { + event.preventDefault(); + } + }, + + // /** Default handling for mouse keypress events. */ + // nodeKeypress: function(ctx) { + // var event = ctx.originalEvent; + // }, + + // /** Trigger lazyLoad event (async). */ + // nodeLazyLoad: function(ctx) { + // var node = ctx.node; + // if(this._triggerNodeEvent()) + // }, + /** Load child nodes (async). + * + * @param {EventData} ctx + * @param {object[]|object|string|$.Promise|function} source + * @returns {$.Promise} The deferred will be resolved as soon as the (ajax) + * data was rendered. + */ + nodeLoadChildren: function (ctx, source) { + var ajax, + delay, + ajaxDfd = null, + resultDfd, + isAsync = true, + tree = ctx.tree, + node = ctx.node, + nodePrevParent = node.parent, + tag = "nodeLoadChildren", + requestId = Date.now(); + + // `source` is a callback: use the returned result instead: + if (_isFunction(source)) { + source = source.call(tree, { type: "source" }, ctx); + _assert( + !_isFunction(source), + "source callback must not return another function" + ); + } + // `source` is already a promise: + if (_isFunction(source.then)) { + // _assert(_isFunction(source.always), "Expected jQuery?"); + ajaxDfd = source; + } else if (source.url) { + // `source` is an Ajax options object + ajax = $.extend({}, ctx.options.ajax, source); + if (ajax.debugDelay) { + // Simulate a slow server + delay = ajax.debugDelay; + delete ajax.debugDelay; // remove debug option + if (_isArray(delay)) { + // random delay range [min..max] + delay = + delay[0] + + Math.random() * (delay[1] - delay[0]); + } + node.warn( + "nodeLoadChildren waiting debugDelay " + + Math.round(delay) + + " ms ..." + ); + ajaxDfd = $.Deferred(function (ajaxDfd) { + setTimeout(function () { + $.ajax(ajax) + .done(function () { + ajaxDfd.resolveWith(this, arguments); + }) + .fail(function () { + ajaxDfd.rejectWith(this, arguments); + }); + }, delay); + }); + } else { + ajaxDfd = $.ajax(ajax); + } + } else if ($.isPlainObject(source) || _isArray(source)) { + // `source` is already a constant dict or list, but we convert + // to a thenable for unified processing. + // 2020-01-03: refactored. + // `ajaxDfd = $.when(source)` would do the trick, but the returned + // promise will resolve async, which broke some tests and + // would probably also break current implementations out there. + // So we mock-up a thenable that resolves synchronously: + ajaxDfd = { + then: function (resolve, reject) { + resolve(source, null, null); + }, + }; + isAsync = false; + } else { + $.error("Invalid source type: " + source); + } + + // Check for overlapping requests + if (node._requestId) { + node.warn( + "Recursive load request #" + + requestId + + " while #" + + node._requestId + + " is pending." + ); + node._requestId = requestId; + // node.debug("Send load request #" + requestId); + } + + if (isAsync) { + tree.debugTime(tag); + tree.nodeSetStatus(ctx, "loading"); + } + + // The async Ajax request has now started... + // Defer the deferred: + // we want to be able to reject invalid responses, even if + // the raw HTTP Ajax XHR resolved as Ok. + // We use the ajaxDfd.then() syntax here, which is compatible with + // jQuery and ECMA6. + // However resultDfd is a jQuery deferred, which is currently the + // expected result type of nodeLoadChildren() + resultDfd = new $.Deferred(); + ajaxDfd.then( + function (data, textStatus, jqXHR) { + // ajaxDfd was resolved, but we reject or resolve resultDfd + // depending on the response data + var errorObj, res; + + if ( + (source.dataType === "json" || + source.dataType === "jsonp") && + typeof data === "string" + ) { + $.error( + "Ajax request returned a string (did you get the JSON dataType wrong?)." + ); + } + if (node._requestId && node._requestId > requestId) { + // The expected request time stamp is later than `requestId` + // (which was kept as as closure variable to this handler function) + // node.warn("Ignored load response for obsolete request #" + requestId + " (expected #" + node._requestId + ")"); + resultDfd.rejectWith(this, [ + RECURSIVE_REQUEST_ERROR, + ]); + return; + // } else { + // node.debug("Response returned for load request #" + requestId); + } + if (node.parent === null && nodePrevParent !== null) { + resultDfd.rejectWith(this, [ + INVALID_REQUEST_TARGET_ERROR, + ]); + return; + } + // Allow to adjust the received response data in the `postProcess` event. + if (ctx.options.postProcess) { + // The handler may either + // - modify `ctx.response` in-place (and leave `ctx.result` undefined) + // => res = undefined + // - return a replacement in `ctx.result` + // => res = <new data> + // If res contains an `error` property, an error status is displayed + try { + res = tree._triggerNodeEvent( + "postProcess", + ctx, + ctx.originalEvent, + { + response: data, + error: null, + dataType: source.dataType, + } + ); + if (res.error) { + tree.warn( + "postProcess returned error:", + res + ); + } + } catch (e) { + res = { + error: e, + message: "" + e, + details: "postProcess failed", + }; + } + if (res.error) { + // Either postProcess failed with an exception, or the returned + // result object has an 'error' property attached: + errorObj = $.isPlainObject(res.error) + ? res.error + : { message: res.error }; + errorObj = tree._makeHookContext( + node, + null, + errorObj + ); + resultDfd.rejectWith(this, [errorObj]); + return; + } + if ( + _isArray(res) || + ($.isPlainObject(res) && _isArray(res.children)) + ) { + // Use `ctx.result` if valid + // (otherwise use existing data, which may have been modified in-place) + data = res; + } + } else if ( + data && + _hasProp(data, "d") && + ctx.options.enableAspx + ) { + // Process ASPX WebMethod JSON object inside "d" property + // (only if no postProcess event was defined) + if (ctx.options.enableAspx === 42) { + tree.warn( + "The default for enableAspx will change to `false` in the fututure. " + + "Pass `enableAspx: true` or implement postProcess to silence this warning." + ); + } + data = + typeof data.d === "string" + ? $.parseJSON(data.d) + : data.d; + } + resultDfd.resolveWith(this, [data]); + }, + function (jqXHR, textStatus, errorThrown) { + // ajaxDfd was rejected, so we reject resultDfd as well + var errorObj = tree._makeHookContext(node, null, { + error: jqXHR, + args: Array.prototype.slice.call(arguments), + message: errorThrown, + details: jqXHR.status + ": " + errorThrown, + }); + resultDfd.rejectWith(this, [errorObj]); + } + ); + + // The async Ajax request has now started. + // resultDfd will be resolved/rejected after the response arrived, + // was postProcessed, and checked. + // Now we implement the UI update and add the data to the tree. + // We also return this promise to the caller. + resultDfd + .done(function (data) { + tree.nodeSetStatus(ctx, "ok"); + var children, metaData, noDataRes; + + if ($.isPlainObject(data)) { + // We got {foo: 'abc', children: [...]} + // Copy extra properties to tree.data.foo + _assert( + node.isRootNode(), + "source may only be an object for root nodes (expecting an array of child objects otherwise)" + ); + _assert( + _isArray(data.children), + "if an object is passed as source, it must contain a 'children' array (all other properties are added to 'tree.data')" + ); + metaData = data; + children = data.children; + delete metaData.children; + // Copy some attributes to tree.data + $.each(TREE_ATTRS, function (i, attr) { + if (metaData[attr] !== undefined) { + tree[attr] = metaData[attr]; + delete metaData[attr]; + } + }); + // Copy all other attributes to tree.data.NAME + $.extend(tree.data, metaData); + } else { + children = data; + } + _assert( + _isArray(children), + "expected array of children" + ); + node._setChildren(children); + + if (tree.options.nodata && children.length === 0) { + if (_isFunction(tree.options.nodata)) { + noDataRes = tree.options.nodata.call( + tree, + { type: "nodata" }, + ctx + ); + } else if ( + tree.options.nodata === true && + node.isRootNode() + ) { + noDataRes = tree.options.strings.noData; + } else if ( + typeof tree.options.nodata === "string" && + node.isRootNode() + ) { + noDataRes = tree.options.nodata; + } + if (noDataRes) { + node.setStatus("nodata", noDataRes); + } + } + // trigger fancytreeloadchildren + tree._triggerNodeEvent("loadChildren", node); + }) + .fail(function (error) { + var ctxErr; + + if (error === RECURSIVE_REQUEST_ERROR) { + node.warn( + "Ignored response for obsolete load request #" + + requestId + + " (expected #" + + node._requestId + + ")" + ); + return; + } else if (error === INVALID_REQUEST_TARGET_ERROR) { + node.warn( + "Lazy parent node was removed while loading: discarding response." + ); + return; + } else if (error.node && error.error && error.message) { + // error is already a context object + ctxErr = error; + } else { + ctxErr = tree._makeHookContext(node, null, { + error: error, // it can be jqXHR or any custom error + args: Array.prototype.slice.call(arguments), + message: error + ? error.message || error.toString() + : "", + }); + if (ctxErr.message === "[object Object]") { + ctxErr.message = ""; + } + } + node.warn( + "Load children failed (" + ctxErr.message + ")", + ctxErr + ); + if ( + tree._triggerNodeEvent( + "loadError", + ctxErr, + null + ) !== false + ) { + tree.nodeSetStatus( + ctx, + "error", + ctxErr.message, + ctxErr.details + ); + } + }) + .always(function () { + node._requestId = null; + if (isAsync) { + tree.debugTimeEnd(tag); + } + }); + + return resultDfd.promise(); + }, + /** [Not Implemented] */ + nodeLoadKeyPath: function (ctx, keyPathList) { + // TODO: implement and improve + // http://code.google.com/p/dynatree/issues/detail?id=222 + }, + /** + * Remove a single direct child of ctx.node. + * @param {EventData} ctx + * @param {FancytreeNode} childNode dircect child of ctx.node + */ + nodeRemoveChild: function (ctx, childNode) { + var idx, + node = ctx.node, + // opts = ctx.options, + subCtx = $.extend({}, ctx, { node: childNode }), + children = node.children; + + // FT.debug("nodeRemoveChild()", node.toString(), childNode.toString()); + + if (children.length === 1) { + _assert(childNode === children[0], "invalid single child"); + return this.nodeRemoveChildren(ctx); + } + if ( + this.activeNode && + (childNode === this.activeNode || + this.activeNode.isDescendantOf(childNode)) + ) { + this.activeNode.setActive(false); // TODO: don't fire events + } + if ( + this.focusNode && + (childNode === this.focusNode || + this.focusNode.isDescendantOf(childNode)) + ) { + this.focusNode = null; + } + // TODO: persist must take care to clear select and expand cookies + this.nodeRemoveMarkup(subCtx); + this.nodeRemoveChildren(subCtx); + idx = $.inArray(childNode, children); + _assert(idx >= 0, "invalid child"); + // Notify listeners + node.triggerModifyChild("remove", childNode); + // Unlink to support GC + childNode.visit(function (n) { + n.parent = null; + }, true); + this._callHook("treeRegisterNode", this, false, childNode); + // remove from child list + children.splice(idx, 1); + }, + /**Remove HTML markup for all descendents of ctx.node. + * @param {EventData} ctx + */ + nodeRemoveChildMarkup: function (ctx) { + var node = ctx.node; + + // FT.debug("nodeRemoveChildMarkup()", node.toString()); + // TODO: Unlink attr.ftnode to support GC + if (node.ul) { + if (node.isRootNode()) { + $(node.ul).empty(); + } else { + $(node.ul).remove(); + node.ul = null; + } + node.visit(function (n) { + n.li = n.ul = null; + }); + } + }, + /**Remove all descendants of ctx.node. + * @param {EventData} ctx + */ + nodeRemoveChildren: function (ctx) { + var //subCtx, + tree = ctx.tree, + node = ctx.node, + children = node.children; + // opts = ctx.options; + + // FT.debug("nodeRemoveChildren()", node.toString()); + if (!children) { + return; + } + if (this.activeNode && this.activeNode.isDescendantOf(node)) { + this.activeNode.setActive(false); // TODO: don't fire events + } + if (this.focusNode && this.focusNode.isDescendantOf(node)) { + this.focusNode = null; + } + // TODO: persist must take care to clear select and expand cookies + this.nodeRemoveChildMarkup(ctx); + // Unlink children to support GC + // TODO: also delete this.children (not possible using visit()) + // subCtx = $.extend({}, ctx); + node.triggerModifyChild("remove", null); + node.visit(function (n) { + n.parent = null; + tree._callHook("treeRegisterNode", tree, false, n); + }); + if (node.lazy) { + // 'undefined' would be interpreted as 'not yet loaded' for lazy nodes + node.children = []; + } else { + node.children = null; + } + if (!node.isRootNode()) { + node.expanded = false; // #449, #459 + } + this.nodeRenderStatus(ctx); + }, + /**Remove HTML markup for ctx.node and all its descendents. + * @param {EventData} ctx + */ + nodeRemoveMarkup: function (ctx) { + var node = ctx.node; + // FT.debug("nodeRemoveMarkup()", node.toString()); + // TODO: Unlink attr.ftnode to support GC + if (node.li) { + $(node.li).remove(); + node.li = null; + } + this.nodeRemoveChildMarkup(ctx); + }, + /** + * Create `<li><span>..</span> .. </li>` tags for this node. + * + * This method takes care that all HTML markup is created that is required + * to display this node in its current state. + * + * Call this method to create new nodes, or after the strucuture + * was changed (e.g. after moving this node or adding/removing children) + * nodeRenderTitle() and nodeRenderStatus() are implied. + * + * ```html + * <li id='KEY' ftnode=NODE> + * <span class='fancytree-node fancytree-expanded fancytree-has-children fancytree-lastsib fancytree-exp-el fancytree-ico-e'> + * <span class="fancytree-expander"></span> + * <span class="fancytree-checkbox"></span> // only present in checkbox mode + * <span class="fancytree-icon"></span> + * <a href="#" class="fancytree-title"> Node 1 </a> + * </span> + * <ul> // only present if node has children + * <li id='KEY' ftnode=NODE> child1 ... </li> + * <li id='KEY' ftnode=NODE> child2 ... </li> + * </ul> + * </li> + * ``` + * + * @param {EventData} ctx + * @param {boolean} [force=false] re-render, even if html markup was already created + * @param {boolean} [deep=false] also render all descendants, even if parent is collapsed + * @param {boolean} [collapsed=false] force root node to be collapsed, so we can apply animated expand later + */ + nodeRender: function (ctx, force, deep, collapsed, _recursive) { + /* This method must take care of all cases where the current data mode + * (i.e. node hierarchy) does not match the current markup. + * + * - node was not yet rendered: + * create markup + * - node was rendered: exit fast + * - children have been added + * - children have been removed + */ + var childLI, + childNode1, + childNode2, + i, + l, + next, + subCtx, + node = ctx.node, + tree = ctx.tree, + opts = ctx.options, + aria = opts.aria, + firstTime = false, + parent = node.parent, + isRootNode = !parent, + children = node.children, + successorLi = null; + // FT.debug("nodeRender(" + !!force + ", " + !!deep + ")", node.toString()); + + if (tree._enableUpdate === false) { + // tree.debug("no render", tree._enableUpdate); + return; + } + if (!isRootNode && !parent.ul) { + // Calling node.collapse on a deep, unrendered node + return; + } + _assert(isRootNode || parent.ul, "parent UL must exist"); + + // Render the node + if (!isRootNode) { + // Discard markup on force-mode, or if it is not linked to parent <ul> + if ( + node.li && + (force || node.li.parentNode !== node.parent.ul) + ) { + if (node.li.parentNode === node.parent.ul) { + // #486: store following node, so we can insert the new markup there later + successorLi = node.li.nextSibling; + } else { + // May happen, when a top-level node was dropped over another + this.debug( + "Unlinking " + + node + + " (must be child of " + + node.parent + + ")" + ); + } + // this.debug("nodeRemoveMarkup..."); + this.nodeRemoveMarkup(ctx); + } + // Create <li><span /> </li> + // node.debug("render..."); + if (node.li) { + // this.nodeRenderTitle(ctx); + this.nodeRenderStatus(ctx); + } else { + // node.debug("render... really"); + firstTime = true; + node.li = document.createElement("li"); + node.li.ftnode = node; + + if (node.key && opts.generateIds) { + node.li.id = opts.idPrefix + node.key; + } + node.span = document.createElement("span"); + node.span.className = "fancytree-node"; + if (aria && !node.tr) { + $(node.li).attr("role", "treeitem"); + } + node.li.appendChild(node.span); + + // Create inner HTML for the <span> (expander, checkbox, icon, and title) + this.nodeRenderTitle(ctx); + + // Allow tweaking and binding, after node was created for the first time + if (opts.createNode) { + opts.createNode.call( + tree, + { type: "createNode" }, + ctx + ); + } + } + // Allow tweaking after node state was rendered + if (opts.renderNode) { + opts.renderNode.call(tree, { type: "renderNode" }, ctx); + } + } + + // Visit child nodes + if (children) { + if (isRootNode || node.expanded || deep === true) { + // Create a UL to hold the children + if (!node.ul) { + node.ul = document.createElement("ul"); + if ( + (collapsed === true && !_recursive) || + !node.expanded + ) { + // hide top UL, so we can use an animation to show it later + node.ul.style.display = "none"; + } + if (aria) { + $(node.ul).attr("role", "group"); + } + if (node.li) { + // issue #67 + node.li.appendChild(node.ul); + } else { + node.tree.$div.append(node.ul); + } + } + // Add child markup + for (i = 0, l = children.length; i < l; i++) { + subCtx = $.extend({}, ctx, { node: children[i] }); + this.nodeRender(subCtx, force, deep, false, true); + } + // Remove <li> if nodes have moved to another parent + childLI = node.ul.firstChild; + while (childLI) { + childNode2 = childLI.ftnode; + if (childNode2 && childNode2.parent !== node) { + node.debug( + "_fixParent: remove missing " + childNode2, + childLI + ); + next = childLI.nextSibling; + childLI.parentNode.removeChild(childLI); + childLI = next; + } else { + childLI = childLI.nextSibling; + } + } + // Make sure, that <li> order matches node.children order. + childLI = node.ul.firstChild; + for (i = 0, l = children.length - 1; i < l; i++) { + childNode1 = children[i]; + childNode2 = childLI.ftnode; + if (childNode1 === childNode2) { + childLI = childLI.nextSibling; + } else { + // node.debug("_fixOrder: mismatch at index " + i + ": " + childNode1 + " != " + childNode2); + node.ul.insertBefore( + childNode1.li, + childNode2.li + ); + } + } + } + } else { + // No children: remove markup if any + if (node.ul) { + // alert("remove child markup for " + node); + this.warn("remove child markup for " + node); + this.nodeRemoveChildMarkup(ctx); + } + } + if (!isRootNode) { + // Update element classes according to node state + // this.nodeRenderStatus(ctx); + // Finally add the whole structure to the DOM, so the browser can render + if (firstTime) { + // #486: successorLi is set, if we re-rendered (i.e. discarded) + // existing markup, which we want to insert at the same position. + // (null is equivalent to append) + // parent.ul.appendChild(node.li); + parent.ul.insertBefore(node.li, successorLi); + } + } + }, + /** Create HTML inside the node's outer `<span>` (i.e. expander, checkbox, + * icon, and title). + * + * nodeRenderStatus() is implied. + * @param {EventData} ctx + * @param {string} [title] optinal new title + */ + nodeRenderTitle: function (ctx, title) { + // set node connector images, links and text + var checkbox, + className, + icon, + nodeTitle, + role, + tabindex, + tooltip, + iconTooltip, + node = ctx.node, + tree = ctx.tree, + opts = ctx.options, + aria = opts.aria, + level = node.getLevel(), + ares = []; + + if (title !== undefined) { + node.title = title; + } + if (!node.span || tree._enableUpdate === false) { + // Silently bail out if node was not rendered yet, assuming + // node.render() will be called as the node becomes visible + return; + } + // Connector (expanded, expandable or simple) + role = + aria && node.hasChildren() !== false + ? " role='button'" + : ""; + if (level < opts.minExpandLevel) { + if (!node.lazy) { + node.expanded = true; + } + if (level > 1) { + ares.push( + "<span " + + role + + " class='fancytree-expander fancytree-expander-fixed'></span>" + ); + } + // .. else (i.e. for root level) skip expander/connector alltogether + } else { + ares.push( + "<span " + role + " class='fancytree-expander'></span>" + ); + } + // Checkbox mode + checkbox = FT.evalOption("checkbox", node, node, opts, false); + + if (checkbox && !node.isStatusNode()) { + role = aria ? " role='checkbox'" : ""; + className = "fancytree-checkbox"; + if ( + checkbox === "radio" || + (node.parent && node.parent.radiogroup) + ) { + className += " fancytree-radio"; + } + ares.push( + "<span " + role + " class='" + className + "'></span>" + ); + } + // Folder or doctype icon + if (node.data.iconClass !== undefined) { + // 2015-11-16 + // Handle / warn about backward compatibility + if (node.icon) { + $.error( + "'iconClass' node option is deprecated since v2.14.0: use 'icon' only instead" + ); + } else { + node.warn( + "'iconClass' node option is deprecated since v2.14.0: use 'icon' instead" + ); + node.icon = node.data.iconClass; + } + } + // If opts.icon is a callback and returns something other than undefined, use that + // else if node.icon is a boolean or string, use that + // else if opts.icon is a boolean or string, use that + // else show standard icon (which may be different for folders or documents) + icon = FT.evalOption("icon", node, node, opts, true); + // if( typeof icon !== "boolean" ) { + // // icon is defined, but not true/false: must be a string + // icon = "" + icon; + // } + if (icon !== false) { + role = aria ? " role='presentation'" : ""; + + iconTooltip = FT.evalOption( + "iconTooltip", + node, + node, + opts, + null + ); + iconTooltip = iconTooltip + ? " title='" + _escapeTooltip(iconTooltip) + "'" + : ""; + + if (typeof icon === "string") { + if (TEST_IMG.test(icon)) { + // node.icon is an image url. Prepend imagePath + icon = + icon.charAt(0) === "/" + ? icon + : (opts.imagePath || "") + icon; + ares.push( + "<img src='" + + icon + + "' class='fancytree-icon'" + + iconTooltip + + " alt='' />" + ); + } else { + ares.push( + "<span " + + role + + " class='fancytree-custom-icon " + + icon + + "'" + + iconTooltip + + "></span>" + ); + } + } else if (icon.text) { + ares.push( + "<span " + + role + + " class='fancytree-custom-icon " + + (icon.addClass || "") + + "'" + + iconTooltip + + ">" + + FT.escapeHtml(icon.text) + + "</span>" + ); + } else if (icon.html) { + ares.push( + "<span " + + role + + " class='fancytree-custom-icon " + + (icon.addClass || "") + + "'" + + iconTooltip + + ">" + + icon.html + + "</span>" + ); + } else { + // standard icon: theme css will take care of this + ares.push( + "<span " + + role + + " class='fancytree-icon'" + + iconTooltip + + "></span>" + ); + } + } + // Node title + nodeTitle = ""; + if (opts.renderTitle) { + nodeTitle = + opts.renderTitle.call( + tree, + { type: "renderTitle" }, + ctx + ) || ""; + } + if (!nodeTitle) { + tooltip = FT.evalOption("tooltip", node, node, opts, null); + if (tooltip === true) { + tooltip = node.title; + } + // if( node.tooltip ) { + // tooltip = node.tooltip; + // } else if ( opts.tooltip ) { + // tooltip = opts.tooltip === true ? node.title : opts.tooltip.call(tree, node); + // } + tooltip = tooltip + ? " title='" + _escapeTooltip(tooltip) + "'" + : ""; + tabindex = opts.titlesTabbable ? " tabindex='0'" : ""; + + nodeTitle = + "<span class='fancytree-title'" + + tooltip + + tabindex + + ">" + + (opts.escapeTitles + ? FT.escapeHtml(node.title) + : node.title) + + "</span>"; + } + ares.push(nodeTitle); + // Note: this will trigger focusout, if node had the focus + //$(node.span).html(ares.join("")); // it will cleanup the jQuery data currently associated with SPAN (if any), but it executes more slowly + node.span.innerHTML = ares.join(""); + // Update CSS classes + this.nodeRenderStatus(ctx); + if (opts.enhanceTitle) { + ctx.$title = $(">span.fancytree-title", node.span); + nodeTitle = + opts.enhanceTitle.call( + tree, + { type: "enhanceTitle" }, + ctx + ) || ""; + } + }, + /** Update element classes according to node state. + * @param {EventData} ctx + */ + nodeRenderStatus: function (ctx) { + // Set classes for current status + var $ariaElem, + node = ctx.node, + tree = ctx.tree, + opts = ctx.options, + // nodeContainer = node[tree.nodeContainerAttrName], + hasChildren = node.hasChildren(), + isLastSib = node.isLastSibling(), + aria = opts.aria, + cn = opts._classNames, + cnList = [], + statusElem = node[tree.statusClassPropName]; + + if (!statusElem || tree._enableUpdate === false) { + // if this function is called for an unrendered node, ignore it (will be updated on nect render anyway) + return; + } + if (aria) { + $ariaElem = $(node.tr || node.li); + } + // Build a list of class names that we will add to the node <span> + cnList.push(cn.node); + if (tree.activeNode === node) { + cnList.push(cn.active); + // $(">span.fancytree-title", statusElem).attr("tabindex", "0"); + // tree.$container.removeAttr("tabindex"); + // }else{ + // $(">span.fancytree-title", statusElem).removeAttr("tabindex"); + // tree.$container.attr("tabindex", "0"); + } + if (tree.focusNode === node) { + cnList.push(cn.focused); + } + if (node.expanded) { + cnList.push(cn.expanded); + } + if (aria) { + if (hasChildren === false) { + $ariaElem.removeAttr("aria-expanded"); + } else { + $ariaElem.attr("aria-expanded", Boolean(node.expanded)); + } + } + if (node.folder) { + cnList.push(cn.folder); + } + if (hasChildren !== false) { + cnList.push(cn.hasChildren); + } + // TODO: required? + if (isLastSib) { + cnList.push(cn.lastsib); + } + if (node.lazy && node.children == null) { + cnList.push(cn.lazy); + } + if (node.partload) { + cnList.push(cn.partload); + } + if (node.partsel) { + cnList.push(cn.partsel); + } + if (FT.evalOption("unselectable", node, node, opts, false)) { + cnList.push(cn.unselectable); + } + if (node._isLoading) { + cnList.push(cn.loading); + } + if (node._error) { + cnList.push(cn.error); + } + if (node.statusNodeType) { + cnList.push(cn.statusNodePrefix + node.statusNodeType); + } + if (node.selected) { + cnList.push(cn.selected); + if (aria) { + $ariaElem.attr("aria-selected", true); + } + } else if (aria) { + $ariaElem.attr("aria-selected", false); + } + if (node.extraClasses) { + cnList.push(node.extraClasses); + } + // IE6 doesn't correctly evaluate multiple class names, + // so we create combined class names that can be used in the CSS + if (hasChildren === false) { + cnList.push( + cn.combinedExpanderPrefix + "n" + (isLastSib ? "l" : "") + ); + } else { + cnList.push( + cn.combinedExpanderPrefix + + (node.expanded ? "e" : "c") + + (node.lazy && node.children == null ? "d" : "") + + (isLastSib ? "l" : "") + ); + } + cnList.push( + cn.combinedIconPrefix + + (node.expanded ? "e" : "c") + + (node.folder ? "f" : "") + ); + // node.span.className = cnList.join(" "); + statusElem.className = cnList.join(" "); + + // TODO: we should not set this in the <span> tag also, if we set it here: + // Maybe most (all) of the classes should be set in LI instead of SPAN? + if (node.li) { + // #719: we have to consider that there may be already other classes: + $(node.li).toggleClass(cn.lastsib, isLastSib); + } + }, + /** Activate node. + * flag defaults to true. + * If flag is true, the node is activated (must be a synchronous operation) + * If flag is false, the node is deactivated (must be a synchronous operation) + * @param {EventData} ctx + * @param {boolean} [flag=true] + * @param {object} [opts] additional options. Defaults to {noEvents: false, noFocus: false} + * @returns {$.Promise} + */ + nodeSetActive: function (ctx, flag, callOpts) { + // Handle user click / [space] / [enter], according to clickFolderMode. + callOpts = callOpts || {}; + var subCtx, + node = ctx.node, + tree = ctx.tree, + opts = ctx.options, + noEvents = callOpts.noEvents === true, + noFocus = callOpts.noFocus === true, + scroll = callOpts.scrollIntoView !== false, + isActive = node === tree.activeNode; + + // flag defaults to true + flag = flag !== false; + // node.debug("nodeSetActive", flag); + + if (isActive === flag) { + // Nothing to do + return _getResolvedPromise(node); + } + // #1042: don't scroll between mousedown/-up when clicking an embedded link + if ( + scroll && + ctx.originalEvent && + $(ctx.originalEvent.target).is("a,:checkbox") + ) { + node.info("Not scrolling while clicking an embedded link."); + scroll = false; + } + if ( + flag && + !noEvents && + this._triggerNodeEvent( + "beforeActivate", + node, + ctx.originalEvent + ) === false + ) { + // Callback returned false + return _getRejectedPromise(node, ["rejected"]); + } + if (flag) { + if (tree.activeNode) { + _assert( + tree.activeNode !== node, + "node was active (inconsistency)" + ); + subCtx = $.extend({}, ctx, { node: tree.activeNode }); + tree.nodeSetActive(subCtx, false); + _assert( + tree.activeNode === null, + "deactivate was out of sync?" + ); + } + + if (opts.activeVisible) { + // If no focus is set (noFocus: true) and there is no focused node, this node is made visible. + // scroll = noFocus && tree.focusNode == null; + // #863: scroll by default (unless `scrollIntoView: false` was passed) + node.makeVisible({ scrollIntoView: scroll }); + } + tree.activeNode = node; + tree.nodeRenderStatus(ctx); + if (!noFocus) { + tree.nodeSetFocus(ctx); + } + if (!noEvents) { + tree._triggerNodeEvent( + "activate", + node, + ctx.originalEvent + ); + } + } else { + _assert( + tree.activeNode === node, + "node was not active (inconsistency)" + ); + tree.activeNode = null; + this.nodeRenderStatus(ctx); + if (!noEvents) { + ctx.tree._triggerNodeEvent( + "deactivate", + node, + ctx.originalEvent + ); + } + } + return _getResolvedPromise(node); + }, + /** Expand or collapse node, return Deferred.promise. + * + * @param {EventData} ctx + * @param {boolean} [flag=true] + * @param {object} [opts] additional options. Defaults to `{noAnimation: false, noEvents: false}` + * @returns {$.Promise} The deferred will be resolved as soon as the (lazy) + * data was retrieved, rendered, and the expand animation finished. + */ + nodeSetExpanded: function (ctx, flag, callOpts) { + callOpts = callOpts || {}; + var _afterLoad, + dfd, + i, + l, + parents, + prevAC, + node = ctx.node, + tree = ctx.tree, + opts = ctx.options, + noAnimation = callOpts.noAnimation === true, + noEvents = callOpts.noEvents === true; + + // flag defaults to true + flag = flag !== false; + + // node.debug("nodeSetExpanded(" + flag + ")"); + + if ($(node.li).hasClass(opts._classNames.animating)) { + node.warn( + "setExpanded(" + flag + ") while animating: ignored." + ); + return _getRejectedPromise(node, ["recursion"]); + } + + if ((node.expanded && flag) || (!node.expanded && !flag)) { + // Nothing to do + // node.debug("nodeSetExpanded(" + flag + "): nothing to do"); + return _getResolvedPromise(node); + } else if (flag && !node.lazy && !node.hasChildren()) { + // Prevent expanding of empty nodes + // return _getRejectedPromise(node, ["empty"]); + return _getResolvedPromise(node); + } else if (!flag && node.getLevel() < opts.minExpandLevel) { + // Prevent collapsing locked levels + return _getRejectedPromise(node, ["locked"]); + } else if ( + !noEvents && + this._triggerNodeEvent( + "beforeExpand", + node, + ctx.originalEvent + ) === false + ) { + // Callback returned false + return _getRejectedPromise(node, ["rejected"]); + } + // If this node inside a collpased node, no animation and scrolling is needed + if (!noAnimation && !node.isVisible()) { + noAnimation = callOpts.noAnimation = true; + } + + dfd = new $.Deferred(); + + // Auto-collapse mode: collapse all siblings + if (flag && !node.expanded && opts.autoCollapse) { + parents = node.getParentList(false, true); + prevAC = opts.autoCollapse; + try { + opts.autoCollapse = false; + for (i = 0, l = parents.length; i < l; i++) { + // TODO: should return promise? + this._callHook( + "nodeCollapseSiblings", + parents[i], + callOpts + ); + } + } finally { + opts.autoCollapse = prevAC; + } + } + // Trigger expand/collapse after expanding + dfd.done(function () { + var lastChild = node.getLastChild(); + + if ( + flag && + opts.autoScroll && + !noAnimation && + lastChild && + tree._enableUpdate + ) { + // Scroll down to last child, but keep current node visible + lastChild + .scrollIntoView(true, { topNode: node }) + .always(function () { + if (!noEvents) { + ctx.tree._triggerNodeEvent( + flag ? "expand" : "collapse", + ctx + ); + } + }); + } else { + if (!noEvents) { + ctx.tree._triggerNodeEvent( + flag ? "expand" : "collapse", + ctx + ); + } + } + }); + // vvv Code below is executed after loading finished: + _afterLoad = function (callback) { + var cn = opts._classNames, + isVisible, + isExpanded, + effect = opts.toggleEffect; + + node.expanded = flag; + tree._callHook( + "treeStructureChanged", + ctx, + flag ? "expand" : "collapse" + ); + // Create required markup, but make sure the top UL is hidden, so we + // can animate later + tree._callHook("nodeRender", ctx, false, false, true); + + // Hide children, if node is collapsed + if (node.ul) { + isVisible = node.ul.style.display !== "none"; + isExpanded = !!node.expanded; + if (isVisible === isExpanded) { + node.warn( + "nodeSetExpanded: UL.style.display already set" + ); + } else if (!effect || noAnimation) { + node.ul.style.display = + node.expanded || !parent ? "" : "none"; + } else { + // The UI toggle() effect works with the ext-wide extension, + // while jQuery.animate() has problems when the title span + // has position: absolute. + // Since jQuery UI 1.12, the blind effect requires the parent + // element to have 'position: relative'. + // See #716, #717 + $(node.li).addClass(cn.animating); // #717 + + if (_isFunction($(node.ul)[effect.effect])) { + // tree.debug( "use jquery." + effect.effect + " method" ); + $(node.ul)[effect.effect]({ + duration: effect.duration, + always: function () { + // node.debug("fancytree-animating end: " + node.li.className); + $(this).removeClass(cn.animating); // #716 + $(node.li).removeClass(cn.animating); // #717 + callback(); + }, + }); + } else { + // The UI toggle() effect works with the ext-wide extension, + // while jQuery.animate() has problems when the title span + // has positon: absolute. + // Since jQuery UI 1.12, the blind effect requires the parent + // element to have 'position: relative'. + // See #716, #717 + // tree.debug("use specified effect (" + effect.effect + ") with the jqueryui.toggle method"); + + // try to stop an animation that might be already in progress + $(node.ul).stop(true, true); //< does not work after resetLazy has been called for a node whose animation wasn't complete and effect was "blind" + + // dirty fix to remove a defunct animation (effect: "blind") after resetLazy has been called + $(node.ul) + .parent() + .find(".ui-effects-placeholder") + .remove(); + + $(node.ul).toggle( + effect.effect, + effect.options, + effect.duration, + function () { + // node.debug("fancytree-animating end: " + node.li.className); + $(this).removeClass(cn.animating); // #716 + $(node.li).removeClass(cn.animating); // #717 + callback(); + } + ); + } + return; + } + } + callback(); + }; + // ^^^ Code above is executed after loading finshed. + + // Load lazy nodes, if any. Then continue with _afterLoad() + if (flag && node.lazy && node.hasChildren() === undefined) { + // node.debug("nodeSetExpanded: load start..."); + node.load() + .done(function () { + // node.debug("nodeSetExpanded: load done"); + if (dfd.notifyWith) { + // requires jQuery 1.6+ + dfd.notifyWith(node, ["loaded"]); + } + _afterLoad(function () { + dfd.resolveWith(node); + }); + }) + .fail(function (errMsg) { + _afterLoad(function () { + dfd.rejectWith(node, [ + "load failed (" + errMsg + ")", + ]); + }); + }); + /* + var source = tree._triggerNodeEvent("lazyLoad", node, ctx.originalEvent); + _assert(typeof source !== "boolean", "lazyLoad event must return source in data.result"); + node.debug("nodeSetExpanded: load start..."); + this._callHook("nodeLoadChildren", ctx, source).done(function(){ + node.debug("nodeSetExpanded: load done"); + if(dfd.notifyWith){ // requires jQuery 1.6+ + dfd.notifyWith(node, ["loaded"]); + } + _afterLoad.call(tree); + }).fail(function(errMsg){ + dfd.rejectWith(node, ["load failed (" + errMsg + ")"]); + }); + */ + } else { + _afterLoad(function () { + dfd.resolveWith(node); + }); + } + // node.debug("nodeSetExpanded: returns"); + return dfd.promise(); + }, + /** Focus or blur this node. + * @param {EventData} ctx + * @param {boolean} [flag=true] + */ + nodeSetFocus: function (ctx, flag) { + // ctx.node.debug("nodeSetFocus(" + flag + ")"); + var ctx2, + tree = ctx.tree, + node = ctx.node, + opts = tree.options, + // et = ctx.originalEvent && ctx.originalEvent.type, + isInput = ctx.originalEvent + ? $(ctx.originalEvent.target).is(":input") + : false; + + flag = flag !== false; + + // (node || tree).debug("nodeSetFocus(" + flag + "), event: " + et + ", isInput: "+ isInput); + // Blur previous node if any + if (tree.focusNode) { + if (tree.focusNode === node && flag) { + // node.debug("nodeSetFocus(" + flag + "): nothing to do"); + return; + } + ctx2 = $.extend({}, ctx, { node: tree.focusNode }); + tree.focusNode = null; + this._triggerNodeEvent("blur", ctx2); + this._callHook("nodeRenderStatus", ctx2); + } + // Set focus to container and node + if (flag) { + if (!this.hasFocus()) { + node.debug("nodeSetFocus: forcing container focus"); + this._callHook("treeSetFocus", ctx, true, { + calledByNode: true, + }); + } + node.makeVisible({ scrollIntoView: false }); + tree.focusNode = node; + if (opts.titlesTabbable) { + if (!isInput) { + // #621 + $(node.span).find(".fancytree-title").focus(); + } + } + if (opts.aria) { + // Set active descendant to node's span ID (create one, if needed) + $(tree.$container).attr( + "aria-activedescendant", + $(node.tr || node.li) + .uniqueId() + .attr("id") + ); + // "ftal_" + opts.idPrefix + node.key); + } + // $(node.span).find(".fancytree-title").focus(); + this._triggerNodeEvent("focus", ctx); + + // determine if we have focus on or inside tree container + var hasFancytreeFocus = + document.activeElement === tree.$container.get(0) || + $(document.activeElement, tree.$container).length >= 1; + + if (!hasFancytreeFocus) { + // We cannot set KB focus to a node, so use the tree container + // #563, #570: IE scrolls on every call to .focus(), if the container + // is partially outside the viewport. So do it only, when absolutely + // necessary. + $(tree.$container).focus(); + } + + // if( opts.autoActivate ){ + // tree.nodeSetActive(ctx, true); + // } + if (opts.autoScroll) { + node.scrollIntoView(); + } + this._callHook("nodeRenderStatus", ctx); + } + }, + /** (De)Select node, return new status (sync). + * + * @param {EventData} ctx + * @param {boolean} [flag=true] + * @param {object} [opts] additional options. Defaults to {noEvents: false, + * propagateDown: null, propagateUp: null, + * callback: null, + * } + * @returns {boolean} previous status + */ + nodeSetSelected: function (ctx, flag, callOpts) { + callOpts = callOpts || {}; + var node = ctx.node, + tree = ctx.tree, + opts = ctx.options, + noEvents = callOpts.noEvents === true, + parent = node.parent; + + // flag defaults to true + flag = flag !== false; + + // node.debug("nodeSetSelected(" + flag + ")", ctx); + + // Cannot (de)select unselectable nodes directly (only by propagation or + // by setting the `.selected` property) + if (FT.evalOption("unselectable", node, node, opts, false)) { + return; + } + + // Remember the user's intent, in case down -> up propagation prevents + // applying it to node.selected + node._lastSelectIntent = flag; // Confusing use of '!' + + // Nothing to do? + if (!!node.selected === flag) { + if (opts.selectMode === 3 && node.partsel && !flag) { + // If propagation prevented selecting this node last time, we still + // want to allow to apply setSelected(false) now + } else { + return flag; + } + } + + if ( + !noEvents && + this._triggerNodeEvent( + "beforeSelect", + node, + ctx.originalEvent + ) === false + ) { + return !!node.selected; + } + if (flag && opts.selectMode === 1) { + // single selection mode (we don't uncheck all tree nodes, for performance reasons) + if (tree.lastSelectedNode) { + tree.lastSelectedNode.setSelected(false); + } + node.selected = flag; + } else if ( + opts.selectMode === 3 && + parent && + !parent.radiogroup && + !node.radiogroup + ) { + // multi-hierarchical selection mode + node.selected = flag; + node.fixSelection3AfterClick(callOpts); + } else if (parent && parent.radiogroup) { + node.visitSiblings(function (n) { + n._changeSelectStatusAttrs(flag && n === node); + }, true); + } else { + // default: selectMode: 2, multi selection mode + node.selected = flag; + } + this.nodeRenderStatus(ctx); + tree.lastSelectedNode = flag ? node : null; + if (!noEvents) { + tree._triggerNodeEvent("select", ctx); + } + }, + /** Show node status (ok, loading, error, nodata) using styles and a dummy child node. + * + * @param {EventData} ctx + * @param status + * @param message + * @param details + * @since 2.3 + */ + nodeSetStatus: function (ctx, status, message, details) { + var node = ctx.node, + tree = ctx.tree; + + function _clearStatusNode() { + // Remove dedicated dummy node, if any + var firstChild = node.children ? node.children[0] : null; + if (firstChild && firstChild.isStatusNode()) { + try { + // I've seen exceptions here with loadKeyPath... + if (node.ul) { + node.ul.removeChild(firstChild.li); + firstChild.li = null; // avoid leaks (DT issue 215) + } + } catch (e) {} + if (node.children.length === 1) { + node.children = []; + } else { + node.children.shift(); + } + tree._callHook( + "treeStructureChanged", + ctx, + "clearStatusNode" + ); + } + } + function _setStatusNode(data, type) { + // Create/modify the dedicated dummy node for 'loading...' or + // 'error!' status. (only called for direct child of the invisible + // system root) + var firstChild = node.children ? node.children[0] : null; + if (firstChild && firstChild.isStatusNode()) { + $.extend(firstChild, data); + firstChild.statusNodeType = type; + tree._callHook("nodeRenderTitle", firstChild); + } else { + node._setChildren([data]); + tree._callHook( + "treeStructureChanged", + ctx, + "setStatusNode" + ); + node.children[0].statusNodeType = type; + tree.render(); + } + return node.children[0]; + } + + switch (status) { + case "ok": + _clearStatusNode(); + node._isLoading = false; + node._error = null; + node.renderStatus(); + break; + case "loading": + if (!node.parent) { + _setStatusNode( + { + title: + tree.options.strings.loading + + (message ? " (" + message + ")" : ""), + // icon: true, // needed for 'loding' icon + checkbox: false, + tooltip: details, + }, + status + ); + } + node._isLoading = true; + node._error = null; + node.renderStatus(); + break; + case "error": + _setStatusNode( + { + title: + tree.options.strings.loadError + + (message ? " (" + message + ")" : ""), + // icon: false, + checkbox: false, + tooltip: details, + }, + status + ); + node._isLoading = false; + node._error = { message: message, details: details }; + node.renderStatus(); + break; + case "nodata": + _setStatusNode( + { + title: message || tree.options.strings.noData, + // icon: false, + checkbox: false, + tooltip: details, + }, + status + ); + node._isLoading = false; + node._error = null; + node.renderStatus(); + break; + default: + $.error("invalid node status " + status); + } + }, + /** + * + * @param {EventData} ctx + */ + nodeToggleExpanded: function (ctx) { + return this.nodeSetExpanded(ctx, !ctx.node.expanded); + }, + /** + * @param {EventData} ctx + */ + nodeToggleSelected: function (ctx) { + var node = ctx.node, + flag = !node.selected; + + // In selectMode: 3 this node may be unselected+partsel, even if + // setSelected(true) was called before, due to `unselectable` children. + // In this case, we now toggle as `setSelected(false)` + if ( + node.partsel && + !node.selected && + node._lastSelectIntent === true + ) { + flag = false; + node.selected = true; // so it is not considered 'nothing to do' + } + node._lastSelectIntent = flag; + return this.nodeSetSelected(ctx, flag); + }, + /** Remove all nodes. + * @param {EventData} ctx + */ + treeClear: function (ctx) { + var tree = ctx.tree; + tree.activeNode = null; + tree.focusNode = null; + tree.$div.find(">ul.fancytree-container").empty(); + // TODO: call destructors and remove reference loops + tree.rootNode.children = null; + tree._callHook("treeStructureChanged", ctx, "clear"); + }, + /** Widget was created (called only once, even it re-initialized). + * @param {EventData} ctx + */ + treeCreate: function (ctx) {}, + /** Widget was destroyed. + * @param {EventData} ctx + */ + treeDestroy: function (ctx) { + this.$div.find(">ul.fancytree-container").remove(); + if (this.$source) { + this.$source.removeClass("fancytree-helper-hidden"); + } + }, + /** Widget was (re-)initialized. + * @param {EventData} ctx + */ + treeInit: function (ctx) { + var tree = ctx.tree, + opts = tree.options; + + //this.debug("Fancytree.treeInit()"); + // Add container to the TAB chain + // See http://www.w3.org/TR/wai-aria-practices/#focus_activedescendant + // #577: Allow to set tabindex to "0", "-1" and "" + tree.$container.attr("tabindex", opts.tabindex); + + // Copy some attributes to tree.data + $.each(TREE_ATTRS, function (i, attr) { + if (opts[attr] !== undefined) { + tree.info("Move option " + attr + " to tree"); + tree[attr] = opts[attr]; + delete opts[attr]; + } + }); + + if (opts.checkboxAutoHide) { + tree.$container.addClass("fancytree-checkbox-auto-hide"); + } + if (opts.rtl) { + tree.$container + .attr("DIR", "RTL") + .addClass("fancytree-rtl"); + } else { + tree.$container + .removeAttr("DIR") + .removeClass("fancytree-rtl"); + } + if (opts.aria) { + tree.$container.attr("role", "tree"); + if (opts.selectMode !== 1) { + tree.$container.attr("aria-multiselectable", true); + } + } + this.treeLoad(ctx); + }, + /** Parse Fancytree from source, as configured in the options. + * @param {EventData} ctx + * @param {object} [source] optional new source (use last data otherwise) + */ + treeLoad: function (ctx, source) { + var metaData, + type, + $ul, + tree = ctx.tree, + $container = ctx.widget.element, + dfd, + // calling context for root node + rootCtx = $.extend({}, ctx, { node: this.rootNode }); + + if (tree.rootNode.children) { + this.treeClear(ctx); + } + source = source || this.options.source; + + if (!source) { + type = $container.data("type") || "html"; + switch (type) { + case "html": + // There should be an embedded `<ul>` with initial nodes, + // but another `<ul class='fancytree-container'>` is appended + // to the tree's <div> on startup anyway. + $ul = $container + .find(">ul") + .not(".fancytree-container") + .first(); + + if ($ul.length) { + $ul.addClass( + "ui-fancytree-source fancytree-helper-hidden" + ); + source = $.ui.fancytree.parseHtml($ul); + // allow to init tree.data.foo from <ul data-foo=''> + this.data = $.extend( + this.data, + _getElementDataAsDict($ul) + ); + } else { + FT.warn( + "No `source` option was passed and container does not contain `<ul>`: assuming `source: []`." + ); + source = []; + } + break; + case "json": + source = $.parseJSON($container.text()); + // $container already contains the <ul>, but we remove the plain (json) text + // $container.empty(); + $container + .contents() + .filter(function () { + return this.nodeType === 3; + }) + .remove(); + if ($.isPlainObject(source)) { + // We got {foo: 'abc', children: [...]} + _assert( + _isArray(source.children), + "if an object is passed as source, it must contain a 'children' array (all other properties are added to 'tree.data')" + ); + metaData = source; + source = source.children; + delete metaData.children; + // Copy some attributes to tree.data + $.each(TREE_ATTRS, function (i, attr) { + if (metaData[attr] !== undefined) { + tree[attr] = metaData[attr]; + delete metaData[attr]; + } + }); + // Copy extra properties to tree.data.foo + $.extend(tree.data, metaData); + } + break; + default: + $.error("Invalid data-type: " + type); + } + } else if (typeof source === "string") { + // TODO: source is an element ID + $.error("Not implemented"); + } + + // preInit is fired when the widget markup is created, but nodes + // not yet loaded + tree._triggerTreeEvent("preInit", null); + + // Trigger fancytreeinit after nodes have been loaded + dfd = this.nodeLoadChildren(rootCtx, source) + .done(function () { + tree._callHook( + "treeStructureChanged", + ctx, + "loadChildren" + ); + tree.render(); + if (ctx.options.selectMode === 3) { + tree.rootNode.fixSelection3FromEndNodes(); + } + if (tree.activeNode && tree.options.activeVisible) { + tree.activeNode.makeVisible(); + } + tree._triggerTreeEvent("init", null, { status: true }); + }) + .fail(function () { + tree.render(); + tree._triggerTreeEvent("init", null, { status: false }); + }); + return dfd; + }, + /** Node was inserted into or removed from the tree. + * @param {EventData} ctx + * @param {boolean} add + * @param {FancytreeNode} node + */ + treeRegisterNode: function (ctx, add, node) { + ctx.tree._callHook( + "treeStructureChanged", + ctx, + add ? "addNode" : "removeNode" + ); + }, + /** Widget got focus. + * @param {EventData} ctx + * @param {boolean} [flag=true] + */ + treeSetFocus: function (ctx, flag, callOpts) { + var targetNode; + + flag = flag !== false; + + // this.debug("treeSetFocus(" + flag + "), callOpts: ", callOpts, this.hasFocus()); + // this.debug(" focusNode: " + this.focusNode); + // this.debug(" activeNode: " + this.activeNode); + if (flag !== this.hasFocus()) { + this._hasFocus = flag; + if (!flag && this.focusNode) { + // Node also looses focus if widget blurs + this.focusNode.setFocus(false); + } else if (flag && (!callOpts || !callOpts.calledByNode)) { + $(this.$container).focus(); + } + this.$container.toggleClass("fancytree-treefocus", flag); + this._triggerTreeEvent(flag ? "focusTree" : "blurTree"); + if (flag && !this.activeNode) { + // #712: Use last mousedowned node ('click' event fires after focusin) + targetNode = + this._lastMousedownNode || this.getFirstChild(); + if (targetNode) { + targetNode.setFocus(); + } + } + } + }, + /** Widget option was set using `$().fancytree("option", "KEY", VALUE)`. + * + * Note: `key` may reference a nested option, e.g. 'dnd5.scroll'. + * In this case `value`contains the complete, modified `dnd5` option hash. + * We can check for changed values like + * if( value.scroll !== tree.options.dnd5.scroll ) {...} + * + * @param {EventData} ctx + * @param {string} key option name + * @param {any} value option value + */ + treeSetOption: function (ctx, key, value) { + var tree = ctx.tree, + callDefault = true, + callCreate = false, + callRender = false; + + switch (key) { + case "aria": + case "checkbox": + case "icon": + case "minExpandLevel": + case "tabindex": + // tree._callHook("treeCreate", tree); + callCreate = true; + callRender = true; + break; + case "checkboxAutoHide": + tree.$container.toggleClass( + "fancytree-checkbox-auto-hide", + !!value + ); + break; + case "escapeTitles": + case "tooltip": + callRender = true; + break; + case "rtl": + if (value === false) { + tree.$container + .removeAttr("DIR") + .removeClass("fancytree-rtl"); + } else { + tree.$container + .attr("DIR", "RTL") + .addClass("fancytree-rtl"); + } + callRender = true; + break; + case "source": + callDefault = false; + tree._callHook("treeLoad", tree, value); + callRender = true; + break; + } + tree.debug( + "set option " + + key + + "=" + + value + + " <" + + typeof value + + ">" + ); + if (callDefault) { + if (this.widget._super) { + // jQuery UI 1.9+ + this.widget._super.call(this.widget, key, value); + } else { + // jQuery UI <= 1.8, we have to manually invoke the _setOption method from the base widget + $.Widget.prototype._setOption.call( + this.widget, + key, + value + ); + } + } + if (callCreate) { + tree._callHook("treeCreate", tree); + } + if (callRender) { + tree.render(true, false); // force, not-deep + } + }, + /** A Node was added, removed, moved, or it's visibility changed. + * @param {EventData} ctx + */ + treeStructureChanged: function (ctx, type) {}, + } + ); + + /******************************************************************************* + * jQuery UI widget boilerplate + */ + + /** + * The plugin (derrived from [jQuery.Widget](http://api.jqueryui.com/jQuery.widget/)). + * + * **Note:** + * These methods implement the standard jQuery UI widget API. + * It is recommended to use methods of the {Fancytree} instance instead + * + * @example + * // DEPRECATED: Access jQuery UI widget methods and members: + * var tree = $("#tree").fancytree("getTree"); + * var node = $("#tree").fancytree("getActiveNode"); + * + * // RECOMMENDED: Use the Fancytree object API + * var tree = $.ui.fancytree.getTree("#tree"); + * var node = tree.getActiveNode(); + * + * // or you may already have stored the tree instance upon creation: + * import {createTree, version} from 'jquery.fancytree' + * const tree = createTree('#tree', { ... }); + * var node = tree.getActiveNode(); + * + * @see {Fancytree_Static#getTree} + * @deprecated Use methods of the {Fancytree} instance instead + * @mixin Fancytree_Widget + */ + + $.widget( + "ui.fancytree", + /** @lends Fancytree_Widget# */ + { + /**These options will be used as defaults + * @type {FancytreeOptions} + */ + options: { + activeVisible: true, + ajax: { + type: "GET", + cache: false, // false: Append random '_' argument to the request url to prevent caching. + // timeout: 0, // >0: Make sure we get an ajax error if server is unreachable + dataType: "json", // Expect json format and pass json object to callbacks. + }, + aria: true, + autoActivate: true, + autoCollapse: false, + autoScroll: false, + checkbox: false, + clickFolderMode: 4, + copyFunctionsToData: false, + debugLevel: null, // 0..4 (null: use global setting $.ui.fancytree.debugLevel) + disabled: false, // TODO: required anymore? + enableAspx: 42, // TODO: this is truethy, but distinguishable from true: default will change to false in the future + escapeTitles: false, + extensions: [], + focusOnSelect: false, + generateIds: false, + icon: true, + idPrefix: "ft_", + keyboard: true, + keyPathSeparator: "/", + minExpandLevel: 1, + nodata: true, // (bool, string, or callback) display message, when no data available + quicksearch: false, + rtl: false, + scrollOfs: { top: 0, bottom: 0 }, + scrollParent: null, + selectMode: 2, + strings: { + loading: "Loading...", // … would be escaped when escapeTitles is true + loadError: "Load error!", + moreData: "More...", + noData: "No data.", + }, + tabindex: "0", + titlesTabbable: false, + toggleEffect: { effect: "slideToggle", duration: 200 }, //< "toggle" or "slideToggle" to use jQuery instead of jQueryUI for toggleEffect animation + tooltip: false, + treeId: null, + _classNames: { + active: "fancytree-active", + animating: "fancytree-animating", + combinedExpanderPrefix: "fancytree-exp-", + combinedIconPrefix: "fancytree-ico-", + error: "fancytree-error", + expanded: "fancytree-expanded", + focused: "fancytree-focused", + folder: "fancytree-folder", + hasChildren: "fancytree-has-children", + lastsib: "fancytree-lastsib", + lazy: "fancytree-lazy", + loading: "fancytree-loading", + node: "fancytree-node", + partload: "fancytree-partload", + partsel: "fancytree-partsel", + radio: "fancytree-radio", + selected: "fancytree-selected", + statusNodePrefix: "fancytree-statusnode-", + unselectable: "fancytree-unselectable", + }, + // events + lazyLoad: null, + postProcess: null, + }, + _deprecationWarning: function (name) { + var tree = this.tree; + + if (tree && tree.options.debugLevel >= 3) { + tree.warn( + "$().fancytree('" + + name + + "') is deprecated (see https://wwwendt.de/tech/fancytree/doc/jsdoc/Fancytree_Widget.html" + ); + } + }, + /* Set up the widget, Called on first $().fancytree() */ + _create: function () { + this.tree = new Fancytree(this); + + this.$source = + this.source || this.element.data("type") === "json" + ? this.element + : this.element.find(">ul").first(); + // Subclass Fancytree instance with all enabled extensions + var extension, + extName, + i, + opts = this.options, + extensions = opts.extensions, + base = this.tree; + + for (i = 0; i < extensions.length; i++) { + extName = extensions[i]; + extension = $.ui.fancytree._extensions[extName]; + if (!extension) { + $.error( + "Could not apply extension '" + + extName + + "' (it is not registered, did you forget to include it?)" + ); + } + // Add extension options as tree.options.EXTENSION + // _assert(!this.tree.options[extName], "Extension name must not exist as option name: " + extName); + + // console.info("extend " + extName, extension.options, this.tree.options[extName]) + // issue #876: we want to replace custom array-options, not merge them + this.tree.options[extName] = _simpleDeepMerge( + {}, + extension.options, + this.tree.options[extName] + ); + // this.tree.options[extName] = $.extend(true, {}, extension.options, this.tree.options[extName]); + + // console.info("extend " + extName + " =>", this.tree.options[extName]) + // console.info("extend " + extName + " org default =>", extension.options) + + // Add a namespace tree.ext.EXTENSION, to hold instance data + _assert( + this.tree.ext[extName] === undefined, + "Extension name must not exist as Fancytree.ext attribute: '" + + extName + + "'" + ); + // this.tree[extName] = extension; + this.tree.ext[extName] = {}; + // Subclass Fancytree methods using proxies. + _subclassObject(this.tree, base, extension, extName); + // current extension becomes base for the next extension + base = extension; + } + // + if (opts.icons !== undefined) { + // 2015-11-16 + if (opts.icon === true) { + this.tree.warn( + "'icons' tree option is deprecated since v2.14.0: use 'icon' instead" + ); + opts.icon = opts.icons; + } else { + $.error( + "'icons' tree option is deprecated since v2.14.0: use 'icon' only instead" + ); + } + } + if (opts.iconClass !== undefined) { + // 2015-11-16 + if (opts.icon) { + $.error( + "'iconClass' tree option is deprecated since v2.14.0: use 'icon' only instead" + ); + } else { + this.tree.warn( + "'iconClass' tree option is deprecated since v2.14.0: use 'icon' instead" + ); + opts.icon = opts.iconClass; + } + } + if (opts.tabbable !== undefined) { + // 2016-04-04 + opts.tabindex = opts.tabbable ? "0" : "-1"; + this.tree.warn( + "'tabbable' tree option is deprecated since v2.17.0: use 'tabindex='" + + opts.tabindex + + "' instead" + ); + } + // + this.tree._callHook("treeCreate", this.tree); + // Note: 'fancytreecreate' event is fired by widget base class + // this.tree._triggerTreeEvent("create"); + }, + + /* Called on every $().fancytree() */ + _init: function () { + this.tree._callHook("treeInit", this.tree); + // TODO: currently we call bind after treeInit, because treeInit + // might change tree.$container. + // It would be better, to move event binding into hooks altogether + this._bind(); + }, + + /* Use the _setOption method to respond to changes to options. */ + _setOption: function (key, value) { + return this.tree._callHook( + "treeSetOption", + this.tree, + key, + value + ); + }, + + /** Use the destroy method to clean up any modifications your widget has made to the DOM */ + _destroy: function () { + this._unbind(); + this.tree._callHook("treeDestroy", this.tree); + // In jQuery UI 1.8, you must invoke the destroy method from the base widget + // $.Widget.prototype.destroy.call(this); + // TODO: delete tree and nodes to make garbage collect easier? + // TODO: In jQuery UI 1.9 and above, you would define _destroy instead of destroy and not call the base method + }, + + // ------------------------------------------------------------------------- + + /* Remove all event handlers for our namespace */ + _unbind: function () { + var ns = this.tree._ns; + this.element.off(ns); + this.tree.$container.off(ns); + $(document).off(ns); + }, + /* Add mouse and kyboard handlers to the container */ + _bind: function () { + var self = this, + opts = this.options, + tree = this.tree, + ns = tree._ns; + // selstartEvent = ( $.support.selectstart ? "selectstart" : "mousedown" ) + + // Remove all previuous handlers for this tree + this._unbind(); + + //alert("keydown" + ns + "foc=" + tree.hasFocus() + tree.$container); + // tree.debug("bind events; container: ", tree.$container); + tree.$container + .on("focusin" + ns + " focusout" + ns, function (event) { + var node = FT.getNode(event), + flag = event.type === "focusin"; + + if (!flag && node && $(event.target).is("a")) { + // #764 + node.debug( + "Ignored focusout on embedded <a> element." + ); + return; + } + // tree.treeOnFocusInOut.call(tree, event); + // tree.debug("Tree container got event " + event.type, node, event, FT.getEventTarget(event)); + if (flag) { + if (tree._getExpiringValue("focusin")) { + // #789: IE 11 may send duplicate focusin events + tree.debug("Ignored double focusin."); + return; + } + tree._setExpiringValue("focusin", true, 50); + + if (!node) { + // #789: IE 11 may send focusin before mousdown(?) + node = tree._getExpiringValue("mouseDownNode"); + if (node) { + tree.debug( + "Reconstruct mouse target for focusin from recent event." + ); + } + } + } + if (node) { + // For example clicking into an <input> that is part of a node + tree._callHook( + "nodeSetFocus", + tree._makeHookContext(node, event), + flag + ); + } else { + if ( + tree.tbody && + $(event.target).parents( + "table.fancytree-container > thead" + ).length + ) { + // #767: ignore events in the table's header + tree.debug( + "Ignore focus event outside table body.", + event + ); + } else { + tree._callHook("treeSetFocus", tree, flag); + } + } + }) + .on( + "selectstart" + ns, + "span.fancytree-title", + function (event) { + // prevent mouse-drags to select text ranges + // tree.debug("<span title> got event " + event.type); + event.preventDefault(); + } + ) + .on("keydown" + ns, function (event) { + // TODO: also bind keyup and keypress + // tree.debug("got event " + event.type + ", hasFocus:" + tree.hasFocus()); + // if(opts.disabled || opts.keyboard === false || !tree.hasFocus() ){ + if (opts.disabled || opts.keyboard === false) { + return true; + } + var res, + node = tree.focusNode, // node may be null + ctx = tree._makeHookContext(node || tree, event), + prevPhase = tree.phase; + + try { + tree.phase = "userEvent"; + // If a 'fancytreekeydown' handler returns false, skip the default + // handling (implemented by tree.nodeKeydown()). + if (node) { + res = tree._triggerNodeEvent( + "keydown", + node, + event + ); + } else { + res = tree._triggerTreeEvent("keydown", event); + } + if (res === "preventNav") { + res = true; // prevent keyboard navigation, but don't prevent default handling of embedded input controls + } else if (res !== false) { + res = tree._callHook("nodeKeydown", ctx); + } + return res; + } finally { + tree.phase = prevPhase; + } + }) + .on("mousedown" + ns, function (event) { + var et = FT.getEventTarget(event); + // self.tree.debug("event(" + event.type + "): node: ", et.node); + // #712: Store the clicked node, so we can use it when we get a focusin event + // ('click' event fires after focusin) + // tree.debug("event(" + event.type + "): node: ", et.node); + tree._lastMousedownNode = et ? et.node : null; + // #789: Store the node also for a short period, so we can use it + // in a *resulting* focusin event + tree._setExpiringValue( + "mouseDownNode", + tree._lastMousedownNode + ); + }) + .on("click" + ns + " dblclick" + ns, function (event) { + if (opts.disabled) { + return true; + } + var ctx, + et = FT.getEventTarget(event), + node = et.node, + tree = self.tree, + prevPhase = tree.phase; + + // self.tree.debug("event(" + event.type + "): node: ", node); + if (!node) { + return true; // Allow bubbling of other events + } + ctx = tree._makeHookContext(node, event); + // self.tree.debug("event(" + event.type + "): node: ", node); + try { + tree.phase = "userEvent"; + switch (event.type) { + case "click": + ctx.targetType = et.type; + if (node.isPagingNode()) { + return ( + tree._triggerNodeEvent( + "clickPaging", + ctx, + event + ) === true + ); + } + return tree._triggerNodeEvent( + "click", + ctx, + event + ) === false + ? false + : tree._callHook("nodeClick", ctx); + case "dblclick": + ctx.targetType = et.type; + return tree._triggerNodeEvent( + "dblclick", + ctx, + event + ) === false + ? false + : tree._callHook("nodeDblclick", ctx); + } + } finally { + tree.phase = prevPhase; + } + }); + }, + /** Return the active node or null. + * @returns {FancytreeNode} + * @deprecated Use methods of the Fancytree instance instead (<a href="Fancytree_Widget.html">example above</a>). + */ + getActiveNode: function () { + this._deprecationWarning("getActiveNode"); + return this.tree.activeNode; + }, + /** Return the matching node or null. + * @param {string} key + * @returns {FancytreeNode} + * @deprecated Use methods of the Fancytree instance instead (<a href="Fancytree_Widget.html">example above</a>). + */ + getNodeByKey: function (key) { + this._deprecationWarning("getNodeByKey"); + return this.tree.getNodeByKey(key); + }, + /** Return the invisible system root node. + * @returns {FancytreeNode} + * @deprecated Use methods of the Fancytree instance instead (<a href="Fancytree_Widget.html">example above</a>). + */ + getRootNode: function () { + this._deprecationWarning("getRootNode"); + return this.tree.rootNode; + }, + /** Return the current tree instance. + * @returns {Fancytree} + * @deprecated Use `$.ui.fancytree.getTree()` instead (<a href="Fancytree_Widget.html">example above</a>). + */ + getTree: function () { + this._deprecationWarning("getTree"); + return this.tree; + }, + } + ); + + // $.ui.fancytree was created by the widget factory. Create a local shortcut: + FT = $.ui.fancytree; + + /** + * Static members in the `$.ui.fancytree` namespace. + * This properties and methods can be accessed without instantiating a concrete + * Fancytree instance. + * + * @example + * // Access static members: + * var node = $.ui.fancytree.getNode(element); + * alert($.ui.fancytree.version); + * + * @mixin Fancytree_Static + */ + $.extend( + $.ui.fancytree, + /** @lends Fancytree_Static# */ + { + /** Version number `"MAJOR.MINOR.PATCH"` + * @type {string} */ + version: "2.38.3", // Set to semver by 'grunt release' + /** @type {string} + * @description `"production" for release builds` */ + buildType: "production", // Set to 'production' by 'grunt build' + /** @type {int} + * @description 0: silent .. 5: verbose (default: 3 for release builds). */ + debugLevel: 3, // Set to 3 by 'grunt build' + // Used by $.ui.fancytree.debug() and as default for tree.options.debugLevel + + _nextId: 1, + _nextNodeKey: 1, + _extensions: {}, + // focusTree: null, + + /** Expose class object as `$.ui.fancytree._FancytreeClass`. + * Useful to extend `$.ui.fancytree._FancytreeClass.prototype`. + * @type {Fancytree} + */ + _FancytreeClass: Fancytree, + /** Expose class object as $.ui.fancytree._FancytreeNodeClass + * Useful to extend `$.ui.fancytree._FancytreeNodeClass.prototype`. + * @type {FancytreeNode} + */ + _FancytreeNodeClass: FancytreeNode, + /* Feature checks to provide backwards compatibility */ + jquerySupports: { + // http://jqueryui.com/upgrade-guide/1.9/#deprecated-offset-option-merged-into-my-and-at + positionMyOfs: isVersionAtLeast($.ui.version, 1, 9), + }, + /** Throw an error if condition fails (debug method). + * @param {boolean} cond + * @param {string} msg + */ + assert: function (cond, msg) { + return _assert(cond, msg); + }, + /** Create a new Fancytree instance on a target element. + * + * @param {Element | jQueryObject | string} el Target DOM element or selector + * @param {FancytreeOptions} [opts] Fancytree options + * @returns {Fancytree} new tree instance + * @example + * var tree = $.ui.fancytree.createTree("#tree", { + * source: {url: "my/webservice"} + * }); // Create tree for this matching element + * + * @since 2.25 + */ + createTree: function (el, opts) { + var $tree = $(el).fancytree(opts); + return FT.getTree($tree); + }, + /** Return a function that executes *fn* at most every *timeout* ms. + * @param {integer} timeout + * @param {function} fn + * @param {boolean} [invokeAsap=false] + * @param {any} [ctx] + */ + debounce: function (timeout, fn, invokeAsap, ctx) { + var timer; + if (arguments.length === 3 && typeof invokeAsap !== "boolean") { + ctx = invokeAsap; + invokeAsap = false; + } + return function () { + var args = arguments; + ctx = ctx || this; + // eslint-disable-next-line no-unused-expressions + invokeAsap && !timer && fn.apply(ctx, args); + clearTimeout(timer); + timer = setTimeout(function () { + // eslint-disable-next-line no-unused-expressions + invokeAsap || fn.apply(ctx, args); + timer = null; + }, timeout); + }; + }, + /** Write message to console if debugLevel >= 4 + * @param {string} msg + */ + debug: function (msg) { + if ($.ui.fancytree.debugLevel >= 4) { + consoleApply("log", arguments); + } + }, + /** Write error message to console if debugLevel >= 1. + * @param {string} msg + */ + error: function (msg) { + if ($.ui.fancytree.debugLevel >= 1) { + consoleApply("error", arguments); + } + }, + /** Convert `<`, `>`, `&`, `"`, `'`, and `/` to the equivalent entities. + * + * @param {string} s + * @returns {string} + */ + escapeHtml: function (s) { + return ("" + s).replace(REX_HTML, function (s) { + return ENTITY_MAP[s]; + }); + }, + /** Make jQuery.position() arguments backwards compatible, i.e. if + * jQuery UI version <= 1.8, convert + * { my: "left+3 center", at: "left bottom", of: $target } + * to + * { my: "left center", at: "left bottom", of: $target, offset: "3 0" } + * + * See http://jqueryui.com/upgrade-guide/1.9/#deprecated-offset-option-merged-into-my-and-at + * and http://jsfiddle.net/mar10/6xtu9a4e/ + * + * @param {object} opts + * @returns {object} the (potentially modified) original opts hash object + */ + fixPositionOptions: function (opts) { + if (opts.offset || ("" + opts.my + opts.at).indexOf("%") >= 0) { + $.error( + "expected new position syntax (but '%' is not supported)" + ); + } + if (!$.ui.fancytree.jquerySupports.positionMyOfs) { + var // parse 'left+3 center' into ['left+3 center', 'left', '+3', 'center', undefined] + myParts = /(\w+)([+-]?\d+)?\s+(\w+)([+-]?\d+)?/.exec( + opts.my + ), + atParts = /(\w+)([+-]?\d+)?\s+(\w+)([+-]?\d+)?/.exec( + opts.at + ), + // convert to numbers + dx = + (myParts[2] ? +myParts[2] : 0) + + (atParts[2] ? +atParts[2] : 0), + dy = + (myParts[4] ? +myParts[4] : 0) + + (atParts[4] ? +atParts[4] : 0); + + opts = $.extend({}, opts, { + // make a copy and overwrite + my: myParts[1] + " " + myParts[3], + at: atParts[1] + " " + atParts[3], + }); + if (dx || dy) { + opts.offset = "" + dx + " " + dy; + } + } + return opts; + }, + /** Return a {node: FancytreeNode, type: TYPE} object for a mouse event. + * + * @param {Event} event Mouse event, e.g. click, ... + * @returns {object} Return a {node: FancytreeNode, type: TYPE} object + * TYPE: 'title' | 'prefix' | 'expander' | 'checkbox' | 'icon' | undefined + */ + getEventTarget: function (event) { + var $target, + tree, + tcn = event && event.target ? event.target.className : "", + res = { node: this.getNode(event.target), type: undefined }; + // We use a fast version of $(res.node).hasClass() + // See http://jsperf.com/test-for-classname/2 + if (/\bfancytree-title\b/.test(tcn)) { + res.type = "title"; + } else if (/\bfancytree-expander\b/.test(tcn)) { + res.type = + res.node.hasChildren() === false + ? "prefix" + : "expander"; + // }else if( /\bfancytree-checkbox\b/.test(tcn) || /\bfancytree-radio\b/.test(tcn) ){ + } else if (/\bfancytree-checkbox\b/.test(tcn)) { + res.type = "checkbox"; + } else if (/\bfancytree(-custom)?-icon\b/.test(tcn)) { + res.type = "icon"; + } else if (/\bfancytree-node\b/.test(tcn)) { + // Somewhere near the title + res.type = "title"; + } else if (event && event.target) { + $target = $(event.target); + if ($target.is("ul[role=group]")) { + // #nnn: Clicking right to a node may hit the surrounding UL + tree = res.node && res.node.tree; + (tree || FT).debug("Ignoring click on outer UL."); + res.node = null; + } else if ($target.closest(".fancytree-title").length) { + // #228: clicking an embedded element inside a title + res.type = "title"; + } else if ($target.closest(".fancytree-checkbox").length) { + // E.g. <svg> inside checkbox span + res.type = "checkbox"; + } else if ($target.closest(".fancytree-expander").length) { + res.type = "expander"; + } + } + return res; + }, + /** Return a string describing the affected node region for a mouse event. + * + * @param {Event} event Mouse event, e.g. click, mousemove, ... + * @returns {string} 'title' | 'prefix' | 'expander' | 'checkbox' | 'icon' | undefined + */ + getEventTargetType: function (event) { + return this.getEventTarget(event).type; + }, + /** Return a FancytreeNode instance from element, event, or jQuery object. + * + * @param {Element | jQueryObject | Event} el + * @returns {FancytreeNode} matching node or null + */ + getNode: function (el) { + if (el instanceof FancytreeNode) { + return el; // el already was a FancytreeNode + } else if (el instanceof $) { + el = el[0]; // el was a jQuery object: use the DOM element + } else if (el.originalEvent !== undefined) { + el = el.target; // el was an Event + } + while (el) { + if (el.ftnode) { + return el.ftnode; + } + el = el.parentNode; + } + return null; + }, + /** Return a Fancytree instance, from element, index, event, or jQueryObject. + * + * @param {Element | jQueryObject | Event | integer | string} [el] + * @returns {Fancytree} matching tree or null + * @example + * $.ui.fancytree.getTree(); // Get first Fancytree instance on page + * $.ui.fancytree.getTree(1); // Get second Fancytree instance on page + * $.ui.fancytree.getTree(event); // Get tree for this mouse- or keyboard event + * $.ui.fancytree.getTree("foo"); // Get tree for this `opts.treeId` + * $.ui.fancytree.getTree("#tree"); // Get tree for this matching element + * + * @since 2.13 + */ + getTree: function (el) { + var widget, + orgEl = el; + + if (el instanceof Fancytree) { + return el; // el already was a Fancytree + } + if (el === undefined) { + el = 0; // get first tree + } + if (typeof el === "number") { + el = $(".fancytree-container").eq(el); // el was an integer: return nth instance + } else if (typeof el === "string") { + // `el` may be a treeId or a selector: + el = $("#ft-id-" + orgEl).eq(0); + if (!el.length) { + el = $(orgEl).eq(0); // el was a selector: use first match + } + } else if ( + el instanceof Element || + el instanceof HTMLDocument + ) { + el = $(el); + } else if (el instanceof $) { + el = el.eq(0); // el was a jQuery object: use the first + } else if (el.originalEvent !== undefined) { + el = $(el.target); // el was an Event + } + // el is a jQuery object wit one element here + el = el.closest(":ui-fancytree"); + widget = el.data("ui-fancytree") || el.data("fancytree"); // the latter is required by jQuery <= 1.8 + return widget ? widget.tree : null; + }, + /** Return an option value that has a default, but may be overridden by a + * callback or a node instance attribute. + * + * Evaluation sequence: + * + * If `tree.options.<optionName>` is a callback that returns something, use that. + * Else if `node.<optionName>` is defined, use that. + * Else if `tree.options.<optionName>` is a value, use that. + * Else use `defaultValue`. + * + * @param {string} optionName name of the option property (on node and tree) + * @param {FancytreeNode} node passed to the callback + * @param {object} nodeObject where to look for the local option property, e.g. `node` or `node.data` + * @param {object} treeOption where to look for the tree option, e.g. `tree.options` or `tree.options.dnd5` + * @param {any} [defaultValue] + * @returns {any} + * + * @example + * // Check for node.foo, tree,options.foo(), and tree.options.foo: + * $.ui.fancytree.evalOption("foo", node, node, tree.options); + * // Check for node.data.bar, tree,options.qux.bar(), and tree.options.qux.bar: + * $.ui.fancytree.evalOption("bar", node, node.data, tree.options.qux); + * + * @since 2.22 + */ + evalOption: function ( + optionName, + node, + nodeObject, + treeOptions, + defaultValue + ) { + var ctx, + res, + tree = node.tree, + treeOpt = treeOptions[optionName], + nodeOpt = nodeObject[optionName]; + + if (_isFunction(treeOpt)) { + ctx = { + node: node, + tree: tree, + widget: tree.widget, + options: tree.widget.options, + typeInfo: tree.types[node.type] || {}, + }; + res = treeOpt.call(tree, { type: optionName }, ctx); + if (res == null) { + res = nodeOpt; + } + } else { + res = nodeOpt == null ? treeOpt : nodeOpt; + } + if (res == null) { + res = defaultValue; // no option set at all: return default + } + return res; + }, + /** Set expander, checkbox, or node icon, supporting string and object format. + * + * @param {Element | jQueryObject} span + * @param {string} baseClass + * @param {string | object} icon + * @since 2.27 + */ + setSpanIcon: function (span, baseClass, icon) { + var $span = $(span); + + if (typeof icon === "string") { + $span.attr("class", baseClass + " " + icon); + } else { + // support object syntax: { text: ligature, addClasse: classname } + if (icon.text) { + $span.text("" + icon.text); + } else if (icon.html) { + span.innerHTML = icon.html; + } + $span.attr( + "class", + baseClass + " " + (icon.addClass || "") + ); + } + }, + /** Convert a keydown or mouse event to a canonical string like 'ctrl+a', + * 'ctrl+shift+f2', 'shift+leftdblclick'. + * + * This is especially handy for switch-statements in event handlers. + * + * @param {event} + * @returns {string} + * + * @example + + switch( $.ui.fancytree.eventToString(event) ) { + case "-": + tree.nodeSetExpanded(ctx, false); + break; + case "shift+return": + tree.nodeSetActive(ctx, true); + break; + case "down": + res = node.navigate(event.which, activate); + break; + default: + handled = false; + } + if( handled ){ + event.preventDefault(); + } + */ + eventToString: function (event) { + // Poor-man's hotkeys. See here for a complete implementation: + // https://github.com/jeresig/jquery.hotkeys + var which = event.which, + et = event.type, + s = []; + + if (event.altKey) { + s.push("alt"); + } + if (event.ctrlKey) { + s.push("ctrl"); + } + if (event.metaKey) { + s.push("meta"); + } + if (event.shiftKey) { + s.push("shift"); + } + + if (et === "click" || et === "dblclick") { + s.push(MOUSE_BUTTONS[event.button] + et); + } else if (et === "wheel") { + s.push(et); + } else if (!IGNORE_KEYCODES[which]) { + s.push( + SPECIAL_KEYCODES[which] || + String.fromCharCode(which).toLowerCase() + ); + } + return s.join("+"); + }, + /** Write message to console if debugLevel >= 3 + * @param {string} msg + */ + info: function (msg) { + if ($.ui.fancytree.debugLevel >= 3) { + consoleApply("info", arguments); + } + }, + /* @deprecated: use eventToString(event) instead. + */ + keyEventToString: function (event) { + this.warn( + "keyEventToString() is deprecated: use eventToString()" + ); + return this.eventToString(event); + }, + /** Return a wrapped handler method, that provides `this._super`. + * + * @example + // Implement `opts.createNode` event to add the 'draggable' attribute + $.ui.fancytree.overrideMethod(ctx.options, "createNode", function(event, data) { + // Default processing if any + this._super.apply(this, arguments); + // Add 'draggable' attribute + data.node.span.draggable = true; + }); + * + * @param {object} instance + * @param {string} methodName + * @param {function} handler + * @param {object} [context] optional context + */ + overrideMethod: function (instance, methodName, handler, context) { + var prevSuper, + _super = instance[methodName] || $.noop; + + instance[methodName] = function () { + var self = context || this; + + try { + prevSuper = self._super; + self._super = _super; + return handler.apply(self, arguments); + } finally { + self._super = prevSuper; + } + }; + }, + /** + * Parse tree data from HTML <ul> markup + * + * @param {jQueryObject} $ul + * @returns {NodeData[]} + */ + parseHtml: function ($ul) { + var classes, + className, + extraClasses, + i, + iPos, + l, + tmp, + tmp2, + $children = $ul.find(">li"), + children = []; + + $children.each(function () { + var allData, + lowerCaseAttr, + $li = $(this), + $liSpan = $li.find(">span", this).first(), + $liA = $liSpan.length ? null : $li.find(">a").first(), + d = { tooltip: null, data: {} }; + + if ($liSpan.length) { + d.title = $liSpan.html(); + } else if ($liA && $liA.length) { + // If a <li><a> tag is specified, use it literally and extract href/target. + d.title = $liA.html(); + d.data.href = $liA.attr("href"); + d.data.target = $liA.attr("target"); + d.tooltip = $liA.attr("title"); + } else { + // If only a <li> tag is specified, use the trimmed string up to + // the next child <ul> tag. + d.title = $li.html(); + iPos = d.title.search(/<ul/i); + if (iPos >= 0) { + d.title = d.title.substring(0, iPos); + } + } + d.title = _trim(d.title); + + // Make sure all fields exist + for (i = 0, l = CLASS_ATTRS.length; i < l; i++) { + d[CLASS_ATTRS[i]] = undefined; + } + // Initialize to `true`, if class is set and collect extraClasses + classes = this.className.split(" "); + extraClasses = []; + for (i = 0, l = classes.length; i < l; i++) { + className = classes[i]; + if (CLASS_ATTR_MAP[className]) { + d[className] = true; + } else { + extraClasses.push(className); + } + } + d.extraClasses = extraClasses.join(" "); + + // Parse node options from ID, title and class attributes + tmp = $li.attr("title"); + if (tmp) { + d.tooltip = tmp; // overrides <a title='...'> + } + tmp = $li.attr("id"); + if (tmp) { + d.key = tmp; + } + // Translate hideCheckbox -> checkbox:false + if ($li.attr("hideCheckbox")) { + d.checkbox = false; + } + // Add <li data-NAME='...'> as node.data.NAME + allData = _getElementDataAsDict($li); + if (allData && !$.isEmptyObject(allData)) { + // #507: convert data-hidecheckbox (lower case) to hideCheckbox + for (lowerCaseAttr in NODE_ATTR_LOWERCASE_MAP) { + if (_hasProp(allData, lowerCaseAttr)) { + allData[ + NODE_ATTR_LOWERCASE_MAP[lowerCaseAttr] + ] = allData[lowerCaseAttr]; + delete allData[lowerCaseAttr]; + } + } + // #56: Allow to set special node.attributes from data-... + for (i = 0, l = NODE_ATTRS.length; i < l; i++) { + tmp = NODE_ATTRS[i]; + tmp2 = allData[tmp]; + if (tmp2 != null) { + delete allData[tmp]; + d[tmp] = tmp2; + } + } + // All other data-... goes to node.data... + $.extend(d.data, allData); + } + // Recursive reading of child nodes, if LI tag contains an UL tag + $ul = $li.find(">ul").first(); + if ($ul.length) { + d.children = $.ui.fancytree.parseHtml($ul); + } else { + d.children = d.lazy ? undefined : null; + } + children.push(d); + // FT.debug("parse ", d, children); + }); + return children; + }, + /** Add Fancytree extension definition to the list of globally available extensions. + * + * @param {object} definition + */ + registerExtension: function (definition) { + _assert( + definition.name != null, + "extensions must have a `name` property." + ); + _assert( + definition.version != null, + "extensions must have a `version` property." + ); + $.ui.fancytree._extensions[definition.name] = definition; + }, + /** Replacement for the deprecated `jQuery.trim()`. + * + * @param {string} text + */ + trim: _trim, + /** Inverse of escapeHtml(). + * + * @param {string} s + * @returns {string} + */ + unescapeHtml: function (s) { + var e = document.createElement("div"); + e.innerHTML = s; + return e.childNodes.length === 0 + ? "" + : e.childNodes[0].nodeValue; + }, + /** Write warning message to console if debugLevel >= 2. + * @param {string} msg + */ + warn: function (msg) { + if ($.ui.fancytree.debugLevel >= 2) { + consoleApply("warn", arguments); + } + }, + } + ); + + // Value returned by `require('jquery.fancytree')` + return $.ui.fancytree; +}); // End of closure + +// Extending Fancytree +// =================== +// +// See also the [live demo](https://wwWendt.de/tech/fancytree/demo/sample-ext-childcounter.html) of this code. +// +// Every extension should have a comment header containing some information +// about the author, copyright and licensing. Also a pointer to the latest +// source code. +// Prefix with `/*!` so the comment is not removed by the minifier. + +/*! + * jquery.fancytree.childcounter.js + * + * Add a child counter bubble to tree nodes. + * (Extension module for jquery.fancytree.js: https://github.com/mar10/fancytree/) + * + * Copyright (c) 2008-2023, Martin Wendt (https://wwWendt.de) + * + * Released under the MIT license + * https://github.com/mar10/fancytree/wiki/LicenseInfo + * + * @version 2.38.3 + * @date 2023-02-01T20:52:50Z + */ + +// To keep the global namespace clean, we wrap everything in a closure. +// The UMD wrapper pattern defines the dependencies on jQuery and the +// Fancytree core module, and makes sure that we can use the `require()` +// syntax with package loaders. + +(function (factory) { + if (typeof define === "function" && define.amd) { + // AMD. Register as an anonymous module. + define(["jquery", "./jquery.fancytree"], factory); + } else if (typeof module === "object" && module.exports) { + // Node/CommonJS + require("./jquery.fancytree"); + module.exports = factory(require("jquery")); + } else { + // Browser globals + factory(jQuery); + } +})(function ($) { + // Consider to use [strict mode](http://ejohn.org/blog/ecmascript-5-strict-mode-json-and-more/) + "use strict"; + + // The [coding guidelines](http://contribute.jquery.org/style-guide/js/) + // require jshint /eslint compliance. + // But for this sample, we want to allow unused variables for demonstration purpose. + + /*eslint-disable no-unused-vars */ + + // Adding methods + // -------------- + + // New member functions can be added to the `Fancytree` class. + // This function will be available for every tree instance: + // + // var tree = $.ui.fancytree.getTree("#tree"); + // tree.countSelected(false); + + $.ui.fancytree._FancytreeClass.prototype.countSelected = function ( + topOnly + ) { + var tree = this, + treeOptions = tree.options; + + return tree.getSelectedNodes(topOnly).length; + }; + + // The `FancytreeNode` class can also be easily extended. This would be called + // like + // node.updateCounters(); + // + // It is also good practice to add a docstring comment. + /** + * [ext-childcounter] Update counter badges for `node` and its parents. + * May be called in the `loadChildren` event, to update parents of lazy loaded + * nodes. + * @alias FancytreeNode#updateCounters + * @requires jquery.fancytree.childcounters.js + */ + $.ui.fancytree._FancytreeNodeClass.prototype.updateCounters = function () { + var node = this, + $badge = $("span.fancytree-childcounter", node.span), + extOpts = node.tree.options.childcounter, + count = node.countChildren(extOpts.deep); + + node.data.childCounter = count; + if ( + (count || !extOpts.hideZeros) && + (!node.isExpanded() || !extOpts.hideExpanded) + ) { + if (!$badge.length) { + $badge = $("<span class='fancytree-childcounter'/>").appendTo( + $( + "span.fancytree-icon,span.fancytree-custom-icon", + node.span + ) + ); + } + $badge.text(count); + } else { + $badge.remove(); + } + if (extOpts.deep && !node.isTopLevel() && !node.isRootNode()) { + node.parent.updateCounters(); + } + }; + + // Finally, we can extend the widget API and create functions that are called + // like so: + // + // $("#tree").fancytree("widgetMethod1", "abc"); + + $.ui.fancytree.prototype.widgetMethod1 = function (arg1) { + var tree = this.tree; + return arg1; + }; + + // Register a Fancytree extension + // ------------------------------ + // A full blown extension, extension is available for all trees and can be + // enabled like so (see also the [live demo](https://wwWendt.de/tech/fancytree/demo/sample-ext-childcounter.html)): + // + // <script src="../src/jquery.fancytree.js"></script> + // <script src="../src/jquery.fancytree.childcounter.js"></script> + // ... + // + // $("#tree").fancytree({ + // extensions: ["childcounter"], + // childcounter: { + // hideExpanded: true + // }, + // ... + // }); + // + + /* 'childcounter' extension */ + $.ui.fancytree.registerExtension({ + // Every extension must be registered by a unique name. + name: "childcounter", + // Version information should be compliant with [semver](http://semver.org) + version: "2.38.3", + + // Extension specific options and their defaults. + // This options will be available as `tree.options.childcounter.hideExpanded` + + options: { + deep: true, + hideZeros: true, + hideExpanded: false, + }, + + // Attributes other than `options` (or functions) can be defined here, and + // will be added to the tree.ext.EXTNAME namespace, in this case `tree.ext.childcounter.foo`. + // They can also be accessed as `this._local.foo` from within the extension + // methods. + foo: 42, + + // Local functions are prefixed with an underscore '_'. + // Callable as `this._local._appendCounter()`. + + _appendCounter: function (bar) { + var tree = this; + }, + + // **Override virtual methods for this extension.** + // + // Fancytree implements a number of 'hook methods', prefixed by 'node...' or 'tree...'. + // with a `ctx` argument (see [EventData](https://wwWendt.de/tech/fancytree/doc/jsdoc/global.html#EventData) + // for details) and an extended calling context:<br> + // `this` : the Fancytree instance<br> + // `this._local`: the namespace that contains extension attributes and private methods (same as this.ext.EXTNAME)<br> + // `this._super`: the virtual function that was overridden (member of previous extension or Fancytree) + // + // See also the [complete list of available hook functions](https://wwWendt.de/tech/fancytree/doc/jsdoc/Fancytree_Hooks.html). + + /* Init */ + // `treeInit` is triggered when a tree is initalized. We can set up classes or + // bind event handlers here... + treeInit: function (ctx) { + var tree = this, // same as ctx.tree, + opts = ctx.options, + extOpts = ctx.options.childcounter; + // Optionally check for dependencies with other extensions + /* this._requireExtension("glyph", false, false); */ + // Call the base implementation + this._superApply(arguments); + // Add a class to the tree container + this.$container.addClass("fancytree-ext-childcounter"); + }, + + // Destroy this tree instance (we only call the default implementation, so + // this method could as well be omitted). + + treeDestroy: function (ctx) { + this._superApply(arguments); + }, + + // Overload the `renderTitle` hook, to append a counter badge + nodeRenderTitle: function (ctx, title) { + var node = ctx.node, + extOpts = ctx.options.childcounter, + count = + node.data.childCounter == null + ? node.countChildren(extOpts.deep) + : +node.data.childCounter; + // Let the base implementation render the title + // We use `_super()` instead of `_superApply()` here, since it is a little bit + // more performant when called often + this._super(ctx, title); + // Append a counter badge + if ( + (count || !extOpts.hideZeros) && + (!node.isExpanded() || !extOpts.hideExpanded) + ) { + $( + "span.fancytree-icon,span.fancytree-custom-icon", + node.span + ).append( + $("<span class='fancytree-childcounter'/>").text(count) + ); + } + }, + // Overload the `setExpanded` hook, so the counters are updated + nodeSetExpanded: function (ctx, flag, callOpts) { + var tree = ctx.tree, + node = ctx.node; + // Let the base implementation expand/collapse the node, then redraw the title + // after the animation has finished + return this._superApply(arguments).always(function () { + tree.nodeRenderTitle(ctx); + }); + }, + + // End of extension definition + }); + // Value returned by `require('jquery.fancytree..')` + return $.ui.fancytree; +}); // End of closure + +/*! + * + * jquery.fancytree.clones.js + * Support faster lookup of nodes by key and shared ref-ids. + * (Extension module for jquery.fancytree.js: https://github.com/mar10/fancytree/) + * + * Copyright (c) 2008-2023, Martin Wendt (https://wwWendt.de) + * + * Released under the MIT license + * https://github.com/mar10/fancytree/wiki/LicenseInfo + * + * @version 2.38.3 + * @date 2023-02-01T20:52:50Z + */ + +(function (factory) { + if (typeof define === "function" && define.amd) { + // AMD. Register as an anonymous module. + define(["jquery", "./jquery.fancytree"], factory); + } else if (typeof module === "object" && module.exports) { + // Node/CommonJS + require("./jquery.fancytree"); + module.exports = factory(require("jquery")); + } else { + // Browser globals + factory(jQuery); + } +})(function ($) { + "use strict"; + + /******************************************************************************* + * Private functions and variables + */ + + var _assert = $.ui.fancytree.assert; + + /* Return first occurrence of member from array. */ + function _removeArrayMember(arr, elem) { + // TODO: use Array.indexOf for IE >= 9 + var i; + for (i = arr.length - 1; i >= 0; i--) { + if (arr[i] === elem) { + arr.splice(i, 1); + return true; + } + } + return false; + } + + /** + * JS Implementation of MurmurHash3 (r136) (as of May 20, 2011) + * + * @author <a href="mailto:gary.court@gmail.com">Gary Court</a> + * @see http://github.com/garycourt/murmurhash-js + * @author <a href="mailto:aappleby@gmail.com">Austin Appleby</a> + * @see http://sites.google.com/site/murmurhash/ + * + * @param {string} key ASCII only + * @param {boolean} [asString=false] + * @param {number} seed Positive integer only + * @return {number} 32-bit positive integer hash + */ + function hashMurmur3(key, asString, seed) { + /*eslint-disable no-bitwise */ + var h1b, + k1, + remainder = key.length & 3, + bytes = key.length - remainder, + h1 = seed, + c1 = 0xcc9e2d51, + c2 = 0x1b873593, + i = 0; + + while (i < bytes) { + k1 = + (key.charCodeAt(i) & 0xff) | + ((key.charCodeAt(++i) & 0xff) << 8) | + ((key.charCodeAt(++i) & 0xff) << 16) | + ((key.charCodeAt(++i) & 0xff) << 24); + ++i; + + k1 = + ((k1 & 0xffff) * c1 + ((((k1 >>> 16) * c1) & 0xffff) << 16)) & + 0xffffffff; + k1 = (k1 << 15) | (k1 >>> 17); + k1 = + ((k1 & 0xffff) * c2 + ((((k1 >>> 16) * c2) & 0xffff) << 16)) & + 0xffffffff; + + h1 ^= k1; + h1 = (h1 << 13) | (h1 >>> 19); + h1b = + ((h1 & 0xffff) * 5 + ((((h1 >>> 16) * 5) & 0xffff) << 16)) & + 0xffffffff; + h1 = + (h1b & 0xffff) + + 0x6b64 + + ((((h1b >>> 16) + 0xe654) & 0xffff) << 16); + } + + k1 = 0; + + switch (remainder) { + case 3: + k1 ^= (key.charCodeAt(i + 2) & 0xff) << 16; + // fall through + case 2: + k1 ^= (key.charCodeAt(i + 1) & 0xff) << 8; + // fall through + case 1: + k1 ^= key.charCodeAt(i) & 0xff; + + k1 = + ((k1 & 0xffff) * c1 + + ((((k1 >>> 16) * c1) & 0xffff) << 16)) & + 0xffffffff; + k1 = (k1 << 15) | (k1 >>> 17); + k1 = + ((k1 & 0xffff) * c2 + + ((((k1 >>> 16) * c2) & 0xffff) << 16)) & + 0xffffffff; + h1 ^= k1; + } + + h1 ^= key.length; + + h1 ^= h1 >>> 16; + h1 = + ((h1 & 0xffff) * 0x85ebca6b + + ((((h1 >>> 16) * 0x85ebca6b) & 0xffff) << 16)) & + 0xffffffff; + h1 ^= h1 >>> 13; + h1 = + ((h1 & 0xffff) * 0xc2b2ae35 + + ((((h1 >>> 16) * 0xc2b2ae35) & 0xffff) << 16)) & + 0xffffffff; + h1 ^= h1 >>> 16; + + if (asString) { + // Convert to 8 digit hex string + return ("0000000" + (h1 >>> 0).toString(16)).substr(-8); + } + return h1 >>> 0; + /*eslint-enable no-bitwise */ + } + + /* + * Return a unique key for node by calculating the hash of the parents refKey-list. + */ + function calcUniqueKey(node) { + var key, + h1, + path = $.map(node.getParentList(false, true), function (e) { + return e.refKey || e.key; + }); + + path = path.join("/"); + // 32-bit has a high probability of collisions, so we pump up to 64-bit + // https://security.stackexchange.com/q/209882/207588 + + h1 = hashMurmur3(path, true); + key = "id_" + h1 + hashMurmur3(h1 + path, true); + + return key; + } + + /** + * [ext-clones] Return a list of clone-nodes (i.e. same refKey) or null. + * @param {boolean} [includeSelf=false] + * @returns {FancytreeNode[] | null} + * + * @alias FancytreeNode#getCloneList + * @requires jquery.fancytree.clones.js + */ + $.ui.fancytree._FancytreeNodeClass.prototype.getCloneList = function ( + includeSelf + ) { + var key, + tree = this.tree, + refList = tree.refMap[this.refKey] || null, + keyMap = tree.keyMap; + + if (refList) { + key = this.key; + // Convert key list to node list + if (includeSelf) { + refList = $.map(refList, function (val) { + return keyMap[val]; + }); + } else { + refList = $.map(refList, function (val) { + return val === key ? null : keyMap[val]; + }); + if (refList.length < 1) { + refList = null; + } + } + } + return refList; + }; + + /** + * [ext-clones] Return true if this node has at least another clone with same refKey. + * @returns {boolean} + * + * @alias FancytreeNode#isClone + * @requires jquery.fancytree.clones.js + */ + $.ui.fancytree._FancytreeNodeClass.prototype.isClone = function () { + var refKey = this.refKey || null, + refList = (refKey && this.tree.refMap[refKey]) || null; + return !!(refList && refList.length > 1); + }; + + /** + * [ext-clones] Update key and/or refKey for an existing node. + * @param {string} key + * @param {string} refKey + * @returns {boolean} + * + * @alias FancytreeNode#reRegister + * @requires jquery.fancytree.clones.js + */ + $.ui.fancytree._FancytreeNodeClass.prototype.reRegister = function ( + key, + refKey + ) { + key = key == null ? null : "" + key; + refKey = refKey == null ? null : "" + refKey; + // this.debug("reRegister", key, refKey); + + var tree = this.tree, + prevKey = this.key, + prevRefKey = this.refKey, + keyMap = tree.keyMap, + refMap = tree.refMap, + refList = refMap[prevRefKey] || null, + // curCloneKeys = refList ? node.getCloneList(true), + modified = false; + + // Key has changed: update all references + if (key != null && key !== this.key) { + if (keyMap[key]) { + $.error( + "[ext-clones] reRegister(" + + key + + "): already exists: " + + this + ); + } + // Update keyMap + delete keyMap[prevKey]; + keyMap[key] = this; + // Update refMap + if (refList) { + refMap[prevRefKey] = $.map(refList, function (e) { + return e === prevKey ? key : e; + }); + } + this.key = key; + modified = true; + } + + // refKey has changed + if (refKey != null && refKey !== this.refKey) { + // Remove previous refKeys + if (refList) { + if (refList.length === 1) { + delete refMap[prevRefKey]; + } else { + refMap[prevRefKey] = $.map(refList, function (e) { + return e === prevKey ? null : e; + }); + } + } + // Add refKey + if (refMap[refKey]) { + refMap[refKey].append(key); + } else { + refMap[refKey] = [this.key]; + } + this.refKey = refKey; + modified = true; + } + return modified; + }; + + /** + * [ext-clones] Define a refKey for an existing node. + * @param {string} refKey + * @returns {boolean} + * + * @alias FancytreeNode#setRefKey + * @requires jquery.fancytree.clones.js + * @since 2.16 + */ + $.ui.fancytree._FancytreeNodeClass.prototype.setRefKey = function (refKey) { + return this.reRegister(null, refKey); + }; + + /** + * [ext-clones] Return all nodes with a given refKey (null if not found). + * @param {string} refKey + * @param {FancytreeNode} [rootNode] optionally restrict results to descendants of this node + * @returns {FancytreeNode[] | null} + * @alias Fancytree#getNodesByRef + * @requires jquery.fancytree.clones.js + */ + $.ui.fancytree._FancytreeClass.prototype.getNodesByRef = function ( + refKey, + rootNode + ) { + var keyMap = this.keyMap, + refList = this.refMap[refKey] || null; + + if (refList) { + // Convert key list to node list + if (rootNode) { + refList = $.map(refList, function (val) { + var node = keyMap[val]; + return node.isDescendantOf(rootNode) ? node : null; + }); + } else { + refList = $.map(refList, function (val) { + return keyMap[val]; + }); + } + if (refList.length < 1) { + refList = null; + } + } + return refList; + }; + + /** + * [ext-clones] Replace a refKey with a new one. + * @param {string} oldRefKey + * @param {string} newRefKey + * @alias Fancytree#changeRefKey + * @requires jquery.fancytree.clones.js + */ + $.ui.fancytree._FancytreeClass.prototype.changeRefKey = function ( + oldRefKey, + newRefKey + ) { + var i, + node, + keyMap = this.keyMap, + refList = this.refMap[oldRefKey] || null; + + if (refList) { + for (i = 0; i < refList.length; i++) { + node = keyMap[refList[i]]; + node.refKey = newRefKey; + } + delete this.refMap[oldRefKey]; + this.refMap[newRefKey] = refList; + } + }; + + /******************************************************************************* + * Extension code + */ + $.ui.fancytree.registerExtension({ + name: "clones", + version: "2.38.3", + // Default options for this extension. + options: { + highlightActiveClones: true, // set 'fancytree-active-clone' on active clones and all peers + highlightClones: false, // set 'fancytree-clone' class on any node that has at least one clone + }, + + treeCreate: function (ctx) { + this._superApply(arguments); + ctx.tree.refMap = {}; + ctx.tree.keyMap = {}; + }, + treeInit: function (ctx) { + this.$container.addClass("fancytree-ext-clones"); + _assert(ctx.options.defaultKey == null); + // Generate unique / reproducible default keys + ctx.options.defaultKey = function (node) { + return calcUniqueKey(node); + }; + // The default implementation loads initial data + this._superApply(arguments); + }, + treeClear: function (ctx) { + ctx.tree.refMap = {}; + ctx.tree.keyMap = {}; + return this._superApply(arguments); + }, + treeRegisterNode: function (ctx, add, node) { + var refList, + len, + tree = ctx.tree, + keyMap = tree.keyMap, + refMap = tree.refMap, + key = node.key, + refKey = node && node.refKey != null ? "" + node.refKey : null; + + // ctx.tree.debug("clones.treeRegisterNode", add, node); + + if (node.isStatusNode()) { + return this._super(ctx, add, node); + } + + if (add) { + if (keyMap[node.key] != null) { + var other = keyMap[node.key], + msg = + "clones.treeRegisterNode: duplicate key '" + + node.key + + "': /" + + node.getPath(true) + + " => " + + other.getPath(true); + // Sometimes this exception is not visible in the console, + // so we also write it: + tree.error(msg); + $.error(msg); + } + keyMap[key] = node; + + if (refKey) { + refList = refMap[refKey]; + if (refList) { + refList.push(key); + if ( + refList.length === 2 && + ctx.options.clones.highlightClones + ) { + // Mark peer node, if it just became a clone (no need to + // mark current node, since it will be rendered later anyway) + keyMap[refList[0]].renderStatus(); + } + } else { + refMap[refKey] = [key]; + } + // node.debug("clones.treeRegisterNode: add clone =>", refMap[refKey]); + } + } else { + if (keyMap[key] == null) { + $.error( + "clones.treeRegisterNode: node.key not registered: " + + node.key + ); + } + delete keyMap[key]; + if (refKey) { + refList = refMap[refKey]; + // node.debug("clones.treeRegisterNode: remove clone BEFORE =>", refMap[refKey]); + if (refList) { + len = refList.length; + if (len <= 1) { + _assert(len === 1); + _assert(refList[0] === key); + delete refMap[refKey]; + } else { + _removeArrayMember(refList, key); + // Unmark peer node, if this was the only clone + if ( + len === 2 && + ctx.options.clones.highlightClones + ) { + // node.debug("clones.treeRegisterNode: last =>", node.getCloneList()); + keyMap[refList[0]].renderStatus(); + } + } + // node.debug("clones.treeRegisterNode: remove clone =>", refMap[refKey]); + } + } + } + return this._super(ctx, add, node); + }, + nodeRenderStatus: function (ctx) { + var $span, + res, + node = ctx.node; + + res = this._super(ctx); + + if (ctx.options.clones.highlightClones) { + $span = $(node[ctx.tree.statusClassPropName]); + // Only if span already exists + if ($span.length && node.isClone()) { + // node.debug("clones.nodeRenderStatus: ", ctx.options.clones.highlightClones); + $span.addClass("fancytree-clone"); + } + } + return res; + }, + nodeSetActive: function (ctx, flag, callOpts) { + var res, + scpn = ctx.tree.statusClassPropName, + node = ctx.node; + + res = this._superApply(arguments); + + if (ctx.options.clones.highlightActiveClones && node.isClone()) { + $.each(node.getCloneList(true), function (idx, n) { + // n.debug("clones.nodeSetActive: ", flag !== false); + $(n[scpn]).toggleClass( + "fancytree-active-clone", + flag !== false + ); + }); + } + return res; + }, + }); + // Value returned by `require('jquery.fancytree..')` + return $.ui.fancytree; +}); // End of closure + +/*! + * jquery.fancytree.dnd.js + * + * Drag-and-drop support (jQuery UI draggable/droppable). + * (Extension module for jquery.fancytree.js: https://github.com/mar10/fancytree/) + * + * Copyright (c) 2008-2023, Martin Wendt (https://wwWendt.de) + * + * Released under the MIT license + * https://github.com/mar10/fancytree/wiki/LicenseInfo + * + * @version 2.38.3 + * @date 2023-02-01T20:52:50Z + */ + +(function (factory) { + if (typeof define === "function" && define.amd) { + // AMD. Register as an anonymous module. + define([ + "jquery", + "jquery-ui/ui/widgets/draggable", + "jquery-ui/ui/widgets/droppable", + "./jquery.fancytree", + ], factory); + } else if (typeof module === "object" && module.exports) { + // Node/CommonJS + require("./jquery.fancytree"); + module.exports = factory(require("jquery")); + } else { + // Browser globals + factory(jQuery); + } +})(function ($) { + "use strict"; + + /****************************************************************************** + * Private functions and variables + */ + var didRegisterDnd = false, + classDropAccept = "fancytree-drop-accept", + classDropAfter = "fancytree-drop-after", + classDropBefore = "fancytree-drop-before", + classDropOver = "fancytree-drop-over", + classDropReject = "fancytree-drop-reject", + classDropTarget = "fancytree-drop-target"; + + /* Convert number to string and prepend +/-; return empty string for 0.*/ + function offsetString(n) { + // eslint-disable-next-line no-nested-ternary + return n === 0 ? "" : n > 0 ? "+" + n : "" + n; + } + + //--- Extend ui.draggable event handling -------------------------------------- + + function _registerDnd() { + if (didRegisterDnd) { + return; + } + + // Register proxy-functions for draggable.start/drag/stop + + $.ui.plugin.add("draggable", "connectToFancytree", { + start: function (event, ui) { + // 'draggable' was renamed to 'ui-draggable' since jQueryUI 1.10 + var draggable = + $(this).data("ui-draggable") || + $(this).data("draggable"), + sourceNode = ui.helper.data("ftSourceNode") || null; + + if (sourceNode) { + // Adjust helper offset, so cursor is slightly outside top/left corner + draggable.offset.click.top = -2; + draggable.offset.click.left = +16; + // Trigger dragStart event + // TODO: when called as connectTo..., the return value is ignored(?) + return sourceNode.tree.ext.dnd._onDragEvent( + "start", + sourceNode, + null, + event, + ui, + draggable + ); + } + }, + drag: function (event, ui) { + var ctx, + isHelper, + logObject, + // 'draggable' was renamed to 'ui-draggable' since jQueryUI 1.10 + draggable = + $(this).data("ui-draggable") || + $(this).data("draggable"), + sourceNode = ui.helper.data("ftSourceNode") || null, + prevTargetNode = ui.helper.data("ftTargetNode") || null, + targetNode = $.ui.fancytree.getNode(event.target), + dndOpts = sourceNode && sourceNode.tree.options.dnd; + + // logObject = sourceNode || prevTargetNode || $.ui.fancytree; + // logObject.debug("Drag event:", event, event.shiftKey); + if (event.target && !targetNode) { + // We got a drag event, but the targetNode could not be found + // at the event location. This may happen, + // 1. if the mouse jumped over the drag helper, + // 2. or if a non-fancytree element is dragged + // We ignore it: + isHelper = + $(event.target).closest( + "div.fancytree-drag-helper,#fancytree-drop-marker" + ).length > 0; + if (isHelper) { + logObject = + sourceNode || prevTargetNode || $.ui.fancytree; + logObject.debug("Drag event over helper: ignored."); + return; + } + } + ui.helper.data("ftTargetNode", targetNode); + + if (dndOpts && dndOpts.updateHelper) { + ctx = sourceNode.tree._makeHookContext(sourceNode, event, { + otherNode: targetNode, + ui: ui, + draggable: draggable, + dropMarker: $("#fancytree-drop-marker"), + }); + dndOpts.updateHelper.call(sourceNode.tree, sourceNode, ctx); + } + + // Leaving a tree node + if (prevTargetNode && prevTargetNode !== targetNode) { + prevTargetNode.tree.ext.dnd._onDragEvent( + "leave", + prevTargetNode, + sourceNode, + event, + ui, + draggable + ); + } + if (targetNode) { + if (!targetNode.tree.options.dnd.dragDrop) { + // not enabled as drop target + } else if (targetNode === prevTargetNode) { + // Moving over same node + targetNode.tree.ext.dnd._onDragEvent( + "over", + targetNode, + sourceNode, + event, + ui, + draggable + ); + } else { + // Entering this node first time + targetNode.tree.ext.dnd._onDragEvent( + "enter", + targetNode, + sourceNode, + event, + ui, + draggable + ); + targetNode.tree.ext.dnd._onDragEvent( + "over", + targetNode, + sourceNode, + event, + ui, + draggable + ); + } + } + // else go ahead with standard event handling + }, + stop: function (event, ui) { + var logObject, + // 'draggable' was renamed to 'ui-draggable' since jQueryUI 1.10: + draggable = + $(this).data("ui-draggable") || + $(this).data("draggable"), + sourceNode = ui.helper.data("ftSourceNode") || null, + targetNode = ui.helper.data("ftTargetNode") || null, + dropped = event.type === "mouseup" && event.which === 1; + + if (!dropped) { + logObject = sourceNode || targetNode || $.ui.fancytree; + logObject.debug("Drag was cancelled"); + } + if (targetNode) { + if (dropped) { + targetNode.tree.ext.dnd._onDragEvent( + "drop", + targetNode, + sourceNode, + event, + ui, + draggable + ); + } + targetNode.tree.ext.dnd._onDragEvent( + "leave", + targetNode, + sourceNode, + event, + ui, + draggable + ); + } + if (sourceNode) { + sourceNode.tree.ext.dnd._onDragEvent( + "stop", + sourceNode, + null, + event, + ui, + draggable + ); + } + }, + }); + + didRegisterDnd = true; + } + + /****************************************************************************** + * Drag and drop support + */ + function _initDragAndDrop(tree) { + var dnd = tree.options.dnd || null, + glyph = tree.options.glyph || null; + + // Register 'connectToFancytree' option with ui.draggable + if (dnd) { + _registerDnd(); + } + // Attach ui.draggable to this Fancytree instance + if (dnd && dnd.dragStart) { + tree.widget.element.draggable( + $.extend( + { + addClasses: false, + // DT issue 244: helper should be child of scrollParent: + appendTo: tree.$container, + // appendTo: "body", + containment: false, + // containment: "parent", + delay: 0, + distance: 4, + revert: false, + scroll: true, // to disable, also set css 'position: inherit' on ul.fancytree-container + scrollSpeed: 7, + scrollSensitivity: 10, + // Delegate draggable.start, drag, and stop events to our handler + connectToFancytree: true, + // Let source tree create the helper element + helper: function (event) { + var $helper, + $nodeTag, + opts, + sourceNode = $.ui.fancytree.getNode( + event.target + ); + + if (!sourceNode) { + // #405, DT issue 211: might happen, if dragging a table *header* + return "<div>ERROR?: helper requested but sourceNode not found</div>"; + } + opts = sourceNode.tree.options.dnd; + $nodeTag = $(sourceNode.span); + // Only event and node argument is available + $helper = $( + "<div class='fancytree-drag-helper'><span class='fancytree-drag-helper-img' /></div>" + ) + .css({ zIndex: 3, position: "relative" }) // so it appears above ext-wide selection bar + .append( + $nodeTag + .find("span.fancytree-title") + .clone() + ); + + // Attach node reference to helper object + $helper.data("ftSourceNode", sourceNode); + + // Support glyph symbols instead of icons + if (glyph) { + $helper + .find(".fancytree-drag-helper-img") + .addClass( + glyph.map._addClass + + " " + + glyph.map.dragHelper + ); + } + // Allow to modify the helper, e.g. to add multi-node-drag feedback + if (opts.initHelper) { + opts.initHelper.call( + sourceNode.tree, + sourceNode, + { + node: sourceNode, + tree: sourceNode.tree, + originalEvent: event, + ui: { helper: $helper }, + } + ); + } + // We return an unconnected element, so `draggable` will add this + // to the parent specified as `appendTo` option + return $helper; + }, + start: function (event, ui) { + var sourceNode = ui.helper.data("ftSourceNode"); + return !!sourceNode; // Abort dragging if no node could be found + }, + }, + tree.options.dnd.draggable + ) + ); + } + // Attach ui.droppable to this Fancytree instance + if (dnd && dnd.dragDrop) { + tree.widget.element.droppable( + $.extend( + { + addClasses: false, + tolerance: "intersect", + greedy: false, + /* + activate: function(event, ui) { + tree.debug("droppable - activate", event, ui, this); + }, + create: function(event, ui) { + tree.debug("droppable - create", event, ui); + }, + deactivate: function(event, ui) { + tree.debug("droppable - deactivate", event, ui); + }, + drop: function(event, ui) { + tree.debug("droppable - drop", event, ui); + }, + out: function(event, ui) { + tree.debug("droppable - out", event, ui); + }, + over: function(event, ui) { + tree.debug("droppable - over", event, ui); + } +*/ + }, + tree.options.dnd.droppable + ) + ); + } + } + + /****************************************************************************** + * + */ + + $.ui.fancytree.registerExtension({ + name: "dnd", + version: "2.38.3", + // Default options for this extension. + options: { + // Make tree nodes accept draggables + autoExpandMS: 1000, // Expand nodes after n milliseconds of hovering. + draggable: null, // Additional options passed to jQuery draggable + droppable: null, // Additional options passed to jQuery droppable + focusOnClick: false, // Focus, although draggable cancels mousedown event (#270) + preventVoidMoves: true, // Prevent dropping nodes 'before self', etc. + preventRecursiveMoves: true, // Prevent dropping nodes on own descendants + smartRevert: true, // set draggable.revert = true if drop was rejected + dropMarkerOffsetX: -24, // absolute position offset for .fancytree-drop-marker relatively to ..fancytree-title (icon/img near a node accepting drop) + dropMarkerInsertOffsetX: -16, // additional offset for drop-marker with hitMode = "before"/"after" + // Events (drag support) + dragStart: null, // Callback(sourceNode, data), return true, to enable dnd + dragStop: null, // Callback(sourceNode, data) + initHelper: null, // Callback(sourceNode, data) + updateHelper: null, // Callback(sourceNode, data) + // Events (drop support) + dragEnter: null, // Callback(targetNode, data) + dragOver: null, // Callback(targetNode, data) + dragExpand: null, // Callback(targetNode, data), return false to prevent autoExpand + dragDrop: null, // Callback(targetNode, data) + dragLeave: null, // Callback(targetNode, data) + }, + + treeInit: function (ctx) { + var tree = ctx.tree; + this._superApply(arguments); + // issue #270: draggable eats mousedown events + if (tree.options.dnd.dragStart) { + tree.$container.on("mousedown", function (event) { + // if( !tree.hasFocus() && ctx.options.dnd.focusOnClick ) { + if (ctx.options.dnd.focusOnClick) { + // #270 + var node = $.ui.fancytree.getNode(event); + if (node) { + node.debug( + "Re-enable focus that was prevented by jQuery UI draggable." + ); + // node.setFocus(); + // $(node.span).closest(":tabbable").focus(); + // $(event.target).trigger("focus"); + // $(event.target).closest(":tabbable").trigger("focus"); + } + setTimeout(function () { + // #300 + $(event.target).closest(":tabbable").focus(); + }, 10); + } + }); + } + _initDragAndDrop(tree); + }, + /* Display drop marker according to hitMode ('after', 'before', 'over'). */ + _setDndStatus: function ( + sourceNode, + targetNode, + helper, + hitMode, + accept + ) { + var markerOffsetX, + pos, + markerAt = "center", + instData = this._local, + dndOpt = this.options.dnd, + glyphOpt = this.options.glyph, + $source = sourceNode ? $(sourceNode.span) : null, + $target = $(targetNode.span), + $targetTitle = $target.find("span.fancytree-title"); + + if (!instData.$dropMarker) { + instData.$dropMarker = $( + "<div id='fancytree-drop-marker'></div>" + ) + .hide() + .css({ "z-index": 1000 }) + .prependTo($(this.$div).parent()); + // .prependTo("body"); + + if (glyphOpt) { + instData.$dropMarker.addClass( + glyphOpt.map._addClass + " " + glyphOpt.map.dropMarker + ); + } + } + if ( + hitMode === "after" || + hitMode === "before" || + hitMode === "over" + ) { + markerOffsetX = dndOpt.dropMarkerOffsetX || 0; + switch (hitMode) { + case "before": + markerAt = "top"; + markerOffsetX += dndOpt.dropMarkerInsertOffsetX || 0; + break; + case "after": + markerAt = "bottom"; + markerOffsetX += dndOpt.dropMarkerInsertOffsetX || 0; + break; + } + + pos = { + my: "left" + offsetString(markerOffsetX) + " center", + at: "left " + markerAt, + of: $targetTitle, + }; + if (this.options.rtl) { + pos.my = "right" + offsetString(-markerOffsetX) + " center"; + pos.at = "right " + markerAt; + } + instData.$dropMarker + .toggleClass(classDropAfter, hitMode === "after") + .toggleClass(classDropOver, hitMode === "over") + .toggleClass(classDropBefore, hitMode === "before") + .toggleClass("fancytree-rtl", !!this.options.rtl) + .show() + .position($.ui.fancytree.fixPositionOptions(pos)); + } else { + instData.$dropMarker.hide(); + } + if ($source) { + $source + .toggleClass(classDropAccept, accept === true) + .toggleClass(classDropReject, accept === false); + } + $target + .toggleClass( + classDropTarget, + hitMode === "after" || + hitMode === "before" || + hitMode === "over" + ) + .toggleClass(classDropAfter, hitMode === "after") + .toggleClass(classDropBefore, hitMode === "before") + .toggleClass(classDropAccept, accept === true) + .toggleClass(classDropReject, accept === false); + + helper + .toggleClass(classDropAccept, accept === true) + .toggleClass(classDropReject, accept === false); + }, + + /* + * Handles drag'n'drop functionality. + * + * A standard jQuery drag-and-drop process may generate these calls: + * + * start: + * _onDragEvent("start", sourceNode, null, event, ui, draggable); + * drag: + * _onDragEvent("leave", prevTargetNode, sourceNode, event, ui, draggable); + * _onDragEvent("over", targetNode, sourceNode, event, ui, draggable); + * _onDragEvent("enter", targetNode, sourceNode, event, ui, draggable); + * stop: + * _onDragEvent("drop", targetNode, sourceNode, event, ui, draggable); + * _onDragEvent("leave", targetNode, sourceNode, event, ui, draggable); + * _onDragEvent("stop", sourceNode, null, event, ui, draggable); + */ + _onDragEvent: function ( + eventName, + node, + otherNode, + event, + ui, + draggable + ) { + // if(eventName !== "over"){ + // this.debug("tree.ext.dnd._onDragEvent(%s, %o, %o) - %o", eventName, node, otherNode, this); + // } + var accept, + nodeOfs, + parentRect, + rect, + relPos, + relPos2, + enterResponse, + hitMode, + r, + opts = this.options, + dnd = opts.dnd, + ctx = this._makeHookContext(node, event, { + otherNode: otherNode, + ui: ui, + draggable: draggable, + }), + res = null, + self = this, + $nodeTag = $(node.span); + + if (dnd.smartRevert) { + draggable.options.revert = "invalid"; + } + + switch (eventName) { + case "start": + if (node.isStatusNode()) { + res = false; + } else if (dnd.dragStart) { + res = dnd.dragStart(node, ctx); + } + if (res === false) { + this.debug("tree.dragStart() cancelled"); + //draggable._clear(); + // NOTE: the return value seems to be ignored (drag is not cancelled, when false is returned) + // TODO: call this._cancelDrag()? + ui.helper.trigger("mouseup").hide(); + } else { + if (dnd.smartRevert) { + // #567, #593: fix revert position + // rect = node.li.getBoundingClientRect(); + rect = + node[ + ctx.tree.nodeContainerAttrName + ].getBoundingClientRect(); + parentRect = $( + draggable.options.appendTo + )[0].getBoundingClientRect(); + draggable.originalPosition.left = Math.max( + 0, + rect.left - parentRect.left + ); + draggable.originalPosition.top = Math.max( + 0, + rect.top - parentRect.top + ); + } + $nodeTag.addClass("fancytree-drag-source"); + // Register global handlers to allow cancel + $(document).on( + "keydown.fancytree-dnd,mousedown.fancytree-dnd", + function (event) { + // node.tree.debug("dnd global event", event.type, event.which); + if ( + event.type === "keydown" && + event.which === $.ui.keyCode.ESCAPE + ) { + self.ext.dnd._cancelDrag(); + } else if (event.type === "mousedown") { + self.ext.dnd._cancelDrag(); + } + } + ); + } + break; + + case "enter": + if ( + dnd.preventRecursiveMoves && + node.isDescendantOf(otherNode) + ) { + r = false; + } else { + r = dnd.dragEnter ? dnd.dragEnter(node, ctx) : null; + } + if (!r) { + // convert null, undefined, false to false + res = false; + } else if (Array.isArray(r)) { + // TODO: also accept passing an object of this format directly + res = { + over: $.inArray("over", r) >= 0, + before: $.inArray("before", r) >= 0, + after: $.inArray("after", r) >= 0, + }; + } else { + res = { + over: r === true || r === "over", + before: r === true || r === "before", + after: r === true || r === "after", + }; + } + ui.helper.data("enterResponse", res); + // this.debug("helper.enterResponse: %o", res); + break; + + case "over": + enterResponse = ui.helper.data("enterResponse"); + hitMode = null; + if (enterResponse === false) { + // Don't call dragOver if onEnter returned false. + // break; + } else if (typeof enterResponse === "string") { + // Use hitMode from onEnter if provided. + hitMode = enterResponse; + } else { + // Calculate hitMode from relative cursor position. + nodeOfs = $nodeTag.offset(); + relPos = { + x: event.pageX - nodeOfs.left, + y: event.pageY - nodeOfs.top, + }; + relPos2 = { + x: relPos.x / $nodeTag.width(), + y: relPos.y / $nodeTag.height(), + }; + + if (enterResponse.after && relPos2.y > 0.75) { + hitMode = "after"; + } else if ( + !enterResponse.over && + enterResponse.after && + relPos2.y > 0.5 + ) { + hitMode = "after"; + } else if (enterResponse.before && relPos2.y <= 0.25) { + hitMode = "before"; + } else if ( + !enterResponse.over && + enterResponse.before && + relPos2.y <= 0.5 + ) { + hitMode = "before"; + } else if (enterResponse.over) { + hitMode = "over"; + } + // Prevent no-ops like 'before source node' + // TODO: these are no-ops when moving nodes, but not in copy mode + if (dnd.preventVoidMoves) { + if (node === otherNode) { + this.debug( + " drop over source node prevented" + ); + hitMode = null; + } else if ( + hitMode === "before" && + otherNode && + node === otherNode.getNextSibling() + ) { + this.debug( + " drop after source node prevented" + ); + hitMode = null; + } else if ( + hitMode === "after" && + otherNode && + node === otherNode.getPrevSibling() + ) { + this.debug( + " drop before source node prevented" + ); + hitMode = null; + } else if ( + hitMode === "over" && + otherNode && + otherNode.parent === node && + otherNode.isLastSibling() + ) { + this.debug( + " drop last child over own parent prevented" + ); + hitMode = null; + } + } + // this.debug("hitMode: %s - %s - %s", hitMode, (node.parent === otherNode), node.isLastSibling()); + ui.helper.data("hitMode", hitMode); + } + // Auto-expand node (only when 'over' the node, not 'before', or 'after') + if ( + hitMode !== "before" && + hitMode !== "after" && + dnd.autoExpandMS && + node.hasChildren() !== false && + !node.expanded && + (!dnd.dragExpand || dnd.dragExpand(node, ctx) !== false) + ) { + node.scheduleAction("expand", dnd.autoExpandMS); + } + if (hitMode && dnd.dragOver) { + // TODO: http://code.google.com/p/dynatree/source/detail?r=625 + ctx.hitMode = hitMode; + res = dnd.dragOver(node, ctx); + } + accept = res !== false && hitMode !== null; + if (dnd.smartRevert) { + draggable.options.revert = !accept; + } + this._local._setDndStatus( + otherNode, + node, + ui.helper, + hitMode, + accept + ); + break; + + case "drop": + hitMode = ui.helper.data("hitMode"); + if (hitMode && dnd.dragDrop) { + ctx.hitMode = hitMode; + dnd.dragDrop(node, ctx); + } + break; + + case "leave": + // Cancel pending expand request + node.scheduleAction("cancel"); + ui.helper.data("enterResponse", null); + ui.helper.data("hitMode", null); + this._local._setDndStatus( + otherNode, + node, + ui.helper, + "out", + undefined + ); + if (dnd.dragLeave) { + dnd.dragLeave(node, ctx); + } + break; + + case "stop": + $nodeTag.removeClass("fancytree-drag-source"); + $(document).off(".fancytree-dnd"); + if (dnd.dragStop) { + dnd.dragStop(node, ctx); + } + break; + + default: + $.error("Unsupported drag event: " + eventName); + } + return res; + }, + + _cancelDrag: function () { + var dd = $.ui.ddmanager.current; + if (dd) { + dd.cancel(); + } + }, + }); + // Value returned by `require('jquery.fancytree..')` + return $.ui.fancytree; +}); // End of closure + +/*! + * jquery.fancytree.dnd5.js + * + * Drag-and-drop support (native HTML5). + * (Extension module for jquery.fancytree.js: https://github.com/mar10/fancytree/) + * + * Copyright (c) 2008-2023, Martin Wendt (https://wwWendt.de) + * + * Released under the MIT license + * https://github.com/mar10/fancytree/wiki/LicenseInfo + * + * @version 2.38.3 + * @date 2023-02-01T20:52:50Z + */ + +/* + #TODO + Compatiblity when dragging between *separate* windows: + + Drag from Chrome Edge FF IE11 Safari + To Chrome ok ok ok NO ? + Edge ok ok ok NO ? + FF ok ok ok NO ? + IE 11 ok ok ok ok ? + Safari ? ? ? ? ok + + */ + +(function (factory) { + if (typeof define === "function" && define.amd) { + // AMD. Register as an anonymous module. + define(["jquery", "./jquery.fancytree"], factory); + } else if (typeof module === "object" && module.exports) { + // Node/CommonJS + require("./jquery.fancytree"); + module.exports = factory(require("jquery")); + } else { + // Browser globals + factory(jQuery); + } +})(function ($) { + "use strict"; + + /****************************************************************************** + * Private functions and variables + */ + var FT = $.ui.fancytree, + isMac = /Mac/.test(navigator.platform), + classDragSource = "fancytree-drag-source", + classDragRemove = "fancytree-drag-remove", + classDropAccept = "fancytree-drop-accept", + classDropAfter = "fancytree-drop-after", + classDropBefore = "fancytree-drop-before", + classDropOver = "fancytree-drop-over", + classDropReject = "fancytree-drop-reject", + classDropTarget = "fancytree-drop-target", + nodeMimeType = "application/x-fancytree-node", + $dropMarker = null, + $dragImage, + $extraHelper, + SOURCE_NODE = null, + SOURCE_NODE_LIST = null, + $sourceList = null, + DRAG_ENTER_RESPONSE = null, + // SESSION_DATA = null, // plain object passed to events as `data` + SUGGESTED_DROP_EFFECT = null, + REQUESTED_DROP_EFFECT = null, + REQUESTED_EFFECT_ALLOWED = null, + LAST_HIT_MODE = null, + DRAG_OVER_STAMP = null; // Time when a node entered the 'over' hitmode + + /* */ + function _clearGlobals() { + DRAG_ENTER_RESPONSE = null; + DRAG_OVER_STAMP = null; + REQUESTED_DROP_EFFECT = null; + REQUESTED_EFFECT_ALLOWED = null; + SUGGESTED_DROP_EFFECT = null; + SOURCE_NODE = null; + SOURCE_NODE_LIST = null; + if ($sourceList) { + $sourceList.removeClass(classDragSource + " " + classDragRemove); + } + $sourceList = null; + if ($dropMarker) { + $dropMarker.hide(); + } + // Take this badge off of me - I can't use it anymore: + if ($extraHelper) { + $extraHelper.remove(); + $extraHelper = null; + } + } + + /* Convert number to string and prepend +/-; return empty string for 0.*/ + function offsetString(n) { + // eslint-disable-next-line no-nested-ternary + return n === 0 ? "" : n > 0 ? "+" + n : "" + n; + } + + /* Convert a dragEnter() or dragOver() response to a canonical form. + * Return false or plain object + * @param {string|object|boolean} r + * @return {object|false} + */ + function normalizeDragEnterResponse(r) { + var res; + + if (!r) { + return false; + } + if ($.isPlainObject(r)) { + res = { + over: !!r.over, + before: !!r.before, + after: !!r.after, + }; + } else if (Array.isArray(r)) { + res = { + over: $.inArray("over", r) >= 0, + before: $.inArray("before", r) >= 0, + after: $.inArray("after", r) >= 0, + }; + } else { + res = { + over: r === true || r === "over", + before: r === true || r === "before", + after: r === true || r === "after", + }; + } + if (Object.keys(res).length === 0) { + return false; + } + // if( Object.keys(res).length === 1 ) { + // res.unique = res[0]; + // } + return res; + } + + /* Convert a dataTransfer.effectAllowed to a canonical form. + * Return false or plain object + * @param {string|boolean} r + * @return {object|false} + */ + // function normalizeEffectAllowed(r) { + // if (!r || r === "none") { + // return false; + // } + // var all = r === "all", + // res = { + // copy: all || /copy/i.test(r), + // link: all || /link/i.test(r), + // move: all || /move/i.test(r), + // }; + + // return res; + // } + + /* Implement auto scrolling when drag cursor is in top/bottom area of scroll parent. */ + function autoScroll(tree, event) { + var spOfs, + scrollTop, + delta, + dndOpts = tree.options.dnd5, + sp = tree.$scrollParent[0], + sensitivity = dndOpts.scrollSensitivity, + speed = dndOpts.scrollSpeed, + scrolled = 0; + + if (sp !== document && sp.tagName !== "HTML") { + spOfs = tree.$scrollParent.offset(); + scrollTop = sp.scrollTop; + if (spOfs.top + sp.offsetHeight - event.pageY < sensitivity) { + delta = + sp.scrollHeight - + tree.$scrollParent.innerHeight() - + scrollTop; + // console.log ("sp.offsetHeight: " + sp.offsetHeight + // + ", spOfs.top: " + spOfs.top + // + ", scrollTop: " + scrollTop + // + ", innerHeight: " + tree.$scrollParent.innerHeight() + // + ", scrollHeight: " + sp.scrollHeight + // + ", delta: " + delta + // ); + if (delta > 0) { + sp.scrollTop = scrolled = scrollTop + speed; + } + } else if (scrollTop > 0 && event.pageY - spOfs.top < sensitivity) { + sp.scrollTop = scrolled = scrollTop - speed; + } + } else { + scrollTop = $(document).scrollTop(); + if (scrollTop > 0 && event.pageY - scrollTop < sensitivity) { + scrolled = scrollTop - speed; + $(document).scrollTop(scrolled); + } else if ( + $(window).height() - (event.pageY - scrollTop) < + sensitivity + ) { + scrolled = scrollTop + speed; + $(document).scrollTop(scrolled); + } + } + if (scrolled) { + tree.debug("autoScroll: " + scrolled + "px"); + } + return scrolled; + } + + /* Guess dropEffect from modifier keys. + * Using rules suggested here: + * https://ux.stackexchange.com/a/83769 + * @returns + * 'copy', 'link', 'move', or 'none' + */ + function evalEffectModifiers(tree, event, effectDefault) { + var res = effectDefault; + + if (isMac) { + if (event.metaKey && event.altKey) { + // Mac: [Control] + [Option] + res = "link"; + } else if (event.ctrlKey) { + // Chrome on Mac: [Control] + res = "link"; + } else if (event.metaKey) { + // Mac: [Command] + res = "move"; + } else if (event.altKey) { + // Mac: [Option] + res = "copy"; + } + } else { + if (event.ctrlKey) { + // Windows: [Ctrl] + res = "copy"; + } else if (event.shiftKey) { + // Windows: [Shift] + res = "move"; + } else if (event.altKey) { + // Windows: [Alt] + res = "link"; + } + } + if (res !== SUGGESTED_DROP_EFFECT) { + tree.info( + "evalEffectModifiers: " + + event.type + + " - evalEffectModifiers(): " + + SUGGESTED_DROP_EFFECT + + " -> " + + res + ); + } + SUGGESTED_DROP_EFFECT = res; + // tree.debug("evalEffectModifiers: " + res); + return res; + } + /* + * Check if the previous callback (dragEnter, dragOver, ...) has changed + * the `data` object and apply those settings. + * + * Safari: + * It seems that `dataTransfer.dropEffect` can only be set on dragStart, and will remain + * even if the cursor changes when [Alt] or [Ctrl] are pressed (?) + * Using rules suggested here: + * https://ux.stackexchange.com/a/83769 + * @returns + * 'copy', 'link', 'move', or 'none' + */ + function prepareDropEffectCallback(event, data) { + var tree = data.tree, + dataTransfer = data.dataTransfer; + + if (event.type === "dragstart") { + data.effectAllowed = tree.options.dnd5.effectAllowed; + data.dropEffect = tree.options.dnd5.dropEffectDefault; + } else { + data.effectAllowed = REQUESTED_EFFECT_ALLOWED; + data.dropEffect = REQUESTED_DROP_EFFECT; + } + data.dropEffectSuggested = evalEffectModifiers( + tree, + event, + tree.options.dnd5.dropEffectDefault + ); + data.isMove = data.dropEffect === "move"; + data.files = dataTransfer.files || []; + + // if (REQUESTED_EFFECT_ALLOWED !== dataTransfer.effectAllowed) { + // tree.warn( + // "prepareDropEffectCallback(" + + // event.type + + // "): dataTransfer.effectAllowed changed from " + + // REQUESTED_EFFECT_ALLOWED + + // " -> " + + // dataTransfer.effectAllowed + // ); + // } + // if (REQUESTED_DROP_EFFECT !== dataTransfer.dropEffect) { + // tree.warn( + // "prepareDropEffectCallback(" + + // event.type + + // "): dataTransfer.dropEffect changed from requested " + + // REQUESTED_DROP_EFFECT + + // " to " + + // dataTransfer.dropEffect + // ); + // } + } + + function applyDropEffectCallback(event, data, allowDrop) { + var tree = data.tree, + dataTransfer = data.dataTransfer; + + if ( + event.type !== "dragstart" && + REQUESTED_EFFECT_ALLOWED !== data.effectAllowed + ) { + tree.warn( + "effectAllowed should only be changed in dragstart event: " + + event.type + + ": data.effectAllowed changed from " + + REQUESTED_EFFECT_ALLOWED + + " -> " + + data.effectAllowed + ); + } + + if (allowDrop === false) { + tree.info("applyDropEffectCallback: allowDrop === false"); + data.effectAllowed = "none"; + data.dropEffect = "none"; + } + // if (REQUESTED_DROP_EFFECT !== data.dropEffect) { + // tree.debug( + // "applyDropEffectCallback(" + + // event.type + + // "): data.dropEffect changed from previous " + + // REQUESTED_DROP_EFFECT + + // " to " + + // data.dropEffect + // ); + // } + + data.isMove = data.dropEffect === "move"; + // data.isMove = data.dropEffectSuggested === "move"; + + // `effectAllowed` must only be defined in dragstart event, so we + // store it in a global variable for reference + if (event.type === "dragstart") { + REQUESTED_EFFECT_ALLOWED = data.effectAllowed; + REQUESTED_DROP_EFFECT = data.dropEffect; + } + + // if (REQUESTED_DROP_EFFECT !== dataTransfer.dropEffect) { + // data.tree.info( + // "applyDropEffectCallback(" + + // event.type + + // "): dataTransfer.dropEffect changed from " + + // REQUESTED_DROP_EFFECT + + // " -> " + + // dataTransfer.dropEffect + // ); + // } + dataTransfer.effectAllowed = REQUESTED_EFFECT_ALLOWED; + dataTransfer.dropEffect = REQUESTED_DROP_EFFECT; + + // tree.debug( + // "applyDropEffectCallback(" + + // event.type + + // "): set " + + // dataTransfer.dropEffect + + // "/" + + // dataTransfer.effectAllowed + // ); + // if (REQUESTED_DROP_EFFECT !== dataTransfer.dropEffect) { + // data.tree.warn( + // "applyDropEffectCallback(" + + // event.type + + // "): could not set dataTransfer.dropEffect to " + + // REQUESTED_DROP_EFFECT + + // ": got " + + // dataTransfer.dropEffect + // ); + // } + return REQUESTED_DROP_EFFECT; + } + + /* Handle dragover event (fired every x ms) on valid drop targets. + * + * - Auto-scroll when cursor is in border regions + * - Apply restrictioan like 'preventVoidMoves' + * - Calculate hit mode + * - Calculate drop effect + * - Trigger dragOver() callback to let user modify hit mode and drop effect + * - Adjust the drop marker accordingly + * + * @returns hitMode + */ + function handleDragOver(event, data) { + // Implement auto-scrolling + if (data.options.dnd5.scroll) { + autoScroll(data.tree, event); + } + // Bail out with previous response if we get an invalid dragover + if (!data.node) { + data.tree.warn("Ignored dragover for non-node"); //, event, data); + return LAST_HIT_MODE; + } + + var markerOffsetX, + nodeOfs, + pos, + relPosY, + hitMode = null, + tree = data.tree, + options = tree.options, + dndOpts = options.dnd5, + targetNode = data.node, + sourceNode = data.otherNode, + markerAt = "center", + $target = $(targetNode.span), + $targetTitle = $target.find("span.fancytree-title"); + + if (DRAG_ENTER_RESPONSE === false) { + tree.debug("Ignored dragover, since dragenter returned false."); + return false; + } else if (typeof DRAG_ENTER_RESPONSE === "string") { + $.error("assert failed: dragenter returned string"); + } + // Calculate hitMode from relative cursor position. + nodeOfs = $target.offset(); + relPosY = (event.pageY - nodeOfs.top) / $target.height(); + if (event.pageY === undefined) { + tree.warn("event.pageY is undefined: see issue #1013."); + } + + if (DRAG_ENTER_RESPONSE.after && relPosY > 0.75) { + hitMode = "after"; + } else if ( + !DRAG_ENTER_RESPONSE.over && + DRAG_ENTER_RESPONSE.after && + relPosY > 0.5 + ) { + hitMode = "after"; + } else if (DRAG_ENTER_RESPONSE.before && relPosY <= 0.25) { + hitMode = "before"; + } else if ( + !DRAG_ENTER_RESPONSE.over && + DRAG_ENTER_RESPONSE.before && + relPosY <= 0.5 + ) { + hitMode = "before"; + } else if (DRAG_ENTER_RESPONSE.over) { + hitMode = "over"; + } + // Prevent no-ops like 'before source node' + // TODO: these are no-ops when moving nodes, but not in copy mode + if (dndOpts.preventVoidMoves && data.dropEffect === "move") { + if (targetNode === sourceNode) { + targetNode.debug("Drop over source node prevented."); + hitMode = null; + } else if ( + hitMode === "before" && + sourceNode && + targetNode === sourceNode.getNextSibling() + ) { + targetNode.debug("Drop after source node prevented."); + hitMode = null; + } else if ( + hitMode === "after" && + sourceNode && + targetNode === sourceNode.getPrevSibling() + ) { + targetNode.debug("Drop before source node prevented."); + hitMode = null; + } else if ( + hitMode === "over" && + sourceNode && + sourceNode.parent === targetNode && + sourceNode.isLastSibling() + ) { + targetNode.debug("Drop last child over own parent prevented."); + hitMode = null; + } + } + // Let callback modify the calculated hitMode + data.hitMode = hitMode; + if (hitMode && dndOpts.dragOver) { + prepareDropEffectCallback(event, data); + dndOpts.dragOver(targetNode, data); + var allowDrop = !!hitMode; + applyDropEffectCallback(event, data, allowDrop); + hitMode = data.hitMode; + } + LAST_HIT_MODE = hitMode; + // + if (hitMode === "after" || hitMode === "before" || hitMode === "over") { + markerOffsetX = dndOpts.dropMarkerOffsetX || 0; + switch (hitMode) { + case "before": + markerAt = "top"; + markerOffsetX += dndOpts.dropMarkerInsertOffsetX || 0; + break; + case "after": + markerAt = "bottom"; + markerOffsetX += dndOpts.dropMarkerInsertOffsetX || 0; + break; + } + + pos = { + my: "left" + offsetString(markerOffsetX) + " center", + at: "left " + markerAt, + of: $targetTitle, + }; + if (options.rtl) { + pos.my = "right" + offsetString(-markerOffsetX) + " center"; + pos.at = "right " + markerAt; + // console.log("rtl", pos); + } + $dropMarker + .toggleClass(classDropAfter, hitMode === "after") + .toggleClass(classDropOver, hitMode === "over") + .toggleClass(classDropBefore, hitMode === "before") + .show() + .position(FT.fixPositionOptions(pos)); + } else { + $dropMarker.hide(); + // console.log("hide dropmarker") + } + + $(targetNode.span) + .toggleClass( + classDropTarget, + hitMode === "after" || + hitMode === "before" || + hitMode === "over" + ) + .toggleClass(classDropAfter, hitMode === "after") + .toggleClass(classDropBefore, hitMode === "before") + .toggleClass(classDropAccept, hitMode === "over") + .toggleClass(classDropReject, hitMode === false); + + return hitMode; + } + + /* + * Handle dragstart drag dragend events on the container + */ + function onDragEvent(event) { + var json, + tree = this, + dndOpts = tree.options.dnd5, + node = FT.getNode(event), + dataTransfer = + event.dataTransfer || event.originalEvent.dataTransfer, + data = { + tree: tree, + node: node, + options: tree.options, + originalEvent: event.originalEvent, + widget: tree.widget, + dataTransfer: dataTransfer, + useDefaultImage: true, + dropEffect: undefined, + dropEffectSuggested: undefined, + effectAllowed: undefined, // set by dragstart + files: undefined, // only for drop events + isCancelled: undefined, // set by dragend + isMove: undefined, + }; + + switch (event.type) { + case "dragstart": + if (!node) { + tree.info("Ignored dragstart on a non-node."); + return false; + } + // Store current source node in different formats + SOURCE_NODE = node; + + // Also optionally store selected nodes + if (dndOpts.multiSource === false) { + SOURCE_NODE_LIST = [node]; + } else if (dndOpts.multiSource === true) { + if (node.isSelected()) { + SOURCE_NODE_LIST = tree.getSelectedNodes(); + } else { + SOURCE_NODE_LIST = [node]; + } + } else { + SOURCE_NODE_LIST = dndOpts.multiSource(node, data); + } + // Cache as array of jQuery objects for faster access: + $sourceList = $( + $.map(SOURCE_NODE_LIST, function (n) { + return n.span; + }) + ); + // Set visual feedback + $sourceList.addClass(classDragSource); + + // Set payload + // Note: + // Transfer data is only accessible on dragstart and drop! + // For all other events the formats and kinds in the drag + // data store list of items representing dragged data can be + // enumerated, but the data itself is unavailable and no new + // data can be added. + var nodeData = node.toDict(true, dndOpts.sourceCopyHook); + nodeData.treeId = node.tree._id; + json = JSON.stringify(nodeData); + try { + dataTransfer.setData(nodeMimeType, json); + dataTransfer.setData("text/html", $(node.span).html()); + dataTransfer.setData("text/plain", node.title); + } catch (ex) { + // IE only accepts 'text' type + tree.warn( + "Could not set data (IE only accepts 'text') - " + ex + ); + } + // We always need to set the 'text' type if we want to drag + // Because IE 11 only accepts this single type. + // If we pass JSON here, IE can can access all node properties, + // even when the source lives in another window. (D'n'd inside + // the same window will always work.) + // The drawback is, that in this case ALL browsers will see + // the JSON representation as 'text', so dragging + // to a text field will insert the JSON string instead of + // the node title. + if (dndOpts.setTextTypeJson) { + dataTransfer.setData("text", json); + } else { + dataTransfer.setData("text", node.title); + } + + // Set the allowed drag modes (combinations of move, copy, and link) + // (effectAllowed can only be set in the dragstart event.) + // This can be overridden in the dragStart() callback + prepareDropEffectCallback(event, data); + + // Let user cancel or modify above settings + // Realize potential changes by previous callback + if (dndOpts.dragStart(node, data) === false) { + // Cancel dragging + // dataTransfer.dropEffect = "none"; + _clearGlobals(); + return false; + } + applyDropEffectCallback(event, data); + + // Unless user set `data.useDefaultImage` to false in dragStart, + // generata a default drag image now: + $extraHelper = null; + + if (data.useDefaultImage) { + // Set the title as drag image (otherwise it would contain the expander) + $dragImage = $(node.span).find(".fancytree-title"); + + if (SOURCE_NODE_LIST && SOURCE_NODE_LIST.length > 1) { + // Add a counter badge to node title if dragging more than one node. + // We want this, because the element that is used as drag image + // must be *visible* in the DOM, so we cannot create some hidden + // custom markup. + // See https://kryogenix.org/code/browser/custom-drag-image.html + // Also, since IE 11 and Edge don't support setDragImage() alltogether, + // it gives som feedback to the user. + // The badge will be removed later on drag end. + $extraHelper = $( + "<span class='fancytree-childcounter'/>" + ) + .text("+" + (SOURCE_NODE_LIST.length - 1)) + .appendTo($dragImage); + } + if (dataTransfer.setDragImage) { + // IE 11 and Edge do not support this + dataTransfer.setDragImage($dragImage[0], -10, -10); + } + } + return true; + + case "drag": + // Called every few milliseconds (no matter if the + // cursor is over a valid drop target) + // data.tree.info("drag", SOURCE_NODE) + prepareDropEffectCallback(event, data); + dndOpts.dragDrag(node, data); + applyDropEffectCallback(event, data); + + $sourceList.toggleClass(classDragRemove, data.isMove); + break; + + case "dragend": + // Called at the end of a d'n'd process (after drop) + // Note caveat: If drop removed the dragged source element, + // we may not get this event, since the target does not exist + // anymore + prepareDropEffectCallback(event, data); + + _clearGlobals(); + + data.isCancelled = !LAST_HIT_MODE; + dndOpts.dragEnd(node, data, !LAST_HIT_MODE); + // applyDropEffectCallback(event, data); + break; + } + } + /* + * Handle dragenter dragover dragleave drop events on the container + */ + function onDropEvent(event) { + var json, + allowAutoExpand, + nodeData, + isSourceFtNode, + r, + res, + tree = this, + dndOpts = tree.options.dnd5, + allowDrop = null, + node = FT.getNode(event), + dataTransfer = + event.dataTransfer || event.originalEvent.dataTransfer, + data = { + tree: tree, + node: node, + options: tree.options, + originalEvent: event.originalEvent, + widget: tree.widget, + hitMode: DRAG_ENTER_RESPONSE, + dataTransfer: dataTransfer, + otherNode: SOURCE_NODE || null, + otherNodeList: SOURCE_NODE_LIST || null, + otherNodeData: null, // set by drop event + useDefaultImage: true, + dropEffect: undefined, + dropEffectSuggested: undefined, + effectAllowed: undefined, // set by dragstart + files: null, // list of File objects (may be []) + isCancelled: undefined, // set by drop event + isMove: undefined, + }; + + // data.isMove = dropEffect === "move"; + + switch (event.type) { + case "dragenter": + // The dragenter event is fired when a dragged element or + // text selection enters a valid drop target. + + DRAG_OVER_STAMP = null; + if (!node) { + // Sometimes we get dragenter for the container element + tree.debug( + "Ignore non-node " + + event.type + + ": " + + event.target.tagName + + "." + + event.target.className + ); + DRAG_ENTER_RESPONSE = false; + break; + } + + $(node.span) + .addClass(classDropOver) + .removeClass(classDropAccept + " " + classDropReject); + + // Data is only readable in the dragstart and drop event, + // but we can check for the type: + isSourceFtNode = + $.inArray(nodeMimeType, dataTransfer.types) >= 0; + + if (dndOpts.preventNonNodes && !isSourceFtNode) { + node.debug("Reject dropping a non-node."); + DRAG_ENTER_RESPONSE = false; + break; + } else if ( + dndOpts.preventForeignNodes && + (!SOURCE_NODE || SOURCE_NODE.tree !== node.tree) + ) { + node.debug("Reject dropping a foreign node."); + DRAG_ENTER_RESPONSE = false; + break; + } else if ( + dndOpts.preventSameParent && + data.otherNode && + data.otherNode.tree === node.tree && + node.parent === data.otherNode.parent + ) { + node.debug("Reject dropping as sibling (same parent)."); + DRAG_ENTER_RESPONSE = false; + break; + } else if ( + dndOpts.preventRecursion && + data.otherNode && + data.otherNode.tree === node.tree && + node.isDescendantOf(data.otherNode) + ) { + node.debug("Reject dropping below own ancestor."); + DRAG_ENTER_RESPONSE = false; + break; + } else if (dndOpts.preventLazyParents && !node.isLoaded()) { + node.warn("Drop over unloaded target node prevented."); + DRAG_ENTER_RESPONSE = false; + break; + } + $dropMarker.show(); + + // Call dragEnter() to figure out if (and where) dropping is allowed + prepareDropEffectCallback(event, data); + r = dndOpts.dragEnter(node, data); + + res = normalizeDragEnterResponse(r); + // alert("res:" + JSON.stringify(res)) + DRAG_ENTER_RESPONSE = res; + + allowDrop = res && (res.over || res.before || res.after); + + applyDropEffectCallback(event, data, allowDrop); + break; + + case "dragover": + if (!node) { + tree.debug( + "Ignore non-node " + + event.type + + ": " + + event.target.tagName + + "." + + event.target.className + ); + break; + } + // The dragover event is fired when an element or text + // selection is being dragged over a valid drop target + // (every few hundred milliseconds). + // tree.debug( + // event.type + + // ": dropEffect: " + + // dataTransfer.dropEffect + // ); + prepareDropEffectCallback(event, data); + LAST_HIT_MODE = handleDragOver(event, data); + + // The flag controls the preventDefault() below: + allowDrop = !!LAST_HIT_MODE; + allowAutoExpand = + LAST_HIT_MODE === "over" || LAST_HIT_MODE === false; + + if ( + allowAutoExpand && + !node.expanded && + node.hasChildren() !== false + ) { + if (!DRAG_OVER_STAMP) { + DRAG_OVER_STAMP = Date.now(); + } else if ( + dndOpts.autoExpandMS && + Date.now() - DRAG_OVER_STAMP > dndOpts.autoExpandMS && + !node.isLoading() && + (!dndOpts.dragExpand || + dndOpts.dragExpand(node, data) !== false) + ) { + node.setExpanded(); + } + } else { + DRAG_OVER_STAMP = null; + } + break; + + case "dragleave": + // NOTE: dragleave is fired AFTER the dragenter event of the + // FOLLOWING element. + if (!node) { + tree.debug( + "Ignore non-node " + + event.type + + ": " + + event.target.tagName + + "." + + event.target.className + ); + break; + } + if (!$(node.span).hasClass(classDropOver)) { + node.debug("Ignore dragleave (multi)."); + break; + } + $(node.span).removeClass( + classDropOver + + " " + + classDropAccept + + " " + + classDropReject + ); + node.scheduleAction("cancel"); + dndOpts.dragLeave(node, data); + $dropMarker.hide(); + break; + + case "drop": + // Data is only readable in the (dragstart and) drop event: + + if ($.inArray(nodeMimeType, dataTransfer.types) >= 0) { + nodeData = dataTransfer.getData(nodeMimeType); + tree.info( + event.type + + ": getData('application/x-fancytree-node'): '" + + nodeData + + "'" + ); + } + if (!nodeData) { + // 1. Source is not a Fancytree node, or + // 2. If the FT mime type was set, but returns '', this + // is probably IE 11 (which only supports 'text') + nodeData = dataTransfer.getData("text"); + tree.info( + event.type + ": getData('text'): '" + nodeData + "'" + ); + } + if (nodeData) { + try { + // 'text' type may contain JSON if IE is involved + // and setTextTypeJson option was set + json = JSON.parse(nodeData); + if (json.title !== undefined) { + data.otherNodeData = json; + } + } catch (ex) { + // assume 'text' type contains plain text, so `otherNodeData` + // should not be set + } + } + tree.debug( + event.type + + ": nodeData: '" + + nodeData + + "', otherNodeData: ", + data.otherNodeData + ); + + $(node.span).removeClass( + classDropOver + + " " + + classDropAccept + + " " + + classDropReject + ); + + // Let user implement the actual drop operation + data.hitMode = LAST_HIT_MODE; + prepareDropEffectCallback(event, data, !LAST_HIT_MODE); + data.isCancelled = !LAST_HIT_MODE; + + var orgSourceElem = SOURCE_NODE && SOURCE_NODE.span, + orgSourceTree = SOURCE_NODE && SOURCE_NODE.tree; + + dndOpts.dragDrop(node, data); + // applyDropEffectCallback(event, data); + + // Prevent browser's default drop handling, i.e. open as link, ... + event.preventDefault(); + + if (orgSourceElem && !document.body.contains(orgSourceElem)) { + // The drop handler removed the original drag source from + // the DOM, so the dragend event will probaly not fire. + if (orgSourceTree === tree) { + tree.debug( + "Drop handler removed source element: generating dragEnd." + ); + dndOpts.dragEnd(SOURCE_NODE, data); + } else { + tree.warn( + "Drop handler removed source element: dragend event may be lost." + ); + } + } + + _clearGlobals(); + + break; + } + // Dnd API madness: we must PREVENT default handling to enable dropping + if (allowDrop) { + event.preventDefault(); + return false; + } + } + + /** [ext-dnd5] Return a Fancytree instance, from element, index, event, or jQueryObject. + * + * @returns {FancytreeNode[]} List of nodes (empty if no drag operation) + * @example + * $.ui.fancytree.getDragNodeList(); + * + * @alias Fancytree_Static#getDragNodeList + * @requires jquery.fancytree.dnd5.js + * @since 2.31 + */ + $.ui.fancytree.getDragNodeList = function () { + return SOURCE_NODE_LIST || []; + }; + + /** [ext-dnd5] Return the FancytreeNode that is currently being dragged. + * + * If multiple nodes are dragged, only the first is returned. + * + * @returns {FancytreeNode | null} dragged nodes or null if no drag operation + * @example + * $.ui.fancytree.getDragNode(); + * + * @alias Fancytree_Static#getDragNode + * @requires jquery.fancytree.dnd5.js + * @since 2.31 + */ + $.ui.fancytree.getDragNode = function () { + return SOURCE_NODE; + }; + + /****************************************************************************** + * + */ + + $.ui.fancytree.registerExtension({ + name: "dnd5", + version: "2.38.3", + // Default options for this extension. + options: { + autoExpandMS: 1500, // Expand nodes after n milliseconds of hovering + dropMarkerInsertOffsetX: -16, // Additional offset for drop-marker with hitMode = "before"/"after" + dropMarkerOffsetX: -24, // Absolute position offset for .fancytree-drop-marker relatively to ..fancytree-title (icon/img near a node accepting drop) + // #1021 `document.body` is not available yet + dropMarkerParent: "body", // Root Container used for drop marker (could be a shadow root) + multiSource: false, // true: Drag multiple (i.e. selected) nodes. Also a callback() is allowed + effectAllowed: "all", // Restrict the possible cursor shapes and modifier operations (can also be set in the dragStart event) + // dropEffect: "auto", // 'copy'|'link'|'move'|'auto'(calculate from `effectAllowed`+modifier keys) or callback(node, data) that returns such string. + dropEffectDefault: "move", // Default dropEffect ('copy', 'link', or 'move') when no modifier is pressed (overide in dragDrag, dragOver). + preventForeignNodes: false, // Prevent dropping nodes from different Fancytrees + preventLazyParents: true, // Prevent dropping items on unloaded lazy Fancytree nodes + preventNonNodes: false, // Prevent dropping items other than Fancytree nodes + preventRecursion: true, // Prevent dropping nodes on own descendants + preventSameParent: false, // Prevent dropping nodes under same direct parent + preventVoidMoves: true, // Prevent dropping nodes 'before self', etc. + scroll: true, // Enable auto-scrolling while dragging + scrollSensitivity: 20, // Active top/bottom margin in pixel + scrollSpeed: 5, // Pixel per event + setTextTypeJson: false, // Allow dragging of nodes to different IE windows + sourceCopyHook: null, // Optional callback passed to `toDict` on dragStart @since 2.38 + // Events (drag support) + dragStart: null, // Callback(sourceNode, data), return true, to enable dnd drag + dragDrag: $.noop, // Callback(sourceNode, data) + dragEnd: $.noop, // Callback(sourceNode, data) + // Events (drop support) + dragEnter: null, // Callback(targetNode, data), return true, to enable dnd drop + dragOver: $.noop, // Callback(targetNode, data) + dragExpand: $.noop, // Callback(targetNode, data), return false to prevent autoExpand + dragDrop: $.noop, // Callback(targetNode, data) + dragLeave: $.noop, // Callback(targetNode, data) + }, + + treeInit: function (ctx) { + var $temp, + tree = ctx.tree, + opts = ctx.options, + glyph = opts.glyph || null, + dndOpts = opts.dnd5; + + if ($.inArray("dnd", opts.extensions) >= 0) { + $.error("Extensions 'dnd' and 'dnd5' are mutually exclusive."); + } + if (dndOpts.dragStop) { + $.error( + "dragStop is not used by ext-dnd5. Use dragEnd instead." + ); + } + if (dndOpts.preventRecursiveMoves != null) { + $.error( + "preventRecursiveMoves was renamed to preventRecursion." + ); + } + + // Implement `opts.createNode` event to add the 'draggable' attribute + // #680: this must happen before calling super.treeInit() + if (dndOpts.dragStart) { + FT.overrideMethod( + ctx.options, + "createNode", + function (event, data) { + // Default processing if any + this._super.apply(this, arguments); + if (data.node.span) { + data.node.span.draggable = true; + } else { + data.node.warn( + "Cannot add `draggable`: no span tag" + ); + } + } + ); + } + this._superApply(arguments); + + this.$container.addClass("fancytree-ext-dnd5"); + + // Store the current scroll parent, which may be the tree + // container, any enclosing div, or the document. + // #761: scrollParent() always needs a container child + $temp = $("<span>").appendTo(this.$container); + this.$scrollParent = $temp.scrollParent(); + $temp.remove(); + + $dropMarker = $("#fancytree-drop-marker"); + if (!$dropMarker.length) { + $dropMarker = $("<div id='fancytree-drop-marker'></div>") + .hide() + .css({ + "z-index": 1000, + // Drop marker should not steal dragenter/dragover events: + "pointer-events": "none", + }) + .prependTo(dndOpts.dropMarkerParent); + if (glyph) { + FT.setSpanIcon( + $dropMarker[0], + glyph.map._addClass, + glyph.map.dropMarker + ); + } + } + $dropMarker.toggleClass("fancytree-rtl", !!opts.rtl); + + // Enable drag support if dragStart() is specified: + if (dndOpts.dragStart) { + // Bind drag event handlers + tree.$container.on( + "dragstart drag dragend", + onDragEvent.bind(tree) + ); + } + // Enable drop support if dragEnter() is specified: + if (dndOpts.dragEnter) { + // Bind drop event handlers + tree.$container.on( + "dragenter dragover dragleave drop", + onDropEvent.bind(tree) + ); + } + }, + }); + // Value returned by `require('jquery.fancytree..')` + return $.ui.fancytree; +}); // End of closure + +/*! + * jquery.fancytree.edit.js + * + * Make node titles editable. + * (Extension module for jquery.fancytree.js: https://github.com/mar10/fancytree/) + * + * Copyright (c) 2008-2023, Martin Wendt (https://wwWendt.de) + * + * Released under the MIT license + * https://github.com/mar10/fancytree/wiki/LicenseInfo + * + * @version 2.38.3 + * @date 2023-02-01T20:52:50Z + */ + +(function (factory) { + if (typeof define === "function" && define.amd) { + // AMD. Register as an anonymous module. + define(["jquery", "./jquery.fancytree"], factory); + } else if (typeof module === "object" && module.exports) { + // Node/CommonJS + require("./jquery.fancytree"); + module.exports = factory(require("jquery")); + } else { + // Browser globals + factory(jQuery); + } +})(function ($) { + "use strict"; + + /******************************************************************************* + * Private functions and variables + */ + + var isMac = /Mac/.test(navigator.platform), + escapeHtml = $.ui.fancytree.escapeHtml, + trim = $.ui.fancytree.trim, + unescapeHtml = $.ui.fancytree.unescapeHtml; + + /** + * [ext-edit] Start inline editing of current node title. + * + * @alias FancytreeNode#editStart + * @requires Fancytree + */ + $.ui.fancytree._FancytreeNodeClass.prototype.editStart = function () { + var $input, + node = this, + tree = this.tree, + local = tree.ext.edit, + instOpts = tree.options.edit, + $title = $(".fancytree-title", node.span), + eventData = { + node: node, + tree: tree, + options: tree.options, + isNew: $(node[tree.statusClassPropName]).hasClass( + "fancytree-edit-new" + ), + orgTitle: node.title, + input: null, + dirty: false, + }; + + // beforeEdit may want to modify the title before editing + if ( + instOpts.beforeEdit.call( + node, + { type: "beforeEdit" }, + eventData + ) === false + ) { + return false; + } + $.ui.fancytree.assert(!local.currentNode, "recursive edit"); + local.currentNode = this; + local.eventData = eventData; + + // Disable standard Fancytree mouse- and key handling + tree.widget._unbind(); + + local.lastDraggableAttrValue = node.span.draggable; + if (local.lastDraggableAttrValue) { + node.span.draggable = false; + } + + // #116: ext-dnd prevents the blur event, so we have to catch outer clicks + $(document).on("mousedown.fancytree-edit", function (event) { + if (!$(event.target).hasClass("fancytree-edit-input")) { + node.editEnd(true, event); + } + }); + + // Replace node with <input> + $input = $("<input />", { + class: "fancytree-edit-input", + type: "text", + value: tree.options.escapeTitles + ? eventData.orgTitle + : unescapeHtml(eventData.orgTitle), + }); + local.eventData.input = $input; + if (instOpts.adjustWidthOfs != null) { + $input.width($title.width() + instOpts.adjustWidthOfs); + } + if (instOpts.inputCss != null) { + $input.css(instOpts.inputCss); + } + + $title.html($input); + + // Focus <input> and bind keyboard handler + $input + .focus() + .change(function (event) { + $input.addClass("fancytree-edit-dirty"); + }) + .on("keydown", function (event) { + switch (event.which) { + case $.ui.keyCode.ESCAPE: + node.editEnd(false, event); + break; + case $.ui.keyCode.ENTER: + node.editEnd(true, event); + return false; // so we don't start editmode on Mac + } + event.stopPropagation(); + }) + .blur(function (event) { + return node.editEnd(true, event); + }); + + instOpts.edit.call(node, { type: "edit" }, eventData); + }; + + /** + * [ext-edit] Stop inline editing. + * @param {Boolean} [applyChanges=false] false: cancel edit, true: save (if modified) + * @alias FancytreeNode#editEnd + * @requires jquery.fancytree.edit.js + */ + $.ui.fancytree._FancytreeNodeClass.prototype.editEnd = function ( + applyChanges, + _event + ) { + var newVal, + node = this, + tree = this.tree, + local = tree.ext.edit, + eventData = local.eventData, + instOpts = tree.options.edit, + $title = $(".fancytree-title", node.span), + $input = $title.find("input.fancytree-edit-input"); + + if (instOpts.trim) { + $input.val(trim($input.val())); + } + newVal = $input.val(); + + eventData.dirty = newVal !== node.title; + eventData.originalEvent = _event; + + // Find out, if saving is required + if (applyChanges === false) { + // If true/false was passed, honor this (except in rename mode, if unchanged) + eventData.save = false; + } else if (eventData.isNew) { + // In create mode, we save everything, except for empty text + eventData.save = newVal !== ""; + } else { + // In rename mode, we save everyting, except for empty or unchanged text + eventData.save = eventData.dirty && newVal !== ""; + } + // Allow to break (keep editor open), modify input, or re-define data.save + if ( + instOpts.beforeClose.call( + node, + { type: "beforeClose" }, + eventData + ) === false + ) { + return false; + } + if ( + eventData.save && + instOpts.save.call(node, { type: "save" }, eventData) === false + ) { + return false; + } + $input.removeClass("fancytree-edit-dirty").off(); + // Unbind outer-click handler + $(document).off(".fancytree-edit"); + + if (eventData.save) { + // # 171: escape user input (not required if global escaping is on) + node.setTitle( + tree.options.escapeTitles ? newVal : escapeHtml(newVal) + ); + node.setFocus(); + } else { + if (eventData.isNew) { + node.remove(); + node = eventData.node = null; + local.relatedNode.setFocus(); + } else { + node.renderTitle(); + node.setFocus(); + } + } + local.eventData = null; + local.currentNode = null; + local.relatedNode = null; + // Re-enable mouse and keyboard handling + tree.widget._bind(); + + if (node && local.lastDraggableAttrValue) { + node.span.draggable = true; + } + + // Set keyboard focus, even if setFocus() claims 'nothing to do' + tree.$container.get(0).focus({ preventScroll: true }); + eventData.input = null; + instOpts.close.call(node, { type: "close" }, eventData); + return true; + }; + + /** + * [ext-edit] Create a new child or sibling node and start edit mode. + * + * @param {String} [mode='child'] 'before', 'after', or 'child' + * @param {Object} [init] NodeData (or simple title string) + * @alias FancytreeNode#editCreateNode + * @requires jquery.fancytree.edit.js + * @since 2.4 + */ + $.ui.fancytree._FancytreeNodeClass.prototype.editCreateNode = function ( + mode, + init + ) { + var newNode, + tree = this.tree, + self = this; + + mode = mode || "child"; + if (init == null) { + init = { title: "" }; + } else if (typeof init === "string") { + init = { title: init }; + } else { + $.ui.fancytree.assert($.isPlainObject(init)); + } + // Make sure node is expanded (and loaded) in 'child' mode + if ( + mode === "child" && + !this.isExpanded() && + this.hasChildren() !== false + ) { + this.setExpanded().done(function () { + self.editCreateNode(mode, init); + }); + return; + } + newNode = this.addNode(init, mode); + + // #644: Don't filter new nodes. + newNode.match = true; + $(newNode[tree.statusClassPropName]) + .removeClass("fancytree-hide") + .addClass("fancytree-match"); + + newNode.makeVisible(/*{noAnimation: true}*/).done(function () { + $(newNode[tree.statusClassPropName]).addClass("fancytree-edit-new"); + self.tree.ext.edit.relatedNode = self; + newNode.editStart(); + }); + }; + + /** + * [ext-edit] Check if any node in this tree in edit mode. + * + * @returns {FancytreeNode | null} + * @alias Fancytree#isEditing + * @requires jquery.fancytree.edit.js + */ + $.ui.fancytree._FancytreeClass.prototype.isEditing = function () { + return this.ext.edit ? this.ext.edit.currentNode : null; + }; + + /** + * [ext-edit] Check if this node is in edit mode. + * @returns {Boolean} true if node is currently beeing edited + * @alias FancytreeNode#isEditing + * @requires jquery.fancytree.edit.js + */ + $.ui.fancytree._FancytreeNodeClass.prototype.isEditing = function () { + return this.tree.ext.edit + ? this.tree.ext.edit.currentNode === this + : false; + }; + + /******************************************************************************* + * Extension code + */ + $.ui.fancytree.registerExtension({ + name: "edit", + version: "2.38.3", + // Default options for this extension. + options: { + adjustWidthOfs: 4, // null: don't adjust input size to content + allowEmpty: false, // Prevent empty input + inputCss: { minWidth: "3em" }, + // triggerCancel: ["esc", "tab", "click"], + triggerStart: ["f2", "mac+enter", "shift+click"], + trim: true, // Trim whitespace before save + // Events: + beforeClose: $.noop, // Return false to prevent cancel/save (data.input is available) + beforeEdit: $.noop, // Return false to prevent edit mode + close: $.noop, // Editor was removed + edit: $.noop, // Editor was opened (available as data.input) + // keypress: $.noop, // Not yet implemented + save: $.noop, // Save data.input.val() or return false to keep editor open + }, + // Local attributes + currentNode: null, + + treeInit: function (ctx) { + var tree = ctx.tree; + + this._superApply(arguments); + + this.$container + .addClass("fancytree-ext-edit") + .on("fancytreebeforeupdateviewport", function (event, data) { + var editNode = tree.isEditing(); + // When scrolling, the TR may be re-used by another node, so the + // active cell marker an + if (editNode) { + editNode.info("Cancel edit due to scroll event."); + editNode.editEnd(false, event); + } + }); + }, + nodeClick: function (ctx) { + var eventStr = $.ui.fancytree.eventToString(ctx.originalEvent), + triggerStart = ctx.options.edit.triggerStart; + + if ( + eventStr === "shift+click" && + $.inArray("shift+click", triggerStart) >= 0 + ) { + if (ctx.originalEvent.shiftKey) { + ctx.node.editStart(); + return false; + } + } + if ( + eventStr === "click" && + $.inArray("clickActive", triggerStart) >= 0 + ) { + // Only when click was inside title text (not aynwhere else in the row) + if ( + ctx.node.isActive() && + !ctx.node.isEditing() && + $(ctx.originalEvent.target).hasClass("fancytree-title") + ) { + ctx.node.editStart(); + return false; + } + } + return this._superApply(arguments); + }, + nodeDblclick: function (ctx) { + if ($.inArray("dblclick", ctx.options.edit.triggerStart) >= 0) { + ctx.node.editStart(); + return false; + } + return this._superApply(arguments); + }, + nodeKeydown: function (ctx) { + switch (ctx.originalEvent.which) { + case 113: // [F2] + if ($.inArray("f2", ctx.options.edit.triggerStart) >= 0) { + ctx.node.editStart(); + return false; + } + break; + case $.ui.keyCode.ENTER: + if ( + $.inArray("mac+enter", ctx.options.edit.triggerStart) >= + 0 && + isMac + ) { + ctx.node.editStart(); + return false; + } + break; + } + return this._superApply(arguments); + }, + }); + // Value returned by `require('jquery.fancytree..')` + return $.ui.fancytree; +}); // End of closure + +/*! + * jquery.fancytree.filter.js + * + * Remove or highlight tree nodes, based on a filter. + * (Extension module for jquery.fancytree.js: https://github.com/mar10/fancytree/) + * + * Copyright (c) 2008-2023, Martin Wendt (https://wwWendt.de) + * + * Released under the MIT license + * https://github.com/mar10/fancytree/wiki/LicenseInfo + * + * @version 2.38.3 + * @date 2023-02-01T20:52:50Z + */ + +(function (factory) { + if (typeof define === "function" && define.amd) { + // AMD. Register as an anonymous module. + define(["jquery", "./jquery.fancytree"], factory); + } else if (typeof module === "object" && module.exports) { + // Node/CommonJS + require("./jquery.fancytree"); + module.exports = factory(require("jquery")); + } else { + // Browser globals + factory(jQuery); + } +})(function ($) { + "use strict"; + + /******************************************************************************* + * Private functions and variables + */ + + var KeyNoData = "__not_found__", + escapeHtml = $.ui.fancytree.escapeHtml, + exoticStartChar = "\uFFF7", + exoticEndChar = "\uFFF8"; + function _escapeRegex(str) { + return (str + "").replace(/([.?*+^$[\]\\(){}|-])/g, "\\$1"); + } + + function extractHtmlText(s) { + if (s.indexOf(">") >= 0) { + return $("<div/>").html(s).text(); + } + return s; + } + + /** + * @description Marks the matching charecters of `text` either by `mark` or + * by exotic*Chars (if `escapeTitles` is `true`) based on `regexMatchArray` + * which is an array of matching groups. + * @param {string} text + * @param {RegExpMatchArray} regexMatchArray + */ + function _markFuzzyMatchedChars(text, regexMatchArray, escapeTitles) { + // It is extremely infuriating that we can not use `let` or `const` or arrow functions. + // Damn you IE!!! + var matchingIndices = []; + // get the indices of matched characters (Iterate through `RegExpMatchArray`) + for ( + var _matchingArrIdx = 1; + _matchingArrIdx < regexMatchArray.length; + _matchingArrIdx++ + ) { + var _mIdx = + // get matching char index by cumulatively adding + // the matched group length + regexMatchArray[_matchingArrIdx].length + + (_matchingArrIdx === 1 ? 0 : 1) + + (matchingIndices[matchingIndices.length - 1] || 0); + matchingIndices.push(_mIdx); + } + // Map each `text` char to its position and store in `textPoses`. + var textPoses = text.split(""); + if (escapeTitles) { + // If escaping the title, then wrap the matchng char within exotic chars + matchingIndices.forEach(function (v) { + textPoses[v] = exoticStartChar + textPoses[v] + exoticEndChar; + }); + } else { + // Otherwise, Wrap the matching chars within `mark`. + matchingIndices.forEach(function (v) { + textPoses[v] = "<mark>" + textPoses[v] + "</mark>"; + }); + } + // Join back the modified `textPoses` to create final highlight markup. + return textPoses.join(""); + } + $.ui.fancytree._FancytreeClass.prototype._applyFilterImpl = function ( + filter, + branchMode, + _opts + ) { + var match, + statusNode, + re, + reHighlight, + reExoticStartChar, + reExoticEndChar, + temp, + prevEnableUpdate, + count = 0, + treeOpts = this.options, + escapeTitles = treeOpts.escapeTitles, + prevAutoCollapse = treeOpts.autoCollapse, + opts = $.extend({}, treeOpts.filter, _opts), + hideMode = opts.mode === "hide", + leavesOnly = !!opts.leavesOnly && !branchMode; + + // Default to 'match title substring (not case sensitive)' + if (typeof filter === "string") { + if (filter === "") { + this.warn( + "Fancytree passing an empty string as a filter is handled as clearFilter()." + ); + this.clearFilter(); + return; + } + if (opts.fuzzy) { + // See https://codereview.stackexchange.com/questions/23899/faster-javascript-fuzzy-string-matching-function/23905#23905 + // and http://www.quora.com/How-is-the-fuzzy-search-algorithm-in-Sublime-Text-designed + // and http://www.dustindiaz.com/autocomplete-fuzzy-matching + match = filter + .split("") + // Escaping the `filter` will not work because, + // it gets further split into individual characters. So, + // escape each character after splitting + .map(_escapeRegex) + .reduce(function (a, b) { + // create capture groups for parts that comes before + // the character + return a + "([^" + b + "]*)" + b; + }, ""); + } else { + match = _escapeRegex(filter); // make sure a '.' is treated literally + } + re = new RegExp(match, "i"); + reHighlight = new RegExp(_escapeRegex(filter), "gi"); + if (escapeTitles) { + reExoticStartChar = new RegExp( + _escapeRegex(exoticStartChar), + "g" + ); + reExoticEndChar = new RegExp(_escapeRegex(exoticEndChar), "g"); + } + filter = function (node) { + if (!node.title) { + return false; + } + var text = escapeTitles + ? node.title + : extractHtmlText(node.title), + // `.match` instead of `.test` to get the capture groups + res = text.match(re); + if (res && opts.highlight) { + if (escapeTitles) { + if (opts.fuzzy) { + temp = _markFuzzyMatchedChars( + text, + res, + escapeTitles + ); + } else { + // #740: we must not apply the marks to escaped entity names, e.g. `"` + // Use some exotic characters to mark matches: + temp = text.replace(reHighlight, function (s) { + return exoticStartChar + s + exoticEndChar; + }); + } + // now we can escape the title... + node.titleWithHighlight = escapeHtml(temp) + // ... and finally insert the desired `<mark>` tags + .replace(reExoticStartChar, "<mark>") + .replace(reExoticEndChar, "</mark>"); + } else { + if (opts.fuzzy) { + node.titleWithHighlight = _markFuzzyMatchedChars( + text, + res + ); + } else { + node.titleWithHighlight = text.replace( + reHighlight, + function (s) { + return "<mark>" + s + "</mark>"; + } + ); + } + } + // node.debug("filter", escapeTitles, text, node.titleWithHighlight); + } + return !!res; + }; + } + + this.enableFilter = true; + this.lastFilterArgs = arguments; + + prevEnableUpdate = this.enableUpdate(false); + + this.$div.addClass("fancytree-ext-filter"); + if (hideMode) { + this.$div.addClass("fancytree-ext-filter-hide"); + } else { + this.$div.addClass("fancytree-ext-filter-dimm"); + } + this.$div.toggleClass( + "fancytree-ext-filter-hide-expanders", + !!opts.hideExpanders + ); + // Reset current filter + this.rootNode.subMatchCount = 0; + this.visit(function (node) { + delete node.match; + delete node.titleWithHighlight; + node.subMatchCount = 0; + }); + statusNode = this.getRootNode()._findDirectChild(KeyNoData); + if (statusNode) { + statusNode.remove(); + } + + // Adjust node.hide, .match, and .subMatchCount properties + treeOpts.autoCollapse = false; // #528 + + this.visit(function (node) { + if (leavesOnly && node.children != null) { + return; + } + var res = filter(node), + matchedByBranch = false; + + if (res === "skip") { + node.visit(function (c) { + c.match = false; + }, true); + return "skip"; + } + if (!res && (branchMode || res === "branch") && node.parent.match) { + res = true; + matchedByBranch = true; + } + if (res) { + count++; + node.match = true; + node.visitParents(function (p) { + if (p !== node) { + p.subMatchCount += 1; + } + // Expand match (unless this is no real match, but only a node in a matched branch) + if (opts.autoExpand && !matchedByBranch && !p.expanded) { + p.setExpanded(true, { + noAnimation: true, + noEvents: true, + scrollIntoView: false, + }); + p._filterAutoExpanded = true; + } + }, true); + } + }); + treeOpts.autoCollapse = prevAutoCollapse; + + if (count === 0 && opts.nodata && hideMode) { + statusNode = opts.nodata; + if (typeof statusNode === "function") { + statusNode = statusNode(); + } + if (statusNode === true) { + statusNode = {}; + } else if (typeof statusNode === "string") { + statusNode = { title: statusNode }; + } + statusNode = $.extend( + { + statusNodeType: "nodata", + key: KeyNoData, + title: this.options.strings.noData, + }, + statusNode + ); + + this.getRootNode().addNode(statusNode).match = true; + } + // Redraw whole tree + this._callHook("treeStructureChanged", this, "applyFilter"); + // this.render(); + this.enableUpdate(prevEnableUpdate); + return count; + }; + + /** + * [ext-filter] Dimm or hide nodes. + * + * @param {function | string} filter + * @param {boolean} [opts={autoExpand: false, leavesOnly: false}] + * @returns {integer} count + * @alias Fancytree#filterNodes + * @requires jquery.fancytree.filter.js + */ + $.ui.fancytree._FancytreeClass.prototype.filterNodes = function ( + filter, + opts + ) { + if (typeof opts === "boolean") { + opts = { leavesOnly: opts }; + this.warn( + "Fancytree.filterNodes() leavesOnly option is deprecated since 2.9.0 / 2015-04-19. Use opts.leavesOnly instead." + ); + } + return this._applyFilterImpl(filter, false, opts); + }; + + /** + * [ext-filter] Dimm or hide whole branches. + * + * @param {function | string} filter + * @param {boolean} [opts={autoExpand: false}] + * @returns {integer} count + * @alias Fancytree#filterBranches + * @requires jquery.fancytree.filter.js + */ + $.ui.fancytree._FancytreeClass.prototype.filterBranches = function ( + filter, + opts + ) { + return this._applyFilterImpl(filter, true, opts); + }; + + /** + * [ext-filter] Re-apply current filter. + * + * @returns {integer} count + * @alias Fancytree#updateFilter + * @requires jquery.fancytree.filter.js + * @since 2.38 + */ + $.ui.fancytree._FancytreeClass.prototype.updateFilter = function () { + if ( + this.enableFilter && + this.lastFilterArgs && + this.options.filter.autoApply + ) { + this._applyFilterImpl.apply(this, this.lastFilterArgs); + } else { + this.warn("updateFilter(): no filter active."); + } + }; + + /** + * [ext-filter] Reset the filter. + * + * @alias Fancytree#clearFilter + * @requires jquery.fancytree.filter.js + */ + $.ui.fancytree._FancytreeClass.prototype.clearFilter = function () { + var $title, + statusNode = this.getRootNode()._findDirectChild(KeyNoData), + escapeTitles = this.options.escapeTitles, + enhanceTitle = this.options.enhanceTitle, + prevEnableUpdate = this.enableUpdate(false); + + if (statusNode) { + statusNode.remove(); + } + // we also counted root node's subMatchCount + delete this.rootNode.match; + delete this.rootNode.subMatchCount; + + this.visit(function (node) { + if (node.match && node.span) { + // #491, #601 + $title = $(node.span).find(">span.fancytree-title"); + if (escapeTitles) { + $title.text(node.title); + } else { + $title.html(node.title); + } + if (enhanceTitle) { + enhanceTitle( + { type: "enhanceTitle" }, + { node: node, $title: $title } + ); + } + } + delete node.match; + delete node.subMatchCount; + delete node.titleWithHighlight; + if (node.$subMatchBadge) { + node.$subMatchBadge.remove(); + delete node.$subMatchBadge; + } + if (node._filterAutoExpanded && node.expanded) { + node.setExpanded(false, { + noAnimation: true, + noEvents: true, + scrollIntoView: false, + }); + } + delete node._filterAutoExpanded; + }); + this.enableFilter = false; + this.lastFilterArgs = null; + this.$div.removeClass( + "fancytree-ext-filter fancytree-ext-filter-dimm fancytree-ext-filter-hide" + ); + this._callHook("treeStructureChanged", this, "clearFilter"); + // this.render(); + this.enableUpdate(prevEnableUpdate); + }; + + /** + * [ext-filter] Return true if a filter is currently applied. + * + * @returns {Boolean} + * @alias Fancytree#isFilterActive + * @requires jquery.fancytree.filter.js + * @since 2.13 + */ + $.ui.fancytree._FancytreeClass.prototype.isFilterActive = function () { + return !!this.enableFilter; + }; + + /** + * [ext-filter] Return true if this node is matched by current filter (or no filter is active). + * + * @returns {Boolean} + * @alias FancytreeNode#isMatched + * @requires jquery.fancytree.filter.js + * @since 2.13 + */ + $.ui.fancytree._FancytreeNodeClass.prototype.isMatched = function () { + return !(this.tree.enableFilter && !this.match); + }; + + /******************************************************************************* + * Extension code + */ + $.ui.fancytree.registerExtension({ + name: "filter", + version: "2.38.3", + // Default options for this extension. + options: { + autoApply: true, // Re-apply last filter if lazy data is loaded + autoExpand: false, // Expand all branches that contain matches while filtered + counter: true, // Show a badge with number of matching child nodes near parent icons + fuzzy: false, // Match single characters in order, e.g. 'fb' will match 'FooBar' + hideExpandedCounter: true, // Hide counter badge if parent is expanded + hideExpanders: false, // Hide expanders if all child nodes are hidden by filter + highlight: true, // Highlight matches by wrapping inside <mark> tags + leavesOnly: false, // Match end nodes only + nodata: true, // Display a 'no data' status node if result is empty + mode: "dimm", // Grayout unmatched nodes (pass "hide" to remove unmatched node instead) + }, + nodeLoadChildren: function (ctx, source) { + var tree = ctx.tree; + + return this._superApply(arguments).done(function () { + if ( + tree.enableFilter && + tree.lastFilterArgs && + ctx.options.filter.autoApply + ) { + tree._applyFilterImpl.apply(tree, tree.lastFilterArgs); + } + }); + }, + nodeSetExpanded: function (ctx, flag, callOpts) { + var node = ctx.node; + + delete node._filterAutoExpanded; + // Make sure counter badge is displayed again, when node is beeing collapsed + if ( + !flag && + ctx.options.filter.hideExpandedCounter && + node.$subMatchBadge + ) { + node.$subMatchBadge.show(); + } + return this._superApply(arguments); + }, + nodeRenderStatus: function (ctx) { + // Set classes for current status + var res, + node = ctx.node, + tree = ctx.tree, + opts = ctx.options.filter, + $title = $(node.span).find("span.fancytree-title"), + $span = $(node[tree.statusClassPropName]), + enhanceTitle = ctx.options.enhanceTitle, + escapeTitles = ctx.options.escapeTitles; + + res = this._super(ctx); + // nothing to do, if node was not yet rendered + if (!$span.length || !tree.enableFilter) { + return res; + } + $span + .toggleClass("fancytree-match", !!node.match) + .toggleClass("fancytree-submatch", !!node.subMatchCount) + .toggleClass( + "fancytree-hide", + !(node.match || node.subMatchCount) + ); + // Add/update counter badge + if ( + opts.counter && + node.subMatchCount && + (!node.isExpanded() || !opts.hideExpandedCounter) + ) { + if (!node.$subMatchBadge) { + node.$subMatchBadge = $( + "<span class='fancytree-childcounter'/>" + ); + $( + "span.fancytree-icon, span.fancytree-custom-icon", + node.span + ).append(node.$subMatchBadge); + } + node.$subMatchBadge.show().text(node.subMatchCount); + } else if (node.$subMatchBadge) { + node.$subMatchBadge.hide(); + } + // node.debug("nodeRenderStatus", node.titleWithHighlight, node.title) + // #601: also check for $title.length, because we don't need to render + // if node.span is null (i.e. not rendered) + if (node.span && (!node.isEditing || !node.isEditing.call(node))) { + if (node.titleWithHighlight) { + $title.html(node.titleWithHighlight); + } else if (escapeTitles) { + $title.text(node.title); + } else { + $title.html(node.title); + } + if (enhanceTitle) { + enhanceTitle( + { type: "enhanceTitle" }, + { node: node, $title: $title } + ); + } + } + return res; + }, + }); + // Value returned by `require('jquery.fancytree..')` + return $.ui.fancytree; +}); // End of closure + +/*! + * jquery.fancytree.glyph.js + * + * Use glyph-fonts, ligature-fonts, or SVG icons instead of icon sprites. + * (Extension module for jquery.fancytree.js: https://github.com/mar10/fancytree/) + * + * Copyright (c) 2008-2023, Martin Wendt (https://wwWendt.de) + * + * Released under the MIT license + * https://github.com/mar10/fancytree/wiki/LicenseInfo + * + * @version 2.38.3 + * @date 2023-02-01T20:52:50Z + */ + +(function (factory) { + if (typeof define === "function" && define.amd) { + // AMD. Register as an anonymous module. + define(["jquery", "./jquery.fancytree"], factory); + } else if (typeof module === "object" && module.exports) { + // Node/CommonJS + require("./jquery.fancytree"); + module.exports = factory(require("jquery")); + } else { + // Browser globals + factory(jQuery); + } +})(function ($) { + "use strict"; + + /****************************************************************************** + * Private functions and variables + */ + + var FT = $.ui.fancytree, + PRESETS = { + awesome3: { + // Outdated! + _addClass: "", + checkbox: "icon-check-empty", + checkboxSelected: "icon-check", + checkboxUnknown: "icon-check icon-muted", + dragHelper: "icon-caret-right", + dropMarker: "icon-caret-right", + error: "icon-exclamation-sign", + expanderClosed: "icon-caret-right", + expanderLazy: "icon-angle-right", + expanderOpen: "icon-caret-down", + loading: "icon-refresh icon-spin", + nodata: "icon-meh", + noExpander: "", + radio: "icon-circle-blank", + radioSelected: "icon-circle", + // radioUnknown: "icon-circle icon-muted", + // Default node icons. + // (Use tree.options.icon callback to define custom icons based on node data) + doc: "icon-file-alt", + docOpen: "icon-file-alt", + folder: "icon-folder-close-alt", + folderOpen: "icon-folder-open-alt", + }, + awesome4: { + _addClass: "fa", + checkbox: "fa-square-o", + checkboxSelected: "fa-check-square-o", + checkboxUnknown: "fa-square fancytree-helper-indeterminate-cb", + dragHelper: "fa-arrow-right", + dropMarker: "fa-long-arrow-right", + error: "fa-warning", + expanderClosed: "fa-caret-right", + expanderLazy: "fa-angle-right", + expanderOpen: "fa-caret-down", + // We may prevent wobbling rotations on FF by creating a separate sub element: + loading: { html: "<span class='fa fa-spinner fa-pulse' />" }, + nodata: "fa-meh-o", + noExpander: "", + radio: "fa-circle-thin", // "fa-circle-o" + radioSelected: "fa-circle", + // radioUnknown: "fa-dot-circle-o", + // Default node icons. + // (Use tree.options.icon callback to define custom icons based on node data) + doc: "fa-file-o", + docOpen: "fa-file-o", + folder: "fa-folder-o", + folderOpen: "fa-folder-open-o", + }, + awesome5: { + // fontawesome 5 have several different base classes + // "far, fas, fal and fab" The rendered svg puts that prefix + // in a different location so we have to keep them separate here + _addClass: "", + checkbox: "far fa-square", + checkboxSelected: "far fa-check-square", + // checkboxUnknown: "far fa-window-close", + checkboxUnknown: + "fas fa-square fancytree-helper-indeterminate-cb", + radio: "far fa-circle", + radioSelected: "fas fa-circle", + radioUnknown: "far fa-dot-circle", + dragHelper: "fas fa-arrow-right", + dropMarker: "fas fa-long-arrow-alt-right", + error: "fas fa-exclamation-triangle", + expanderClosed: "fas fa-caret-right", + expanderLazy: "fas fa-angle-right", + expanderOpen: "fas fa-caret-down", + loading: "fas fa-spinner fa-pulse", + nodata: "far fa-meh", + noExpander: "", + // Default node icons. + // (Use tree.options.icon callback to define custom icons based on node data) + doc: "far fa-file", + docOpen: "far fa-file", + folder: "far fa-folder", + folderOpen: "far fa-folder-open", + }, + bootstrap3: { + _addClass: "glyphicon", + checkbox: "glyphicon-unchecked", + checkboxSelected: "glyphicon-check", + checkboxUnknown: + "glyphicon-expand fancytree-helper-indeterminate-cb", // "glyphicon-share", + dragHelper: "glyphicon-play", + dropMarker: "glyphicon-arrow-right", + error: "glyphicon-warning-sign", + expanderClosed: "glyphicon-menu-right", // glyphicon-plus-sign + expanderLazy: "glyphicon-menu-right", // glyphicon-plus-sign + expanderOpen: "glyphicon-menu-down", // glyphicon-minus-sign + loading: "glyphicon-refresh fancytree-helper-spin", + nodata: "glyphicon-info-sign", + noExpander: "", + radio: "glyphicon-remove-circle", // "glyphicon-unchecked", + radioSelected: "glyphicon-ok-circle", // "glyphicon-check", + // radioUnknown: "glyphicon-ban-circle", + // Default node icons. + // (Use tree.options.icon callback to define custom icons based on node data) + doc: "glyphicon-file", + docOpen: "glyphicon-file", + folder: "glyphicon-folder-close", + folderOpen: "glyphicon-folder-open", + }, + material: { + _addClass: "material-icons", + checkbox: { text: "check_box_outline_blank" }, + checkboxSelected: { text: "check_box" }, + checkboxUnknown: { text: "indeterminate_check_box" }, + dragHelper: { text: "play_arrow" }, + dropMarker: { text: "arrow-forward" }, + error: { text: "warning" }, + expanderClosed: { text: "chevron_right" }, + expanderLazy: { text: "last_page" }, + expanderOpen: { text: "expand_more" }, + loading: { + text: "autorenew", + addClass: "fancytree-helper-spin", + }, + nodata: { text: "info" }, + noExpander: { text: "" }, + radio: { text: "radio_button_unchecked" }, + radioSelected: { text: "radio_button_checked" }, + // Default node icons. + // (Use tree.options.icon callback to define custom icons based on node data) + doc: { text: "insert_drive_file" }, + docOpen: { text: "insert_drive_file" }, + folder: { text: "folder" }, + folderOpen: { text: "folder_open" }, + }, + }; + + function setIcon(node, span, baseClass, opts, type) { + var map = opts.map, + icon = map[type], + $span = $(span), + $counter = $span.find(".fancytree-childcounter"), + setClass = baseClass + " " + (map._addClass || ""); + + // #871 Allow a callback + if (typeof icon === "function") { + icon = icon.call(this, node, span, type); + } + // node.debug( "setIcon(" + baseClass + ", " + type + "): " + "oldIcon" + " -> " + icon ); + // #871: propsed this, but I am not sure how robust this is, e.g. + // the prefix (fas, far) class changes are not considered? + // if (span.tagName === "svg" && opts.preset === "awesome5") { + // // fa5 script converts <i> to <svg> so call a specific handler. + // var oldIcon = "fa-" + $span.data("icon"); + // // node.debug( "setIcon(" + baseClass + ", " + type + "): " + oldIcon + " -> " + icon ); + // if (typeof oldIcon === "string") { + // $span.removeClass(oldIcon); + // } + // if (typeof icon === "string") { + // $span.addClass(icon); + // } + // return; + // } + if (typeof icon === "string") { + // #883: remove inner html that may be added by prev. mode + span.innerHTML = ""; + $span.attr("class", setClass + " " + icon).append($counter); + } else if (icon) { + if (icon.text) { + span.textContent = "" + icon.text; + } else if (icon.html) { + span.innerHTML = icon.html; + } else { + span.innerHTML = ""; + } + $span + .attr("class", setClass + " " + (icon.addClass || "")) + .append($counter); + } + } + + $.ui.fancytree.registerExtension({ + name: "glyph", + version: "2.38.3", + // Default options for this extension. + options: { + preset: null, // 'awesome3', 'awesome4', 'bootstrap3', 'material' + map: {}, + }, + + treeInit: function (ctx) { + var tree = ctx.tree, + opts = ctx.options.glyph; + + if (opts.preset) { + FT.assert( + !!PRESETS[opts.preset], + "Invalid value for `options.glyph.preset`: " + opts.preset + ); + opts.map = $.extend({}, PRESETS[opts.preset], opts.map); + } else { + tree.warn("ext-glyph: missing `preset` option."); + } + this._superApply(arguments); + tree.$container.addClass("fancytree-ext-glyph"); + }, + nodeRenderStatus: function (ctx) { + var checkbox, + icon, + res, + span, + node = ctx.node, + $span = $(node.span), + opts = ctx.options.glyph; + + res = this._super(ctx); + + if (node.isRootNode()) { + return res; + } + span = $span.children(".fancytree-expander").get(0); + if (span) { + // if( node.isLoading() ){ + // icon = "loading"; + if (node.expanded && node.hasChildren()) { + icon = "expanderOpen"; + } else if (node.isUndefined()) { + icon = "expanderLazy"; + } else if (node.hasChildren()) { + icon = "expanderClosed"; + } else { + icon = "noExpander"; + } + // span.className = "fancytree-expander " + map[icon]; + setIcon(node, span, "fancytree-expander", opts, icon); + } + + if (node.tr) { + span = $("td", node.tr).find(".fancytree-checkbox").get(0); + } else { + span = $span.children(".fancytree-checkbox").get(0); + } + if (span) { + checkbox = FT.evalOption("checkbox", node, node, opts, false); + if ( + (node.parent && node.parent.radiogroup) || + checkbox === "radio" + ) { + icon = node.selected ? "radioSelected" : "radio"; + setIcon( + node, + span, + "fancytree-checkbox fancytree-radio", + opts, + icon + ); + } else { + // eslint-disable-next-line no-nested-ternary + icon = node.selected + ? "checkboxSelected" + : node.partsel + ? "checkboxUnknown" + : "checkbox"; + // span.className = "fancytree-checkbox " + map[icon]; + setIcon(node, span, "fancytree-checkbox", opts, icon); + } + } + + // Standard icon (note that this does not match .fancytree-custom-icon, + // that might be set by opts.icon callbacks) + span = $span.children(".fancytree-icon").get(0); + if (span) { + if (node.statusNodeType) { + icon = node.statusNodeType; // loading, error + } else if (node.folder) { + icon = + node.expanded && node.hasChildren() + ? "folderOpen" + : "folder"; + } else { + icon = node.expanded ? "docOpen" : "doc"; + } + setIcon(node, span, "fancytree-icon", opts, icon); + } + return res; + }, + nodeSetStatus: function (ctx, status, message, details) { + var res, + span, + opts = ctx.options.glyph, + node = ctx.node; + + res = this._superApply(arguments); + + if ( + status === "error" || + status === "loading" || + status === "nodata" + ) { + if (node.parent) { + span = $(".fancytree-expander", node.span).get(0); + if (span) { + setIcon(node, span, "fancytree-expander", opts, status); + } + } else { + // + span = $( + ".fancytree-statusnode-" + status, + node[this.nodeContainerAttrName] + ) + .find(".fancytree-icon") + .get(0); + if (span) { + setIcon(node, span, "fancytree-icon", opts, status); + } + } + } + return res; + }, + }); + // Value returned by `require('jquery.fancytree..')` + return $.ui.fancytree; +}); // End of closure + +/*! + * jquery.fancytree.gridnav.js + * + * Support keyboard navigation for trees with embedded input controls. + * (Extension module for jquery.fancytree.js: https://github.com/mar10/fancytree/) + * + * Copyright (c) 2008-2023, Martin Wendt (https://wwWendt.de) + * + * Released under the MIT license + * https://github.com/mar10/fancytree/wiki/LicenseInfo + * + * @version 2.38.3 + * @date 2023-02-01T20:52:50Z + */ + +(function (factory) { + if (typeof define === "function" && define.amd) { + // AMD. Register as an anonymous module. + define([ + "jquery", + "./jquery.fancytree", + "./jquery.fancytree.table", + ], factory); + } else if (typeof module === "object" && module.exports) { + // Node/CommonJS + require("./jquery.fancytree.table"); // core + table + module.exports = factory(require("jquery")); + } else { + // Browser globals + factory(jQuery); + } +})(function ($) { + "use strict"; + + /******************************************************************************* + * Private functions and variables + */ + + // Allow these navigation keys even when input controls are focused + + var KC = $.ui.keyCode, + // which keys are *not* handled by embedded control, but passed to tree + // navigation handler: + NAV_KEYS = { + text: [KC.UP, KC.DOWN], + checkbox: [KC.UP, KC.DOWN, KC.LEFT, KC.RIGHT], + link: [KC.UP, KC.DOWN, KC.LEFT, KC.RIGHT], + radiobutton: [KC.UP, KC.DOWN, KC.LEFT, KC.RIGHT], + "select-one": [KC.LEFT, KC.RIGHT], + "select-multiple": [KC.LEFT, KC.RIGHT], + }; + + /* Calculate TD column index (considering colspans).*/ + function getColIdx($tr, $td) { + var colspan, + td = $td.get(0), + idx = 0; + + $tr.children().each(function () { + if (this === td) { + return false; + } + colspan = $(this).prop("colspan"); + idx += colspan ? colspan : 1; + }); + return idx; + } + + /* Find TD at given column index (considering colspans).*/ + function findTdAtColIdx($tr, colIdx) { + var colspan, + res = null, + idx = 0; + + $tr.children().each(function () { + if (idx >= colIdx) { + res = $(this); + return false; + } + colspan = $(this).prop("colspan"); + idx += colspan ? colspan : 1; + }); + return res; + } + + /* Find adjacent cell for a given direction. Skip empty cells and consider merged cells */ + function findNeighbourTd($target, keyCode) { + var $tr, + colIdx, + $td = $target.closest("td"), + $tdNext = null; + + switch (keyCode) { + case KC.LEFT: + $tdNext = $td.prev(); + break; + case KC.RIGHT: + $tdNext = $td.next(); + break; + case KC.UP: + case KC.DOWN: + $tr = $td.parent(); + colIdx = getColIdx($tr, $td); + while (true) { + $tr = keyCode === KC.UP ? $tr.prev() : $tr.next(); + if (!$tr.length) { + break; + } + // Skip hidden rows + if ($tr.is(":hidden")) { + continue; + } + // Find adjacent cell in the same column + $tdNext = findTdAtColIdx($tr, colIdx); + // Skip cells that don't conatain a focusable element + if ($tdNext && $tdNext.find(":input,a").length) { + break; + } + } + break; + } + return $tdNext; + } + + /******************************************************************************* + * Extension code + */ + $.ui.fancytree.registerExtension({ + name: "gridnav", + version: "2.38.3", + // Default options for this extension. + options: { + autofocusInput: false, // Focus first embedded input if node gets activated + handleCursorKeys: true, // Allow UP/DOWN in inputs to move to prev/next node + }, + + treeInit: function (ctx) { + // gridnav requires the table extension to be loaded before itself + this._requireExtension("table", true, true); + this._superApply(arguments); + + this.$container.addClass("fancytree-ext-gridnav"); + + // Activate node if embedded input gets focus (due to a click) + this.$container.on("focusin", function (event) { + var ctx2, + node = $.ui.fancytree.getNode(event.target); + + if (node && !node.isActive()) { + // Call node.setActive(), but also pass the event + ctx2 = ctx.tree._makeHookContext(node, event); + ctx.tree._callHook("nodeSetActive", ctx2, true); + } + }); + }, + nodeSetActive: function (ctx, flag, callOpts) { + var $outer, + opts = ctx.options.gridnav, + node = ctx.node, + event = ctx.originalEvent || {}, + triggeredByInput = $(event.target).is(":input"); + + flag = flag !== false; + + this._superApply(arguments); + + if (flag) { + if (ctx.options.titlesTabbable) { + if (!triggeredByInput) { + $(node.span).find("span.fancytree-title").focus(); + node.setFocus(); + } + // If one node is tabbable, the container no longer needs to be + ctx.tree.$container.attr("tabindex", "-1"); + // ctx.tree.$container.removeAttr("tabindex"); + } else if (opts.autofocusInput && !triggeredByInput) { + // Set focus to input sub input (if node was clicked, but not + // when TAB was pressed ) + $outer = $(node.tr || node.span); + $outer.find(":input:enabled").first().focus(); + } + } + }, + nodeKeydown: function (ctx) { + var inputType, + handleKeys, + $td, + opts = ctx.options.gridnav, + event = ctx.originalEvent, + $target = $(event.target); + + if ($target.is(":input:enabled")) { + inputType = $target.prop("type"); + } else if ($target.is("a")) { + inputType = "link"; + } + // ctx.tree.debug("ext-gridnav nodeKeydown", event, inputType); + + if (inputType && opts.handleCursorKeys) { + handleKeys = NAV_KEYS[inputType]; + if (handleKeys && $.inArray(event.which, handleKeys) >= 0) { + $td = findNeighbourTd($target, event.which); + if ($td && $td.length) { + // ctx.node.debug("ignore keydown in input", event.which, handleKeys); + $td.find(":input:enabled,a").focus(); + // Prevent Fancytree default navigation + return false; + } + } + return true; + } + // ctx.tree.debug("ext-gridnav NOT HANDLED", event, inputType); + return this._superApply(arguments); + }, + }); + // Value returned by `require('jquery.fancytree..')` + return $.ui.fancytree; +}); // End of closure + +/*! + * jquery.fancytree.multi.js + * + * Allow multiple selection of nodes by mouse or keyboard. + * (Extension module for jquery.fancytree.js: https://github.com/mar10/fancytree/) + * + * Copyright (c) 2008-2023, Martin Wendt (https://wwWendt.de) + * + * Released under the MIT license + * https://github.com/mar10/fancytree/wiki/LicenseInfo + * + * @version 2.38.3 + * @date 2023-02-01T20:52:50Z + */ + +(function (factory) { + if (typeof define === "function" && define.amd) { + // AMD. Register as an anonymous module. + define(["jquery", "./jquery.fancytree"], factory); + } else if (typeof module === "object" && module.exports) { + // Node/CommonJS + require("./jquery.fancytree"); + module.exports = factory(require("jquery")); + } else { + // Browser globals + factory(jQuery); + } +})(function ($) { + "use strict"; + + /******************************************************************************* + * Private functions and variables + */ + + // var isMac = /Mac/.test(navigator.platform); + + /******************************************************************************* + * Extension code + */ + $.ui.fancytree.registerExtension({ + name: "multi", + version: "2.38.3", + // Default options for this extension. + options: { + allowNoSelect: false, // + mode: "sameParent", // + // Events: + // beforeSelect: $.noop // Return false to prevent cancel/save (data.input is available) + }, + + treeInit: function (ctx) { + this._superApply(arguments); + this.$container.addClass("fancytree-ext-multi"); + if (ctx.options.selectMode === 1) { + $.error( + "Fancytree ext-multi: selectMode: 1 (single) is not compatible." + ); + } + }, + nodeClick: function (ctx) { + var //pluginOpts = ctx.options.multi, + tree = ctx.tree, + node = ctx.node, + activeNode = tree.getActiveNode() || tree.getFirstChild(), + isCbClick = ctx.targetType === "checkbox", + isExpanderClick = ctx.targetType === "expander", + eventStr = $.ui.fancytree.eventToString(ctx.originalEvent); + + switch (eventStr) { + case "click": + if (isExpanderClick) { + break; + } // Default handler will expand/collapse + if (!isCbClick) { + tree.selectAll(false); + // Select clicked node (radio-button mode) + node.setSelected(); + } + // Default handler will toggle checkbox clicks and activate + break; + case "shift+click": + // node.debug("click") + tree.visitRows( + function (n) { + // n.debug("click2", n===node, node) + n.setSelected(); + if (n === node) { + return false; + } + }, + { + start: activeNode, + reverse: activeNode.isBelowOf(node), + } + ); + break; + case "ctrl+click": + case "meta+click": // Mac: [Command] + node.toggleSelected(); + return; + } + return this._superApply(arguments); + }, + nodeKeydown: function (ctx) { + var tree = ctx.tree, + node = ctx.node, + event = ctx.originalEvent, + eventStr = $.ui.fancytree.eventToString(event); + + switch (eventStr) { + case "up": + case "down": + tree.selectAll(false); + node.navigate(event.which, true); + tree.getActiveNode().setSelected(); + break; + case "shift+up": + case "shift+down": + node.navigate(event.which, true); + tree.getActiveNode().setSelected(); + break; + } + return this._superApply(arguments); + }, + }); + // Value returned by `require('jquery.fancytree..')` + return $.ui.fancytree; +}); // End of closure + +/*! + * jquery.fancytree.persist.js + * + * Persist tree status in cookiesRemove or highlight tree nodes, based on a filter. + * (Extension module for jquery.fancytree.js: https://github.com/mar10/fancytree/) + * + * @depends: js-cookie or jquery-cookie + * + * Copyright (c) 2008-2023, Martin Wendt (https://wwWendt.de) + * + * Released under the MIT license + * https://github.com/mar10/fancytree/wiki/LicenseInfo + * + * @version 2.38.3 + * @date 2023-02-01T20:52:50Z + */ + +(function (factory) { + if (typeof define === "function" && define.amd) { + // AMD. Register as an anonymous module. + define(["jquery", "./jquery.fancytree"], factory); + } else if (typeof module === "object" && module.exports) { + // Node/CommonJS + require("./jquery.fancytree"); + module.exports = factory(require("jquery")); + } else { + // Browser globals + factory(jQuery); + } +})(function ($) { + "use strict"; + /* global Cookies:false */ + + /******************************************************************************* + * Private functions and variables + */ + var cookieStore = null, + localStorageStore = null, + sessionStorageStore = null, + _assert = $.ui.fancytree.assert, + ACTIVE = "active", + EXPANDED = "expanded", + FOCUS = "focus", + SELECTED = "selected"; + + // Accessing window.xxxStorage may raise security exceptions (see #1022) + try { + _assert(window.localStorage && window.localStorage.getItem); + localStorageStore = { + get: function (key) { + return window.localStorage.getItem(key); + }, + set: function (key, value) { + window.localStorage.setItem(key, value); + }, + remove: function (key) { + window.localStorage.removeItem(key); + }, + }; + } catch (e) { + $.ui.fancytree.warn("Could not access window.localStorage", e); + } + + try { + _assert(window.sessionStorage && window.sessionStorage.getItem); + sessionStorageStore = { + get: function (key) { + return window.sessionStorage.getItem(key); + }, + set: function (key, value) { + window.sessionStorage.setItem(key, value); + }, + remove: function (key) { + window.sessionStorage.removeItem(key); + }, + }; + } catch (e) { + $.ui.fancytree.warn("Could not access window.sessionStorage", e); + } + + if (typeof Cookies === "function") { + // Assume https://github.com/js-cookie/js-cookie + cookieStore = { + get: Cookies.get, + set: function (key, value) { + Cookies.set(key, value, this.options.persist.cookie); + }, + remove: Cookies.remove, + }; + } else if ($ && typeof $.cookie === "function") { + // Fall back to https://github.com/carhartl/jquery-cookie + cookieStore = { + get: $.cookie, + set: function (key, value) { + $.cookie(key, value, this.options.persist.cookie); + }, + remove: $.removeCookie, + }; + } + + /* Recursively load lazy nodes + * @param {string} mode 'load', 'expand', false + */ + function _loadLazyNodes(tree, local, keyList, mode, dfd) { + var i, + key, + l, + node, + foundOne = false, + expandOpts = tree.options.persist.expandOpts, + deferredList = [], + missingKeyList = []; + + keyList = keyList || []; + dfd = dfd || $.Deferred(); + + for (i = 0, l = keyList.length; i < l; i++) { + key = keyList[i]; + node = tree.getNodeByKey(key); + if (node) { + if (mode && node.isUndefined()) { + foundOne = true; + tree.debug( + "_loadLazyNodes: " + node + " is lazy: loading..." + ); + if (mode === "expand") { + deferredList.push(node.setExpanded(true, expandOpts)); + } else { + deferredList.push(node.load()); + } + } else { + tree.debug("_loadLazyNodes: " + node + " already loaded."); + node.setExpanded(true, expandOpts); + } + } else { + missingKeyList.push(key); + tree.debug("_loadLazyNodes: " + node + " was not yet found."); + } + } + + $.when.apply($, deferredList).always(function () { + // All lazy-expands have finished + if (foundOne && missingKeyList.length > 0) { + // If we read new nodes from server, try to resolve yet-missing keys + _loadLazyNodes(tree, local, missingKeyList, mode, dfd); + } else { + if (missingKeyList.length) { + tree.warn( + "_loadLazyNodes: could not load those keys: ", + missingKeyList + ); + for (i = 0, l = missingKeyList.length; i < l; i++) { + key = keyList[i]; + local._appendKey(EXPANDED, keyList[i], false); + } + } + dfd.resolve(); + } + }); + return dfd; + } + + /** + * [ext-persist] Remove persistence data of the given type(s). + * Called like + * $.ui.fancytree.getTree("#tree").clearCookies("active expanded focus selected"); + * + * @alias Fancytree#clearPersistData + * @requires jquery.fancytree.persist.js + */ + $.ui.fancytree._FancytreeClass.prototype.clearPersistData = function ( + types + ) { + var local = this.ext.persist, + prefix = local.cookiePrefix; + + types = types || "active expanded focus selected"; + if (types.indexOf(ACTIVE) >= 0) { + local._data(prefix + ACTIVE, null); + } + if (types.indexOf(EXPANDED) >= 0) { + local._data(prefix + EXPANDED, null); + } + if (types.indexOf(FOCUS) >= 0) { + local._data(prefix + FOCUS, null); + } + if (types.indexOf(SELECTED) >= 0) { + local._data(prefix + SELECTED, null); + } + }; + + $.ui.fancytree._FancytreeClass.prototype.clearCookies = function (types) { + this.warn( + "'tree.clearCookies()' is deprecated since v2.27.0: use 'clearPersistData()' instead." + ); + return this.clearPersistData(types); + }; + + /** + * [ext-persist] Return persistence information from cookies + * + * Called like + * $.ui.fancytree.getTree("#tree").getPersistData(); + * + * @alias Fancytree#getPersistData + * @requires jquery.fancytree.persist.js + */ + $.ui.fancytree._FancytreeClass.prototype.getPersistData = function () { + var local = this.ext.persist, + prefix = local.cookiePrefix, + delim = local.cookieDelimiter, + res = {}; + + res[ACTIVE] = local._data(prefix + ACTIVE); + res[EXPANDED] = (local._data(prefix + EXPANDED) || "").split(delim); + res[SELECTED] = (local._data(prefix + SELECTED) || "").split(delim); + res[FOCUS] = local._data(prefix + FOCUS); + return res; + }; + + /****************************************************************************** + * Extension code + */ + $.ui.fancytree.registerExtension({ + name: "persist", + version: "2.38.3", + // Default options for this extension. + options: { + cookieDelimiter: "~", + cookiePrefix: undefined, // 'fancytree-<treeId>-' by default + cookie: { + raw: false, + expires: "", + path: "", + domain: "", + secure: false, + }, + expandLazy: false, // true: recursively expand and load lazy nodes + expandOpts: undefined, // optional `opts` argument passed to setExpanded() + fireActivate: true, // false: suppress `activate` event after active node was restored + overrideSource: true, // true: cookie takes precedence over `source` data attributes. + store: "auto", // 'cookie': force cookie, 'local': force localStore, 'session': force sessionStore + types: "active expanded focus selected", + }, + + /* Generic read/write string data to cookie, sessionStorage or localStorage. */ + _data: function (key, value) { + var store = this._local.store; + + if (value === undefined) { + return store.get.call(this, key); + } else if (value === null) { + store.remove.call(this, key); + } else { + store.set.call(this, key, value); + } + }, + + /* Append `key` to a cookie. */ + _appendKey: function (type, key, flag) { + key = "" + key; // #90 + var local = this._local, + instOpts = this.options.persist, + delim = instOpts.cookieDelimiter, + cookieName = local.cookiePrefix + type, + data = local._data(cookieName), + keyList = data ? data.split(delim) : [], + idx = $.inArray(key, keyList); + // Remove, even if we add a key, so the key is always the last entry + if (idx >= 0) { + keyList.splice(idx, 1); + } + // Append key to cookie + if (flag) { + keyList.push(key); + } + local._data(cookieName, keyList.join(delim)); + }, + + treeInit: function (ctx) { + var tree = ctx.tree, + opts = ctx.options, + local = this._local, + instOpts = this.options.persist; + + // // For 'auto' or 'cookie' mode, the cookie plugin must be available + // _assert((instOpts.store !== "auto" && instOpts.store !== "cookie") || cookieStore, + // "Missing required plugin for 'persist' extension: js.cookie.js or jquery.cookie.js"); + + local.cookiePrefix = + instOpts.cookiePrefix || "fancytree-" + tree._id + "-"; + local.storeActive = instOpts.types.indexOf(ACTIVE) >= 0; + local.storeExpanded = instOpts.types.indexOf(EXPANDED) >= 0; + local.storeSelected = instOpts.types.indexOf(SELECTED) >= 0; + local.storeFocus = instOpts.types.indexOf(FOCUS) >= 0; + local.store = null; + + if (instOpts.store === "auto") { + instOpts.store = localStorageStore ? "local" : "cookie"; + } + if ($.isPlainObject(instOpts.store)) { + local.store = instOpts.store; + } else if (instOpts.store === "cookie") { + local.store = cookieStore; + } else if (instOpts.store === "local") { + local.store = + instOpts.store === "local" + ? localStorageStore + : sessionStorageStore; + } else if (instOpts.store === "session") { + local.store = + instOpts.store === "local" + ? localStorageStore + : sessionStorageStore; + } + _assert(local.store, "Need a valid store."); + + // Bind init-handler to apply cookie state + tree.$div.on("fancytreeinit", function (event) { + if ( + tree._triggerTreeEvent("beforeRestore", null, {}) === false + ) { + return; + } + + var cookie, + dfd, + i, + keyList, + node, + prevFocus = local._data(local.cookiePrefix + FOCUS), // record this before node.setActive() overrides it; + noEvents = instOpts.fireActivate === false; + + // tree.debug("document.cookie:", document.cookie); + + cookie = local._data(local.cookiePrefix + EXPANDED); + keyList = cookie && cookie.split(instOpts.cookieDelimiter); + + if (local.storeExpanded) { + // Recursively load nested lazy nodes if expandLazy is 'expand' or 'load' + // Also remove expand-cookies for unmatched nodes + dfd = _loadLazyNodes( + tree, + local, + keyList, + instOpts.expandLazy ? "expand" : false, + null + ); + } else { + // nothing to do + dfd = new $.Deferred().resolve(); + } + + dfd.done(function () { + if (local.storeSelected) { + cookie = local._data(local.cookiePrefix + SELECTED); + if (cookie) { + keyList = cookie.split(instOpts.cookieDelimiter); + for (i = 0; i < keyList.length; i++) { + node = tree.getNodeByKey(keyList[i]); + if (node) { + if ( + node.selected === undefined || + (instOpts.overrideSource && + node.selected === false) + ) { + // node.setSelected(); + node.selected = true; + node.renderStatus(); + } + } else { + // node is no longer member of the tree: remove from cookie also + local._appendKey( + SELECTED, + keyList[i], + false + ); + } + } + } + // In selectMode 3 we have to fix the child nodes, since we + // only stored the selected *top* nodes + if (tree.options.selectMode === 3) { + tree.visit(function (n) { + if (n.selected) { + n.fixSelection3AfterClick(); + return "skip"; + } + }); + } + } + if (local.storeActive) { + cookie = local._data(local.cookiePrefix + ACTIVE); + if ( + cookie && + (opts.persist.overrideSource || !tree.activeNode) + ) { + node = tree.getNodeByKey(cookie); + if (node) { + node.debug("persist: set active", cookie); + // We only want to set the focus if the container + // had the keyboard focus before + node.setActive(true, { + noFocus: true, + noEvents: noEvents, + }); + } + } + } + if (local.storeFocus && prevFocus) { + node = tree.getNodeByKey(prevFocus); + if (node) { + // node.debug("persist: set focus", cookie); + if (tree.options.titlesTabbable) { + $(node.span).find(".fancytree-title").focus(); + } else { + $(tree.$container).focus(); + } + // node.setFocus(); + } + } + tree._triggerTreeEvent("restore", null, {}); + }); + }); + // Init the tree + return this._superApply(arguments); + }, + nodeSetActive: function (ctx, flag, callOpts) { + var res, + local = this._local; + + flag = flag !== false; + res = this._superApply(arguments); + + if (local.storeActive) { + local._data( + local.cookiePrefix + ACTIVE, + this.activeNode ? this.activeNode.key : null + ); + } + return res; + }, + nodeSetExpanded: function (ctx, flag, callOpts) { + var res, + node = ctx.node, + local = this._local; + + flag = flag !== false; + res = this._superApply(arguments); + + if (local.storeExpanded) { + local._appendKey(EXPANDED, node.key, flag); + } + return res; + }, + nodeSetFocus: function (ctx, flag) { + var res, + local = this._local; + + flag = flag !== false; + res = this._superApply(arguments); + + if (local.storeFocus) { + local._data( + local.cookiePrefix + FOCUS, + this.focusNode ? this.focusNode.key : null + ); + } + return res; + }, + nodeSetSelected: function (ctx, flag, callOpts) { + var res, + selNodes, + tree = ctx.tree, + node = ctx.node, + local = this._local; + + flag = flag !== false; + res = this._superApply(arguments); + + if (local.storeSelected) { + if (tree.options.selectMode === 3) { + // In selectMode 3 we only store the the selected *top* nodes. + // De-selecting a node may also de-select some parents, so we + // calculate the current status again + selNodes = $.map(tree.getSelectedNodes(true), function (n) { + return n.key; + }); + selNodes = selNodes.join( + ctx.options.persist.cookieDelimiter + ); + local._data(local.cookiePrefix + SELECTED, selNodes); + } else { + // beforeSelect can prevent the change - flag doesn't reflect the node.selected state + local._appendKey(SELECTED, node.key, node.selected); + } + } + return res; + }, + }); + // Value returned by `require('jquery.fancytree..')` + return $.ui.fancytree; +}); // End of closure + +/*! + * jquery.fancytree.table.js + * + * Render tree as table (aka 'tree grid', 'table tree'). + * (Extension module for jquery.fancytree.js: https://github.com/mar10/fancytree/) + * + * Copyright (c) 2008-2023, Martin Wendt (https://wwWendt.de) + * + * Released under the MIT license + * https://github.com/mar10/fancytree/wiki/LicenseInfo + * + * @version 2.38.3 + * @date 2023-02-01T20:52:50Z + */ + +(function (factory) { + if (typeof define === "function" && define.amd) { + // AMD. Register as an anonymous module. + define(["jquery", "./jquery.fancytree"], factory); + } else if (typeof module === "object" && module.exports) { + // Node/CommonJS + require("./jquery.fancytree"); + module.exports = factory(require("jquery")); + } else { + // Browser globals + factory(jQuery); + } +})(function ($) { + "use strict"; + + /****************************************************************************** + * Private functions and variables + */ + var _assert = $.ui.fancytree.assert; + + function insertFirstChild(referenceNode, newNode) { + referenceNode.insertBefore(newNode, referenceNode.firstChild); + } + + function insertSiblingAfter(referenceNode, newNode) { + referenceNode.parentNode.insertBefore( + newNode, + referenceNode.nextSibling + ); + } + + /* Show/hide all rows that are structural descendants of `parent`. */ + function setChildRowVisibility(parent, flag) { + parent.visit(function (node) { + var tr = node.tr; + // currentFlag = node.hide ? false : flag; // fix for ext-filter + if (tr) { + tr.style.display = node.hide || !flag ? "none" : ""; + } + if (!node.expanded) { + return "skip"; + } + }); + } + + /* Find node that is rendered in previous row. */ + function findPrevRowNode(node) { + var i, + last, + prev, + parent = node.parent, + siblings = parent ? parent.children : null; + + if (siblings && siblings.length > 1 && siblings[0] !== node) { + // use the lowest descendant of the preceeding sibling + i = $.inArray(node, siblings); + prev = siblings[i - 1]; + _assert(prev.tr); + // descend to lowest child (with a <tr> tag) + while (prev.children && prev.children.length) { + last = prev.children[prev.children.length - 1]; + if (!last.tr) { + break; + } + prev = last; + } + } else { + // if there is no preceding sibling, use the direct parent + prev = parent; + } + return prev; + } + + $.ui.fancytree.registerExtension({ + name: "table", + version: "2.38.3", + // Default options for this extension. + options: { + checkboxColumnIdx: null, // render the checkboxes into the this column index (default: nodeColumnIdx) + indentation: 16, // indent every node level by 16px + mergeStatusColumns: true, // display 'nodata', 'loading', 'error' centered in a single, merged TR + nodeColumnIdx: 0, // render node expander, icon, and title to this column (default: #0) + }, + // Overide virtual methods for this extension. + // `this` : is this extension object + // `this._super`: the virtual function that was overriden (member of prev. extension or Fancytree) + treeInit: function (ctx) { + var i, + n, + $row, + $tbody, + tree = ctx.tree, + opts = ctx.options, + tableOpts = opts.table, + $table = tree.widget.element; + + if (tableOpts.customStatus != null) { + if (opts.renderStatusColumns == null) { + tree.warn( + "The 'customStatus' option is deprecated since v2.15.0. Use 'renderStatusColumns' instead." + ); + opts.renderStatusColumns = tableOpts.customStatus; + } else { + $.error( + "The 'customStatus' option is deprecated since v2.15.0. Use 'renderStatusColumns' only instead." + ); + } + } + if (opts.renderStatusColumns) { + if (opts.renderStatusColumns === true) { + opts.renderStatusColumns = opts.renderColumns; + // } else if( opts.renderStatusColumns === "wide" ) { + // opts.renderStatusColumns = _renderStatusNodeWide; + } + } + + $table.addClass("fancytree-container fancytree-ext-table"); + $tbody = $table.find(">tbody"); + if (!$tbody.length) { + // TODO: not sure if we can rely on browsers to insert missing <tbody> before <tr>s: + if ($table.find(">tr").length) { + $.error( + "Expected table > tbody > tr. If you see this please open an issue." + ); + } + $tbody = $("<tbody>").appendTo($table); + } + + tree.tbody = $tbody[0]; + + // Prepare row templates: + // Determine column count from table header if any + tree.columnCount = $("thead >tr", $table) + .last() + .find(">th", $table).length; + // Read TR templates from tbody if any + $row = $tbody.children("tr").first(); + if ($row.length) { + n = $row.children("td").length; + if (tree.columnCount && n !== tree.columnCount) { + tree.warn( + "Column count mismatch between thead (" + + tree.columnCount + + ") and tbody (" + + n + + "): using tbody." + ); + tree.columnCount = n; + } + $row = $row.clone(); + } else { + // Only thead is defined: create default row markup + _assert( + tree.columnCount >= 1, + "Need either <thead> or <tbody> with <td> elements to determine column count." + ); + $row = $("<tr />"); + for (i = 0; i < tree.columnCount; i++) { + $row.append("<td />"); + } + } + $row.find(">td") + .eq(tableOpts.nodeColumnIdx) + .html("<span class='fancytree-node' />"); + if (opts.aria) { + $row.attr("role", "row"); + $row.find("td").attr("role", "gridcell"); + } + tree.rowFragment = document.createDocumentFragment(); + tree.rowFragment.appendChild($row.get(0)); + + // // If tbody contains a second row, use this as status node template + // $row = $tbody.children("tr").eq(1); + // if( $row.length === 0 ) { + // tree.statusRowFragment = tree.rowFragment; + // } else { + // $row = $row.clone(); + // tree.statusRowFragment = document.createDocumentFragment(); + // tree.statusRowFragment.appendChild($row.get(0)); + // } + // + $tbody.empty(); + + // Make sure that status classes are set on the node's <tr> elements + tree.statusClassPropName = "tr"; + tree.ariaPropName = "tr"; + this.nodeContainerAttrName = "tr"; + + // #489: make sure $container is set to <table>, even if ext-dnd is listed before ext-table + tree.$container = $table; + + this._superApply(arguments); + + // standard Fancytree created a root UL + $(tree.rootNode.ul).remove(); + tree.rootNode.ul = null; + + // Add container to the TAB chain + // #577: Allow to set tabindex to "0", "-1" and "" + this.$container.attr("tabindex", opts.tabindex); + // this.$container.attr("tabindex", opts.tabbable ? "0" : "-1"); + if (opts.aria) { + tree.$container + .attr("role", "treegrid") + .attr("aria-readonly", true); + } + }, + nodeRemoveChildMarkup: function (ctx) { + var node = ctx.node; + // node.debug("nodeRemoveChildMarkup()"); + node.visit(function (n) { + if (n.tr) { + $(n.tr).remove(); + n.tr = null; + } + }); + }, + nodeRemoveMarkup: function (ctx) { + var node = ctx.node; + // node.debug("nodeRemoveMarkup()"); + if (node.tr) { + $(node.tr).remove(); + node.tr = null; + } + this.nodeRemoveChildMarkup(ctx); + }, + /* Override standard render. */ + nodeRender: function (ctx, force, deep, collapsed, _recursive) { + var children, + firstTr, + i, + l, + newRow, + prevNode, + prevTr, + subCtx, + tree = ctx.tree, + node = ctx.node, + opts = ctx.options, + isRootNode = !node.parent; + + if (tree._enableUpdate === false) { + // $.ui.fancytree.debug("*** nodeRender _enableUpdate: false"); + return; + } + if (!_recursive) { + ctx.hasCollapsedParents = node.parent && !node.parent.expanded; + } + // $.ui.fancytree.debug("*** nodeRender " + node + ", isRoot=" + isRootNode, "tr=" + node.tr, "hcp=" + ctx.hasCollapsedParents, "parent.tr=" + (node.parent && node.parent.tr)); + if (!isRootNode) { + if (node.tr && force) { + this.nodeRemoveMarkup(ctx); + } + if (node.tr) { + if (force) { + // Set icon, link, and title (normally this is only required on initial render) + this.nodeRenderTitle(ctx); // triggers renderColumns() + } else { + // Update element classes according to node state + this.nodeRenderStatus(ctx); + } + } else { + if (ctx.hasCollapsedParents && !deep) { + // #166: we assume that the parent will be (recursively) rendered + // later anyway. + // node.debug("nodeRender ignored due to unrendered parent"); + return; + } + // Create new <tr> after previous row + // if( node.isStatusNode() ) { + // newRow = tree.statusRowFragment.firstChild.cloneNode(true); + // } else { + newRow = tree.rowFragment.firstChild.cloneNode(true); + // } + prevNode = findPrevRowNode(node); + // $.ui.fancytree.debug("*** nodeRender " + node + ": prev: " + prevNode.key); + _assert(prevNode); + if (collapsed === true && _recursive) { + // hide all child rows, so we can use an animation to show it later + newRow.style.display = "none"; + } else if (deep && ctx.hasCollapsedParents) { + // also hide this row if deep === true but any parent is collapsed + newRow.style.display = "none"; + // newRow.style.color = "red"; + } + if (prevNode.tr) { + insertSiblingAfter(prevNode.tr, newRow); + } else { + _assert( + !prevNode.parent, + "prev. row must have a tr, or be system root" + ); + // tree.tbody.appendChild(newRow); + insertFirstChild(tree.tbody, newRow); // #675 + } + node.tr = newRow; + if (node.key && opts.generateIds) { + node.tr.id = opts.idPrefix + node.key; + } + node.tr.ftnode = node; + // if(opts.aria){ + // $(node.tr).attr("aria-labelledby", "ftal_" + opts.idPrefix + node.key); + // } + node.span = $("span.fancytree-node", node.tr).get(0); + // Set icon, link, and title (normally this is only required on initial render) + this.nodeRenderTitle(ctx); + // Allow tweaking, binding, after node was created for the first time + // tree._triggerNodeEvent("createNode", ctx); + if (opts.createNode) { + opts.createNode.call(tree, { type: "createNode" }, ctx); + } + } + } + // Allow tweaking after node state was rendered + // tree._triggerNodeEvent("renderNode", ctx); + if (opts.renderNode) { + opts.renderNode.call(tree, { type: "renderNode" }, ctx); + } + // Visit child nodes + // Add child markup + children = node.children; + if (children && (isRootNode || deep || node.expanded)) { + for (i = 0, l = children.length; i < l; i++) { + subCtx = $.extend({}, ctx, { node: children[i] }); + subCtx.hasCollapsedParents = + subCtx.hasCollapsedParents || !node.expanded; + this.nodeRender(subCtx, force, deep, collapsed, true); + } + } + // Make sure, that <tr> order matches node.children order. + if (children && !_recursive) { + // we only have to do it once, for the root branch + prevTr = node.tr || null; + firstTr = tree.tbody.firstChild; + // Iterate over all descendants + node.visit(function (n) { + if (n.tr) { + if ( + !n.parent.expanded && + n.tr.style.display !== "none" + ) { + // fix after a node was dropped over a collapsed + n.tr.style.display = "none"; + setChildRowVisibility(n, false); + } + if (n.tr.previousSibling !== prevTr) { + node.debug("_fixOrder: mismatch at node: " + n); + var nextTr = prevTr ? prevTr.nextSibling : firstTr; + tree.tbody.insertBefore(n.tr, nextTr); + } + prevTr = n.tr; + } + }); + } + // Update element classes according to node state + // if(!isRootNode){ + // this.nodeRenderStatus(ctx); + // } + }, + nodeRenderTitle: function (ctx, title) { + var $cb, + res, + tree = ctx.tree, + node = ctx.node, + opts = ctx.options, + isStatusNode = node.isStatusNode(); + + res = this._super(ctx, title); + + if (node.isRootNode()) { + return res; + } + // Move checkbox to custom column + if ( + opts.checkbox && + !isStatusNode && + opts.table.checkboxColumnIdx != null + ) { + $cb = $("span.fancytree-checkbox", node.span); //.detach(); + $(node.tr) + .find("td") + .eq(+opts.table.checkboxColumnIdx) + .html($cb); + } + // Update element classes according to node state + this.nodeRenderStatus(ctx); + + if (isStatusNode) { + if (opts.renderStatusColumns) { + // Let user code write column content + opts.renderStatusColumns.call( + tree, + { type: "renderStatusColumns" }, + ctx + ); + } else if (opts.table.mergeStatusColumns && node.isTopLevel()) { + $(node.tr) + .find(">td") + .eq(0) + .prop("colspan", tree.columnCount) + .text(node.title) + .addClass("fancytree-status-merged") + .nextAll() + .remove(); + } // else: default rendering for status node: leave other cells empty + } else if (opts.renderColumns) { + opts.renderColumns.call(tree, { type: "renderColumns" }, ctx); + } + return res; + }, + nodeRenderStatus: function (ctx) { + var indent, + node = ctx.node, + opts = ctx.options; + + this._super(ctx); + + $(node.tr).removeClass("fancytree-node"); + // indent + indent = (node.getLevel() - 1) * opts.table.indentation; + if (opts.rtl) { + $(node.span).css({ paddingRight: indent + "px" }); + } else { + $(node.span).css({ paddingLeft: indent + "px" }); + } + }, + /* Expand node, return Deferred.promise. */ + nodeSetExpanded: function (ctx, flag, callOpts) { + // flag defaults to true + flag = flag !== false; + + if ((ctx.node.expanded && flag) || (!ctx.node.expanded && !flag)) { + // Expanded state isn't changed - just call base implementation + return this._superApply(arguments); + } + + var dfd = new $.Deferred(), + subOpts = $.extend({}, callOpts, { + noEvents: true, + noAnimation: true, + }); + + callOpts = callOpts || {}; + + function _afterExpand(ok, args) { + // ctx.tree.info("ok:" + ok, args); + if (ok) { + // #1108 minExpandLevel: 2 together with table extension does not work + // don't call when 'ok' is false: + setChildRowVisibility(ctx.node, flag); + if ( + flag && + ctx.options.autoScroll && + !callOpts.noAnimation && + ctx.node.hasChildren() + ) { + // Scroll down to last child, but keep current node visible + ctx.node + .getLastChild() + .scrollIntoView(true, { topNode: ctx.node }) + .always(function () { + if (!callOpts.noEvents) { + ctx.tree._triggerNodeEvent( + flag ? "expand" : "collapse", + ctx + ); + } + dfd.resolveWith(ctx.node); + }); + } else { + if (!callOpts.noEvents) { + ctx.tree._triggerNodeEvent( + flag ? "expand" : "collapse", + ctx + ); + } + dfd.resolveWith(ctx.node); + } + } else { + if (!callOpts.noEvents) { + ctx.tree._triggerNodeEvent( + flag ? "expand" : "collapse", + ctx + ); + } + dfd.rejectWith(ctx.node); + } + } + // Call base-expand with disabled events and animation + this._super(ctx, flag, subOpts) + .done(function () { + _afterExpand(true, arguments); + }) + .fail(function () { + _afterExpand(false, arguments); + }); + return dfd.promise(); + }, + nodeSetStatus: function (ctx, status, message, details) { + if (status === "ok") { + var node = ctx.node, + firstChild = node.children ? node.children[0] : null; + if (firstChild && firstChild.isStatusNode()) { + $(firstChild.tr).remove(); + } + } + return this._superApply(arguments); + }, + treeClear: function (ctx) { + this.nodeRemoveChildMarkup(this._makeHookContext(this.rootNode)); + return this._superApply(arguments); + }, + treeDestroy: function (ctx) { + this.$container.find("tbody").empty(); + if (this.$source) { + this.$source.removeClass("fancytree-helper-hidden"); + } + return this._superApply(arguments); + }, + /*, + treeSetFocus: function(ctx, flag) { +// alert("treeSetFocus" + ctx.tree.$container); + ctx.tree.$container.focus(); + $.ui.fancytree.focusTree = ctx.tree; + }*/ + }); + // Value returned by `require('jquery.fancytree..')` + return $.ui.fancytree; +}); // End of closure + +/*! + * jquery.fancytree.themeroller.js + * + * Enable jQuery UI ThemeRoller styles. + * (Extension module for jquery.fancytree.js: https://github.com/mar10/fancytree/) + * + * @see http://jqueryui.com/themeroller/ + * + * Copyright (c) 2008-2023, Martin Wendt (https://wwWendt.de) + * + * Released under the MIT license + * https://github.com/mar10/fancytree/wiki/LicenseInfo + * + * @version 2.38.3 + * @date 2023-02-01T20:52:50Z + */ + +(function (factory) { + if (typeof define === "function" && define.amd) { + // AMD. Register as an anonymous module. + define(["jquery", "./jquery.fancytree"], factory); + } else if (typeof module === "object" && module.exports) { + // Node/CommonJS + require("./jquery.fancytree"); + module.exports = factory(require("jquery")); + } else { + // Browser globals + factory(jQuery); + } +})(function ($) { + "use strict"; + + /******************************************************************************* + * Extension code + */ + $.ui.fancytree.registerExtension({ + name: "themeroller", + version: "2.38.3", + // Default options for this extension. + options: { + activeClass: "ui-state-active", // Class added to active node + // activeClass: "ui-state-highlight", + addClass: "ui-corner-all", // Class added to all nodes + focusClass: "ui-state-focus", // Class added to focused node + hoverClass: "ui-state-hover", // Class added to hovered node + selectedClass: "ui-state-highlight", // Class added to selected nodes + // selectedClass: "ui-state-active" + }, + + treeInit: function (ctx) { + var $el = ctx.widget.element, + opts = ctx.options.themeroller; + + this._superApply(arguments); + + if ($el[0].nodeName === "TABLE") { + $el.addClass("ui-widget ui-corner-all"); + $el.find(">thead tr").addClass("ui-widget-header"); + $el.find(">tbody").addClass("ui-widget-conent"); + } else { + $el.addClass("ui-widget ui-widget-content ui-corner-all"); + } + + $el.on( + "mouseenter mouseleave", + ".fancytree-node", + function (event) { + var node = $.ui.fancytree.getNode(event.target), + flag = event.type === "mouseenter"; + + $(node.tr ? node.tr : node.span).toggleClass( + opts.hoverClass + " " + opts.addClass, + flag + ); + } + ); + }, + treeDestroy: function (ctx) { + this._superApply(arguments); + ctx.widget.element.removeClass( + "ui-widget ui-widget-content ui-corner-all" + ); + }, + nodeRenderStatus: function (ctx) { + var classes = {}, + node = ctx.node, + $el = $(node.tr ? node.tr : node.span), + opts = ctx.options.themeroller; + + this._super(ctx); + /* + .ui-state-highlight: Class to be applied to highlighted or selected elements. Applies "highlight" container styles to an element and its child text, links, and icons. + .ui-state-error: Class to be applied to error messaging container elements. Applies "error" container styles to an element and its child text, links, and icons. + .ui-state-error-text: An additional class that applies just the error text color without background. Can be used on form labels for instance. Also applies error icon color to child icons. + + .ui-state-default: Class to be applied to clickable button-like elements. Applies "clickable default" container styles to an element and its child text, links, and icons. + .ui-state-hover: Class to be applied on mouseover to clickable button-like elements. Applies "clickable hover" container styles to an element and its child text, links, and icons. + .ui-state-focus: Class to be applied on keyboard focus to clickable button-like elements. Applies "clickable hover" container styles to an element and its child text, links, and icons. + .ui-state-active: Class to be applied on mousedown to clickable button-like elements. Applies "clickable active" container styles to an element and its child text, links, and icons. +*/ + // Set ui-state-* class (handle the case that the same class is assigned + // to different states) + classes[opts.activeClass] = false; + classes[opts.focusClass] = false; + classes[opts.selectedClass] = false; + if (node.isActive()) { + classes[opts.activeClass] = true; + } + if (node.hasFocus()) { + classes[opts.focusClass] = true; + } + // activeClass takes precedence before selectedClass: + if (node.isSelected() && !node.isActive()) { + classes[opts.selectedClass] = true; + } + $el.toggleClass(opts.activeClass, classes[opts.activeClass]); + $el.toggleClass(opts.focusClass, classes[opts.focusClass]); + $el.toggleClass(opts.selectedClass, classes[opts.selectedClass]); + // Additional classes (e.g. 'ui-corner-all') + $el.addClass(opts.addClass); + }, + }); + // Value returned by `require('jquery.fancytree..')` + return $.ui.fancytree; +}); // End of closure + +/*! + * jquery.fancytree.wide.js + * Support for 100% wide selection bars. + * (Extension module for jquery.fancytree.js: https://github.com/mar10/fancytree/) + * + * Copyright (c) 2008-2023, Martin Wendt (https://wwWendt.de) + * + * Released under the MIT license + * https://github.com/mar10/fancytree/wiki/LicenseInfo + * + * @version 2.38.3 + * @date 2023-02-01T20:52:50Z + */ + +(function (factory) { + if (typeof define === "function" && define.amd) { + // AMD. Register as an anonymous module. + define(["jquery", "./jquery.fancytree"], factory); + } else if (typeof module === "object" && module.exports) { + // Node/CommonJS + require("./jquery.fancytree"); + module.exports = factory(require("jquery")); + } else { + // Browser globals + factory(jQuery); + } +})(function ($) { + "use strict"; + + var reNumUnit = /^([+-]?(?:\d+|\d*\.\d+))([a-z]*|%)$/; // split "1.5em" to ["1.5", "em"] + + /******************************************************************************* + * Private functions and variables + */ + // var _assert = $.ui.fancytree.assert; + + /* Calculate inner width without scrollbar */ + // function realInnerWidth($el) { + // // http://blog.jquery.com/2012/08/16/jquery-1-8-box-sizing-width-csswidth-and-outerwidth/ + // // inst.contWidth = parseFloat(this.$container.css("width"), 10); + // // 'Client width without scrollbar' - 'padding' + // return $el[0].clientWidth - ($el.innerWidth() - parseFloat($el.css("width"), 10)); + // } + + /* Create a global embedded CSS style for the tree. */ + function defineHeadStyleElement(id, cssText) { + id = "fancytree-style-" + id; + var $headStyle = $("#" + id); + + if (!cssText) { + $headStyle.remove(); + return null; + } + if (!$headStyle.length) { + $headStyle = $("<style />") + .attr("id", id) + .addClass("fancytree-style") + .prop("type", "text/css") + .appendTo("head"); + } + try { + $headStyle.html(cssText); + } catch (e) { + // fix for IE 6-8 + $headStyle[0].styleSheet.cssText = cssText; + } + return $headStyle; + } + + /* Calculate the CSS rules that indent title spans. */ + function renderLevelCss( + containerId, + depth, + levelOfs, + lineOfs, + labelOfs, + measureUnit + ) { + var i, + prefix = "#" + containerId + " span.fancytree-level-", + rules = []; + + for (i = 0; i < depth; i++) { + rules.push( + prefix + + (i + 1) + + " span.fancytree-title { padding-left: " + + (i * levelOfs + lineOfs) + + measureUnit + + "; }" + ); + } + // Some UI animations wrap the UL inside a DIV and set position:relative on both. + // This breaks the left:0 and padding-left:nn settings of the title + rules.push( + "#" + + containerId + + " div.ui-effects-wrapper ul li span.fancytree-title, " + + "#" + + containerId + + " li.fancytree-animating span.fancytree-title " + // #716 + "{ padding-left: " + + labelOfs + + measureUnit + + "; position: static; width: auto; }" + ); + return rules.join("\n"); + } + + // /** + // * [ext-wide] Recalculate the width of the selection bar after the tree container + // * was resized.<br> + // * May be called explicitly on container resize, since there is no resize event + // * for DIV tags. + // * + // * @alias Fancytree#wideUpdate + // * @requires jquery.fancytree.wide.js + // */ + // $.ui.fancytree._FancytreeClass.prototype.wideUpdate = function(){ + // var inst = this.ext.wide, + // prevCw = inst.contWidth, + // prevLo = inst.lineOfs; + + // inst.contWidth = realInnerWidth(this.$container); + // // Each title is precceeded by 2 or 3 icons (16px + 3 margin) + // // + 1px title border and 3px title padding + // // TODO: use code from treeInit() below + // inst.lineOfs = (this.options.checkbox ? 3 : 2) * 19; + // if( prevCw !== inst.contWidth || prevLo !== inst.lineOfs ) { + // this.debug("wideUpdate: " + inst.contWidth); + // this.visit(function(node){ + // node.tree._callHook("nodeRenderTitle", node); + // }); + // } + // }; + + /******************************************************************************* + * Extension code + */ + $.ui.fancytree.registerExtension({ + name: "wide", + version: "2.38.3", + // Default options for this extension. + options: { + iconWidth: null, // Adjust this if @fancy-icon-width != "16px" + iconSpacing: null, // Adjust this if @fancy-icon-spacing != "3px" + labelSpacing: null, // Adjust this if padding between icon and label != "3px" + levelOfs: null, // Adjust this if ul padding != "16px" + }, + + treeCreate: function (ctx) { + this._superApply(arguments); + this.$container.addClass("fancytree-ext-wide"); + + var containerId, + cssText, + iconSpacingUnit, + labelSpacingUnit, + iconWidthUnit, + levelOfsUnit, + instOpts = ctx.options.wide, + // css sniffing + $dummyLI = $( + "<li id='fancytreeTemp'><span class='fancytree-node'><span class='fancytree-icon' /><span class='fancytree-title' /></span><ul />" + ).appendTo(ctx.tree.$container), + $dummyIcon = $dummyLI.find(".fancytree-icon"), + $dummyUL = $dummyLI.find("ul"), + // $dummyTitle = $dummyLI.find(".fancytree-title"), + iconSpacing = + instOpts.iconSpacing || $dummyIcon.css("margin-left"), + iconWidth = instOpts.iconWidth || $dummyIcon.css("width"), + labelSpacing = instOpts.labelSpacing || "3px", + levelOfs = instOpts.levelOfs || $dummyUL.css("padding-left"); + + $dummyLI.remove(); + + iconSpacingUnit = iconSpacing.match(reNumUnit)[2]; + iconSpacing = parseFloat(iconSpacing, 10); + labelSpacingUnit = labelSpacing.match(reNumUnit)[2]; + labelSpacing = parseFloat(labelSpacing, 10); + iconWidthUnit = iconWidth.match(reNumUnit)[2]; + iconWidth = parseFloat(iconWidth, 10); + levelOfsUnit = levelOfs.match(reNumUnit)[2]; + if ( + iconSpacingUnit !== iconWidthUnit || + levelOfsUnit !== iconWidthUnit || + labelSpacingUnit !== iconWidthUnit + ) { + $.error( + "iconWidth, iconSpacing, and levelOfs must have the same css measure unit" + ); + } + this._local.measureUnit = iconWidthUnit; + this._local.levelOfs = parseFloat(levelOfs); + this._local.lineOfs = + (1 + + (ctx.options.checkbox ? 1 : 0) + + (ctx.options.icon === false ? 0 : 1)) * + (iconWidth + iconSpacing) + + iconSpacing; + this._local.labelOfs = labelSpacing; + this._local.maxDepth = 10; + + // Get/Set a unique Id on the container (if not already exists) + containerId = this.$container.uniqueId().attr("id"); + // Generated css rules for some levels (extended on demand) + cssText = renderLevelCss( + containerId, + this._local.maxDepth, + this._local.levelOfs, + this._local.lineOfs, + this._local.labelOfs, + this._local.measureUnit + ); + defineHeadStyleElement(containerId, cssText); + }, + treeDestroy: function (ctx) { + // Remove generated css rules + defineHeadStyleElement(this.$container.attr("id"), null); + return this._superApply(arguments); + }, + nodeRenderStatus: function (ctx) { + var containerId, + cssText, + res, + node = ctx.node, + level = node.getLevel(); + + res = this._super(ctx); + // Generate some more level-n rules if required + if (level > this._local.maxDepth) { + containerId = this.$container.attr("id"); + this._local.maxDepth *= 2; + node.debug( + "Define global ext-wide css up to level " + + this._local.maxDepth + ); + cssText = renderLevelCss( + containerId, + this._local.maxDepth, + this._local.levelOfs, + this._local.lineOfs, + this._local.labelSpacing, + this._local.measureUnit + ); + defineHeadStyleElement(containerId, cssText); + } + // Add level-n class to apply indentation padding. + // (Setting element style would not work, since it cannot easily be + // overriden while animations run) + $(node.span).addClass("fancytree-level-" + level); + return res; + }, + }); + // Value returned by `require('jquery.fancytree..')` + return $.ui.fancytree; +}); // End of closure diff --git a/plugins/55/indexmenu/scripts/fancytree/jquery.fancytree-all.min.js b/plugins/55/indexmenu/scripts/fancytree/jquery.fancytree-all.min.js new file mode 100644 index 0000000..977c906 --- /dev/null +++ b/plugins/55/indexmenu/scripts/fancytree/jquery.fancytree-all.min.js @@ -0,0 +1,62 @@ +/*! jQuery Fancytree Plugin - 2.38.3 - 2023-02-01T20:52:50Z + * https://github.com/mar10/fancytree + * Copyright (c) 2023 Martin Wendt; Licensed MIT + */ +(function( factory ) { + if ( typeof define === "function" && define.amd ) { + // AMD. Register as an anonymous module. + define( [ + "jquery", + "jquery-ui/ui/widgets/mouse", + "jquery-ui/ui/widgets/draggable", + "jquery-ui/ui/widgets/droppable", + "jquery-ui/ui/effects/effect-blind", + "jquery-ui/ui/data", + "jquery-ui/ui/effect", + "jquery-ui/ui/focusable", + "jquery-ui/ui/keycode", + "jquery-ui/ui/position", + "jquery-ui/ui/scroll-parent", + "jquery-ui/ui/tabbable", + "jquery-ui/ui/unique-id", + "jquery-ui/ui/widget" + ], factory ); + } else if ( typeof module === "object" && module.exports ) { + // Node/CommonJS + module.exports = factory(require("jquery")); + } else { + // Browser globals + factory( jQuery ); + } +}(function( $ ) { + +!function(e){"function"==typeof define&&define.amd?define(["jquery","./jquery.fancytree.ui-deps"],e):"object"==typeof module&&module.exports?(require("./jquery.fancytree.ui-deps"),module.exports=e(require("jquery"))):e(jQuery)}(function(k){"use strict";if(!k.ui||!k.ui.fancytree){for(var e,h=null,c=new RegExp(/\.|\//),t=/[&<>"'/]/g,n=/[<>"'/]/g,f="$recursive_request",p="$request_target_invalid",i={"&":"&","<":"<",">":">",'"':""","'":"'","/":"/"},r={16:!0,17:!0,18:!0},u={8:"backspace",9:"tab",10:"return",13:"return",19:"pause",20:"capslock",27:"esc",32:"space",33:"pageup",34:"pagedown",35:"end",36:"home",37:"left",38:"up",39:"right",40:"down",45:"insert",46:"del",59:";",61:"=",96:"0",97:"1",98:"2",99:"3",100:"4",101:"5",102:"6",103:"7",104:"8",105:"9",106:"*",107:"+",109:"-",110:".",111:"/",112:"f1",113:"f2",114:"f3",115:"f4",116:"f5",117:"f6",118:"f7",119:"f8",120:"f9",121:"f10",122:"f11",123:"f12",144:"numlock",145:"scroll",173:"-",186:";",187:"=",188:",",189:"-",190:".",191:"/",192:"`",219:"[",220:"\\",221:"]",222:"'"},g={16:"shift",17:"ctrl",18:"alt",91:"meta",93:"meta"},o={0:"",1:"left",2:"middle",3:"right"},v="active expanded focus folder lazy radiogroup selected unselectable unselectableIgnore".split(" "),y={},b="columns types".split(" "),m="checkbox expanded extraClasses folder icon iconTooltip key lazy partsel radiogroup refKey selected statusNodeType title tooltip type unselectable unselectableIgnore unselectableStatus".split(" "),s={},x={},a={active:!0,children:!0,data:!0,focus:!0},l=0;l<v.length;l++)y[v[l]]=!0;for(l=0;l<m.length;l++)e=m[l],s[e]=!0,e!==e.toLowerCase()&&(x[e.toLowerCase()]=e);var N=Array.isArray;return _(k.ui,"Fancytree requires jQuery UI (http://jqueryui.com)"),Date.now||(Date.now=function(){return(new Date).getTime()}),I.prototype={_findDirectChild:function(e){var t,n,i=this.children;if(i)if("string"==typeof e){for(t=0,n=i.length;t<n;t++)if(i[t].key===e)return i[t]}else{if("number"==typeof e)return this.children[e];if(e.parent===this)return e}return null},_setChildren:function(e){_(e&&(!this.children||0===this.children.length),"only init supported"),this.children=[];for(var t=0,n=e.length;t<n;t++)this.children.push(new I(this,e[t]));this.tree._callHook("treeStructureChanged",this.tree,"setChildren")},addChildren:function(e,t){var n,i,r,o,s=this.getFirstChild(),a=this.getLastChild(),l=[];for(k.isPlainObject(e)&&(e=[e]),this.children||(this.children=[]),n=0,i=e.length;n<i;n++)l.push(new I(this,e[n]));if(o=l[0],null==t?this.children=this.children.concat(l):(t=this._findDirectChild(t),_(0<=(r=k.inArray(t,this.children)),"insertBefore must be an existing child"),this.children.splice.apply(this.children,[r,0].concat(l))),s&&!t){for(n=0,i=l.length;n<i;n++)l[n].render();s!==this.getFirstChild()&&s.renderStatus(),a!==this.getLastChild()&&a.renderStatus()}else this.parent&&!this.parent.ul&&!this.tr||this.render();return 3===this.tree.options.selectMode&&this.fixSelection3FromEndNodes(),this.triggerModifyChild("add",1===l.length?l[0]:null),o},addClass:function(e){return this.toggleClass(e,!0)},addNode:function(e,t){switch(t=void 0===t||"over"===t?"child":t){case"after":return this.getParent().addChildren(e,this.getNextSibling());case"before":return this.getParent().addChildren(e,this);case"firstChild":var n=this.children?this.children[0]:null;return this.addChildren(e,n);case"child":case"over":return this.addChildren(e)}_(!1,"Invalid mode: "+t)},addPagingNode:function(e,t){var n,i;if(t=t||"child",!1!==e)return e=k.extend({title:this.tree.options.strings.moreData,statusNodeType:"paging",icon:!1},e),this.partload=!0,this.addNode(e,t);for(n=this.children.length-1;0<=n;n--)"paging"===(i=this.children[n]).statusNodeType&&this.removeChild(i);this.partload=!1},appendSibling:function(e){return this.addNode(e,"after")},applyCommand:function(e,t){return this.tree.applyCommand(e,this,t)},applyPatch:function(e){if(null===e)return this.remove(),T(this);var t,n,i={children:!0,expanded:!0,parent:!0};for(t in e)C(e,t)&&(n=e[t],i[t]||w(n)||(s[t]?this[t]=n:this.data[t]=n));return C(e,"children")&&(this.removeChildren(),e.children&&this._setChildren(e.children)),this.isVisible()&&(this.renderTitle(),this.renderStatus()),C(e,"expanded")?this.setExpanded(e.expanded):T(this)},collapseSiblings:function(){return this.tree._callHook("nodeCollapseSiblings",this)},copyTo:function(e,t,n){return e.addNode(this.toDict(!0,n),t)},countChildren:function(e){var t,n,i,r=this.children;if(!r)return 0;if(i=r.length,!1!==e)for(t=0,n=i;t<n;t++)i+=r[t].countChildren();return i},debug:function(e){4<=this.tree.options.debugLevel&&(Array.prototype.unshift.call(arguments,this.toString()),d("log",arguments))},discard:function(){return this.warn("FancytreeNode.discard() is deprecated since 2014-02-16. Use .resetLazy() instead."),this.resetLazy()},discardMarkup:function(e){this.tree._callHook(e?"nodeRemoveMarkup":"nodeRemoveChildMarkup",this)},error:function(e){1<=this.tree.options.debugLevel&&(Array.prototype.unshift.call(arguments,this.toString()),d("error",arguments))},findAll:function(t){t=w(t)?t:R(t);var n=[];return this.visit(function(e){t(e)&&n.push(e)}),n},findFirst:function(t){t=w(t)?t:R(t);var n=null;return this.visit(function(e){if(t(e))return n=e,!1}),n},findRelatedNode:function(e,t){return this.tree.findRelatedNode(this,e,t)},_changeSelectStatusAttrs:function(e){var t=!1,n=this.tree.options,i=h.evalOption("unselectable",this,this,n,!1),n=h.evalOption("unselectableStatus",this,this,n,void 0);switch(e=i&&null!=n?n:e){case!1:t=this.selected||this.partsel,this.selected=!1,this.partsel=!1;break;case!0:t=!this.selected||!this.partsel,this.selected=!0,this.partsel=!0;break;case void 0:t=this.selected||!this.partsel,this.selected=!1,this.partsel=!0;break;default:_(!1,"invalid state: "+e)}return t&&this.renderStatus(),t},fixSelection3AfterClick:function(e){var t=this.isSelected();this.visit(function(e){if(e._changeSelectStatusAttrs(t),e.radiogroup)return"skip"}),this.fixSelection3FromEndNodes(e)},fixSelection3FromEndNodes:function(e){var u=this.tree.options;_(3===u.selectMode,"expected selectMode 3"),function e(t){var n,i,r,o,s,a,l,d,c=t.children;if(c&&c.length){for(l=!(a=!0),n=0,i=c.length;n<i;n++)o=e(r=c[n]),h.evalOption("unselectableIgnore",r,r,u,!1)||(!1!==o&&(l=!0),!0!==o&&(a=!1));s=!!a||!!l&&void 0}else s=null==(d=h.evalOption("unselectableStatus",t,t,u,void 0))?!!t.selected:!!d;return t.partsel&&!t.selected&&t.lazy&&null==t.children&&(s=void 0),t._changeSelectStatusAttrs(s),s}(this),this.visitParents(function(e){for(var t,n,i,r=e.children,o=!0,s=!1,a=0,l=r.length;a<l;a++)t=r[a],h.evalOption("unselectableIgnore",t,t,u,!1)||(((n=null==(i=h.evalOption("unselectableStatus",t,t,u,void 0))?!!t.selected:!!i)||t.partsel)&&(s=!0),n||(o=!1));e._changeSelectStatusAttrs(n=!!o||!!s&&void 0)})},fromDict:function(e){for(var t in e)s[t]?this[t]=e[t]:"data"===t?k.extend(this.data,e.data):w(e[t])||a[t]||(this.data[t]=e[t]);e.children&&(this.removeChildren(),this.addChildren(e.children)),this.renderTitle()},getChildren:function(){if(void 0!==this.hasChildren())return this.children},getFirstChild:function(){return this.children?this.children[0]:null},getIndex:function(){return k.inArray(this,this.parent.children)},getIndexHier:function(e,n){e=e||".";var i,r=[];return k.each(this.getParentList(!1,!0),function(e,t){i=""+(t.getIndex()+1),n&&(i=("0000000"+i).substr(-n)),r.push(i)}),r.join(e)},getKeyPath:function(e){var t=this.tree.options.keyPathSeparator;return t+this.getPath(!e,"key",t)},getLastChild:function(){return this.children?this.children[this.children.length-1]:null},getLevel:function(){for(var e=0,t=this.parent;t;)e++,t=t.parent;return e},getNextSibling:function(){if(this.parent)for(var e=this.parent.children,t=0,n=e.length-1;t<n;t++)if(e[t]===this)return e[t+1];return null},getParent:function(){return this.parent},getParentList:function(e,t){for(var n=[],i=t?this:this.parent;i;)(e||i.parent)&&n.unshift(i),i=i.parent;return n},getPath:function(e,t,n){n=n||"/";var i,r=[],o=w(t=t||"title");return this.visitParents(function(e){e.parent&&(i=o?t(e):e[t],r.unshift(i))},e=!1!==e),r.join(n)},getPrevSibling:function(){if(this.parent)for(var e=this.parent.children,t=1,n=e.length;t<n;t++)if(e[t]===this)return e[t-1];return null},getSelectedNodes:function(t){var n=[];return this.visit(function(e){if(e.selected&&(n.push(e),!0===t))return"skip"}),n},hasChildren:function(){return this.lazy?null==this.children?void 0:0!==this.children.length&&(1!==this.children.length||!this.children[0].isStatusNode()||void 0):!(!this.children||!this.children.length)},hasClass:function(e){return 0<=(" "+(this.extraClasses||"")+" ").indexOf(" "+e+" ")},hasFocus:function(){return this.tree.hasFocus()&&this.tree.focusNode===this},info:function(e){3<=this.tree.options.debugLevel&&(Array.prototype.unshift.call(arguments,this.toString()),d("info",arguments))},isActive:function(){return this.tree.activeNode===this},isBelowOf:function(e){return this.getIndexHier(".",5)>e.getIndexHier(".",5)},isChildOf:function(e){return this.parent&&this.parent===e},isDescendantOf:function(e){if(!e||e.tree!==this.tree)return!1;for(var t=this.parent;t;){if(t===e)return!0;t===t.parent&&k.error("Recursive parent link: "+t),t=t.parent}return!1},isExpanded:function(){return!!this.expanded},isFirstSibling:function(){var e=this.parent;return!e||e.children[0]===this},isFolder:function(){return!!this.folder},isLastSibling:function(){var e=this.parent;return!e||e.children[e.children.length-1]===this},isLazy:function(){return!!this.lazy},isLoaded:function(){return!this.lazy||void 0!==this.hasChildren()},isLoading:function(){return!!this._isLoading},isRoot:function(){return this.isRootNode()},isPartsel:function(){return!this.selected&&!!this.partsel},isPartload:function(){return!!this.partload},isRootNode:function(){return this.tree.rootNode===this},isSelected:function(){return!!this.selected},isStatusNode:function(){return!!this.statusNodeType},isPagingNode:function(){return"paging"===this.statusNodeType},isTopLevel:function(){return this.tree.rootNode===this.parent},isUndefined:function(){return void 0===this.hasChildren()},isVisible:function(){var e,t,n=this.tree.enableFilter,i=this.getParentList(!1,!1);if(n&&!this.match&&!this.subMatchCount)return!1;for(e=0,t=i.length;e<t;e++)if(!i[e].expanded)return!1;return!0},lazyLoad:function(e){k.error("FancytreeNode.lazyLoad() is deprecated since 2014-02-16. Use .load() instead.")},load:function(e){var t=this,n=this.isExpanded();return _(this.isLazy(),"load() requires a lazy node"),e||this.isUndefined()?(this.isLoaded()&&this.resetLazy(),!1===(e=this.tree._triggerNodeEvent("lazyLoad",this))?T(this):(_("boolean"!=typeof e,"lazyLoad event must return source in data.result"),e=this.tree._callHook("nodeLoadChildren",this,e),n?(this.expanded=!0,e.always(function(){t.render()})):e.always(function(){t.renderStatus()}),e)):T(this)},makeVisible:function(e){for(var t=this,n=[],i=new k.Deferred,r=this.getParentList(!1,!1),o=r.length,s=!(e&&!0===e.noAnimation),a=!(e&&!1===e.scrollIntoView),l=o-1;0<=l;l--)n.push(r[l].setExpanded(!0,e));return k.when.apply(k,n).done(function(){a?t.scrollIntoView(s).done(function(){i.resolve()}):i.resolve()}),i.promise()},moveTo:function(t,e,n){void 0===e||"over"===e?e="child":"firstChild"===e&&(t.children&&t.children.length?(e="before",t=t.children[0]):e="child");var i,r=this.tree,o=this.parent,s="child"===e?t:t.parent;if(this!==t){if(this.parent?s.isDescendantOf(this)&&k.error("Cannot move a node to its own descendant"):k.error("Cannot move system root"),s!==o&&o.triggerModifyChild("remove",this),1===this.parent.children.length){if(this.parent===s)return;this.parent.children=this.parent.lazy?[]:null,this.parent.expanded=!1}else _(0<=(i=k.inArray(this,this.parent.children)),"invalid source parent"),this.parent.children.splice(i,1);if((this.parent=s).hasChildren())switch(e){case"child":s.children.push(this);break;case"before":_(0<=(i=k.inArray(t,s.children)),"invalid target parent"),s.children.splice(i,0,this);break;case"after":_(0<=(i=k.inArray(t,s.children)),"invalid target parent"),s.children.splice(i+1,0,this);break;default:k.error("Invalid mode "+e)}else s.children=[this];n&&t.visit(n,!0),s===o?s.triggerModifyChild("move",this):s.triggerModifyChild("add",this),r!==t.tree&&(this.warn("Cross-tree moveTo is experimental!"),this.visit(function(e){e.tree=t.tree},!0)),r._callHook("treeStructureChanged",r,"moveTo"),o.isDescendantOf(s)||o.render(),s.isDescendantOf(o)||s===o||s.render()}},navigate:function(e,t){var n=k.ui.keyCode;switch(e){case"left":case n.LEFT:if(this.expanded)return this.setExpanded(!1);break;case"right":case n.RIGHT:if(!this.expanded&&(this.children||this.lazy))return this.setExpanded()}if(n=this.findRelatedNode(e)){try{n.makeVisible({scrollIntoView:!1})}catch(e){}return!1===t?(n.setFocus(),T()):n.setActive()}return this.warn("Could not find related node '"+e+"'."),T()},remove:function(){return this.parent.removeChild(this)},removeChild:function(e){return this.tree._callHook("nodeRemoveChild",this,e)},removeChildren:function(){return this.tree._callHook("nodeRemoveChildren",this)},removeClass:function(e){return this.toggleClass(e,!1)},render:function(e,t){return this.tree._callHook("nodeRender",this,e,t)},renderTitle:function(){return this.tree._callHook("nodeRenderTitle",this)},renderStatus:function(){return this.tree._callHook("nodeRenderStatus",this)},replaceWith:function(e){var n=this.parent,i=k.inArray(this,n.children),r=this;return _(this.isPagingNode(),"replaceWith() currently requires a paging status node"),(e=this.tree._callHook("nodeLoadChildren",this,e)).done(function(e){var t=r.children;for(l=0;l<t.length;l++)t[l].parent=n;n.children.splice.apply(n.children,[i+1,0].concat(t)),r.children=null,r.remove(),n.render()}).fail(function(){r.setExpanded()}),e},resetLazy:function(){this.removeChildren(),this.expanded=!1,this.lazy=!0,this.children=void 0,this.renderStatus()},scheduleAction:function(e,t){this.tree.timer&&(clearTimeout(this.tree.timer),this.tree.debug("clearTimeout(%o)",this.tree.timer)),this.tree.timer=null;var n=this;switch(e){case"cancel":break;case"expand":this.tree.timer=setTimeout(function(){n.tree.debug("setTimeout: trigger expand"),n.setExpanded(!0)},t);break;case"activate":this.tree.timer=setTimeout(function(){n.tree.debug("setTimeout: trigger activate"),n.setActive(!0)},t);break;default:k.error("Invalid mode "+e)}},scrollIntoView:function(e,t){if(void 0!==t&&((p=t).tree&&void 0!==p.statusNodeType))throw Error("scrollIntoView() with 'topNode' option is deprecated since 2014-05-08. Use 'options.topNode' instead.");var n=k.extend({effects:!0===e?{duration:200,queue:!1}:e,scrollOfs:this.tree.options.scrollOfs,scrollParent:this.tree.options.scrollParent,topNode:null},t),i=n.scrollParent,r=this.tree.$container,o=r.css("overflow-y");i?i.jquery||(i=k(i)):i=!this.tree.tbody&&("scroll"===o||"auto"===o)?r:r.scrollParent(),i[0]!==document&&i[0]!==document.body||(this.debug("scrollIntoView(): normalizing scrollParent to 'window':",i[0]),i=k(window));var s,a,l=new k.Deferred,d=this,c=k(this.span).height(),u=n.scrollOfs.top||0,h=n.scrollOfs.bottom||0,f=i.height(),p=i.scrollTop(),e=i,t=i[0]===window,o=n.topNode||null,r=null;return this.isRootNode()||!this.isVisible()?(this.info("scrollIntoView(): node is invisible."),T()):(t?(a=k(this.span).offset().top,s=o&&o.span?k(o.span).offset().top:0,e=k("html,body")):(_(i[0]!==document&&i[0]!==document.body,"scrollParent should be a simple element or `window`, not document or body."),t=i.offset().top,a=k(this.span).offset().top-t+p,s=o?k(o.span).offset().top-t+p:0,f-=Math.max(0,i.innerHeight()-i[0].clientHeight)),a<p+u?r=a-u:p+f-h<a+c&&(r=a+c-f+h,o&&(_(o.isRootNode()||o.isVisible(),"topNode must be visible"),s<r&&(r=s-u))),null===r?l.resolveWith(this):n.effects?(n.effects.complete=function(){l.resolveWith(d)},e.stop(!0).animate({scrollTop:r},n.effects)):(e[0].scrollTop=r,l.resolveWith(this)),l.promise())},setActive:function(e,t){return this.tree._callHook("nodeSetActive",this,e,t)},setExpanded:function(e,t){return this.tree._callHook("nodeSetExpanded",this,e,t)},setFocus:function(e){return this.tree._callHook("nodeSetFocus",this,e)},setSelected:function(e,t){return this.tree._callHook("nodeSetSelected",this,e,t)},setStatus:function(e,t,n){return this.tree._callHook("nodeSetStatus",this,e,t,n)},setTitle:function(e){this.title=e,this.renderTitle(),this.triggerModify("rename")},sortChildren:function(e,t){var n,i,r=this.children;if(r){if(r.sort(e=e||function(e,t){e=e.title.toLowerCase(),t=t.title.toLowerCase();return e===t?0:t<e?1:-1}),t)for(n=0,i=r.length;n<i;n++)r[n].children&&r[n].sortChildren(e,"$norender$");"$norender$"!==t&&this.render(),this.triggerModifyChild("sort")}},toDict:function(e,t){var n,i,r,o,s={},a=this;if(k.each(m,function(e,t){!a[t]&&!1!==a[t]||(s[t]=a[t])}),k.isEmptyObject(this.data)||(s.data=k.extend({},this.data),k.isEmptyObject(s.data)&&delete s.data),t){if(!1===(o=t(s,a)))return!1;"skip"===o&&(e=!1)}if(e&&N(this.children))for(s.children=[],n=0,i=this.children.length;n<i;n++)(r=this.children[n]).isStatusNode()||!1!==(o=r.toDict(!0,t))&&s.children.push(o);return s},toggleClass:function(e,t){var n,i,r=e.match(/\S+/g)||[],o=0,s=!1,a=this[this.tree.statusClassPropName],l=" "+(this.extraClasses||"")+" ";for(a&&k(a).toggleClass(e,t);n=r[o++];)if(i=0<=l.indexOf(" "+n+" "),t=void 0===t?!i:!!t)i||(l+=n+" ",s=!0);else for(;-1<l.indexOf(" "+n+" ");)l=l.replace(" "+n+" "," ");return this.extraClasses=S(l),s},toggleExpanded:function(){return this.tree._callHook("nodeToggleExpanded",this)},toggleSelected:function(){return this.tree._callHook("nodeToggleSelected",this)},toString:function(){return"FancytreeNode@"+this.key+"[title='"+this.title+"']"},triggerModifyChild:function(e,t,n){var i=this.tree.options.modifyChild;i&&(t&&t.parent!==this&&k.error("childNode "+t+" is not a child of "+this),t={node:this,tree:this.tree,operation:e,childNode:t||null},n&&k.extend(t,n),i({type:"modifyChild"},t))},triggerModify:function(e,t){this.parent.triggerModifyChild(e,this,t)},visit:function(e,t){var n,i,r=!0,o=this.children;if(!0===t&&(!1===(r=e(this))||"skip"===r))return r;if(o)for(n=0,i=o.length;n<i&&!1!==(r=o[n].visit(e,!0));n++);return r},visitAndLoad:function(n,e,t){var i,r,o,s=this;return!n||!0!==e||!1!==(r=n(s))&&"skip"!==r?s.children||s.lazy?(i=new k.Deferred,o=[],s.load().done(function(){for(var e=0,t=s.children.length;e<t;e++){if(!1===(r=s.children[e].visitAndLoad(n,!0,!0))){i.reject();break}"skip"!==r&&o.push(r)}k.when.apply(this,o).then(function(){i.resolve()})}),i.promise()):T():t?r:T()},visitParents:function(e,t){if(t&&!1===e(this))return!1;for(var n=this.parent;n;){if(!1===e(n))return!1;n=n.parent}return!0},visitSiblings:function(e,t){for(var n,i=this.parent.children,r=0,o=i.length;r<o;r++)if(n=i[r],(t||n!==this)&&!1===e(n))return!1;return!0},warn:function(e){2<=this.tree.options.debugLevel&&(Array.prototype.unshift.call(arguments,this.toString()),d("warn",arguments))}},F.prototype={_makeHookContext:function(e,t,n){var i,r;return void 0!==e.node?(t&&e.originalEvent!==t&&k.error("invalid args"),i=e):e.tree?i={node:e,tree:r=e.tree,widget:r.widget,options:r.widget.options,originalEvent:t,typeInfo:r.types[e.type]||{}}:e.widget?i={node:null,tree:e,widget:e.widget,options:e.widget.options,originalEvent:t}:k.error("invalid args"),n&&k.extend(i,n),i},_callHook:function(e,t,n){var i=this._makeHookContext(t),r=this[e],t=Array.prototype.slice.call(arguments,2);return w(r)||k.error("_callHook('"+e+"') is not a function"),t.unshift(i),r.apply(this,t)},_setExpiringValue:function(e,t,n){this._tempCache[e]={value:t,expire:Date.now()+(+n||50)}},_getExpiringValue:function(e){var t=this._tempCache[e];return t&&t.expire>Date.now()?t.value:(delete this._tempCache[e],null)},_usesExtension:function(e){return 0<=k.inArray(e,this.options.extensions)},_requireExtension:function(e,t,n,i){null!=n&&(n=!!n);var r=this._local.name,o=this.options.extensions,s=k.inArray(e,o)<k.inArray(r,o),o=t&&null==this.ext[e],s=!o&&null!=n&&n!==s;return _(r&&r!==e,"invalid or same name '"+r+"' (require yourself?)"),!o&&!s||(i||(o||t?(i="'"+r+"' extension requires '"+e+"'",s&&(i+=" to be registered "+(n?"before":"after")+" itself")):i="If used together, `"+e+"` must be registered "+(n?"before":"after")+" `"+r+"`"),k.error(i),!1)},activateKey:function(e,t){e=this.getNodeByKey(e);return e?e.setActive(!0,t):this.activeNode&&this.activeNode.setActive(!1,t),e},addPagingNode:function(e,t){return this.rootNode.addPagingNode(e,t)},applyCommand:function(e,t,n){var i;switch(t=t||this.getActiveNode(),e){case"moveUp":(i=t.getPrevSibling())&&(t.moveTo(i,"before"),t.setActive());break;case"moveDown":(i=t.getNextSibling())&&(t.moveTo(i,"after"),t.setActive());break;case"indent":(i=t.getPrevSibling())&&(t.moveTo(i,"child"),i.setExpanded(),t.setActive());break;case"outdent":t.isTopLevel()||(t.moveTo(t.getParent(),"after"),t.setActive());break;case"remove":i=t.getPrevSibling()||t.getParent(),t.remove(),i&&i.setActive();break;case"addChild":t.editCreateNode("child","");break;case"addSibling":t.editCreateNode("after","");break;case"rename":t.editStart();break;case"down":case"first":case"last":case"left":case"parent":case"right":case"up":return t.navigate(e);default:k.error("Unhandled command: '"+e+"'")}},applyPatch:function(e){for(var t,n,i,r,o=e.length,s=[],a=0;a<o;a++)_(2===(t=e[a]).length,"patchList must be an array of length-2-arrays"),n=t[0],i=t[1],(r=null===n?this.rootNode:this.getNodeByKey(n))?(t=new k.Deferred,s.push(t),r.applyPatch(i).always(A(t,r))):this.warn("could not find node with key '"+n+"'");return k.when.apply(k,s).promise()},clear:function(e){this._callHook("treeClear",this)},count:function(){return this.rootNode.countChildren()},debug:function(e){4<=this.options.debugLevel&&(Array.prototype.unshift.call(arguments,this.toString()),d("log",arguments))},destroy:function(){this.widget.destroy()},enable:function(e){!1===e?this.widget.disable():this.widget.enable()},enableUpdate:function(e){return!!this._enableUpdate==!!(e=!1!==e)?e:((this._enableUpdate=e)?(this.debug("enableUpdate(true): redraw "),this._callHook("treeStructureChanged",this,"enableUpdate"),this.render()):this.debug("enableUpdate(false)..."),!e)},error:function(e){1<=this.options.debugLevel&&(Array.prototype.unshift.call(arguments,this.toString()),d("error",arguments))},expandAll:function(t,n){var e=this.enableUpdate(!1);t=!1!==t,this.visit(function(e){!1!==e.hasChildren()&&e.isExpanded()!==t&&e.setExpanded(t,n)}),this.enableUpdate(e)},findAll:function(e){return this.rootNode.findAll(e)},findFirst:function(e){return this.rootNode.findFirst(e)},findNextNode:function(t,n){var i,r=null,e=this.getFirstChild();function o(e){if((r=t(e)?e:r)||e===n)return!1}return t="string"==typeof t?(i=new RegExp("^"+t,"i"),function(e){return i.test(e.title)}):t,this.visitRows(o,{start:n=n||e,includeSelf:!1}),r||n===e||this.visitRows(o,{start:e,includeSelf:!0}),r},findRelatedNode:function(e,t,n){var i=null,r=k.ui.keyCode;switch(t){case"parent":case r.BACKSPACE:e.parent&&e.parent.parent&&(i=e.parent);break;case"first":case r.HOME:this.visit(function(e){if(e.isVisible())return i=e,!1});break;case"last":case r.END:this.visit(function(e){e.isVisible()&&(i=e)});break;case"left":case r.LEFT:e.expanded?e.setExpanded(!1):e.parent&&e.parent.parent&&(i=e.parent);break;case"right":case r.RIGHT:e.expanded||!e.children&&!e.lazy?e.children&&e.children.length&&(i=e.children[0]):(e.setExpanded(),i=e);break;case"up":case r.UP:this.visitRows(function(e){return i=e,!1},{start:e,reverse:!0,includeSelf:!1});break;case"down":case r.DOWN:this.visitRows(function(e){return i=e,!1},{start:e,includeSelf:!1});break;default:this.tree.warn("Unknown relation '"+t+"'.")}return i},generateFormElements:function(e,t,n){n=n||{};var i="string"==typeof e?e:"ft_"+this._id+"[]",r="string"==typeof t?t:"ft_"+this._id+"_active",o="fancytree_result_"+this._id,s=k("#"+o),a=3===this.options.selectMode&&!1!==n.stopOnParents;function l(e){s.append(k("<input>",{type:"checkbox",name:i,value:e.key,checked:!0}))}s.length?s.empty():s=k("<div>",{id:o}).hide().insertAfter(this.$container),!1!==t&&this.activeNode&&s.append(k("<input>",{type:"radio",name:r,value:this.activeNode.key,checked:!0})),n.filter?this.visit(function(e){var t=n.filter(e);if("skip"===t)return t;!1!==t&&l(e)}):!1!==e&&(a=this.getSelectedNodes(a),k.each(a,function(e,t){l(t)}))},getActiveNode:function(){return this.activeNode},getFirstChild:function(){return this.rootNode.getFirstChild()},getFocusNode:function(){return this.focusNode},getOption:function(e){return this.widget.option(e)},getNodeByKey:function(t,e){var n,i;return!e&&(n=document.getElementById(this.options.idPrefix+t))?n.ftnode||null:(e=e||this.rootNode,t=""+t,e.visit(function(e){if(e.key===t)return i=e,!1},!(i=null)),i)},getRootNode:function(){return this.rootNode},getSelectedNodes:function(e){return this.rootNode.getSelectedNodes(e)},hasFocus:function(){return!!this._hasFocus},info:function(e){3<=this.options.debugLevel&&(Array.prototype.unshift.call(arguments,this.toString()),d("info",arguments))},isLoading:function(){var t=!1;return this.rootNode.visit(function(e){if(e._isLoading||e._requestId)return!(t=!0)},!0),t},loadKeyPath:function(e,t){var i,n,r,o=this,s=new k.Deferred,a=this.getRootNode(),l=this.options.keyPathSeparator,d=[],c=k.extend({},t);for("function"==typeof t?i=t:t&&t.callback&&(i=t.callback),c.callback=function(e,t,n){i&&i.call(e,t,n),s.notifyWith(e,[{node:t,status:n}])},null==c.matchKey&&(c.matchKey=function(e,t){return e.key===t}),N(e)||(e=[e]),n=0;n<e.length;n++)(r=e[n]).charAt(0)===l&&(r=r.substr(1)),d.push(r.split(l));return setTimeout(function(){o._loadKeyPathImpl(s,c,a,d).done(function(){s.resolve()})},0),s.promise()},_loadKeyPathImpl:function(e,o,t,n){var i,r,s,a,l,d,c,u,h,f,p=this;for(c={},r=0;r<n.length;r++)for(h=n[r],u=t;h.length;){if(s=h.shift(),!(a=function(e,t){var n,i,r=e.children;if(r)for(n=0,i=r.length;n<i;n++)if(o.matchKey(r[n],t))return r[n];return null}(u,s))){this.warn("loadKeyPath: key not found: "+s+" (parent: "+u+")"),o.callback(this,s,"error");break}if(0===h.length){o.callback(this,a,"ok");break}if(a.lazy&&void 0===a.hasChildren()){o.callback(this,a,"loaded"),c[s=a.key]?c[s].pathSegList.push(h):c[s]={parent:a,pathSegList:[h]};break}o.callback(this,a,"loaded"),u=a}for(l in i=[],c)C(c,l)&&(d=c[l],f=new k.Deferred,i.push(f),function(t,n,e){o.callback(p,n,"loading"),n.load().done(function(){p._loadKeyPathImpl.call(p,t,o,n,e).always(A(t,p))}).fail(function(e){p.warn("loadKeyPath: error loading lazy "+n),o.callback(p,a,"error"),t.rejectWith(p)})}(f,d.parent,d.pathSegList));return k.when.apply(k,i).promise()},reactivate:function(e){var t,n=this.activeNode;return n?(this.activeNode=null,t=n.setActive(!0,{noFocus:!0}),e&&n.setFocus(),t):T()},reload:function(e){return this._callHook("treeClear",this),this._callHook("treeLoad",this,e)},render:function(e,t){return this.rootNode.render(e,t)},selectAll:function(t){this.visit(function(e){e.setSelected(t)})},setFocus:function(e){return this._callHook("treeSetFocus",this,e)},setOption:function(e,t){return this.widget.option(e,t)},debugTime:function(e){4<=this.options.debugLevel&&window.console.time(this+" - "+e)},debugTimeEnd:function(e){4<=this.options.debugLevel&&window.console.timeEnd(this+" - "+e)},toDict:function(e,t){t=this.rootNode.toDict(!0,t);return e?t:t.children},toString:function(){return"Fancytree@"+this._id},_triggerNodeEvent:function(e,t,n,i){i=this._makeHookContext(t,n,i),n=this.widget._trigger(e,n,i);return!1!==n&&void 0!==i.result?i.result:n},_triggerTreeEvent:function(e,t,n){n=this._makeHookContext(this,t,n),t=this.widget._trigger(e,t,n);return!1!==t&&void 0!==n.result?n.result:t},visit:function(e){return this.rootNode.visit(e,!1)},visitRows:function(t,e){if(!this.rootNode.hasChildren())return!1;if(e&&e.reverse)return delete e.reverse,this._visitRowsUp(t,e);for(var n,i,r,o=0,s=!1===(e=e||{}).includeSelf,a=!!e.includeHidden,l=!a&&this.enableFilter,d=e.start||this.rootNode.children[0],c=d.parent;c;){for(_(0<=(i=(r=c.children).indexOf(d)+o),"Could not find "+d+" in parent's children: "+c),n=i;n<r.length;n++)if(d=r[n],!l||d.match||d.subMatchCount){if(!s&&!1===t(d))return!1;if(s=!1,d.children&&d.children.length&&(a||d.expanded)&&!1===d.visit(function(e){return!l||e.match||e.subMatchCount?!1!==t(e)&&(a||!e.children||e.expanded?void 0:"skip"):"skip"},!1))return!1}c=(d=c).parent,o=1}return!0},_visitRowsUp:function(e,t){for(var n,i,r,o=!!t.includeHidden,s=t.start||this.rootNode.children[0];;){if((n=(r=s.parent).children)[0]===s){if(!(s=r).parent)break;n=r.children}else for(i=n.indexOf(s),s=n[i-1];(o||s.expanded)&&s.children&&s.children.length;)s=(n=(r=s).children)[n.length-1];if((o||s.isVisible())&&!1===e(s))return!1}},warn:function(e){2<=this.options.debugLevel&&(Array.prototype.unshift.call(arguments,this.toString()),d("warn",arguments))}},k.extend(F.prototype,{nodeClick:function(e){var t,n,i=e.targetType,r=e.node;if("expander"===i)r.isLoading()?r.debug("Got 2nd click while loading: ignored"):this._callHook("nodeToggleExpanded",e);else if("checkbox"===i)this._callHook("nodeToggleSelected",e),e.options.focusOnSelect&&this._callHook("nodeSetFocus",e,!0);else{if(t=!(n=!1),r.folder)switch(e.options.clickFolderMode){case 2:t=!(n=!0);break;case 3:n=t=!0}t&&(this.nodeSetFocus(e),this._callHook("nodeSetActive",e,!0)),n&&this._callHook("nodeToggleExpanded",e)}},nodeCollapseSiblings:function(e,t){var n,i,r,o=e.node;if(o.parent)for(i=0,r=(n=o.parent.children).length;i<r;i++)n[i]!==o&&n[i].expanded&&this._callHook("nodeSetExpanded",n[i],!1,t)},nodeDblclick:function(e){"title"===e.targetType&&4===e.options.clickFolderMode&&this._callHook("nodeToggleExpanded",e),"title"===e.targetType&&e.originalEvent.preventDefault()},nodeKeydown:function(e){var t=e.originalEvent,n=e.node,i=e.tree,r=e.options,o=t.which,s=t.key||String.fromCharCode(o),a=!!(t.altKey||t.ctrlKey||t.metaKey),l=!g[o]&&!u[o]&&!a,o=k(t.target),d=!0,c=!(t.ctrlKey||!r.autoActivate);if(n||(a=this.getActiveNode()||this.getFirstChild())&&(a.setFocus(),(n=e.node=this.focusNode).debug("Keydown force focus on active node")),r.quicksearch&&l&&!o.is(":input:enabled"))return 500<(o=Date.now())-i.lastQuicksearchTime&&(i.lastQuicksearchTerm=""),i.lastQuicksearchTime=o,i.lastQuicksearchTerm+=s,(s=i.findNextNode(i.lastQuicksearchTerm,i.getActiveNode()))&&s.setActive(),void t.preventDefault();switch(h.eventToString(t)){case"+":case"=":i.nodeSetExpanded(e,!0);break;case"-":i.nodeSetExpanded(e,!1);break;case"space":n.isPagingNode()?i._triggerNodeEvent("clickPaging",e,t):h.evalOption("checkbox",n,n,r,!1)?i.nodeToggleSelected(e):i.nodeSetActive(e,!0);break;case"return":i.nodeSetActive(e,!0);break;case"home":case"end":case"backspace":case"left":case"right":case"up":case"down":n.navigate(t.which,c);break;default:d=!1}d&&t.preventDefault()},nodeLoadChildren:function(o,s){var t,n,a,e=null,i=!0,l=o.tree,d=o.node,c=d.parent,r="nodeLoadChildren",u=Date.now();return w(s)&&_(!w(s=s.call(l,{type:"source"},o)),"source callback must not return another function"),w(s.then)?e=s:s.url?e=(t=k.extend({},o.options.ajax,s)).debugDelay?(n=t.debugDelay,delete t.debugDelay,N(n)&&(n=n[0]+Math.random()*(n[1]-n[0])),d.warn("nodeLoadChildren waiting debugDelay "+Math.round(n)+" ms ..."),k.Deferred(function(e){setTimeout(function(){k.ajax(t).done(function(){e.resolveWith(this,arguments)}).fail(function(){e.rejectWith(this,arguments)})},n)})):k.ajax(t):k.isPlainObject(s)||N(s)?i=!(e={then:function(e,t){e(s,null,null)}}):k.error("Invalid source type: "+s),d._requestId&&(d.warn("Recursive load request #"+u+" while #"+d._requestId+" is pending."),d._requestId=u),i&&(l.debugTime(r),l.nodeSetStatus(o,"loading")),a=new k.Deferred,e.then(function(e,t,n){var i,r;if("json"!==s.dataType&&"jsonp"!==s.dataType||"string"!=typeof e||k.error("Ajax request returned a string (did you get the JSON dataType wrong?)."),d._requestId&&d._requestId>u)a.rejectWith(this,[f]);else if(null!==d.parent||null===c){if(o.options.postProcess){try{(r=l._triggerNodeEvent("postProcess",o,o.originalEvent,{response:e,error:null,dataType:s.dataType})).error&&l.warn("postProcess returned error:",r)}catch(e){r={error:e,message:""+e,details:"postProcess failed"}}if(r.error)return i=k.isPlainObject(r.error)?r.error:{message:r.error},i=l._makeHookContext(d,null,i),void a.rejectWith(this,[i]);(N(r)||k.isPlainObject(r)&&N(r.children))&&(e=r)}else e&&C(e,"d")&&o.options.enableAspx&&(42===o.options.enableAspx&&l.warn("The default for enableAspx will change to `false` in the fututure. Pass `enableAspx: true` or implement postProcess to silence this warning."),e="string"==typeof e.d?k.parseJSON(e.d):e.d);a.resolveWith(this,[e])}else a.rejectWith(this,[p])},function(e,t,n){n=l._makeHookContext(d,null,{error:e,args:Array.prototype.slice.call(arguments),message:n,details:e.status+": "+n});a.rejectWith(this,[n])}),a.done(function(e){var t,n,i;l.nodeSetStatus(o,"ok"),k.isPlainObject(e)?(_(d.isRootNode(),"source may only be an object for root nodes (expecting an array of child objects otherwise)"),_(N(e.children),"if an object is passed as source, it must contain a 'children' array (all other properties are added to 'tree.data')"),t=(n=e).children,delete n.children,k.each(b,function(e,t){void 0!==n[t]&&(l[t]=n[t],delete n[t])}),k.extend(l.data,n)):t=e,_(N(t),"expected array of children"),d._setChildren(t),l.options.nodata&&0===t.length&&(w(l.options.nodata)?i=l.options.nodata.call(l,{type:"nodata"},o):!0===l.options.nodata&&d.isRootNode()?i=l.options.strings.noData:"string"==typeof l.options.nodata&&d.isRootNode()&&(i=l.options.nodata),i&&d.setStatus("nodata",i)),l._triggerNodeEvent("loadChildren",d)}).fail(function(e){var t;e!==f?e!==p?(e.node&&e.error&&e.message?t=e:"[object Object]"===(t=l._makeHookContext(d,null,{error:e,args:Array.prototype.slice.call(arguments),message:e?e.message||e.toString():""})).message&&(t.message=""),d.warn("Load children failed ("+t.message+")",t),!1!==l._triggerNodeEvent("loadError",t,null)&&l.nodeSetStatus(o,"error",t.message,t.details)):d.warn("Lazy parent node was removed while loading: discarding response."):d.warn("Ignored response for obsolete load request #"+u+" (expected #"+d._requestId+")")}).always(function(){d._requestId=null,i&&l.debugTimeEnd(r)}),a.promise()},nodeLoadKeyPath:function(e,t){},nodeRemoveChild:function(e,t){var n=e.node,i=k.extend({},e,{node:t}),r=n.children;if(1===r.length)return _(t===r[0],"invalid single child"),this.nodeRemoveChildren(e);this.activeNode&&(t===this.activeNode||this.activeNode.isDescendantOf(t))&&this.activeNode.setActive(!1),this.focusNode&&(t===this.focusNode||this.focusNode.isDescendantOf(t))&&(this.focusNode=null),this.nodeRemoveMarkup(i),this.nodeRemoveChildren(i),_(0<=(i=k.inArray(t,r)),"invalid child"),n.triggerModifyChild("remove",t),t.visit(function(e){e.parent=null},!0),this._callHook("treeRegisterNode",this,!1,t),r.splice(i,1)},nodeRemoveChildMarkup:function(e){e=e.node;e.ul&&(e.isRootNode()?k(e.ul).empty():(k(e.ul).remove(),e.ul=null),e.visit(function(e){e.li=e.ul=null}))},nodeRemoveChildren:function(e){var t=e.tree,n=e.node;n.children&&(this.activeNode&&this.activeNode.isDescendantOf(n)&&this.activeNode.setActive(!1),this.focusNode&&this.focusNode.isDescendantOf(n)&&(this.focusNode=null),this.nodeRemoveChildMarkup(e),n.triggerModifyChild("remove",null),n.visit(function(e){e.parent=null,t._callHook("treeRegisterNode",t,!1,e)}),n.lazy?n.children=[]:n.children=null,n.isRootNode()||(n.expanded=!1),this.nodeRenderStatus(e))},nodeRemoveMarkup:function(e){var t=e.node;t.li&&(k(t.li).remove(),t.li=null),this.nodeRemoveChildMarkup(e)},nodeRender:function(e,t,n,i,r){var o,s,a,l,d,c,u,h=e.node,f=e.tree,p=e.options,g=p.aria,v=!1,y=h.parent,b=!y,m=h.children,x=null;if(!1!==f._enableUpdate&&(b||y.ul)){if(_(b||y.ul,"parent UL must exist"),b||(h.li&&(t||h.li.parentNode!==h.parent.ul)&&(h.li.parentNode===h.parent.ul?x=h.li.nextSibling:this.debug("Unlinking "+h+" (must be child of "+h.parent+")"),this.nodeRemoveMarkup(e)),h.li?this.nodeRenderStatus(e):(v=!0,h.li=document.createElement("li"),(h.li.ftnode=h).key&&p.generateIds&&(h.li.id=p.idPrefix+h.key),h.span=document.createElement("span"),h.span.className="fancytree-node",g&&!h.tr&&k(h.li).attr("role","treeitem"),h.li.appendChild(h.span),this.nodeRenderTitle(e),p.createNode&&p.createNode.call(f,{type:"createNode"},e)),p.renderNode&&p.renderNode.call(f,{type:"renderNode"},e)),m){if(b||h.expanded||!0===n){for(h.ul||(h.ul=document.createElement("ul"),(!0!==i||r)&&h.expanded||(h.ul.style.display="none"),g&&k(h.ul).attr("role","group"),h.li?h.li.appendChild(h.ul):h.tree.$div.append(h.ul)),l=0,d=m.length;l<d;l++)u=k.extend({},e,{node:m[l]}),this.nodeRender(u,t,n,!1,!0);for(o=h.ul.firstChild;o;)o=(a=o.ftnode)&&a.parent!==h?(h.debug("_fixParent: remove missing "+a,o),c=o.nextSibling,o.parentNode.removeChild(o),c):o.nextSibling;for(o=h.ul.firstChild,l=0,d=m.length-1;l<d;l++)(s=m[l])===(a=o.ftnode)?o=o.nextSibling:h.ul.insertBefore(s.li,a.li)}}else h.ul&&(this.warn("remove child markup for "+h),this.nodeRemoveChildMarkup(e));b||v&&y.ul.insertBefore(h.li,x)}},nodeRenderTitle:function(e,t){var n,i,r=e.node,o=e.tree,s=e.options,a=s.aria,l=r.getLevel(),d=[];void 0!==t&&(r.title=t),r.span&&!1!==o._enableUpdate&&(t=a&&!1!==r.hasChildren()?" role='button'":"",l<s.minExpandLevel?(r.lazy||(r.expanded=!0),1<l&&d.push("<span "+t+" class='fancytree-expander fancytree-expander-fixed'></span>")):d.push("<span "+t+" class='fancytree-expander'></span>"),(l=h.evalOption("checkbox",r,r,s,!1))&&!r.isStatusNode()&&(n="fancytree-checkbox",("radio"===l||r.parent&&r.parent.radiogroup)&&(n+=" fancytree-radio"),d.push("<span "+(t=a?" role='checkbox'":"")+" class='"+n+"'></span>")),void 0!==r.data.iconClass&&(r.icon?k.error("'iconClass' node option is deprecated since v2.14.0: use 'icon' only instead"):(r.warn("'iconClass' node option is deprecated since v2.14.0: use 'icon' instead"),r.icon=r.data.iconClass)),!1!==(n=h.evalOption("icon",r,r,s,!0))&&(t=a?" role='presentation'":"",i=(i=h.evalOption("iconTooltip",r,r,s,null))?" title='"+P(i)+"'":"","string"==typeof n?c.test(n)?(n="/"===n.charAt(0)?n:(s.imagePath||"")+n,d.push("<img src='"+n+"' class='fancytree-icon'"+i+" alt='' />")):d.push("<span "+t+" class='fancytree-custom-icon "+n+"'"+i+"></span>"):n.text?d.push("<span "+t+" class='fancytree-custom-icon "+(n.addClass||"")+"'"+i+">"+h.escapeHtml(n.text)+"</span>"):n.html?d.push("<span "+t+" class='fancytree-custom-icon "+(n.addClass||"")+"'"+i+">"+n.html+"</span>"):d.push("<span "+t+" class='fancytree-icon'"+i+"></span>")),t="",t=(t=s.renderTitle?s.renderTitle.call(o,{type:"renderTitle"},e)||"":t)||"<span class='fancytree-title'"+(i=(i=!0===(i=h.evalOption("tooltip",r,r,s,null))?r.title:i)?" title='"+P(i)+"'":"")+(s.titlesTabbable?" tabindex='0'":"")+">"+(s.escapeTitles?h.escapeHtml(r.title):r.title)+"</span>",d.push(t),r.span.innerHTML=d.join(""),this.nodeRenderStatus(e),s.enhanceTitle&&(e.$title=k(">span.fancytree-title",r.span),t=s.enhanceTitle.call(o,{type:"enhanceTitle"},e)||""))},nodeRenderStatus:function(e){var t,n=e.node,i=e.tree,r=e.options,o=n.hasChildren(),s=n.isLastSibling(),a=r.aria,l=r._classNames,d=[],e=n[i.statusClassPropName];e&&!1!==i._enableUpdate&&(a&&(t=k(n.tr||n.li)),d.push(l.node),i.activeNode===n&&d.push(l.active),i.focusNode===n&&d.push(l.focused),n.expanded&&d.push(l.expanded),a&&(!1===o?t.removeAttr("aria-expanded"):t.attr("aria-expanded",Boolean(n.expanded))),n.folder&&d.push(l.folder),!1!==o&&d.push(l.hasChildren),s&&d.push(l.lastsib),n.lazy&&null==n.children&&d.push(l.lazy),n.partload&&d.push(l.partload),n.partsel&&d.push(l.partsel),h.evalOption("unselectable",n,n,r,!1)&&d.push(l.unselectable),n._isLoading&&d.push(l.loading),n._error&&d.push(l.error),n.statusNodeType&&d.push(l.statusNodePrefix+n.statusNodeType),n.selected?(d.push(l.selected),a&&t.attr("aria-selected",!0)):a&&t.attr("aria-selected",!1),n.extraClasses&&d.push(n.extraClasses),!1===o?d.push(l.combinedExpanderPrefix+"n"+(s?"l":"")):d.push(l.combinedExpanderPrefix+(n.expanded?"e":"c")+(n.lazy&&null==n.children?"d":"")+(s?"l":"")),d.push(l.combinedIconPrefix+(n.expanded?"e":"c")+(n.folder?"f":"")),e.className=d.join(" "),n.li&&k(n.li).toggleClass(l.lastsib,s))},nodeSetActive:function(e,t,n){var i=e.node,r=e.tree,o=e.options,s=!0===(n=n||{}).noEvents,a=!0===n.noFocus,n=!1!==n.scrollIntoView;return i===r.activeNode===(t=!1!==t)?T(i):(n&&e.originalEvent&&k(e.originalEvent.target).is("a,:checkbox")&&(i.info("Not scrolling while clicking an embedded link."),n=!1),t&&!s&&!1===this._triggerNodeEvent("beforeActivate",i,e.originalEvent)?L(i,["rejected"]):(t?(r.activeNode&&(_(r.activeNode!==i,"node was active (inconsistency)"),t=k.extend({},e,{node:r.activeNode}),r.nodeSetActive(t,!1),_(null===r.activeNode,"deactivate was out of sync?")),o.activeVisible&&i.makeVisible({scrollIntoView:n}),r.activeNode=i,r.nodeRenderStatus(e),a||r.nodeSetFocus(e),s||r._triggerNodeEvent("activate",i,e.originalEvent)):(_(r.activeNode===i,"node was not active (inconsistency)"),r.activeNode=null,this.nodeRenderStatus(e),s||e.tree._triggerNodeEvent("deactivate",i,e.originalEvent)),T(i)))},nodeSetExpanded:function(i,r,e){var t,n,o,s,a,l,d=i.node,c=i.tree,u=i.options,h=!0===(e=e||{}).noAnimation,f=!0===e.noEvents;if(r=!1!==r,k(d.li).hasClass(u._classNames.animating))return d.warn("setExpanded("+r+") while animating: ignored."),L(d,["recursion"]);if(d.expanded&&r||!d.expanded&&!r)return T(d);if(r&&!d.lazy&&!d.hasChildren())return T(d);if(!r&&d.getLevel()<u.minExpandLevel)return L(d,["locked"]);if(!f&&!1===this._triggerNodeEvent("beforeExpand",d,i.originalEvent))return L(d,["rejected"]);if(h||d.isVisible()||(h=e.noAnimation=!0),n=new k.Deferred,r&&!d.expanded&&u.autoCollapse){a=d.getParentList(!1,!0),l=u.autoCollapse;try{for(u.autoCollapse=!1,o=0,s=a.length;o<s;o++)this._callHook("nodeCollapseSiblings",a[o],e)}finally{u.autoCollapse=l}}return n.done(function(){var e=d.getLastChild();r&&u.autoScroll&&!h&&e&&c._enableUpdate?e.scrollIntoView(!0,{topNode:d}).always(function(){f||i.tree._triggerNodeEvent(r?"expand":"collapse",i)}):f||i.tree._triggerNodeEvent(r?"expand":"collapse",i)}),t=function(e){var t=u._classNames,n=u.toggleEffect;if(d.expanded=r,c._callHook("treeStructureChanged",i,r?"expand":"collapse"),c._callHook("nodeRender",i,!1,!1,!0),d.ul)if("none"!==d.ul.style.display==!!d.expanded)d.warn("nodeSetExpanded: UL.style.display already set");else{if(n&&!h)return k(d.li).addClass(t.animating),void(w(k(d.ul)[n.effect])?k(d.ul)[n.effect]({duration:n.duration,always:function(){k(this).removeClass(t.animating),k(d.li).removeClass(t.animating),e()}}):(k(d.ul).stop(!0,!0),k(d.ul).parent().find(".ui-effects-placeholder").remove(),k(d.ul).toggle(n.effect,n.options,n.duration,function(){k(this).removeClass(t.animating),k(d.li).removeClass(t.animating),e()})));d.ul.style.display=d.expanded||!parent?"":"none"}e()},r&&d.lazy&&void 0===d.hasChildren()?d.load().done(function(){n.notifyWith&&n.notifyWith(d,["loaded"]),t(function(){n.resolveWith(d)})}).fail(function(e){t(function(){n.rejectWith(d,["load failed ("+e+")"])})}):t(function(){n.resolveWith(d)}),n.promise()},nodeSetFocus:function(e,t){var n,i=e.tree,r=e.node,o=i.options,s=!!e.originalEvent&&k(e.originalEvent.target).is(":input");if(t=!1!==t,i.focusNode){if(i.focusNode===r&&t)return;n=k.extend({},e,{node:i.focusNode}),i.focusNode=null,this._triggerNodeEvent("blur",n),this._callHook("nodeRenderStatus",n)}t&&(this.hasFocus()||(r.debug("nodeSetFocus: forcing container focus"),this._callHook("treeSetFocus",e,!0,{calledByNode:!0})),r.makeVisible({scrollIntoView:!1}),i.focusNode=r,o.titlesTabbable&&(s||k(r.span).find(".fancytree-title").focus()),o.aria&&k(i.$container).attr("aria-activedescendant",k(r.tr||r.li).uniqueId().attr("id")),this._triggerNodeEvent("focus",e),document.activeElement===i.$container.get(0)||1<=k(document.activeElement,i.$container).length||k(i.$container).focus(),o.autoScroll&&r.scrollIntoView(),this._callHook("nodeRenderStatus",e))},nodeSetSelected:function(e,t,n){var i=e.node,r=e.tree,o=e.options,s=!0===(n=n||{}).noEvents,a=i.parent;if(t=!1!==t,!h.evalOption("unselectable",i,i,o,!1))return i._lastSelectIntent=t,!!i.selected!==t||3===o.selectMode&&i.partsel&&!t?s||!1!==this._triggerNodeEvent("beforeSelect",i,e.originalEvent)?(t&&1===o.selectMode?(r.lastSelectedNode&&r.lastSelectedNode.setSelected(!1),i.selected=t):3!==o.selectMode||!a||a.radiogroup||i.radiogroup?a&&a.radiogroup?i.visitSiblings(function(e){e._changeSelectStatusAttrs(t&&e===i)},!0):i.selected=t:(i.selected=t,i.fixSelection3AfterClick(n)),this.nodeRenderStatus(e),r.lastSelectedNode=t?i:null,void(s||r._triggerNodeEvent("select",e))):!!i.selected:t},nodeSetStatus:function(i,e,t,n){var r=i.node,o=i.tree;function s(e,t){var n=r.children?r.children[0]:null;return n&&n.isStatusNode()?(k.extend(n,e),n.statusNodeType=t,o._callHook("nodeRenderTitle",n)):(r._setChildren([e]),o._callHook("treeStructureChanged",i,"setStatusNode"),r.children[0].statusNodeType=t,o.render()),r.children[0]}switch(e){case"ok":!function(){var e=r.children?r.children[0]:null;if(e&&e.isStatusNode()){try{r.ul&&(r.ul.removeChild(e.li),e.li=null)}catch(e){}1===r.children.length?r.children=[]:r.children.shift(),o._callHook("treeStructureChanged",i,"clearStatusNode")}}(),r._isLoading=!1,r._error=null,r.renderStatus();break;case"loading":r.parent||s({title:o.options.strings.loading+(t?" ("+t+")":""),checkbox:!1,tooltip:n},e),r._isLoading=!0,r._error=null,r.renderStatus();break;case"error":s({title:o.options.strings.loadError+(t?" ("+t+")":""),checkbox:!1,tooltip:n},e),r._isLoading=!1,r._error={message:t,details:n},r.renderStatus();break;case"nodata":s({title:t||o.options.strings.noData,checkbox:!1,tooltip:n},e),r._isLoading=!1,r._error=null,r.renderStatus();break;default:k.error("invalid node status "+e)}},nodeToggleExpanded:function(e){return this.nodeSetExpanded(e,!e.node.expanded)},nodeToggleSelected:function(e){var t=e.node,n=!t.selected;return t.partsel&&!t.selected&&!0===t._lastSelectIntent&&(t.selected=!(n=!1)),t._lastSelectIntent=n,this.nodeSetSelected(e,n)},treeClear:function(e){var t=e.tree;t.activeNode=null,t.focusNode=null,t.$div.find(">ul.fancytree-container").empty(),t.rootNode.children=null,t._callHook("treeStructureChanged",e,"clear")},treeCreate:function(e){},treeDestroy:function(e){this.$div.find(">ul.fancytree-container").remove(),this.$source&&this.$source.removeClass("fancytree-helper-hidden")},treeInit:function(e){var n=e.tree,i=n.options;n.$container.attr("tabindex",i.tabindex),k.each(b,function(e,t){void 0!==i[t]&&(n.info("Move option "+t+" to tree"),n[t]=i[t],delete i[t])}),i.checkboxAutoHide&&n.$container.addClass("fancytree-checkbox-auto-hide"),i.rtl?n.$container.attr("DIR","RTL").addClass("fancytree-rtl"):n.$container.removeAttr("DIR").removeClass("fancytree-rtl"),i.aria&&(n.$container.attr("role","tree"),1!==i.selectMode&&n.$container.attr("aria-multiselectable",!0)),this.treeLoad(e)},treeLoad:function(e,t){var n,i,r,o=e.tree,s=e.widget.element,a=k.extend({},e,{node:this.rootNode});if(o.rootNode.children&&this.treeClear(e),t=t||this.options.source)"string"==typeof t&&k.error("Not implemented");else switch(i=s.data("type")||"html"){case"html":(r=s.find(">ul").not(".fancytree-container").first()).length?(r.addClass("ui-fancytree-source fancytree-helper-hidden"),t=k.ui.fancytree.parseHtml(r),this.data=k.extend(this.data,H(r))):(h.warn("No `source` option was passed and container does not contain `<ul>`: assuming `source: []`."),t=[]);break;case"json":t=k.parseJSON(s.text()),s.contents().filter(function(){return 3===this.nodeType}).remove(),k.isPlainObject(t)&&(_(N(t.children),"if an object is passed as source, it must contain a 'children' array (all other properties are added to 'tree.data')"),t=(n=t).children,delete n.children,k.each(b,function(e,t){void 0!==n[t]&&(o[t]=n[t],delete n[t])}),k.extend(o.data,n));break;default:k.error("Invalid data-type: "+i)}return o._triggerTreeEvent("preInit",null),this.nodeLoadChildren(a,t).done(function(){o._callHook("treeStructureChanged",e,"loadChildren"),o.render(),3===e.options.selectMode&&o.rootNode.fixSelection3FromEndNodes(),o.activeNode&&o.options.activeVisible&&o.activeNode.makeVisible(),o._triggerTreeEvent("init",null,{status:!0})}).fail(function(){o.render(),o._triggerTreeEvent("init",null,{status:!1})})},treeRegisterNode:function(e,t,n){e.tree._callHook("treeStructureChanged",e,t?"addNode":"removeNode")},treeSetFocus:function(e,t,n){var i;(t=!1!==t)!==this.hasFocus()&&(!(this._hasFocus=t)&&this.focusNode?this.focusNode.setFocus(!1):!t||n&&n.calledByNode||k(this.$container).focus(),this.$container.toggleClass("fancytree-treefocus",t),this._triggerTreeEvent(t?"focusTree":"blurTree"),t&&!this.activeNode&&(i=this._lastMousedownNode||this.getFirstChild())&&i.setFocus())},treeSetOption:function(e,t,n){var i=e.tree,r=!0,o=!1,s=!1;switch(t){case"aria":case"checkbox":case"icon":case"minExpandLevel":case"tabindex":s=o=!0;break;case"checkboxAutoHide":i.$container.toggleClass("fancytree-checkbox-auto-hide",!!n);break;case"escapeTitles":case"tooltip":s=!0;break;case"rtl":!1===n?i.$container.removeAttr("DIR").removeClass("fancytree-rtl"):i.$container.attr("DIR","RTL").addClass("fancytree-rtl"),s=!0;break;case"source":r=!1,i._callHook("treeLoad",i,n),s=!0}i.debug("set option "+t+"="+n+" <"+typeof n+">"),r&&(this.widget._super||k.Widget.prototype._setOption).call(this.widget,t,n),o&&i._callHook("treeCreate",i),s&&i.render(!0,!1)},treeStructureChanged:function(e,t){}}),k.widget("ui.fancytree",{options:{activeVisible:!0,ajax:{type:"GET",cache:!1,dataType:"json"},aria:!0,autoActivate:!0,autoCollapse:!1,autoScroll:!1,checkbox:!1,clickFolderMode:4,copyFunctionsToData:!1,debugLevel:null,disabled:!1,enableAspx:42,escapeTitles:!1,extensions:[],focusOnSelect:!1,generateIds:!1,icon:!0,idPrefix:"ft_",keyboard:!0,keyPathSeparator:"/",minExpandLevel:1,nodata:!0,quicksearch:!1,rtl:!1,scrollOfs:{top:0,bottom:0},scrollParent:null,selectMode:2,strings:{loading:"Loading...",loadError:"Load error!",moreData:"More...",noData:"No data."},tabindex:"0",titlesTabbable:!1,toggleEffect:{effect:"slideToggle",duration:200},tooltip:!1,treeId:null,_classNames:{active:"fancytree-active",animating:"fancytree-animating",combinedExpanderPrefix:"fancytree-exp-",combinedIconPrefix:"fancytree-ico-",error:"fancytree-error",expanded:"fancytree-expanded",focused:"fancytree-focused",folder:"fancytree-folder",hasChildren:"fancytree-has-children",lastsib:"fancytree-lastsib",lazy:"fancytree-lazy",loading:"fancytree-loading",node:"fancytree-node",partload:"fancytree-partload",partsel:"fancytree-partsel",radio:"fancytree-radio",selected:"fancytree-selected",statusNodePrefix:"fancytree-statusnode-",unselectable:"fancytree-unselectable"},lazyLoad:null,postProcess:null},_deprecationWarning:function(e){var t=this.tree;t&&3<=t.options.debugLevel&&t.warn("$().fancytree('"+e+"') is deprecated (see https://wwwendt.de/tech/fancytree/doc/jsdoc/Fancytree_Widget.html")},_create:function(){this.tree=new F(this),this.$source=this.source||"json"===this.element.data("type")?this.element:this.element.find(">ul").first();for(var e,t,n=this.options,i=n.extensions,r=(this.tree,0);r<i.length;r++)t=i[r],(e=k.ui.fancytree._extensions[t])||k.error("Could not apply extension '"+t+"' (it is not registered, did you forget to include it?)"),this.tree.options[t]=function e(t){var n,i,r,o,s=t||{},a=1,l=arguments.length;if("object"==typeof s||w(s)||(s={}),a===l)throw Error("need at least two args");for(;a<l;a++)if(null!=(n=arguments[a]))for(i in n)C(n,i)&&(o=s[i],s!==(r=n[i])&&(r&&k.isPlainObject(r)?(o=o&&k.isPlainObject(o)?o:{},s[i]=e(o,r)):void 0!==r&&(s[i]=r)));return s}({},e.options,this.tree.options[t]),_(void 0===this.tree.ext[t],"Extension name must not exist as Fancytree.ext attribute: '"+t+"'"),this.tree.ext[t]={},function(e,t,n){for(var i in t)"function"==typeof t[i]?"function"==typeof e[i]?e[i]=E(i,e,0,t,n):"_"===i.charAt(0)?e.ext[n][i]=E(i,e,0,t,n):k.error("Could not override tree."+i+". Use prefix '_' to create tree."+n+"._"+i):"options"!==i&&(e.ext[n][i]=t[i])}(this.tree,e,t),0;void 0!==n.icons&&(!0===n.icon?(this.tree.warn("'icons' tree option is deprecated since v2.14.0: use 'icon' instead"),n.icon=n.icons):k.error("'icons' tree option is deprecated since v2.14.0: use 'icon' only instead")),void 0!==n.iconClass&&(n.icon?k.error("'iconClass' tree option is deprecated since v2.14.0: use 'icon' only instead"):(this.tree.warn("'iconClass' tree option is deprecated since v2.14.0: use 'icon' instead"),n.icon=n.iconClass)),void 0!==n.tabbable&&(n.tabindex=n.tabbable?"0":"-1",this.tree.warn("'tabbable' tree option is deprecated since v2.17.0: use 'tabindex='"+n.tabindex+"' instead")),this.tree._callHook("treeCreate",this.tree)},_init:function(){this.tree._callHook("treeInit",this.tree),this._bind()},_setOption:function(e,t){return this.tree._callHook("treeSetOption",this.tree,e,t)},_destroy:function(){this._unbind(),this.tree._callHook("treeDestroy",this.tree)},_unbind:function(){var e=this.tree._ns;this.element.off(e),this.tree.$container.off(e),k(document).off(e)},_bind:function(){var s=this,a=this.options,o=this.tree,e=o._ns;this._unbind(),o.$container.on("focusin"+e+" focusout"+e,function(e){var t=h.getNode(e),n="focusin"===e.type;if(!n&&t&&k(e.target).is("a"))t.debug("Ignored focusout on embedded <a> element.");else{if(n){if(o._getExpiringValue("focusin"))return void o.debug("Ignored double focusin.");o._setExpiringValue("focusin",!0,50),t||(t=o._getExpiringValue("mouseDownNode"))&&o.debug("Reconstruct mouse target for focusin from recent event.")}t?o._callHook("nodeSetFocus",o._makeHookContext(t,e),n):o.tbody&&k(e.target).parents("table.fancytree-container > thead").length?o.debug("Ignore focus event outside table body.",e):o._callHook("treeSetFocus",o,n)}}).on("selectstart"+e,"span.fancytree-title",function(e){e.preventDefault()}).on("keydown"+e,function(e){if(a.disabled||!1===a.keyboard)return!0;var t,n=o.focusNode,i=o._makeHookContext(n||o,e),r=o.phase;try{return o.phase="userEvent","preventNav"===(t=n?o._triggerNodeEvent("keydown",n,e):o._triggerTreeEvent("keydown",e))?t=!0:!1!==t&&(t=o._callHook("nodeKeydown",i)),t}finally{o.phase=r}}).on("mousedown"+e,function(e){e=h.getEventTarget(e);o._lastMousedownNode=e?e.node:null,o._setExpiringValue("mouseDownNode",o._lastMousedownNode)}).on("click"+e+" dblclick"+e,function(e){if(a.disabled)return!0;var t,n=h.getEventTarget(e),i=n.node,r=s.tree,o=r.phase;if(!i)return!0;t=r._makeHookContext(i,e);try{switch(r.phase="userEvent",e.type){case"click":return t.targetType=n.type,i.isPagingNode()?!0===r._triggerNodeEvent("clickPaging",t,e):!1!==r._triggerNodeEvent("click",t,e)&&r._callHook("nodeClick",t);case"dblclick":return t.targetType=n.type,!1!==r._triggerNodeEvent("dblclick",t,e)&&r._callHook("nodeDblclick",t)}}finally{r.phase=o}})},getActiveNode:function(){return this._deprecationWarning("getActiveNode"),this.tree.activeNode},getNodeByKey:function(e){return this._deprecationWarning("getNodeByKey"),this.tree.getNodeByKey(e)},getRootNode:function(){return this._deprecationWarning("getRootNode"),this.tree.rootNode},getTree:function(){return this._deprecationWarning("getTree"),this.tree}}),h=k.ui.fancytree,k.extend(k.ui.fancytree,{version:"2.38.3",buildType: "production",debugLevel: 3,_nextId:1,_nextNodeKey:1,_extensions:{},_FancytreeClass:F,_FancytreeNodeClass:I,jquerySupports:{positionMyOfs:function(e){for(var t,n,i=k.map(S(e).split("."),function(e){return parseInt(e,10)}),r=k.map(Array.prototype.slice.call(arguments,1),function(e){return parseInt(e,10)}),o=0;o<r.length;o++)if((t=i[o]||0)!==(n=r[o]||0))return n<t;return!0}(k.ui.version,1,9)},assert:_,createTree:function(e,t){t=k(e).fancytree(t);return h.getTree(t)},debounce:function(t,n,i,r){var o;return 3===arguments.length&&"boolean"!=typeof i&&(r=i,i=!1),function(){var e=arguments;r=r||this,i&&!o&&n.apply(r,e),clearTimeout(o),o=setTimeout(function(){i||n.apply(r,e),o=null},t)}},debug:function(e){4<=k.ui.fancytree.debugLevel&&d("log",arguments)},error:function(e){1<=k.ui.fancytree.debugLevel&&d("error",arguments)},escapeHtml:function(e){return(""+e).replace(t,function(e){return i[e]})},fixPositionOptions:function(e){var t,n,i,r;return(e.offset||0<=(""+e.my+e.at).indexOf("%"))&&k.error("expected new position syntax (but '%' is not supported)"),k.ui.fancytree.jquerySupports.positionMyOfs||(t=/(\w+)([+-]?\d+)?\s+(\w+)([+-]?\d+)?/.exec(e.my),n=/(\w+)([+-]?\d+)?\s+(\w+)([+-]?\d+)?/.exec(e.at),i=(t[2]?+t[2]:0)+(n[2]?+n[2]:0),r=(t[4]?+t[4]:0)+(n[4]?+n[4]:0),e=k.extend({},e,{my:t[1]+" "+t[3],at:n[1]+" "+n[3]}),(i||r)&&(e.offset=i+" "+r)),e},getEventTarget:function(e){var t=e&&e.target?e.target.className:"",n={node:this.getNode(e.target),type:void 0};return/\bfancytree-title\b/.test(t)?n.type="title":/\bfancytree-expander\b/.test(t)?n.type=!1===n.node.hasChildren()?"prefix":"expander":/\bfancytree-checkbox\b/.test(t)?n.type="checkbox":/\bfancytree(-custom)?-icon\b/.test(t)?n.type="icon":/\bfancytree-node\b/.test(t)?n.type="title":e&&e.target&&((e=k(e.target)).is("ul[role=group]")?((n.node&&n.node.tree||h).debug("Ignoring click on outer UL."),n.node=null):e.closest(".fancytree-title").length?n.type="title":e.closest(".fancytree-checkbox").length?n.type="checkbox":e.closest(".fancytree-expander").length&&(n.type="expander")),n},getEventTargetType:function(e){return this.getEventTarget(e).type},getNode:function(e){if(e instanceof I)return e;for(e instanceof k?e=e[0]:void 0!==e.originalEvent&&(e=e.target);e;){if(e.ftnode)return e.ftnode;e=e.parentNode}return null},getTree:function(e){var t=e;return e instanceof F?e:("number"==typeof(e=void 0===e?0:e)?e=k(".fancytree-container").eq(e):"string"==typeof e?(e=k("#ft-id-"+t).eq(0)).length||(e=k(t).eq(0)):e instanceof Element||e instanceof HTMLDocument?e=k(e):e instanceof k?e=e.eq(0):void 0!==e.originalEvent&&(e=k(e.target)),(e=(e=e.closest(":ui-fancytree")).data("ui-fancytree")||e.data("fancytree"))?e.tree:null)},evalOption:function(e,t,n,i,r){var o,s=t.tree,i=i[e],n=n[e];return w(i)?(o={node:t,tree:s,widget:s.widget,options:s.widget.options,typeInfo:s.types[t.type]||{}},null==(o=i.call(s,{type:e},o))&&(o=n)):o=null==n?i:n,o=null==o?r:o},setSpanIcon:function(e,t,n){var i=k(e);"string"==typeof n?i.attr("class",t+" "+n):(n.text?i.text(""+n.text):n.html&&(e.innerHTML=n.html),i.attr("class",t+" "+(n.addClass||"")))},eventToString:function(e){var t=e.which,n=e.type,i=[];return e.altKey&&i.push("alt"),e.ctrlKey&&i.push("ctrl"),e.metaKey&&i.push("meta"),e.shiftKey&&i.push("shift"),"click"===n||"dblclick"===n?i.push(o[e.button]+n):"wheel"===n?i.push(n):r[t]||i.push(u[t]||String.fromCharCode(t).toLowerCase()),i.join("+")},info:function(e){3<=k.ui.fancytree.debugLevel&&d("info",arguments)},keyEventToString:function(e){return this.warn("keyEventToString() is deprecated: use eventToString()"),this.eventToString(e)},overrideMethod:function(e,t,n,i){var r,o=e[t]||k.noop;e[t]=function(){var e=i||this;try{return r=e._super,e._super=o,n.apply(e,arguments)}finally{e._super=r}}},parseHtml:function(s){var a,l,d,c,u,h,f,p,e=s.find(">li"),g=[];return e.each(function(){var e,t,n=k(this),i=n.find(">span",this).first(),r=i.length?null:n.find(">a").first(),o={tooltip:null,data:{}};for(i.length?o.title=i.html():r&&r.length?(o.title=r.html(),o.data.href=r.attr("href"),o.data.target=r.attr("target"),o.tooltip=r.attr("title")):(o.title=n.html(),0<=(u=o.title.search(/<ul/i))&&(o.title=o.title.substring(0,u))),o.title=S(o.title),c=0,h=v.length;c<h;c++)o[v[c]]=void 0;for(a=this.className.split(" "),d=[],c=0,h=a.length;c<h;c++)l=a[c],y[l]?o[l]=!0:d.push(l);if(o.extraClasses=d.join(" "),(f=n.attr("title"))&&(o.tooltip=f),(f=n.attr("id"))&&(o.key=f),n.attr("hideCheckbox")&&(o.checkbox=!1),(e=H(n))&&!k.isEmptyObject(e)){for(t in x)C(e,t)&&(e[x[t]]=e[t],delete e[t]);for(c=0,h=m.length;c<h;c++)f=m[c],null!=(p=e[f])&&(delete e[f],o[f]=p);k.extend(o.data,e)}(s=n.find(">ul").first()).length?o.children=k.ui.fancytree.parseHtml(s):o.children=o.lazy?void 0:null,g.push(o)}),g},registerExtension:function(e){_(null!=e.name,"extensions must have a `name` property."),_(null!=e.version,"extensions must have a `version` property."),k.ui.fancytree._extensions[e.name]=e},trim:S,unescapeHtml:function(e){var t=document.createElement("div");return t.innerHTML=e,0===t.childNodes.length?"":t.childNodes[0].nodeValue},warn:function(e){2<=k.ui.fancytree.debugLevel&&d("warn",arguments)}}),k.ui.fancytree}function _(e,t){e||(k.ui.fancytree.error(t="Fancytree assertion failed"+(t=t?": "+t:"")),k.error(t))}function C(e,t){return Object.prototype.hasOwnProperty.call(e,t)}function w(e){return"function"==typeof e}function S(e){return null==e?"":e.trim()}function d(t,n){var i,r,t=window.console?window.console[t]:null;if(t)try{t.apply(window.console,n)}catch(e){for(r="",i=0;i<n.length;i++)r+=n[i];t(r)}}function E(e,i,t,n,r){var o,s,a;function l(){return o.apply(i,arguments)}function d(e){return o.apply(i,e)}return o=i[e],s=n[e],a=i.ext[r],function(){var e=i._local,t=i._super,n=i._superApply;try{return i._local=a,i._super=l,i._superApply=d,s.apply(i,arguments)}finally{i._local=e,i._super=t,i._superApply=n}}}function T(e,t){return(void 0===e?k.Deferred(function(){this.resolve()}):k.Deferred(function(){this.resolveWith(e,t)})).promise()}function L(e,t){return(void 0===e?k.Deferred(function(){this.reject()}):k.Deferred(function(){this.rejectWith(e,t)})).promise()}function A(e,t){return function(){e.resolveWith(t)}}function H(e){var t=k.extend({},e.data()),e=t.json;return delete t.fancytree,delete t.uiFancytree,e&&(delete t.json,t=k.extend(t,e)),t}function P(e){return(""+e).replace(n,function(e){return i[e]})}function R(t){return t=t.toLowerCase(),function(e){return 0<=e.title.toLowerCase().indexOf(t)}}function I(e,t){var n,i,r;for(this.parent=e,this.tree=e.tree,this.ul=null,this.li=null,this.statusNodeType=null,this._isLoading=!1,this._error=null,this.data={},n=0,i=m.length;n<i;n++)this[r=m[n]]=t[r];for(r in null==this.unselectableIgnore&&null==this.unselectableStatus||(this.unselectable=!0),t.hideCheckbox&&k.error("'hideCheckbox' node option was removed in v2.23.0: use 'checkbox: false'"),t.data&&k.extend(this.data,t.data),t)s[r]||!this.tree.options.copyFunctionsToData&&w(t[r])||a[r]||(this.data[r]=t[r]);null==this.key?this.tree.options.defaultKey?(this.key=""+this.tree.options.defaultKey(this),_(this.key,"defaultKey() must return a unique key")):this.key="_"+h._nextNodeKey++:this.key=""+this.key,t.active&&(_(null===this.tree.activeNode,"only one active node allowed"),this.tree.activeNode=this),t.selected&&(this.tree.lastSelectedNode=this),(e=t.children)?e.length?this._setChildren(e):this.children=this.lazy?[]:null:this.children=null,this.tree._callHook("treeRegisterNode",this.tree,!0,this)}function F(e){this.widget=e,this.$div=e.element,this.options=e.options,this.options&&(void 0!==this.options.lazyload&&k.error("The 'lazyload' event is deprecated since 2014-02-25. Use 'lazyLoad' (with uppercase L) instead."),void 0!==this.options.loaderror&&k.error("The 'loaderror' event was renamed since 2014-07-03. Use 'loadError' (with uppercase E) instead."),void 0!==this.options.fx&&k.error("The 'fx' option was replaced by 'toggleEffect' since 2014-11-30."),void 0!==this.options.removeNode&&k.error("The 'removeNode' event was replaced by 'modifyChild' since 2.20 (2016-09-10).")),this.ext={},this.types={},this.columns={},this.data=H(this.$div),this._id=""+(this.options.treeId||k.ui.fancytree._nextId++),this._ns=".fancytree-"+this._id,this.activeNode=null,this.focusNode=null,this._hasFocus=null,this._tempCache={},this._lastMousedownNode=null,this._enableUpdate=!0,this.lastSelectedNode=null,this.systemFocusElement=null,this.lastQuicksearchTerm="",this.lastQuicksearchTime=0,this.viewport=null,this.statusClassPropName="span",this.ariaPropName="li",this.nodeContainerAttrName="li",this.$div.find(">ul.fancytree-container").remove(),this.rootNode=new I({tree:this},{title:"root",key:"root_"+this._id,children:null,expanded:!0}),this.rootNode.parent=null,e=k("<ul>",{id:"ft-id-"+this._id,class:"ui-fancytree fancytree-container fancytree-plain"}).appendTo(this.$div),this.$container=e,this.rootNode.ul=e[0],null==this.options.debugLevel&&(this.options.debugLevel=h.debugLevel)}k.ui.fancytree.warn("Fancytree: ignored duplicate include")}); + +/*! Extension 'jquery.fancytree.childcounter.min.js' */!function(e){"function"==typeof define&&define.amd?define(["jquery","./jquery.fancytree"],e):"object"==typeof module&&module.exports?(require("./jquery.fancytree"),module.exports=e(require("jquery"))):e(jQuery)}(function(i){"use strict";return i.ui.fancytree._FancytreeClass.prototype.countSelected=function(e){this.options;return this.getSelectedNodes(e).length},i.ui.fancytree._FancytreeNodeClass.prototype.updateCounters=function(){var e=this,n=i("span.fancytree-childcounter",e.span),t=e.tree.options.childcounter,o=e.countChildren(t.deep);!(e.data.childCounter=o)&&t.hideZeros||e.isExpanded()&&t.hideExpanded?n.remove():(n=!n.length?i("<span class='fancytree-childcounter'/>").appendTo(i("span.fancytree-icon,span.fancytree-custom-icon",e.span)):n).text(o),!t.deep||e.isTopLevel()||e.isRootNode()||e.parent.updateCounters()},i.ui.fancytree.prototype.widgetMethod1=function(e){this.tree;return e},i.ui.fancytree.registerExtension({name:"childcounter",version:"2.38.3",options:{deep:!0,hideZeros:!0,hideExpanded:!1},foo:42,_appendCounter:function(e){},treeInit:function(e){e.options,e.options.childcounter;this._superApply(arguments),this.$container.addClass("fancytree-ext-childcounter")},treeDestroy:function(e){this._superApply(arguments)},nodeRenderTitle:function(e,n){var t=e.node,o=e.options.childcounter,r=null==t.data.childCounter?t.countChildren(o.deep):+t.data.childCounter;this._super(e,n),!r&&o.hideZeros||t.isExpanded()&&o.hideExpanded||i("span.fancytree-icon,span.fancytree-custom-icon",t.span).append(i("<span class='fancytree-childcounter'/>").text(r))},nodeSetExpanded:function(e,n,t){var o=e.tree;e.node;return this._superApply(arguments).always(function(){o.nodeRenderTitle(e)})}}),i.ui.fancytree}); + +/*! Extension 'jquery.fancytree.clones.min.js' */!function(e){"function"==typeof define&&define.amd?define(["jquery","./jquery.fancytree"],e):"object"==typeof module&&module.exports?(require("./jquery.fancytree"),module.exports=e(require("jquery"))):e(jQuery)}(function(c){"use strict";var f=c.ui.fancytree.assert;function n(e,t,n){for(var r,s,i=3&e.length,o=e.length-i,l=n,a=3432918353,u=461845907,c=0;c<o;)s=255&e.charCodeAt(c)|(255&e.charCodeAt(++c))<<8|(255&e.charCodeAt(++c))<<16|(255&e.charCodeAt(++c))<<24,++c,l=27492+(65535&(r=5*(65535&(l=(l^=s=(65535&(s=(s=(65535&s)*a+(((s>>>16)*a&65535)<<16)&4294967295)<<15|s>>>17))*u+(((s>>>16)*u&65535)<<16)&4294967295)<<13|l>>>19))+((5*(l>>>16)&65535)<<16)&4294967295))+((58964+(r>>>16)&65535)<<16);switch(s=0,i){case 3:s^=(255&e.charCodeAt(c+2))<<16;case 2:s^=(255&e.charCodeAt(c+1))<<8;case 1:l^=s=(65535&(s=(s=(65535&(s^=255&e.charCodeAt(c)))*a+(((s>>>16)*a&65535)<<16)&4294967295)<<15|s>>>17))*u+(((s>>>16)*u&65535)<<16)&4294967295}return l^=e.length,l=2246822507*(65535&(l^=l>>>16))+((2246822507*(l>>>16)&65535)<<16)&4294967295,l=3266489909*(65535&(l^=l>>>13))+((3266489909*(l>>>16)&65535)<<16)&4294967295,l^=l>>>16,t?("0000000"+(l>>>0).toString(16)).substr(-8):l>>>0}return c.ui.fancytree._FancytreeNodeClass.prototype.getCloneList=function(e){var t,n=this.tree,r=n.refMap[this.refKey]||null,s=n.keyMap;return r&&(t=this.key,e?r=c.map(r,function(e){return s[e]}):(r=c.map(r,function(e){return e===t?null:s[e]})).length<1&&(r=null)),r},c.ui.fancytree._FancytreeNodeClass.prototype.isClone=function(){var e=this.refKey||null,e=e&&this.tree.refMap[e]||null;return!!(e&&1<e.length)},c.ui.fancytree._FancytreeNodeClass.prototype.reRegister=function(t,e){e=null==e?null:""+e;var n=this.tree,r=this.key,s=this.refKey,i=n.keyMap,o=n.refMap,l=o[s]||null,n=!1;return null!=(t=null==t?null:""+t)&&t!==this.key&&(i[t]&&c.error("[ext-clones] reRegister("+t+"): already exists: "+this),delete i[r],i[t]=this,l&&(o[s]=c.map(l,function(e){return e===r?t:e})),this.key=t,n=!0),null!=e&&e!==this.refKey&&(l&&(1===l.length?delete o[s]:o[s]=c.map(l,function(e){return e===r?null:e})),o[e]?o[e].append(t):o[e]=[this.key],this.refKey=e,n=!0),n},c.ui.fancytree._FancytreeNodeClass.prototype.setRefKey=function(e){return this.reRegister(null,e)},c.ui.fancytree._FancytreeClass.prototype.getNodesByRef=function(e,t){var n=this.keyMap,e=this.refMap[e]||null;return e=e&&(e=t?c.map(e,function(e){e=n[e];return e.isDescendantOf(t)?e:null}):c.map(e,function(e){return n[e]})).length<1?null:e},c.ui.fancytree._FancytreeClass.prototype.changeRefKey=function(e,t){var n,r=this.keyMap,s=this.refMap[e]||null;if(s){for(n=0;n<s.length;n++)r[s[n]].refKey=t;delete this.refMap[e],this.refMap[t]=s}},c.ui.fancytree.registerExtension({name:"clones",version:"2.38.3",options:{highlightActiveClones:!0,highlightClones:!1},treeCreate:function(e){this._superApply(arguments),e.tree.refMap={},e.tree.keyMap={}},treeInit:function(e){this.$container.addClass("fancytree-ext-clones"),f(null==e.options.defaultKey),e.options.defaultKey=function(e){return t=e,"id_"+(t=n(e=(e=c.map(e.getParentList(!1,!0),function(e){return e.refKey||e.key})).join("/"),!0))+n(t+e,!0);var t},this._superApply(arguments)},treeClear:function(e){return e.tree.refMap={},e.tree.keyMap={},this._superApply(arguments)},treeRegisterNode:function(e,t,n){var r,s,i=e.tree,o=i.keyMap,l=i.refMap,a=n.key,u=n&&null!=n.refKey?""+n.refKey:null;return n.isStatusNode()||(t?(null!=o[n.key]&&(s=o[n.key],s="clones.treeRegisterNode: duplicate key '"+n.key+"': /"+n.getPath(!0)+" => "+s.getPath(!0),i.error(s),c.error(s)),o[a]=n,u&&((r=l[u])?(r.push(a),2===r.length&&e.options.clones.highlightClones&&o[r[0]].renderStatus()):l[u]=[a])):(null==o[a]&&c.error("clones.treeRegisterNode: node.key not registered: "+n.key),delete o[a],u&&(r=l[u])&&((s=r.length)<=1?(f(1===s),f(r[0]===a),delete l[u]):(function(e,t){for(var n=e.length-1;0<=n;n--)if(e[n]===t)return e.splice(n,1)}(r,a),2===s&&e.options.clones.highlightClones&&o[r[0]].renderStatus())))),this._super(e,t,n)},nodeRenderStatus:function(e){var t,n=e.node,r=this._super(e);return e.options.clones.highlightClones&&(t=c(n[e.tree.statusClassPropName])).length&&n.isClone()&&t.addClass("fancytree-clone"),r},nodeSetActive:function(e,n,t){var r=e.tree.statusClassPropName,s=e.node,i=this._superApply(arguments);return e.options.clones.highlightActiveClones&&s.isClone()&&c.each(s.getCloneList(!0),function(e,t){c(t[r]).toggleClass("fancytree-active-clone",!1!==n)}),i}}),c.ui.fancytree}); + +/*! Extension 'jquery.fancytree.dnd.min.js' */!function(e){"function"==typeof define&&define.amd?define(["jquery","jquery-ui/ui/widgets/draggable","jquery-ui/ui/widgets/droppable","./jquery.fancytree"],e):"object"==typeof module&&module.exports?(require("./jquery.fancytree"),module.exports=e(require("jquery"))):e(jQuery)}(function(v){"use strict";var t=!1,g="fancytree-drop-accept",u="fancytree-drop-after",c="fancytree-drop-before",f="fancytree-drop-reject";function h(e){return 0===e?"":0<e?"+"+e:""+e}function r(e){var r=e.options.dnd||null,n=e.options.glyph||null;r&&(t||(v.ui.plugin.add("draggable","connectToFancytree",{start:function(e,r){var t=v(this).data("ui-draggable")||v(this).data("draggable"),a=r.helper.data("ftSourceNode")||null;if(a)return t.offset.click.top=-2,t.offset.click.left=16,a.tree.ext.dnd._onDragEvent("start",a,null,e,r,t)},drag:function(e,r){var t,a=v(this).data("ui-draggable")||v(this).data("draggable"),n=r.helper.data("ftSourceNode")||null,o=r.helper.data("ftTargetNode")||null,d=v.ui.fancytree.getNode(e.target),l=n&&n.tree.options.dnd;e.target&&!d&&0<v(e.target).closest("div.fancytree-drag-helper,#fancytree-drop-marker").length?(n||o||v.ui.fancytree).debug("Drag event over helper: ignored."):(r.helper.data("ftTargetNode",d),l&&l.updateHelper&&(t=n.tree._makeHookContext(n,e,{otherNode:d,ui:r,draggable:a,dropMarker:v("#fancytree-drop-marker")}),l.updateHelper.call(n.tree,n,t)),o&&o!==d&&o.tree.ext.dnd._onDragEvent("leave",o,n,e,r,a),d&&d.tree.options.dnd.dragDrop&&(d===o||d.tree.ext.dnd._onDragEvent("enter",d,n,e,r,a),d.tree.ext.dnd._onDragEvent("over",d,n,e,r,a)))},stop:function(e,r){var t=v(this).data("ui-draggable")||v(this).data("draggable"),a=r.helper.data("ftSourceNode")||null,n=r.helper.data("ftTargetNode")||null,o="mouseup"===e.type&&1===e.which;o||(a||n||v.ui.fancytree).debug("Drag was cancelled"),n&&(o&&n.tree.ext.dnd._onDragEvent("drop",n,a,e,r,t),n.tree.ext.dnd._onDragEvent("leave",n,a,e,r,t)),a&&a.tree.ext.dnd._onDragEvent("stop",a,null,e,r,t)}}),t=!0)),r&&r.dragStart&&e.widget.element.draggable(v.extend({addClasses:!1,appendTo:e.$container,containment:!1,delay:0,distance:4,revert:!1,scroll:!0,scrollSpeed:7,scrollSensitivity:10,connectToFancytree:!0,helper:function(e){var r,t,a=v.ui.fancytree.getNode(e.target);return a?(t=a.tree.options.dnd,r=v(a.span),(r=v("<div class='fancytree-drag-helper'><span class='fancytree-drag-helper-img' /></div>").css({zIndex:3,position:"relative"}).append(r.find("span.fancytree-title").clone())).data("ftSourceNode",a),n&&r.find(".fancytree-drag-helper-img").addClass(n.map._addClass+" "+n.map.dragHelper),t.initHelper&&t.initHelper.call(a.tree,a,{node:a,tree:a.tree,originalEvent:e,ui:{helper:r}}),r):"<div>ERROR?: helper requested but sourceNode not found</div>"},start:function(e,r){return!!r.helper.data("ftSourceNode")}},e.options.dnd.draggable)),r&&r.dragDrop&&e.widget.element.droppable(v.extend({addClasses:!1,tolerance:"intersect",greedy:!1},e.options.dnd.droppable))}return v.ui.fancytree.registerExtension({name:"dnd",version:"2.38.3",options:{autoExpandMS:1e3,draggable:null,droppable:null,focusOnClick:!1,preventVoidMoves:!0,preventRecursiveMoves:!0,smartRevert:!0,dropMarkerOffsetX:-24,dropMarkerInsertOffsetX:-16,dragStart:null,dragStop:null,initHelper:null,updateHelper:null,dragEnter:null,dragOver:null,dragExpand:null,dragDrop:null,dragLeave:null},treeInit:function(t){var e=t.tree;this._superApply(arguments),e.options.dnd.dragStart&&e.$container.on("mousedown",function(e){var r;t.options.dnd.focusOnClick&&((r=v.ui.fancytree.getNode(e))&&r.debug("Re-enable focus that was prevented by jQuery UI draggable."),setTimeout(function(){v(e.target).closest(":tabbable").focus()},10))}),r(e)},_setDndStatus:function(e,r,t,a,n){var o,d="center",l=this._local,s=this.options.dnd,i=this.options.glyph,p=e?v(e.span):null,e=v(r.span),r=e.find("span.fancytree-title");if(l.$dropMarker||(l.$dropMarker=v("<div id='fancytree-drop-marker'></div>").hide().css({"z-index":1e3}).prependTo(v(this.$div).parent()),i&&l.$dropMarker.addClass(i.map._addClass+" "+i.map.dropMarker)),"after"===a||"before"===a||"over"===a){switch(o=s.dropMarkerOffsetX||0,a){case"before":d="top",o+=s.dropMarkerInsertOffsetX||0;break;case"after":d="bottom",o+=s.dropMarkerInsertOffsetX||0}r={my:"left"+h(o)+" center",at:"left "+d,of:r},this.options.rtl&&(r.my="right"+h(-o)+" center",r.at="right "+d),l.$dropMarker.toggleClass(u,"after"===a).toggleClass("fancytree-drop-over","over"===a).toggleClass(c,"before"===a).toggleClass("fancytree-rtl",!!this.options.rtl).show().position(v.ui.fancytree.fixPositionOptions(r))}else l.$dropMarker.hide();p&&p.toggleClass(g,!0===n).toggleClass(f,!1===n),e.toggleClass("fancytree-drop-target","after"===a||"before"===a||"over"===a).toggleClass(u,"after"===a).toggleClass(c,"before"===a).toggleClass(g,!0===n).toggleClass(f,!1===n),t.toggleClass(g,!0===n).toggleClass(f,!1===n)},_onDragEvent:function(e,r,t,a,n,o){var d,l,s,i,p=this.options.dnd,g=this._makeHookContext(r,a,{otherNode:t,ui:n,draggable:o}),u=null,c=this,f=v(r.span);switch(p.smartRevert&&(o.options.revert="invalid"),e){case"start":r.isStatusNode()?u=!1:p.dragStart&&(u=p.dragStart(r,g)),!1===u?(this.debug("tree.dragStart() cancelled"),n.helper.trigger("mouseup").hide()):(p.smartRevert&&(d=r[g.tree.nodeContainerAttrName].getBoundingClientRect(),l=v(o.options.appendTo)[0].getBoundingClientRect(),o.originalPosition.left=Math.max(0,d.left-l.left),o.originalPosition.top=Math.max(0,d.top-l.top)),f.addClass("fancytree-drag-source"),v(document).on("keydown.fancytree-dnd,mousedown.fancytree-dnd",function(e){("keydown"===e.type&&e.which===v.ui.keyCode.ESCAPE||"mousedown"===e.type)&&c.ext.dnd._cancelDrag()}));break;case"enter":u=!!(i=(!p.preventRecursiveMoves||!r.isDescendantOf(t))&&(p.dragEnter?p.dragEnter(r,g):null))&&(Array.isArray(i)?{over:0<=v.inArray("over",i),before:0<=v.inArray("before",i),after:0<=v.inArray("after",i)}:{over:!0===i||"over"===i,before:!0===i||"before"===i,after:!0===i||"after"===i}),n.helper.data("enterResponse",u);break;case"over":s=null,!1===(l=n.helper.data("enterResponse"))||("string"==typeof l?s=l:(i=f.offset(),i={x:(i={x:a.pageX-i.left,y:a.pageY-i.top}).x/f.width(),y:i.y/f.height()},l.after&&.75<i.y||!l.over&&l.after&&.5<i.y?s="after":l.before&&i.y<=.25||!l.over&&l.before&&i.y<=.5?s="before":l.over&&(s="over"),p.preventVoidMoves&&(r===t?(this.debug(" drop over source node prevented"),s=null):"before"===s&&t&&r===t.getNextSibling()?(this.debug(" drop after source node prevented"),s=null):"after"===s&&t&&r===t.getPrevSibling()?(this.debug(" drop before source node prevented"),s=null):"over"===s&&t&&t.parent===r&&t.isLastSibling()&&(this.debug(" drop last child over own parent prevented"),s=null)),n.helper.data("hitMode",s))),"before"===s||"after"===s||!p.autoExpandMS||!1===r.hasChildren()||r.expanded||p.dragExpand&&!1===p.dragExpand(r,g)||r.scheduleAction("expand",p.autoExpandMS),s&&p.dragOver&&(g.hitMode=s,u=p.dragOver(r,g)),l=!1!==u&&null!==s,p.smartRevert&&(o.options.revert=!l),this._local._setDndStatus(t,r,n.helper,s,l);break;case"drop":(s=n.helper.data("hitMode"))&&p.dragDrop&&(g.hitMode=s,p.dragDrop(r,g));break;case"leave":r.scheduleAction("cancel"),n.helper.data("enterResponse",null),n.helper.data("hitMode",null),this._local._setDndStatus(t,r,n.helper,"out",void 0),p.dragLeave&&p.dragLeave(r,g);break;case"stop":f.removeClass("fancytree-drag-source"),v(document).off(".fancytree-dnd"),p.dragStop&&p.dragStop(r,g);break;default:v.error("Unsupported drag event: "+e)}return u},_cancelDrag:function(){var e=v.ui.ddmanager.current;e&&e.cancel()}}),v.ui.fancytree}); + +/*! Extension 'jquery.fancytree.dnd5.min.js' */!function(e){"function"==typeof define&&define.amd?define(["jquery","./jquery.fancytree"],e):"object"==typeof module&&module.exports?(require("./jquery.fancytree"),module.exports=e(require("jquery"))):e(jQuery)}(function(c){"use strict";var s,l,u=c.ui.fancytree,n=/Mac/.test(navigator.platform),i="fancytree-drag-source",f="fancytree-drag-remove",v="fancytree-drop-accept",y="fancytree-drop-after",b="fancytree-drop-before",h="fancytree-drop-over",m="fancytree-drop-reject",E="fancytree-drop-target",p="application/x-fancytree-node",D=null,g=null,w=null,N=null,x=null,d=null,S=null,k=null,C=null,M=null;function A(){w=g=d=k=S=M=x=null,N&&N.removeClass(i+" "+f),N=null,D&&D.hide(),l&&(l.remove(),l=null)}function T(e){return 0===e?"":0<e?"+"+e:""+e}function I(e,r){var t,o=r.tree,a=r.dataTransfer;"dragstart"===e.type?(r.effectAllowed=o.options.dnd5.effectAllowed,r.dropEffect=o.options.dnd5.dropEffectDefault):(r.effectAllowed=k,r.dropEffect=S),r.dropEffectSuggested=(t=e,o=(e=o).options.dnd5.dropEffectDefault,n?t.metaKey&&t.altKey||t.ctrlKey?o="link":t.metaKey?o="move":t.altKey&&(o="copy"):t.ctrlKey?o="copy":t.shiftKey?o="move":t.altKey&&(o="link"),o!==d&&e.info("evalEffectModifiers: "+t.type+" - evalEffectModifiers(): "+d+" -> "+o),d=o),r.isMove="move"===r.dropEffect,r.files=a.files||[]}function O(e,r,t){var o=r.tree,a=r.dataTransfer;return"dragstart"!==e.type&&k!==r.effectAllowed&&o.warn("effectAllowed should only be changed in dragstart event: "+e.type+": data.effectAllowed changed from "+k+" -> "+r.effectAllowed),!1===t&&(o.info("applyDropEffectCallback: allowDrop === false"),r.effectAllowed="none",r.dropEffect="none"),r.isMove="move"===r.dropEffect,"dragstart"===e.type&&(k=r.effectAllowed,S=r.dropEffect),a.effectAllowed=k,a.dropEffect=S}function P(e,r){if(r.options.dnd5.scroll&&(g=r.tree,d=e,a=g.options.dnd5,n=g.$scrollParent[0],l=a.scrollSensitivity,p=a.scrollSpeed,o=0,n!==document&&"HTML"!==n.tagName?(a=g.$scrollParent.offset(),i=n.scrollTop,a.top+n.offsetHeight-d.pageY<l?0<n.scrollHeight-g.$scrollParent.innerHeight()-i&&(n.scrollTop=o=i+p):0<i&&d.pageY-a.top<l&&(n.scrollTop=o=i-p)):0<(i=c(document).scrollTop())&&d.pageY-i<l?(o=i-p,c(document).scrollTop(o)):c(window).height()-(d.pageY-i)<l&&(o=i+p,c(document).scrollTop(o)),o&&g.debug("autoScroll: "+o+"px")),!r.node)return r.tree.warn("Ignored dragover for non-node"),C;var t,o,a=null,n=r.tree,d=n.options,s=d.dnd5,l=r.node,i=r.otherNode,f="center",p=c(l.span),g=p.find("span.fancytree-title");if(!1===x)return n.debug("Ignored dragover, since dragenter returned false."),!1;if("string"==typeof x&&c.error("assert failed: dragenter returned string"),o=p.offset(),p=(e.pageY-o.top)/p.height(),void 0===e.pageY&&n.warn("event.pageY is undefined: see issue #1013."),x.after&&.75<p||!x.over&&x.after&&.5<p?a="after":x.before&&p<=.25||!x.over&&x.before&&p<=.5?a="before":x.over&&(a="over"),s.preventVoidMoves&&"move"===r.dropEffect&&(l===i?(l.debug("Drop over source node prevented."),a=null):"before"===a&&i&&l===i.getNextSibling()?(l.debug("Drop after source node prevented."),a=null):"after"===a&&i&&l===i.getPrevSibling()?(l.debug("Drop before source node prevented."),a=null):"over"===a&&i&&i.parent===l&&i.isLastSibling()&&(l.debug("Drop last child over own parent prevented."),a=null)),(r.hitMode=a)&&s.dragOver&&(I(e,r),s.dragOver(l,r),O(e,r,!!a),a=r.hitMode),"after"===(C=a)||"before"===a||"over"===a){switch(t=s.dropMarkerOffsetX||0,a){case"before":f="top",t+=s.dropMarkerInsertOffsetX||0;break;case"after":f="bottom",t+=s.dropMarkerInsertOffsetX||0}g={my:"left"+T(t)+" center",at:"left "+f,of:g},d.rtl&&(g.my="right"+T(-t)+" center",g.at="right "+f),D.toggleClass(y,"after"===a).toggleClass(h,"over"===a).toggleClass(b,"before"===a).show().position(u.fixPositionOptions(g))}else D.hide();return c(l.span).toggleClass(E,"after"===a||"before"===a||"over"===a).toggleClass(y,"after"===a).toggleClass(b,"before"===a).toggleClass(v,"over"===a).toggleClass(m,!1===a),a}function j(e){var r,t=this,o=t.options.dnd5,a=null,n=u.getNode(e),d=e.dataTransfer||e.originalEvent.dataTransfer,s={tree:t,node:n,options:t.options,originalEvent:e.originalEvent,widget:t.widget,hitMode:x,dataTransfer:d,otherNode:g||null,otherNodeList:w||null,otherNodeData:null,useDefaultImage:!0,dropEffect:void 0,dropEffectSuggested:void 0,effectAllowed:void 0,files:null,isCancelled:void 0,isMove:void 0};switch(e.type){case"dragenter":if(M=null,!n){t.debug("Ignore non-node "+e.type+": "+e.target.tagName+"."+e.target.className),x=!1;break}if(c(n.span).addClass(h).removeClass(v+" "+m),r=0<=c.inArray(p,d.types),o.preventNonNodes&&!r){n.debug("Reject dropping a non-node."),x=!1;break}if(o.preventForeignNodes&&(!g||g.tree!==n.tree)){n.debug("Reject dropping a foreign node."),x=!1;break}if(o.preventSameParent&&s.otherNode&&s.otherNode.tree===n.tree&&n.parent===s.otherNode.parent){n.debug("Reject dropping as sibling (same parent)."),x=!1;break}if(o.preventRecursion&&s.otherNode&&s.otherNode.tree===n.tree&&n.isDescendantOf(s.otherNode)){n.debug("Reject dropping below own ancestor."),x=!1;break}if(o.preventLazyParents&&!n.isLoaded()){n.warn("Drop over unloaded target node prevented."),x=!1;break}D.show(),I(e,s),r=o.dragEnter(n,s),r=!!(r=r)&&(r=c.isPlainObject(r)?{over:!!r.over,before:!!r.before,after:!!r.after}:Array.isArray(r)?{over:0<=c.inArray("over",r),before:0<=c.inArray("before",r),after:0<=c.inArray("after",r)}:{over:!0===r||"over"===r,before:!0===r||"before"===r,after:!0===r||"after"===r},0!==Object.keys(r).length&&r),O(e,s,a=(x=r)&&(r.over||r.before||r.after));break;case"dragover":if(!n){t.debug("Ignore non-node "+e.type+": "+e.target.tagName+"."+e.target.className);break}I(e,s),a=!!(C=P(e,s)),("over"===C||!1===C)&&!n.expanded&&!1!==n.hasChildren()?M?!(o.autoExpandMS&&Date.now()-M>o.autoExpandMS)||n.isLoading()||o.dragExpand&&!1===o.dragExpand(n,s)||n.setExpanded():M=Date.now():M=null;break;case"dragleave":if(!n){t.debug("Ignore non-node "+e.type+": "+e.target.tagName+"."+e.target.className);break}if(!c(n.span).hasClass(h)){n.debug("Ignore dragleave (multi).");break}c(n.span).removeClass(h+" "+v+" "+m),n.scheduleAction("cancel"),o.dragLeave(n,s),D.hide();break;case"drop":if(0<=c.inArray(p,d.types)&&(i=d.getData(p),t.info(e.type+": getData('application/x-fancytree-node'): '"+i+"'")),i||(i=d.getData("text"),t.info(e.type+": getData('text'): '"+i+"'")),i)try{void 0!==(l=JSON.parse(i)).title&&(s.otherNodeData=l)}catch(e){}t.debug(e.type+": nodeData: '"+i+"', otherNodeData: ",s.otherNodeData),c(n.span).removeClass(h+" "+v+" "+m),s.hitMode=C,I(e,s),s.isCancelled=!C;var l=g&&g.span,i=g&&g.tree;o.dragDrop(n,s),e.preventDefault(),l&&!document.body.contains(l)&&(i===t?(t.debug("Drop handler removed source element: generating dragEnd."),o.dragEnd(g,s)):t.warn("Drop handler removed source element: dragend event may be lost.")),A()}if(a)return e.preventDefault(),!1}return c.ui.fancytree.getDragNodeList=function(){return w||[]},c.ui.fancytree.getDragNode=function(){return g},c.ui.fancytree.registerExtension({name:"dnd5",version:"2.38.3",options:{autoExpandMS:1500,dropMarkerInsertOffsetX:-16,dropMarkerOffsetX:-24,dropMarkerParent:"body",multiSource:!1,effectAllowed:"all",dropEffectDefault:"move",preventForeignNodes:!1,preventLazyParents:!0,preventNonNodes:!1,preventRecursion:!0,preventSameParent:!1,preventVoidMoves:!0,scroll:!0,scrollSensitivity:20,scrollSpeed:5,setTextTypeJson:!1,sourceCopyHook:null,dragStart:null,dragDrag:c.noop,dragEnd:c.noop,dragEnter:null,dragOver:c.noop,dragExpand:c.noop,dragDrop:c.noop,dragLeave:c.noop},treeInit:function(e){var r=e.tree,t=e.options,o=t.glyph||null,a=t.dnd5;0<=c.inArray("dnd",t.extensions)&&c.error("Extensions 'dnd' and 'dnd5' are mutually exclusive."),a.dragStop&&c.error("dragStop is not used by ext-dnd5. Use dragEnd instead."),null!=a.preventRecursiveMoves&&c.error("preventRecursiveMoves was renamed to preventRecursion."),a.dragStart&&u.overrideMethod(e.options,"createNode",function(e,r){this._super.apply(this,arguments),r.node.span?r.node.span.draggable=!0:r.node.warn("Cannot add `draggable`: no span tag")}),this._superApply(arguments),this.$container.addClass("fancytree-ext-dnd5"),e=c("<span>").appendTo(this.$container),this.$scrollParent=e.scrollParent(),e.remove(),(D=c("#fancytree-drop-marker")).length||(D=c("<div id='fancytree-drop-marker'></div>").hide().css({"z-index":1e3,"pointer-events":"none"}).prependTo(a.dropMarkerParent),o&&u.setSpanIcon(D[0],o.map._addClass,o.map.dropMarker)),D.toggleClass("fancytree-rtl",!!t.rtl),a.dragStart&&r.$container.on("dragstart drag dragend",function(e){var r=this,t=r.options.dnd5,o=u.getNode(e),a=e.dataTransfer||e.originalEvent.dataTransfer,n={tree:r,node:o,options:r.options,originalEvent:e.originalEvent,widget:r.widget,dataTransfer:a,useDefaultImage:!0,dropEffect:void 0,dropEffectSuggested:void 0,effectAllowed:void 0,files:void 0,isCancelled:void 0,isMove:void 0};switch(e.type){case"dragstart":if(!o)return r.info("Ignored dragstart on a non-node."),!1;g=o,w=!1===t.multiSource?[o]:!0===t.multiSource?o.isSelected()?r.getSelectedNodes():[o]:t.multiSource(o,n),(N=c(c.map(w,function(e){return e.span}))).addClass(i);var d=o.toDict(!0,t.sourceCopyHook);d.treeId=o.tree._id,d=JSON.stringify(d);try{a.setData(p,d),a.setData("text/html",c(o.span).html()),a.setData("text/plain",o.title)}catch(e){r.warn("Could not set data (IE only accepts 'text') - "+e)}return(t.setTextTypeJson?a.setData("text",d):a.setData("text",o.title),I(e,n),!1===t.dragStart(o,n))?(A(),!1):(O(e,n),l=null,n.useDefaultImage&&(s=c(o.span).find(".fancytree-title"),w&&1<w.length&&(l=c("<span class='fancytree-childcounter'/>").text("+"+(w.length-1)).appendTo(s)),a.setDragImage&&a.setDragImage(s[0],-10,-10)),!0);case"drag":I(e,n),t.dragDrag(o,n),O(e,n),N.toggleClass(f,n.isMove);break;case"dragend":I(e,n),A(),n.isCancelled=!C,t.dragEnd(o,n,!C)}}.bind(r)),a.dragEnter&&r.$container.on("dragenter dragover dragleave drop",j.bind(r))}}),c.ui.fancytree}); + +/*! Extension 'jquery.fancytree.edit.min.js' */!function(e){"function"==typeof define&&define.amd?define(["jquery","./jquery.fancytree"],e):"object"==typeof module&&module.exports?(require("./jquery.fancytree"),module.exports=e(require("jquery"))):e(jQuery)}(function(l){"use strict";var t=/Mac/.test(navigator.platform),c=l.ui.fancytree.escapeHtml,u=l.ui.fancytree.trim,o=l.ui.fancytree.unescapeHtml;return l.ui.fancytree._FancytreeNodeClass.prototype.editStart=function(){var t,i=this,e=this.tree,n=e.ext.edit,r=e.options.edit,a=l(".fancytree-title",i.span),s={node:i,tree:e,options:e.options,isNew:l(i[e.statusClassPropName]).hasClass("fancytree-edit-new"),orgTitle:i.title,input:null,dirty:!1};if(!1===r.beforeEdit.call(i,{type:"beforeEdit"},s))return!1;l.ui.fancytree.assert(!n.currentNode,"recursive edit"),n.currentNode=this,n.eventData=s,e.widget._unbind(),n.lastDraggableAttrValue=i.span.draggable,n.lastDraggableAttrValue&&(i.span.draggable=!1),l(document).on("mousedown.fancytree-edit",function(e){l(e.target).hasClass("fancytree-edit-input")||i.editEnd(!0,e)}),t=l("<input />",{class:"fancytree-edit-input",type:"text",value:e.options.escapeTitles?s.orgTitle:o(s.orgTitle)}),n.eventData.input=t,null!=r.adjustWidthOfs&&t.width(a.width()+r.adjustWidthOfs),null!=r.inputCss&&t.css(r.inputCss),a.html(t),t.focus().change(function(e){t.addClass("fancytree-edit-dirty")}).on("keydown",function(e){switch(e.which){case l.ui.keyCode.ESCAPE:i.editEnd(!1,e);break;case l.ui.keyCode.ENTER:return i.editEnd(!0,e),!1}e.stopPropagation()}).blur(function(e){return i.editEnd(!0,e)}),r.edit.call(i,{type:"edit"},s)},l.ui.fancytree._FancytreeNodeClass.prototype.editEnd=function(e,t){var i,n=this,r=this.tree,a=r.ext.edit,s=a.eventData,o=r.options.edit,d=l(".fancytree-title",n.span).find("input.fancytree-edit-input");return o.trim&&d.val(u(d.val())),i=d.val(),s.dirty=i!==n.title,s.originalEvent=t,!1===e?s.save=!1:s.isNew?s.save=""!==i:s.save=s.dirty&&""!==i,!1!==o.beforeClose.call(n,{type:"beforeClose"},s)&&((!s.save||!1!==o.save.call(n,{type:"save"},s))&&(d.removeClass("fancytree-edit-dirty").off(),l(document).off(".fancytree-edit"),s.save?(n.setTitle(r.options.escapeTitles?i:c(i)),n.setFocus()):s.isNew?(n.remove(),n=s.node=null,a.relatedNode.setFocus()):(n.renderTitle(),n.setFocus()),a.eventData=null,a.currentNode=null,a.relatedNode=null,r.widget._bind(),n&&a.lastDraggableAttrValue&&(n.span.draggable=!0),r.$container.get(0).focus({preventScroll:!0}),s.input=null,o.close.call(n,{type:"close"},s),!0))},l.ui.fancytree._FancytreeNodeClass.prototype.editCreateNode=function(e,t){var i,n=this.tree,r=this;e=e||"child",null==t?t={title:""}:"string"==typeof t?t={title:t}:l.ui.fancytree.assert(l.isPlainObject(t)),"child"!==e||this.isExpanded()||!1===this.hasChildren()?((i=this.addNode(t,e)).match=!0,l(i[n.statusClassPropName]).removeClass("fancytree-hide").addClass("fancytree-match"),i.makeVisible().done(function(){l(i[n.statusClassPropName]).addClass("fancytree-edit-new"),r.tree.ext.edit.relatedNode=r,i.editStart()})):this.setExpanded().done(function(){r.editCreateNode(e,t)})},l.ui.fancytree._FancytreeClass.prototype.isEditing=function(){return this.ext.edit?this.ext.edit.currentNode:null},l.ui.fancytree._FancytreeNodeClass.prototype.isEditing=function(){return!!this.tree.ext.edit&&this.tree.ext.edit.currentNode===this},l.ui.fancytree.registerExtension({name:"edit",version:"2.38.3",options:{adjustWidthOfs:4,allowEmpty:!1,inputCss:{minWidth:"3em"},triggerStart:["f2","mac+enter","shift+click"],trim:!0,beforeClose:l.noop,beforeEdit:l.noop,close:l.noop,edit:l.noop,save:l.noop},currentNode:null,treeInit:function(e){var n=e.tree;this._superApply(arguments),this.$container.addClass("fancytree-ext-edit").on("fancytreebeforeupdateviewport",function(e,t){var i=n.isEditing();i&&(i.info("Cancel edit due to scroll event."),i.editEnd(!1,e))})},nodeClick:function(e){var t=l.ui.fancytree.eventToString(e.originalEvent),i=e.options.edit.triggerStart;return"shift+click"===t&&0<=l.inArray("shift+click",i)&&e.originalEvent.shiftKey||"click"===t&&0<=l.inArray("clickActive",i)&&e.node.isActive()&&!e.node.isEditing()&&l(e.originalEvent.target).hasClass("fancytree-title")?(e.node.editStart(),!1):this._superApply(arguments)},nodeDblclick:function(e){return 0<=l.inArray("dblclick",e.options.edit.triggerStart)?(e.node.editStart(),!1):this._superApply(arguments)},nodeKeydown:function(e){switch(e.originalEvent.which){case 113:if(0<=l.inArray("f2",e.options.edit.triggerStart))return e.node.editStart(),!1;break;case l.ui.keyCode.ENTER:if(0<=l.inArray("mac+enter",e.options.edit.triggerStart)&&t)return e.node.editStart(),!1}return this._superApply(arguments)}}),l.ui.fancytree}); + +/*! Extension 'jquery.fancytree.filter.min.js' */!function(e){"function"==typeof define&&define.amd?define(["jquery","./jquery.fancytree"],e):"object"==typeof module&&module.exports?(require("./jquery.fancytree"),module.exports=e(require("jquery"))):e(jQuery)}(function(g){"use strict";var m="__not_found__",x=g.ui.fancytree.escapeHtml;function v(e){return(e+"").replace(/([.?*+^$[\]\\(){}|-])/g,"\\$1")}function C(e,t,i){for(var n=[],a=1;a<t.length;a++){var r=t[a].length+(1===a?0:1)+(n[n.length-1]||0);n.push(r)}var s=e.split("");return i?n.forEach(function(e){s[e]="\ufff7"+s[e]+"\ufff8"}):n.forEach(function(e){s[e]="<mark>"+s[e]+"</mark>"}),s.join("")}return g.ui.fancytree._FancytreeClass.prototype._applyFilterImpl=function(n,a,e){var t,r,s,l,o,h,d=0,i=this.options,c=i.escapeTitles,u=i.autoCollapse,p=g.extend({},i.filter,e),f="hide"===p.mode,y=!!p.leavesOnly&&!a;if("string"==typeof n){if(""===n)return this.warn("Fancytree passing an empty string as a filter is handled as clearFilter()."),void this.clearFilter();t=p.fuzzy?n.split("").map(v).reduce(function(e,t){return e+"([^"+t+"]*)"+t},""):v(n),r=new RegExp(t,"i"),s=new RegExp(v(n),"gi"),c&&(l=new RegExp(v("\ufff7"),"g"),o=new RegExp(v("\ufff8"),"g")),n=function(e){if(!e.title)return!1;var t,i=c?e.title:0<=(t=e.title).indexOf(">")?g("<div/>").html(t).text():t,t=i.match(r);return t&&p.highlight&&(c?(h=p.fuzzy?C(i,t,c):i.replace(s,function(e){return"\ufff7"+e+"\ufff8"}),e.titleWithHighlight=x(h).replace(l,"<mark>").replace(o,"</mark>")):p.fuzzy?e.titleWithHighlight=C(i,t):e.titleWithHighlight=i.replace(s,function(e){return"<mark>"+e+"</mark>"})),!!t}}return this.enableFilter=!0,this.lastFilterArgs=arguments,e=this.enableUpdate(!1),this.$div.addClass("fancytree-ext-filter"),f?this.$div.addClass("fancytree-ext-filter-hide"):this.$div.addClass("fancytree-ext-filter-dimm"),this.$div.toggleClass("fancytree-ext-filter-hide-expanders",!!p.hideExpanders),this.rootNode.subMatchCount=0,this.visit(function(e){delete e.match,delete e.titleWithHighlight,e.subMatchCount=0}),(t=this.getRootNode()._findDirectChild(m))&&t.remove(),i.autoCollapse=!1,this.visit(function(t){if(!y||null==t.children){var e=n(t),i=!1;if("skip"===e)return t.visit(function(e){e.match=!1},!0),"skip";e||!a&&"branch"!==e||!t.parent.match||(i=e=!0),e&&(d++,t.match=!0,t.visitParents(function(e){e!==t&&(e.subMatchCount+=1),!p.autoExpand||i||e.expanded||(e.setExpanded(!0,{noAnimation:!0,noEvents:!0,scrollIntoView:!1}),e._filterAutoExpanded=!0)},!0))}}),i.autoCollapse=u,0===d&&p.nodata&&f&&(!0===(t="function"==typeof(t=p.nodata)?t():t)?t={}:"string"==typeof t&&(t={title:t}),t=g.extend({statusNodeType:"nodata",key:m,title:this.options.strings.noData},t),this.getRootNode().addNode(t).match=!0),this._callHook("treeStructureChanged",this,"applyFilter"),this.enableUpdate(e),d},g.ui.fancytree._FancytreeClass.prototype.filterNodes=function(e,t){return"boolean"==typeof t&&(t={leavesOnly:t},this.warn("Fancytree.filterNodes() leavesOnly option is deprecated since 2.9.0 / 2015-04-19. Use opts.leavesOnly instead.")),this._applyFilterImpl(e,!1,t)},g.ui.fancytree._FancytreeClass.prototype.filterBranches=function(e,t){return this._applyFilterImpl(e,!0,t)},g.ui.fancytree._FancytreeClass.prototype.updateFilter=function(){this.enableFilter&&this.lastFilterArgs&&this.options.filter.autoApply?this._applyFilterImpl.apply(this,this.lastFilterArgs):this.warn("updateFilter(): no filter active.")},g.ui.fancytree._FancytreeClass.prototype.clearFilter=function(){var t,e=this.getRootNode()._findDirectChild(m),i=this.options.escapeTitles,n=this.options.enhanceTitle,a=this.enableUpdate(!1);e&&e.remove(),delete this.rootNode.match,delete this.rootNode.subMatchCount,this.visit(function(e){e.match&&e.span&&(t=g(e.span).find(">span.fancytree-title"),i?t.text(e.title):t.html(e.title),n&&n({type:"enhanceTitle"},{node:e,$title:t})),delete e.match,delete e.subMatchCount,delete e.titleWithHighlight,e.$subMatchBadge&&(e.$subMatchBadge.remove(),delete e.$subMatchBadge),e._filterAutoExpanded&&e.expanded&&e.setExpanded(!1,{noAnimation:!0,noEvents:!0,scrollIntoView:!1}),delete e._filterAutoExpanded}),this.enableFilter=!1,this.lastFilterArgs=null,this.$div.removeClass("fancytree-ext-filter fancytree-ext-filter-dimm fancytree-ext-filter-hide"),this._callHook("treeStructureChanged",this,"clearFilter"),this.enableUpdate(a)},g.ui.fancytree._FancytreeClass.prototype.isFilterActive=function(){return!!this.enableFilter},g.ui.fancytree._FancytreeNodeClass.prototype.isMatched=function(){return!(this.tree.enableFilter&&!this.match)},g.ui.fancytree.registerExtension({name:"filter",version:"2.38.3",options:{autoApply:!0,autoExpand:!1,counter:!0,fuzzy:!1,hideExpandedCounter:!0,hideExpanders:!1,highlight:!0,leavesOnly:!1,nodata:!0,mode:"dimm"},nodeLoadChildren:function(e,t){var i=e.tree;return this._superApply(arguments).done(function(){i.enableFilter&&i.lastFilterArgs&&e.options.filter.autoApply&&i._applyFilterImpl.apply(i,i.lastFilterArgs)})},nodeSetExpanded:function(e,t,i){var n=e.node;return delete n._filterAutoExpanded,!t&&e.options.filter.hideExpandedCounter&&n.$subMatchBadge&&n.$subMatchBadge.show(),this._superApply(arguments)},nodeRenderStatus:function(e){var t=e.node,i=e.tree,n=e.options.filter,a=g(t.span).find("span.fancytree-title"),r=g(t[i.statusClassPropName]),s=e.options.enhanceTitle,l=e.options.escapeTitles,e=this._super(e);return r.length&&i.enableFilter&&(r.toggleClass("fancytree-match",!!t.match).toggleClass("fancytree-submatch",!!t.subMatchCount).toggleClass("fancytree-hide",!(t.match||t.subMatchCount)),!n.counter||!t.subMatchCount||t.isExpanded()&&n.hideExpandedCounter?t.$subMatchBadge&&t.$subMatchBadge.hide():(t.$subMatchBadge||(t.$subMatchBadge=g("<span class='fancytree-childcounter'/>"),g("span.fancytree-icon, span.fancytree-custom-icon",t.span).append(t.$subMatchBadge)),t.$subMatchBadge.show().text(t.subMatchCount)),!t.span||t.isEditing&&t.isEditing.call(t)||(t.titleWithHighlight?a.html(t.titleWithHighlight):l?a.text(t.title):a.html(t.title),s&&s({type:"enhanceTitle"},{node:t,$title:a}))),e}}),g.ui.fancytree}); + +/*! Extension 'jquery.fancytree.glyph.min.js' */!function(e){"function"==typeof define&&define.amd?define(["jquery","./jquery.fancytree"],e):"object"==typeof module&&module.exports?(require("./jquery.fancytree"),module.exports=e(require("jquery"))):e(jQuery)}(function(i){"use strict";var d=i.ui.fancytree,n={awesome3:{_addClass:"",checkbox:"icon-check-empty",checkboxSelected:"icon-check",checkboxUnknown:"icon-check icon-muted",dragHelper:"icon-caret-right",dropMarker:"icon-caret-right",error:"icon-exclamation-sign",expanderClosed:"icon-caret-right",expanderLazy:"icon-angle-right",expanderOpen:"icon-caret-down",loading:"icon-refresh icon-spin",nodata:"icon-meh",noExpander:"",radio:"icon-circle-blank",radioSelected:"icon-circle",doc:"icon-file-alt",docOpen:"icon-file-alt",folder:"icon-folder-close-alt",folderOpen:"icon-folder-open-alt"},awesome4:{_addClass:"fa",checkbox:"fa-square-o",checkboxSelected:"fa-check-square-o",checkboxUnknown:"fa-square fancytree-helper-indeterminate-cb",dragHelper:"fa-arrow-right",dropMarker:"fa-long-arrow-right",error:"fa-warning",expanderClosed:"fa-caret-right",expanderLazy:"fa-angle-right",expanderOpen:"fa-caret-down",loading:{html:"<span class='fa fa-spinner fa-pulse' />"},nodata:"fa-meh-o",noExpander:"",radio:"fa-circle-thin",radioSelected:"fa-circle",doc:"fa-file-o",docOpen:"fa-file-o",folder:"fa-folder-o",folderOpen:"fa-folder-open-o"},awesome5:{_addClass:"",checkbox:"far fa-square",checkboxSelected:"far fa-check-square",checkboxUnknown:"fas fa-square fancytree-helper-indeterminate-cb",radio:"far fa-circle",radioSelected:"fas fa-circle",radioUnknown:"far fa-dot-circle",dragHelper:"fas fa-arrow-right",dropMarker:"fas fa-long-arrow-alt-right",error:"fas fa-exclamation-triangle",expanderClosed:"fas fa-caret-right",expanderLazy:"fas fa-angle-right",expanderOpen:"fas fa-caret-down",loading:"fas fa-spinner fa-pulse",nodata:"far fa-meh",noExpander:"",doc:"far fa-file",docOpen:"far fa-file",folder:"far fa-folder",folderOpen:"far fa-folder-open"},bootstrap3:{_addClass:"glyphicon",checkbox:"glyphicon-unchecked",checkboxSelected:"glyphicon-check",checkboxUnknown:"glyphicon-expand fancytree-helper-indeterminate-cb",dragHelper:"glyphicon-play",dropMarker:"glyphicon-arrow-right",error:"glyphicon-warning-sign",expanderClosed:"glyphicon-menu-right",expanderLazy:"glyphicon-menu-right",expanderOpen:"glyphicon-menu-down",loading:"glyphicon-refresh fancytree-helper-spin",nodata:"glyphicon-info-sign",noExpander:"",radio:"glyphicon-remove-circle",radioSelected:"glyphicon-ok-circle",doc:"glyphicon-file",docOpen:"glyphicon-file",folder:"glyphicon-folder-close",folderOpen:"glyphicon-folder-open"},material:{_addClass:"material-icons",checkbox:{text:"check_box_outline_blank"},checkboxSelected:{text:"check_box"},checkboxUnknown:{text:"indeterminate_check_box"},dragHelper:{text:"play_arrow"},dropMarker:{text:"arrow-forward"},error:{text:"warning"},expanderClosed:{text:"chevron_right"},expanderLazy:{text:"last_page"},expanderOpen:{text:"expand_more"},loading:{text:"autorenew",addClass:"fancytree-helper-spin"},nodata:{text:"info"},noExpander:{text:""},radio:{text:"radio_button_unchecked"},radioSelected:{text:"radio_button_checked"},doc:{text:"insert_drive_file"},docOpen:{text:"insert_drive_file"},folder:{text:"folder"},folderOpen:{text:"folder_open"}}};function l(e,r,n,a,o){var t=a.map,c=t[o],d=i(r),a=d.find(".fancytree-childcounter"),t=n+" "+(t._addClass||"");"string"==typeof(c="function"==typeof c?c.call(this,e,r,o):c)?(r.innerHTML="",d.attr("class",t+" "+c).append(a)):c&&(c.text?r.textContent=""+c.text:c.html?r.innerHTML=c.html:r.innerHTML="",d.attr("class",t+" "+(c.addClass||"")).append(a))}return i.ui.fancytree.registerExtension({name:"glyph",version:"2.38.3",options:{preset:null,map:{}},treeInit:function(e){var r=e.tree,e=e.options.glyph;e.preset?(d.assert(!!n[e.preset],"Invalid value for `options.glyph.preset`: "+e.preset),e.map=i.extend({},n[e.preset],e.map)):r.warn("ext-glyph: missing `preset` option."),this._superApply(arguments),r.$container.addClass("fancytree-ext-glyph")},nodeRenderStatus:function(e){var r,n,a=e.node,o=i(a.span),t=e.options.glyph,c=this._super(e);return a.isRootNode()||((n=o.children(".fancytree-expander").get(0))&&(r=a.expanded&&a.hasChildren()?"expanderOpen":a.isUndefined()?"expanderLazy":a.hasChildren()?"expanderClosed":"noExpander",l(a,n,"fancytree-expander",t,r)),(n=(a.tr?i("td",a.tr).find(".fancytree-checkbox"):o.children(".fancytree-checkbox")).get(0))&&(e=d.evalOption("checkbox",a,a,t,!1),a.parent&&a.parent.radiogroup||"radio"===e?l(a,n,"fancytree-checkbox fancytree-radio",t,r=a.selected?"radioSelected":"radio"):l(a,n,"fancytree-checkbox",t,r=a.selected?"checkboxSelected":a.partsel?"checkboxUnknown":"checkbox")),(n=o.children(".fancytree-icon").get(0))&&(r=a.statusNodeType||(a.folder?a.expanded&&a.hasChildren()?"folderOpen":"folder":a.expanded?"docOpen":"doc"),l(a,n,"fancytree-icon",t,r))),c},nodeSetStatus:function(e,r,n,a){var o,t=e.options.glyph,c=e.node,e=this._superApply(arguments);return"error"!==r&&"loading"!==r&&"nodata"!==r||(c.parent?(o=i(".fancytree-expander",c.span).get(0))&&l(c,o,"fancytree-expander",t,r):(o=i(".fancytree-statusnode-"+r,c[this.nodeContainerAttrName]).find(".fancytree-icon").get(0))&&l(c,o,"fancytree-icon",t,r)),e}}),i.ui.fancytree}); + +/*! Extension 'jquery.fancytree.gridnav.min.js' */!function(e){"function"==typeof define&&define.amd?define(["jquery","./jquery.fancytree","./jquery.fancytree.table"],e):"object"==typeof module&&module.exports?(require("./jquery.fancytree.table"),module.exports=e(require("jquery"))):e(jQuery)}(function(l){"use strict";var p=l.ui.keyCode,o={text:[p.UP,p.DOWN],checkbox:[p.UP,p.DOWN,p.LEFT,p.RIGHT],link:[p.UP,p.DOWN,p.LEFT,p.RIGHT],radiobutton:[p.UP,p.DOWN,p.LEFT,p.RIGHT],"select-one":[p.LEFT,p.RIGHT],"select-multiple":[p.LEFT,p.RIGHT]};function a(e,t){var n,i,r,o,a,s,u=e.closest("td"),c=null;switch(t){case p.LEFT:c=u.prev();break;case p.RIGHT:c=u.next();break;case p.UP:case p.DOWN:for(n=u.parent(),r=n,a=u.get(0),s=0,r.children().each(function(){return this!==a&&(o=l(this).prop("colspan"),void(s+=o||1))}),i=s;(n=t===p.UP?n.prev():n.next()).length&&(n.is(":hidden")||!(c=function(e,t){var n,i=null,r=0;return e.children().each(function(){return t<=r?(i=l(this),!1):(n=l(this).prop("colspan"),void(r+=n||1))}),i}(n,i))||!c.find(":input,a").length););}return c}return l.ui.fancytree.registerExtension({name:"gridnav",version:"2.38.3",options:{autofocusInput:!1,handleCursorKeys:!0},treeInit:function(n){this._requireExtension("table",!0,!0),this._superApply(arguments),this.$container.addClass("fancytree-ext-gridnav"),this.$container.on("focusin",function(e){var t=l.ui.fancytree.getNode(e.target);t&&!t.isActive()&&(e=n.tree._makeHookContext(t,e),n.tree._callHook("nodeSetActive",e,!0))})},nodeSetActive:function(e,t,n){var i=e.options.gridnav,r=e.node,o=e.originalEvent||{},o=l(o.target).is(":input");t=!1!==t,this._superApply(arguments),t&&(e.options.titlesTabbable?(o||(l(r.span).find("span.fancytree-title").focus(),r.setFocus()),e.tree.$container.attr("tabindex","-1")):i.autofocusInput&&!o&&l(r.tr||r.span).find(":input:enabled").first().focus())},nodeKeydown:function(e){var t,n,i=e.options.gridnav,r=e.originalEvent,e=l(r.target);return e.is(":input:enabled")?t=e.prop("type"):e.is("a")&&(t="link"),t&&i.handleCursorKeys?!((t=o[t])&&0<=l.inArray(r.which,t)&&(n=a(e,r.which))&&n.length)||(n.find(":input:enabled,a").focus(),!1):this._superApply(arguments)}}),l.ui.fancytree}); + +/*! Extension 'jquery.fancytree.multi.min.js' */!function(e){"function"==typeof define&&define.amd?define(["jquery","./jquery.fancytree"],e):"object"==typeof module&&module.exports?(require("./jquery.fancytree"),module.exports=e(require("jquery"))):e(jQuery)}(function(o){"use strict";return o.ui.fancytree.registerExtension({name:"multi",version:"2.38.3",options:{allowNoSelect:!1,mode:"sameParent"},treeInit:function(e){this._superApply(arguments),this.$container.addClass("fancytree-ext-multi"),1===e.options.selectMode&&o.error("Fancytree ext-multi: selectMode: 1 (single) is not compatible.")},nodeClick:function(e){var t=e.tree,i=e.node,r=t.getActiveNode()||t.getFirstChild(),n="checkbox"===e.targetType,c="expander"===e.targetType;switch(o.ui.fancytree.eventToString(e.originalEvent)){case"click":if(c)break;n||(t.selectAll(!1),i.setSelected());break;case"shift+click":t.visitRows(function(e){if(e.setSelected(),e===i)return!1},{start:r,reverse:r.isBelowOf(i)});break;case"ctrl+click":case"meta+click":return void i.toggleSelected()}return this._superApply(arguments)},nodeKeydown:function(e){var t=e.tree,i=e.node,r=e.originalEvent;switch(o.ui.fancytree.eventToString(r)){case"up":case"down":t.selectAll(!1),i.navigate(r.which,!0),t.getActiveNode().setSelected();break;case"shift+up":case"shift+down":i.navigate(r.which,!0),t.getActiveNode().setSelected()}return this._superApply(arguments)}}),o.ui.fancytree}); + +/*! Extension 'jquery.fancytree.persist.min.js' */!function(e){"function"==typeof define&&define.amd?define(["jquery","./jquery.fancytree"],e):"object"==typeof module&&module.exports?(require("./jquery.fancytree"),module.exports=e(require("jquery"))):e(jQuery)}(function(y){"use strict";var t=null,o=null,i=null,s=y.ui.fancytree.assert,u="active",v="expanded",p="focus",f="selected";try{s(window.localStorage&&window.localStorage.getItem),o={get:function(e){return window.localStorage.getItem(e)},set:function(e,t){window.localStorage.setItem(e,t)},remove:function(e){window.localStorage.removeItem(e)}}}catch(e){y.ui.fancytree.warn("Could not access window.localStorage",e)}try{s(window.sessionStorage&&window.sessionStorage.getItem),i={get:function(e){return window.sessionStorage.getItem(e)},set:function(e,t){window.sessionStorage.setItem(e,t)},remove:function(e){window.sessionStorage.removeItem(e)}}}catch(e){y.ui.fancytree.warn("Could not access window.sessionStorage",e)}return"function"==typeof Cookies?t={get:Cookies.get,set:function(e,t){Cookies.set(e,t,this.options.persist.cookie)},remove:Cookies.remove}:y&&"function"==typeof y.cookie&&(t={get:y.cookie,set:function(e,t){y.cookie(e,t,this.options.persist.cookie)},remove:y.removeCookie}),y.ui.fancytree._FancytreeClass.prototype.clearPersistData=function(e){var t=this.ext.persist,o=t.cookiePrefix;0<=(e=e||"active expanded focus selected").indexOf(u)&&t._data(o+u,null),0<=e.indexOf(v)&&t._data(o+v,null),0<=e.indexOf(p)&&t._data(o+p,null),0<=e.indexOf(f)&&t._data(o+f,null)},y.ui.fancytree._FancytreeClass.prototype.clearCookies=function(e){return this.warn("'tree.clearCookies()' is deprecated since v2.27.0: use 'clearPersistData()' instead."),this.clearPersistData(e)},y.ui.fancytree._FancytreeClass.prototype.getPersistData=function(){var e=this.ext.persist,t=e.cookiePrefix,o=e.cookieDelimiter,i={};return i[u]=e._data(t+u),i[v]=(e._data(t+v)||"").split(o),i[f]=(e._data(t+f)||"").split(o),i[p]=e._data(t+p),i},y.ui.fancytree.registerExtension({name:"persist",version:"2.38.3",options:{cookieDelimiter:"~",cookiePrefix:void 0,cookie:{raw:!1,expires:"",path:"",domain:"",secure:!1},expandLazy:!1,expandOpts:void 0,fireActivate:!0,overrideSource:!0,store:"auto",types:"active expanded focus selected"},_data:function(e,t){var o=this._local.store;if(void 0===t)return o.get.call(this,e);null===t?o.remove.call(this,e):o.set.call(this,e,t)},_appendKey:function(e,t,o){t=""+t;var i=this._local,s=this.options.persist.cookieDelimiter,r=i.cookiePrefix+e,n=i._data(r),e=n?n.split(s):[],n=y.inArray(t,e);0<=n&&e.splice(n,1),o&&e.push(t),i._data(r,e.join(s))},treeInit:function(e){var a=e.tree,c=e.options,d=this._local,l=this.options.persist;return d.cookiePrefix=l.cookiePrefix||"fancytree-"+a._id+"-",d.storeActive=0<=l.types.indexOf(u),d.storeExpanded=0<=l.types.indexOf(v),d.storeSelected=0<=l.types.indexOf(f),d.storeFocus=0<=l.types.indexOf(p),d.store=null,"auto"===l.store&&(l.store=o?"local":"cookie"),y.isPlainObject(l.store)?d.store=l.store:"cookie"===l.store?d.store=t:"local"!==l.store&&"session"!==l.store||(d.store="local"===l.store?o:i),s(d.store,"Need a valid store."),a.$div.on("fancytreeinit",function(e){var t,o,i,s,r,n;!1!==a._triggerTreeEvent("beforeRestore",null,{})&&(i=d._data(d.cookiePrefix+p),s=!1===l.fireActivate,r=d._data(d.cookiePrefix+v),n=r&&r.split(l.cookieDelimiter),(d.storeExpanded?function e(t,o,i,s,r){var n,a,c,d,l=!1,u=t.options.persist.expandOpts,p=[],f=[];for(i=i||[],r=r||y.Deferred(),n=0,c=i.length;n<c;n++)a=i[n],(d=t.getNodeByKey(a))?s&&d.isUndefined()?(l=!0,t.debug("_loadLazyNodes: "+d+" is lazy: loading..."),"expand"===s?p.push(d.setExpanded(!0,u)):p.push(d.load())):(t.debug("_loadLazyNodes: "+d+" already loaded."),d.setExpanded(!0,u)):(f.push(a),t.debug("_loadLazyNodes: "+d+" was not yet found."));return y.when.apply(y,p).always(function(){if(l&&0<f.length)e(t,o,f,s,r);else{if(f.length)for(t.warn("_loadLazyNodes: could not load those keys: ",f),n=0,c=f.length;n<c;n++)a=i[n],o._appendKey(v,i[n],!1);r.resolve()}}),r}(a,d,n,!!l.expandLazy&&"expand",null):(new y.Deferred).resolve()).done(function(){if(d.storeSelected){if(r=d._data(d.cookiePrefix+f))for(n=r.split(l.cookieDelimiter),t=0;t<n.length;t++)(o=a.getNodeByKey(n[t]))?(void 0===o.selected||l.overrideSource&&!1===o.selected)&&(o.selected=!0,o.renderStatus()):d._appendKey(f,n[t],!1);3===a.options.selectMode&&a.visit(function(e){if(e.selected)return e.fixSelection3AfterClick(),"skip"})}d.storeActive&&(!(r=d._data(d.cookiePrefix+u))||!c.persist.overrideSource&&a.activeNode||(o=a.getNodeByKey(r))&&(o.debug("persist: set active",r),o.setActive(!0,{noFocus:!0,noEvents:s}))),d.storeFocus&&i&&(o=a.getNodeByKey(i))&&(a.options.titlesTabbable?y(o.span).find(".fancytree-title"):y(a.$container)).focus(),a._triggerTreeEvent("restore",null,{})}))}),this._superApply(arguments)},nodeSetActive:function(e,t,o){var i=this._local;return t=!1!==t,t=this._superApply(arguments),i.storeActive&&i._data(i.cookiePrefix+u,this.activeNode?this.activeNode.key:null),t},nodeSetExpanded:function(e,t,o){var i=e.node,s=this._local;return t=!1!==t,e=this._superApply(arguments),s.storeExpanded&&s._appendKey(v,i.key,t),e},nodeSetFocus:function(e,t){var o=this._local;return t=!1!==t,t=this._superApply(arguments),o.storeFocus&&o._data(o.cookiePrefix+p,this.focusNode?this.focusNode.key:null),t},nodeSetSelected:function(e,t,o){var i=e.tree,s=e.node,r=this._local;return t=!1!==t,t=this._superApply(arguments),r.storeSelected&&(3===i.options.selectMode?(i=(i=y.map(i.getSelectedNodes(!0),function(e){return e.key})).join(e.options.persist.cookieDelimiter),r._data(r.cookiePrefix+f,i)):r._appendKey(f,s.key,s.selected)),t}}),y.ui.fancytree}); + +/*! Extension 'jquery.fancytree.table.min.js' */!function(e){"function"==typeof define&&define.amd?define(["jquery","./jquery.fancytree"],e):"object"==typeof module&&module.exports?(require("./jquery.fancytree"),module.exports=e(require("jquery"))):e(jQuery)}(function(v){"use strict";var g=v.ui.fancytree.assert;function x(e,n){e.visit(function(e){var t=e.tr;if(t&&(t.style.display=e.hide||!n?"none":""),!e.expanded)return"skip"})}return v.ui.fancytree.registerExtension({name:"table",version:"2.38.3",options:{checkboxColumnIdx:null,indentation:16,mergeStatusColumns:!0,nodeColumnIdx:0},treeInit:function(e){var t,n,r,o=e.tree,d=e.options,s=d.table,a=o.widget.element;if(null!=s.customStatus&&(null==d.renderStatusColumns?(o.warn("The 'customStatus' option is deprecated since v2.15.0. Use 'renderStatusColumns' instead."),d.renderStatusColumns=s.customStatus):v.error("The 'customStatus' option is deprecated since v2.15.0. Use 'renderStatusColumns' only instead.")),d.renderStatusColumns&&!0===d.renderStatusColumns&&(d.renderStatusColumns=d.renderColumns),a.addClass("fancytree-container fancytree-ext-table"),(r=a.find(">tbody")).length||(a.find(">tr").length&&v.error("Expected table > tbody > tr. If you see this please open an issue."),r=v("<tbody>").appendTo(a)),o.tbody=r[0],o.columnCount=v("thead >tr",a).last().find(">th",a).length,(n=r.children("tr").first()).length)e=n.children("td").length,o.columnCount&&e!==o.columnCount&&(o.warn("Column count mismatch between thead ("+o.columnCount+") and tbody ("+e+"): using tbody."),o.columnCount=e),n=n.clone();else for(g(1<=o.columnCount,"Need either <thead> or <tbody> with <td> elements to determine column count."),n=v("<tr />"),t=0;t<o.columnCount;t++)n.append("<td />");n.find(">td").eq(s.nodeColumnIdx).html("<span class='fancytree-node' />"),d.aria&&(n.attr("role","row"),n.find("td").attr("role","gridcell")),o.rowFragment=document.createDocumentFragment(),o.rowFragment.appendChild(n.get(0)),r.empty(),o.statusClassPropName="tr",o.ariaPropName="tr",this.nodeContainerAttrName="tr",o.$container=a,this._superApply(arguments),v(o.rootNode.ul).remove(),o.rootNode.ul=null,this.$container.attr("tabindex",d.tabindex),d.aria&&o.$container.attr("role","treegrid").attr("aria-readonly",!0)},nodeRemoveChildMarkup:function(e){e.node.visit(function(e){e.tr&&(v(e.tr).remove(),e.tr=null)})},nodeRemoveMarkup:function(e){var t=e.node;t.tr&&(v(t.tr).remove(),t.tr=null),this.nodeRemoveChildMarkup(e)},nodeRender:function(e,t,n,r,o){var d,s,a,i,l,u,c,p,h,m=e.tree,f=e.node,y=e.options,C=!f.parent;if(!1!==m._enableUpdate){if(o||(e.hasCollapsedParents=f.parent&&!f.parent.expanded),!C)if(f.tr&&t&&this.nodeRemoveMarkup(e),f.tr)t?this.nodeRenderTitle(e):this.nodeRenderStatus(e);else{if(e.hasCollapsedParents&&!n)return;l=m.rowFragment.firstChild.cloneNode(!0),p=function(e){var t,n,r=e.parent,o=r?r.children:null;if(o&&1<o.length&&o[0]!==e)for(n=o[v.inArray(e,o)-1],g(n.tr);n.children&&n.children.length&&(t=n.children[n.children.length-1]).tr;)n=t;else n=r;return n}(f),g(p),(!0===r&&o||n&&e.hasCollapsedParents)&&(l.style.display="none"),p.tr?(h=p.tr).parentNode.insertBefore(l,h.nextSibling):(g(!p.parent,"prev. row must have a tr, or be system root"),(p=m.tbody).insertBefore(l,p.firstChild)),f.tr=l,f.key&&y.generateIds&&(f.tr.id=y.idPrefix+f.key),(f.tr.ftnode=f).span=v("span.fancytree-node",f.tr).get(0),this.nodeRenderTitle(e),y.createNode&&y.createNode.call(m,{type:"createNode"},e)}if(y.renderNode&&y.renderNode.call(m,{type:"renderNode"},e),(d=f.children)&&(C||n||f.expanded))for(a=0,i=d.length;a<i;a++)(c=v.extend({},e,{node:d[a]})).hasCollapsedParents=c.hasCollapsedParents||!f.expanded,this.nodeRender(c,t,n,r,!0);d&&!o&&(u=f.tr||null,s=m.tbody.firstChild,f.visit(function(e){var t;e.tr&&(e.parent.expanded||"none"===e.tr.style.display||(e.tr.style.display="none",x(e,!1)),e.tr.previousSibling!==u&&(f.debug("_fixOrder: mismatch at node: "+e),t=u?u.nextSibling:s,m.tbody.insertBefore(e.tr,t)),u=e.tr)}))}},nodeRenderTitle:function(e,t){var n=e.tree,r=e.node,o=e.options,d=r.isStatusNode(),s=this._super(e,t);return r.isRootNode()||(o.checkbox&&!d&&null!=o.table.checkboxColumnIdx&&(t=v("span.fancytree-checkbox",r.span),v(r.tr).find("td").eq(+o.table.checkboxColumnIdx).html(t)),this.nodeRenderStatus(e),d?o.renderStatusColumns?o.renderStatusColumns.call(n,{type:"renderStatusColumns"},e):o.table.mergeStatusColumns&&r.isTopLevel()&&v(r.tr).find(">td").eq(0).prop("colspan",n.columnCount).text(r.title).addClass("fancytree-status-merged").nextAll().remove():o.renderColumns&&o.renderColumns.call(n,{type:"renderColumns"},e)),s},nodeRenderStatus:function(e){var t=e.node,n=e.options;this._super(e),v(t.tr).removeClass("fancytree-node"),e=(t.getLevel()-1)*n.table.indentation,n.rtl?v(t.span).css({paddingRight:e+"px"}):v(t.span).css({paddingLeft:e+"px"})},nodeSetExpanded:function(t,n,r){if(n=!1!==n,t.node.expanded&&n||!t.node.expanded&&!n)return this._superApply(arguments);var o=new v.Deferred,e=v.extend({},r,{noEvents:!0,noAnimation:!0});function d(e){e?(x(t.node,n),n&&t.options.autoScroll&&!r.noAnimation&&t.node.hasChildren()?t.node.getLastChild().scrollIntoView(!0,{topNode:t.node}).always(function(){r.noEvents||t.tree._triggerNodeEvent(n?"expand":"collapse",t),o.resolveWith(t.node)}):(r.noEvents||t.tree._triggerNodeEvent(n?"expand":"collapse",t),o.resolveWith(t.node))):(r.noEvents||t.tree._triggerNodeEvent(n?"expand":"collapse",t),o.rejectWith(t.node))}return r=r||{},this._super(t,n,e).done(function(){d(!0)}).fail(function(){d(!1)}),o.promise()},nodeSetStatus:function(e,t,n,r){return"ok"!==t||(e=(e=e.node).children?e.children[0]:null)&&e.isStatusNode()&&v(e.tr).remove(),this._superApply(arguments)},treeClear:function(e){return this.nodeRemoveChildMarkup(this._makeHookContext(this.rootNode)),this._superApply(arguments)},treeDestroy:function(e){return this.$container.find("tbody").empty(),this.$source&&this.$source.removeClass("fancytree-helper-hidden"),this._superApply(arguments)}}),v.ui.fancytree}); + +/*! Extension 'jquery.fancytree.themeroller.min.js' */!function(e){"function"==typeof define&&define.amd?define(["jquery","./jquery.fancytree"],e):"object"==typeof module&&module.exports?(require("./jquery.fancytree"),module.exports=e(require("jquery"))):e(jQuery)}(function(l){"use strict";return l.ui.fancytree.registerExtension({name:"themeroller",version:"2.38.3",options:{activeClass:"ui-state-active",addClass:"ui-corner-all",focusClass:"ui-state-focus",hoverClass:"ui-state-hover",selectedClass:"ui-state-highlight"},treeInit:function(e){var s=e.widget.element,t=e.options.themeroller;this._superApply(arguments),"TABLE"===s[0].nodeName?(s.addClass("ui-widget ui-corner-all"),s.find(">thead tr").addClass("ui-widget-header"),s.find(">tbody").addClass("ui-widget-conent")):s.addClass("ui-widget ui-widget-content ui-corner-all"),s.on("mouseenter mouseleave",".fancytree-node",function(e){var s=l.ui.fancytree.getNode(e.target),e="mouseenter"===e.type;l(s.tr||s.span).toggleClass(t.hoverClass+" "+t.addClass,e)})},treeDestroy:function(e){this._superApply(arguments),e.widget.element.removeClass("ui-widget ui-widget-content ui-corner-all")},nodeRenderStatus:function(e){var s={},t=e.node,a=l(t.tr||t.span),i=e.options.themeroller;this._super(e),s[i.activeClass]=!1,s[i.focusClass]=!1,s[i.selectedClass]=!1,t.isActive()&&(s[i.activeClass]=!0),t.hasFocus()&&(s[i.focusClass]=!0),t.isSelected()&&!t.isActive()&&(s[i.selectedClass]=!0),a.toggleClass(i.activeClass,s[i.activeClass]),a.toggleClass(i.focusClass,s[i.focusClass]),a.toggleClass(i.selectedClass,s[i.selectedClass]),a.addClass(i.addClass)}}),l.ui.fancytree}); + +/*! Extension 'jquery.fancytree.wide.min.js' */!function(e){"function"==typeof define&&define.amd?define(["jquery","./jquery.fancytree"],e):"object"==typeof module&&module.exports?(require("./jquery.fancytree"),module.exports=e(require("jquery"))):e(jQuery)}(function(o){"use strict";var p=/^([+-]?(?:\d+|\d*\.\d+))([a-z]*|%)$/;function f(e,t){var a=o("#"+(e="fancytree-style-"+e));if(t){a.length||(a=o("<style />").attr("id",e).addClass("fancytree-style").prop("type","text/css").appendTo("head"));try{a.html(t)}catch(e){a[0].styleSheet.cssText=t}return a}a.remove()}function u(e,t,a,n,l,i){for(var s="#"+e+" span.fancytree-level-",c=[],r=0;r<t;r++)c.push(s+(r+1)+" span.fancytree-title { padding-left: "+(r*a+n)+i+"; }");return c.push("#"+e+" div.ui-effects-wrapper ul li span.fancytree-title, #"+e+" li.fancytree-animating span.fancytree-title { padding-left: "+l+i+"; position: static; width: auto; }"),c.join("\n")}return o.ui.fancytree.registerExtension({name:"wide",version:"2.38.3",options:{iconWidth:null,iconSpacing:null,labelSpacing:null,levelOfs:null},treeCreate:function(e){this._superApply(arguments),this.$container.addClass("fancytree-ext-wide");var t=e.options.wide,a=o("<li id='fancytreeTemp'><span class='fancytree-node'><span class='fancytree-icon' /><span class='fancytree-title' /></span><ul />").appendTo(e.tree.$container),n=a.find(".fancytree-icon"),l=a.find("ul"),i=t.iconSpacing||n.css("margin-left"),s=t.iconWidth||n.css("width"),c=t.labelSpacing||"3px",r=t.levelOfs||l.css("padding-left");a.remove(),n=i.match(p)[2],i=parseFloat(i,10),t=c.match(p)[2],c=parseFloat(c,10),l=s.match(p)[2],s=parseFloat(s,10),a=r.match(p)[2],n===l&&a===l&&t===l||o.error("iconWidth, iconSpacing, and levelOfs must have the same css measure unit"),this._local.measureUnit=l,this._local.levelOfs=parseFloat(r),this._local.lineOfs=(1+(e.options.checkbox?1:0)+(!1===e.options.icon?0:1))*(s+i)+i,this._local.labelOfs=c,this._local.maxDepth=10,f(c=this.$container.uniqueId().attr("id"),u(c,this._local.maxDepth,this._local.levelOfs,this._local.lineOfs,this._local.labelOfs,this._local.measureUnit))},treeDestroy:function(e){return f(this.$container.attr("id"),null),this._superApply(arguments)},nodeRenderStatus:function(e){var t=e.node,a=t.getLevel(),n=this._super(e);return a>this._local.maxDepth&&(e=this.$container.attr("id"),this._local.maxDepth*=2,t.debug("Define global ext-wide css up to level "+this._local.maxDepth),f(e,u(e,this._local.maxDepth,this._local.levelOfs,this._local.lineOfs,this._local.labelSpacing,this._local.measureUnit))),o(t.span).addClass("fancytree-level-"+a),n}}),o.ui.fancytree}); +// Value returned by `require('jquery.fancytree')` +return $.ui.fancytree; +})); // End of closure diff --git a/plugins/55/indexmenu/scripts/fancytree/jquery.fancytree.min.js b/plugins/55/indexmenu/scripts/fancytree/jquery.fancytree.min.js new file mode 100644 index 0000000..452a287 --- /dev/null +++ b/plugins/55/indexmenu/scripts/fancytree/jquery.fancytree.min.js @@ -0,0 +1 @@ +!function(e){"function"==typeof define&&define.amd?define(["jquery","./jquery.fancytree.ui-deps"],e):"object"==typeof module&&module.exports?(require("./jquery.fancytree.ui-deps"),module.exports=e(require("jquery"))):e(jQuery)}(function(k){"use strict";if(!k.ui||!k.ui.fancytree){for(var e,h=null,c=new RegExp(/\.|\//),t=/[&<>"'/]/g,n=/[<>"'/]/g,f="$recursive_request",p="$request_target_invalid",i={"&":"&","<":"<",">":">",'"':""","'":"'","/":"/"},r={16:!0,17:!0,18:!0},u={8:"backspace",9:"tab",10:"return",13:"return",19:"pause",20:"capslock",27:"esc",32:"space",33:"pageup",34:"pagedown",35:"end",36:"home",37:"left",38:"up",39:"right",40:"down",45:"insert",46:"del",59:";",61:"=",96:"0",97:"1",98:"2",99:"3",100:"4",101:"5",102:"6",103:"7",104:"8",105:"9",106:"*",107:"+",109:"-",110:".",111:"/",112:"f1",113:"f2",114:"f3",115:"f4",116:"f5",117:"f6",118:"f7",119:"f8",120:"f9",121:"f10",122:"f11",123:"f12",144:"numlock",145:"scroll",173:"-",186:";",187:"=",188:",",189:"-",190:".",191:"/",192:"`",219:"[",220:"\\",221:"]",222:"'"},g={16:"shift",17:"ctrl",18:"alt",91:"meta",93:"meta"},o={0:"",1:"left",2:"middle",3:"right"},v="active expanded focus folder lazy radiogroup selected unselectable unselectableIgnore".split(" "),y={},b="columns types".split(" "),m="checkbox expanded extraClasses folder icon iconTooltip key lazy partsel radiogroup refKey selected statusNodeType title tooltip type unselectable unselectableIgnore unselectableStatus".split(" "),s={},x={},a={active:!0,children:!0,data:!0,focus:!0},l=0;l<v.length;l++)y[v[l]]=!0;for(l=0;l<m.length;l++)e=m[l],s[e]=!0,e!==e.toLowerCase()&&(x[e.toLowerCase()]=e);var N=Array.isArray;return _(k.ui,"Fancytree requires jQuery UI (http://jqueryui.com)"),Date.now||(Date.now=function(){return(new Date).getTime()}),I.prototype={_findDirectChild:function(e){var t,n,i=this.children;if(i)if("string"==typeof e){for(t=0,n=i.length;t<n;t++)if(i[t].key===e)return i[t]}else{if("number"==typeof e)return this.children[e];if(e.parent===this)return e}return null},_setChildren:function(e){_(e&&(!this.children||0===this.children.length),"only init supported"),this.children=[];for(var t=0,n=e.length;t<n;t++)this.children.push(new I(this,e[t]));this.tree._callHook("treeStructureChanged",this.tree,"setChildren")},addChildren:function(e,t){var n,i,r,o,s=this.getFirstChild(),a=this.getLastChild(),l=[];for(k.isPlainObject(e)&&(e=[e]),this.children||(this.children=[]),n=0,i=e.length;n<i;n++)l.push(new I(this,e[n]));if(o=l[0],null==t?this.children=this.children.concat(l):(t=this._findDirectChild(t),_(0<=(r=k.inArray(t,this.children)),"insertBefore must be an existing child"),this.children.splice.apply(this.children,[r,0].concat(l))),s&&!t){for(n=0,i=l.length;n<i;n++)l[n].render();s!==this.getFirstChild()&&s.renderStatus(),a!==this.getLastChild()&&a.renderStatus()}else this.parent&&!this.parent.ul&&!this.tr||this.render();return 3===this.tree.options.selectMode&&this.fixSelection3FromEndNodes(),this.triggerModifyChild("add",1===l.length?l[0]:null),o},addClass:function(e){return this.toggleClass(e,!0)},addNode:function(e,t){switch(t=void 0===t||"over"===t?"child":t){case"after":return this.getParent().addChildren(e,this.getNextSibling());case"before":return this.getParent().addChildren(e,this);case"firstChild":var n=this.children?this.children[0]:null;return this.addChildren(e,n);case"child":case"over":return this.addChildren(e)}_(!1,"Invalid mode: "+t)},addPagingNode:function(e,t){var n,i;if(t=t||"child",!1!==e)return e=k.extend({title:this.tree.options.strings.moreData,statusNodeType:"paging",icon:!1},e),this.partload=!0,this.addNode(e,t);for(n=this.children.length-1;0<=n;n--)"paging"===(i=this.children[n]).statusNodeType&&this.removeChild(i);this.partload=!1},appendSibling:function(e){return this.addNode(e,"after")},applyCommand:function(e,t){return this.tree.applyCommand(e,this,t)},applyPatch:function(e){if(null===e)return this.remove(),T(this);var t,n,i={children:!0,expanded:!0,parent:!0};for(t in e)C(e,t)&&(n=e[t],i[t]||w(n)||(s[t]?this[t]=n:this.data[t]=n));return C(e,"children")&&(this.removeChildren(),e.children&&this._setChildren(e.children)),this.isVisible()&&(this.renderTitle(),this.renderStatus()),C(e,"expanded")?this.setExpanded(e.expanded):T(this)},collapseSiblings:function(){return this.tree._callHook("nodeCollapseSiblings",this)},copyTo:function(e,t,n){return e.addNode(this.toDict(!0,n),t)},countChildren:function(e){var t,n,i,r=this.children;if(!r)return 0;if(i=r.length,!1!==e)for(t=0,n=i;t<n;t++)i+=r[t].countChildren();return i},debug:function(e){4<=this.tree.options.debugLevel&&(Array.prototype.unshift.call(arguments,this.toString()),d("log",arguments))},discard:function(){return this.warn("FancytreeNode.discard() is deprecated since 2014-02-16. Use .resetLazy() instead."),this.resetLazy()},discardMarkup:function(e){this.tree._callHook(e?"nodeRemoveMarkup":"nodeRemoveChildMarkup",this)},error:function(e){1<=this.tree.options.debugLevel&&(Array.prototype.unshift.call(arguments,this.toString()),d("error",arguments))},findAll:function(t){t=w(t)?t:R(t);var n=[];return this.visit(function(e){t(e)&&n.push(e)}),n},findFirst:function(t){t=w(t)?t:R(t);var n=null;return this.visit(function(e){if(t(e))return n=e,!1}),n},findRelatedNode:function(e,t){return this.tree.findRelatedNode(this,e,t)},_changeSelectStatusAttrs:function(e){var t=!1,n=this.tree.options,i=h.evalOption("unselectable",this,this,n,!1),n=h.evalOption("unselectableStatus",this,this,n,void 0);switch(e=i&&null!=n?n:e){case!1:t=this.selected||this.partsel,this.selected=!1,this.partsel=!1;break;case!0:t=!this.selected||!this.partsel,this.selected=!0,this.partsel=!0;break;case void 0:t=this.selected||!this.partsel,this.selected=!1,this.partsel=!0;break;default:_(!1,"invalid state: "+e)}return t&&this.renderStatus(),t},fixSelection3AfterClick:function(e){var t=this.isSelected();this.visit(function(e){if(e._changeSelectStatusAttrs(t),e.radiogroup)return"skip"}),this.fixSelection3FromEndNodes(e)},fixSelection3FromEndNodes:function(e){var u=this.tree.options;_(3===u.selectMode,"expected selectMode 3"),function e(t){var n,i,r,o,s,a,l,d,c=t.children;if(c&&c.length){for(l=!(a=!0),n=0,i=c.length;n<i;n++)o=e(r=c[n]),h.evalOption("unselectableIgnore",r,r,u,!1)||(!1!==o&&(l=!0),!0!==o&&(a=!1));s=!!a||!!l&&void 0}else s=null==(d=h.evalOption("unselectableStatus",t,t,u,void 0))?!!t.selected:!!d;return t.partsel&&!t.selected&&t.lazy&&null==t.children&&(s=void 0),t._changeSelectStatusAttrs(s),s}(this),this.visitParents(function(e){for(var t,n,i,r=e.children,o=!0,s=!1,a=0,l=r.length;a<l;a++)t=r[a],h.evalOption("unselectableIgnore",t,t,u,!1)||(((n=null==(i=h.evalOption("unselectableStatus",t,t,u,void 0))?!!t.selected:!!i)||t.partsel)&&(s=!0),n||(o=!1));e._changeSelectStatusAttrs(n=!!o||!!s&&void 0)})},fromDict:function(e){for(var t in e)s[t]?this[t]=e[t]:"data"===t?k.extend(this.data,e.data):w(e[t])||a[t]||(this.data[t]=e[t]);e.children&&(this.removeChildren(),this.addChildren(e.children)),this.renderTitle()},getChildren:function(){if(void 0!==this.hasChildren())return this.children},getFirstChild:function(){return this.children?this.children[0]:null},getIndex:function(){return k.inArray(this,this.parent.children)},getIndexHier:function(e,n){e=e||".";var i,r=[];return k.each(this.getParentList(!1,!0),function(e,t){i=""+(t.getIndex()+1),n&&(i=("0000000"+i).substr(-n)),r.push(i)}),r.join(e)},getKeyPath:function(e){var t=this.tree.options.keyPathSeparator;return t+this.getPath(!e,"key",t)},getLastChild:function(){return this.children?this.children[this.children.length-1]:null},getLevel:function(){for(var e=0,t=this.parent;t;)e++,t=t.parent;return e},getNextSibling:function(){if(this.parent)for(var e=this.parent.children,t=0,n=e.length-1;t<n;t++)if(e[t]===this)return e[t+1];return null},getParent:function(){return this.parent},getParentList:function(e,t){for(var n=[],i=t?this:this.parent;i;)(e||i.parent)&&n.unshift(i),i=i.parent;return n},getPath:function(e,t,n){n=n||"/";var i,r=[],o=w(t=t||"title");return this.visitParents(function(e){e.parent&&(i=o?t(e):e[t],r.unshift(i))},e=!1!==e),r.join(n)},getPrevSibling:function(){if(this.parent)for(var e=this.parent.children,t=1,n=e.length;t<n;t++)if(e[t]===this)return e[t-1];return null},getSelectedNodes:function(t){var n=[];return this.visit(function(e){if(e.selected&&(n.push(e),!0===t))return"skip"}),n},hasChildren:function(){return this.lazy?null==this.children?void 0:0!==this.children.length&&(1!==this.children.length||!this.children[0].isStatusNode()||void 0):!(!this.children||!this.children.length)},hasClass:function(e){return 0<=(" "+(this.extraClasses||"")+" ").indexOf(" "+e+" ")},hasFocus:function(){return this.tree.hasFocus()&&this.tree.focusNode===this},info:function(e){3<=this.tree.options.debugLevel&&(Array.prototype.unshift.call(arguments,this.toString()),d("info",arguments))},isActive:function(){return this.tree.activeNode===this},isBelowOf:function(e){return this.getIndexHier(".",5)>e.getIndexHier(".",5)},isChildOf:function(e){return this.parent&&this.parent===e},isDescendantOf:function(e){if(!e||e.tree!==this.tree)return!1;for(var t=this.parent;t;){if(t===e)return!0;t===t.parent&&k.error("Recursive parent link: "+t),t=t.parent}return!1},isExpanded:function(){return!!this.expanded},isFirstSibling:function(){var e=this.parent;return!e||e.children[0]===this},isFolder:function(){return!!this.folder},isLastSibling:function(){var e=this.parent;return!e||e.children[e.children.length-1]===this},isLazy:function(){return!!this.lazy},isLoaded:function(){return!this.lazy||void 0!==this.hasChildren()},isLoading:function(){return!!this._isLoading},isRoot:function(){return this.isRootNode()},isPartsel:function(){return!this.selected&&!!this.partsel},isPartload:function(){return!!this.partload},isRootNode:function(){return this.tree.rootNode===this},isSelected:function(){return!!this.selected},isStatusNode:function(){return!!this.statusNodeType},isPagingNode:function(){return"paging"===this.statusNodeType},isTopLevel:function(){return this.tree.rootNode===this.parent},isUndefined:function(){return void 0===this.hasChildren()},isVisible:function(){var e,t,n=this.tree.enableFilter,i=this.getParentList(!1,!1);if(n&&!this.match&&!this.subMatchCount)return!1;for(e=0,t=i.length;e<t;e++)if(!i[e].expanded)return!1;return!0},lazyLoad:function(e){k.error("FancytreeNode.lazyLoad() is deprecated since 2014-02-16. Use .load() instead.")},load:function(e){var t=this,n=this.isExpanded();return _(this.isLazy(),"load() requires a lazy node"),e||this.isUndefined()?(this.isLoaded()&&this.resetLazy(),!1===(e=this.tree._triggerNodeEvent("lazyLoad",this))?T(this):(_("boolean"!=typeof e,"lazyLoad event must return source in data.result"),e=this.tree._callHook("nodeLoadChildren",this,e),n?(this.expanded=!0,e.always(function(){t.render()})):e.always(function(){t.renderStatus()}),e)):T(this)},makeVisible:function(e){for(var t=this,n=[],i=new k.Deferred,r=this.getParentList(!1,!1),o=r.length,s=!(e&&!0===e.noAnimation),a=!(e&&!1===e.scrollIntoView),l=o-1;0<=l;l--)n.push(r[l].setExpanded(!0,e));return k.when.apply(k,n).done(function(){a?t.scrollIntoView(s).done(function(){i.resolve()}):i.resolve()}),i.promise()},moveTo:function(t,e,n){void 0===e||"over"===e?e="child":"firstChild"===e&&(t.children&&t.children.length?(e="before",t=t.children[0]):e="child");var i,r=this.tree,o=this.parent,s="child"===e?t:t.parent;if(this!==t){if(this.parent?s.isDescendantOf(this)&&k.error("Cannot move a node to its own descendant"):k.error("Cannot move system root"),s!==o&&o.triggerModifyChild("remove",this),1===this.parent.children.length){if(this.parent===s)return;this.parent.children=this.parent.lazy?[]:null,this.parent.expanded=!1}else _(0<=(i=k.inArray(this,this.parent.children)),"invalid source parent"),this.parent.children.splice(i,1);if((this.parent=s).hasChildren())switch(e){case"child":s.children.push(this);break;case"before":_(0<=(i=k.inArray(t,s.children)),"invalid target parent"),s.children.splice(i,0,this);break;case"after":_(0<=(i=k.inArray(t,s.children)),"invalid target parent"),s.children.splice(i+1,0,this);break;default:k.error("Invalid mode "+e)}else s.children=[this];n&&t.visit(n,!0),s===o?s.triggerModifyChild("move",this):s.triggerModifyChild("add",this),r!==t.tree&&(this.warn("Cross-tree moveTo is experimental!"),this.visit(function(e){e.tree=t.tree},!0)),r._callHook("treeStructureChanged",r,"moveTo"),o.isDescendantOf(s)||o.render(),s.isDescendantOf(o)||s===o||s.render()}},navigate:function(e,t){var n=k.ui.keyCode;switch(e){case"left":case n.LEFT:if(this.expanded)return this.setExpanded(!1);break;case"right":case n.RIGHT:if(!this.expanded&&(this.children||this.lazy))return this.setExpanded()}if(n=this.findRelatedNode(e)){try{n.makeVisible({scrollIntoView:!1})}catch(e){}return!1===t?(n.setFocus(),T()):n.setActive()}return this.warn("Could not find related node '"+e+"'."),T()},remove:function(){return this.parent.removeChild(this)},removeChild:function(e){return this.tree._callHook("nodeRemoveChild",this,e)},removeChildren:function(){return this.tree._callHook("nodeRemoveChildren",this)},removeClass:function(e){return this.toggleClass(e,!1)},render:function(e,t){return this.tree._callHook("nodeRender",this,e,t)},renderTitle:function(){return this.tree._callHook("nodeRenderTitle",this)},renderStatus:function(){return this.tree._callHook("nodeRenderStatus",this)},replaceWith:function(e){var n=this.parent,i=k.inArray(this,n.children),r=this;return _(this.isPagingNode(),"replaceWith() currently requires a paging status node"),(e=this.tree._callHook("nodeLoadChildren",this,e)).done(function(e){var t=r.children;for(l=0;l<t.length;l++)t[l].parent=n;n.children.splice.apply(n.children,[i+1,0].concat(t)),r.children=null,r.remove(),n.render()}).fail(function(){r.setExpanded()}),e},resetLazy:function(){this.removeChildren(),this.expanded=!1,this.lazy=!0,this.children=void 0,this.renderStatus()},scheduleAction:function(e,t){this.tree.timer&&(clearTimeout(this.tree.timer),this.tree.debug("clearTimeout(%o)",this.tree.timer)),this.tree.timer=null;var n=this;switch(e){case"cancel":break;case"expand":this.tree.timer=setTimeout(function(){n.tree.debug("setTimeout: trigger expand"),n.setExpanded(!0)},t);break;case"activate":this.tree.timer=setTimeout(function(){n.tree.debug("setTimeout: trigger activate"),n.setActive(!0)},t);break;default:k.error("Invalid mode "+e)}},scrollIntoView:function(e,t){if(void 0!==t&&((p=t).tree&&void 0!==p.statusNodeType))throw Error("scrollIntoView() with 'topNode' option is deprecated since 2014-05-08. Use 'options.topNode' instead.");var n=k.extend({effects:!0===e?{duration:200,queue:!1}:e,scrollOfs:this.tree.options.scrollOfs,scrollParent:this.tree.options.scrollParent,topNode:null},t),i=n.scrollParent,r=this.tree.$container,o=r.css("overflow-y");i?i.jquery||(i=k(i)):i=!this.tree.tbody&&("scroll"===o||"auto"===o)?r:r.scrollParent(),i[0]!==document&&i[0]!==document.body||(this.debug("scrollIntoView(): normalizing scrollParent to 'window':",i[0]),i=k(window));var s,a,l=new k.Deferred,d=this,c=k(this.span).height(),u=n.scrollOfs.top||0,h=n.scrollOfs.bottom||0,f=i.height(),p=i.scrollTop(),e=i,t=i[0]===window,o=n.topNode||null,r=null;return this.isRootNode()||!this.isVisible()?(this.info("scrollIntoView(): node is invisible."),T()):(t?(a=k(this.span).offset().top,s=o&&o.span?k(o.span).offset().top:0,e=k("html,body")):(_(i[0]!==document&&i[0]!==document.body,"scrollParent should be a simple element or `window`, not document or body."),t=i.offset().top,a=k(this.span).offset().top-t+p,s=o?k(o.span).offset().top-t+p:0,f-=Math.max(0,i.innerHeight()-i[0].clientHeight)),a<p+u?r=a-u:p+f-h<a+c&&(r=a+c-f+h,o&&(_(o.isRootNode()||o.isVisible(),"topNode must be visible"),s<r&&(r=s-u))),null===r?l.resolveWith(this):n.effects?(n.effects.complete=function(){l.resolveWith(d)},e.stop(!0).animate({scrollTop:r},n.effects)):(e[0].scrollTop=r,l.resolveWith(this)),l.promise())},setActive:function(e,t){return this.tree._callHook("nodeSetActive",this,e,t)},setExpanded:function(e,t){return this.tree._callHook("nodeSetExpanded",this,e,t)},setFocus:function(e){return this.tree._callHook("nodeSetFocus",this,e)},setSelected:function(e,t){return this.tree._callHook("nodeSetSelected",this,e,t)},setStatus:function(e,t,n){return this.tree._callHook("nodeSetStatus",this,e,t,n)},setTitle:function(e){this.title=e,this.renderTitle(),this.triggerModify("rename")},sortChildren:function(e,t){var n,i,r=this.children;if(r){if(r.sort(e=e||function(e,t){e=e.title.toLowerCase(),t=t.title.toLowerCase();return e===t?0:t<e?1:-1}),t)for(n=0,i=r.length;n<i;n++)r[n].children&&r[n].sortChildren(e,"$norender$");"$norender$"!==t&&this.render(),this.triggerModifyChild("sort")}},toDict:function(e,t){var n,i,r,o,s={},a=this;if(k.each(m,function(e,t){!a[t]&&!1!==a[t]||(s[t]=a[t])}),k.isEmptyObject(this.data)||(s.data=k.extend({},this.data),k.isEmptyObject(s.data)&&delete s.data),t){if(!1===(o=t(s,a)))return!1;"skip"===o&&(e=!1)}if(e&&N(this.children))for(s.children=[],n=0,i=this.children.length;n<i;n++)(r=this.children[n]).isStatusNode()||!1!==(o=r.toDict(!0,t))&&s.children.push(o);return s},toggleClass:function(e,t){var n,i,r=e.match(/\S+/g)||[],o=0,s=!1,a=this[this.tree.statusClassPropName],l=" "+(this.extraClasses||"")+" ";for(a&&k(a).toggleClass(e,t);n=r[o++];)if(i=0<=l.indexOf(" "+n+" "),t=void 0===t?!i:!!t)i||(l+=n+" ",s=!0);else for(;-1<l.indexOf(" "+n+" ");)l=l.replace(" "+n+" "," ");return this.extraClasses=S(l),s},toggleExpanded:function(){return this.tree._callHook("nodeToggleExpanded",this)},toggleSelected:function(){return this.tree._callHook("nodeToggleSelected",this)},toString:function(){return"FancytreeNode@"+this.key+"[title='"+this.title+"']"},triggerModifyChild:function(e,t,n){var i=this.tree.options.modifyChild;i&&(t&&t.parent!==this&&k.error("childNode "+t+" is not a child of "+this),t={node:this,tree:this.tree,operation:e,childNode:t||null},n&&k.extend(t,n),i({type:"modifyChild"},t))},triggerModify:function(e,t){this.parent.triggerModifyChild(e,this,t)},visit:function(e,t){var n,i,r=!0,o=this.children;if(!0===t&&(!1===(r=e(this))||"skip"===r))return r;if(o)for(n=0,i=o.length;n<i&&!1!==(r=o[n].visit(e,!0));n++);return r},visitAndLoad:function(n,e,t){var i,r,o,s=this;return!n||!0!==e||!1!==(r=n(s))&&"skip"!==r?s.children||s.lazy?(i=new k.Deferred,o=[],s.load().done(function(){for(var e=0,t=s.children.length;e<t;e++){if(!1===(r=s.children[e].visitAndLoad(n,!0,!0))){i.reject();break}"skip"!==r&&o.push(r)}k.when.apply(this,o).then(function(){i.resolve()})}),i.promise()):T():t?r:T()},visitParents:function(e,t){if(t&&!1===e(this))return!1;for(var n=this.parent;n;){if(!1===e(n))return!1;n=n.parent}return!0},visitSiblings:function(e,t){for(var n,i=this.parent.children,r=0,o=i.length;r<o;r++)if(n=i[r],(t||n!==this)&&!1===e(n))return!1;return!0},warn:function(e){2<=this.tree.options.debugLevel&&(Array.prototype.unshift.call(arguments,this.toString()),d("warn",arguments))}},F.prototype={_makeHookContext:function(e,t,n){var i,r;return void 0!==e.node?(t&&e.originalEvent!==t&&k.error("invalid args"),i=e):e.tree?i={node:e,tree:r=e.tree,widget:r.widget,options:r.widget.options,originalEvent:t,typeInfo:r.types[e.type]||{}}:e.widget?i={node:null,tree:e,widget:e.widget,options:e.widget.options,originalEvent:t}:k.error("invalid args"),n&&k.extend(i,n),i},_callHook:function(e,t,n){var i=this._makeHookContext(t),r=this[e],t=Array.prototype.slice.call(arguments,2);return w(r)||k.error("_callHook('"+e+"') is not a function"),t.unshift(i),r.apply(this,t)},_setExpiringValue:function(e,t,n){this._tempCache[e]={value:t,expire:Date.now()+(+n||50)}},_getExpiringValue:function(e){var t=this._tempCache[e];return t&&t.expire>Date.now()?t.value:(delete this._tempCache[e],null)},_usesExtension:function(e){return 0<=k.inArray(e,this.options.extensions)},_requireExtension:function(e,t,n,i){null!=n&&(n=!!n);var r=this._local.name,o=this.options.extensions,s=k.inArray(e,o)<k.inArray(r,o),o=t&&null==this.ext[e],s=!o&&null!=n&&n!==s;return _(r&&r!==e,"invalid or same name '"+r+"' (require yourself?)"),!o&&!s||(i||(o||t?(i="'"+r+"' extension requires '"+e+"'",s&&(i+=" to be registered "+(n?"before":"after")+" itself")):i="If used together, `"+e+"` must be registered "+(n?"before":"after")+" `"+r+"`"),k.error(i),!1)},activateKey:function(e,t){e=this.getNodeByKey(e);return e?e.setActive(!0,t):this.activeNode&&this.activeNode.setActive(!1,t),e},addPagingNode:function(e,t){return this.rootNode.addPagingNode(e,t)},applyCommand:function(e,t,n){var i;switch(t=t||this.getActiveNode(),e){case"moveUp":(i=t.getPrevSibling())&&(t.moveTo(i,"before"),t.setActive());break;case"moveDown":(i=t.getNextSibling())&&(t.moveTo(i,"after"),t.setActive());break;case"indent":(i=t.getPrevSibling())&&(t.moveTo(i,"child"),i.setExpanded(),t.setActive());break;case"outdent":t.isTopLevel()||(t.moveTo(t.getParent(),"after"),t.setActive());break;case"remove":i=t.getPrevSibling()||t.getParent(),t.remove(),i&&i.setActive();break;case"addChild":t.editCreateNode("child","");break;case"addSibling":t.editCreateNode("after","");break;case"rename":t.editStart();break;case"down":case"first":case"last":case"left":case"parent":case"right":case"up":return t.navigate(e);default:k.error("Unhandled command: '"+e+"'")}},applyPatch:function(e){for(var t,n,i,r,o=e.length,s=[],a=0;a<o;a++)_(2===(t=e[a]).length,"patchList must be an array of length-2-arrays"),n=t[0],i=t[1],(r=null===n?this.rootNode:this.getNodeByKey(n))?(t=new k.Deferred,s.push(t),r.applyPatch(i).always(A(t,r))):this.warn("could not find node with key '"+n+"'");return k.when.apply(k,s).promise()},clear:function(e){this._callHook("treeClear",this)},count:function(){return this.rootNode.countChildren()},debug:function(e){4<=this.options.debugLevel&&(Array.prototype.unshift.call(arguments,this.toString()),d("log",arguments))},destroy:function(){this.widget.destroy()},enable:function(e){!1===e?this.widget.disable():this.widget.enable()},enableUpdate:function(e){return!!this._enableUpdate==!!(e=!1!==e)?e:((this._enableUpdate=e)?(this.debug("enableUpdate(true): redraw "),this._callHook("treeStructureChanged",this,"enableUpdate"),this.render()):this.debug("enableUpdate(false)..."),!e)},error:function(e){1<=this.options.debugLevel&&(Array.prototype.unshift.call(arguments,this.toString()),d("error",arguments))},expandAll:function(t,n){var e=this.enableUpdate(!1);t=!1!==t,this.visit(function(e){!1!==e.hasChildren()&&e.isExpanded()!==t&&e.setExpanded(t,n)}),this.enableUpdate(e)},findAll:function(e){return this.rootNode.findAll(e)},findFirst:function(e){return this.rootNode.findFirst(e)},findNextNode:function(t,n){var i,r=null,e=this.getFirstChild();function o(e){if((r=t(e)?e:r)||e===n)return!1}return t="string"==typeof t?(i=new RegExp("^"+t,"i"),function(e){return i.test(e.title)}):t,this.visitRows(o,{start:n=n||e,includeSelf:!1}),r||n===e||this.visitRows(o,{start:e,includeSelf:!0}),r},findRelatedNode:function(e,t,n){var i=null,r=k.ui.keyCode;switch(t){case"parent":case r.BACKSPACE:e.parent&&e.parent.parent&&(i=e.parent);break;case"first":case r.HOME:this.visit(function(e){if(e.isVisible())return i=e,!1});break;case"last":case r.END:this.visit(function(e){e.isVisible()&&(i=e)});break;case"left":case r.LEFT:e.expanded?e.setExpanded(!1):e.parent&&e.parent.parent&&(i=e.parent);break;case"right":case r.RIGHT:e.expanded||!e.children&&!e.lazy?e.children&&e.children.length&&(i=e.children[0]):(e.setExpanded(),i=e);break;case"up":case r.UP:this.visitRows(function(e){return i=e,!1},{start:e,reverse:!0,includeSelf:!1});break;case"down":case r.DOWN:this.visitRows(function(e){return i=e,!1},{start:e,includeSelf:!1});break;default:this.tree.warn("Unknown relation '"+t+"'.")}return i},generateFormElements:function(e,t,n){n=n||{};var i="string"==typeof e?e:"ft_"+this._id+"[]",r="string"==typeof t?t:"ft_"+this._id+"_active",o="fancytree_result_"+this._id,s=k("#"+o),a=3===this.options.selectMode&&!1!==n.stopOnParents;function l(e){s.append(k("<input>",{type:"checkbox",name:i,value:e.key,checked:!0}))}s.length?s.empty():s=k("<div>",{id:o}).hide().insertAfter(this.$container),!1!==t&&this.activeNode&&s.append(k("<input>",{type:"radio",name:r,value:this.activeNode.key,checked:!0})),n.filter?this.visit(function(e){var t=n.filter(e);if("skip"===t)return t;!1!==t&&l(e)}):!1!==e&&(a=this.getSelectedNodes(a),k.each(a,function(e,t){l(t)}))},getActiveNode:function(){return this.activeNode},getFirstChild:function(){return this.rootNode.getFirstChild()},getFocusNode:function(){return this.focusNode},getOption:function(e){return this.widget.option(e)},getNodeByKey:function(t,e){var n,i;return!e&&(n=document.getElementById(this.options.idPrefix+t))?n.ftnode||null:(e=e||this.rootNode,t=""+t,e.visit(function(e){if(e.key===t)return i=e,!1},!(i=null)),i)},getRootNode:function(){return this.rootNode},getSelectedNodes:function(e){return this.rootNode.getSelectedNodes(e)},hasFocus:function(){return!!this._hasFocus},info:function(e){3<=this.options.debugLevel&&(Array.prototype.unshift.call(arguments,this.toString()),d("info",arguments))},isLoading:function(){var t=!1;return this.rootNode.visit(function(e){if(e._isLoading||e._requestId)return!(t=!0)},!0),t},loadKeyPath:function(e,t){var i,n,r,o=this,s=new k.Deferred,a=this.getRootNode(),l=this.options.keyPathSeparator,d=[],c=k.extend({},t);for("function"==typeof t?i=t:t&&t.callback&&(i=t.callback),c.callback=function(e,t,n){i&&i.call(e,t,n),s.notifyWith(e,[{node:t,status:n}])},null==c.matchKey&&(c.matchKey=function(e,t){return e.key===t}),N(e)||(e=[e]),n=0;n<e.length;n++)(r=e[n]).charAt(0)===l&&(r=r.substr(1)),d.push(r.split(l));return setTimeout(function(){o._loadKeyPathImpl(s,c,a,d).done(function(){s.resolve()})},0),s.promise()},_loadKeyPathImpl:function(e,o,t,n){var i,r,s,a,l,d,c,u,h,f,p=this;for(c={},r=0;r<n.length;r++)for(h=n[r],u=t;h.length;){if(s=h.shift(),!(a=function(e,t){var n,i,r=e.children;if(r)for(n=0,i=r.length;n<i;n++)if(o.matchKey(r[n],t))return r[n];return null}(u,s))){this.warn("loadKeyPath: key not found: "+s+" (parent: "+u+")"),o.callback(this,s,"error");break}if(0===h.length){o.callback(this,a,"ok");break}if(a.lazy&&void 0===a.hasChildren()){o.callback(this,a,"loaded"),c[s=a.key]?c[s].pathSegList.push(h):c[s]={parent:a,pathSegList:[h]};break}o.callback(this,a,"loaded"),u=a}for(l in i=[],c)C(c,l)&&(d=c[l],f=new k.Deferred,i.push(f),function(t,n,e){o.callback(p,n,"loading"),n.load().done(function(){p._loadKeyPathImpl.call(p,t,o,n,e).always(A(t,p))}).fail(function(e){p.warn("loadKeyPath: error loading lazy "+n),o.callback(p,a,"error"),t.rejectWith(p)})}(f,d.parent,d.pathSegList));return k.when.apply(k,i).promise()},reactivate:function(e){var t,n=this.activeNode;return n?(this.activeNode=null,t=n.setActive(!0,{noFocus:!0}),e&&n.setFocus(),t):T()},reload:function(e){return this._callHook("treeClear",this),this._callHook("treeLoad",this,e)},render:function(e,t){return this.rootNode.render(e,t)},selectAll:function(t){this.visit(function(e){e.setSelected(t)})},setFocus:function(e){return this._callHook("treeSetFocus",this,e)},setOption:function(e,t){return this.widget.option(e,t)},debugTime:function(e){4<=this.options.debugLevel&&window.console.time(this+" - "+e)},debugTimeEnd:function(e){4<=this.options.debugLevel&&window.console.timeEnd(this+" - "+e)},toDict:function(e,t){t=this.rootNode.toDict(!0,t);return e?t:t.children},toString:function(){return"Fancytree@"+this._id},_triggerNodeEvent:function(e,t,n,i){i=this._makeHookContext(t,n,i),n=this.widget._trigger(e,n,i);return!1!==n&&void 0!==i.result?i.result:n},_triggerTreeEvent:function(e,t,n){n=this._makeHookContext(this,t,n),t=this.widget._trigger(e,t,n);return!1!==t&&void 0!==n.result?n.result:t},visit:function(e){return this.rootNode.visit(e,!1)},visitRows:function(t,e){if(!this.rootNode.hasChildren())return!1;if(e&&e.reverse)return delete e.reverse,this._visitRowsUp(t,e);for(var n,i,r,o=0,s=!1===(e=e||{}).includeSelf,a=!!e.includeHidden,l=!a&&this.enableFilter,d=e.start||this.rootNode.children[0],c=d.parent;c;){for(_(0<=(i=(r=c.children).indexOf(d)+o),"Could not find "+d+" in parent's children: "+c),n=i;n<r.length;n++)if(d=r[n],!l||d.match||d.subMatchCount){if(!s&&!1===t(d))return!1;if(s=!1,d.children&&d.children.length&&(a||d.expanded)&&!1===d.visit(function(e){return!l||e.match||e.subMatchCount?!1!==t(e)&&(a||!e.children||e.expanded?void 0:"skip"):"skip"},!1))return!1}c=(d=c).parent,o=1}return!0},_visitRowsUp:function(e,t){for(var n,i,r,o=!!t.includeHidden,s=t.start||this.rootNode.children[0];;){if((n=(r=s.parent).children)[0]===s){if(!(s=r).parent)break;n=r.children}else for(i=n.indexOf(s),s=n[i-1];(o||s.expanded)&&s.children&&s.children.length;)s=(n=(r=s).children)[n.length-1];if((o||s.isVisible())&&!1===e(s))return!1}},warn:function(e){2<=this.options.debugLevel&&(Array.prototype.unshift.call(arguments,this.toString()),d("warn",arguments))}},k.extend(F.prototype,{nodeClick:function(e){var t,n,i=e.targetType,r=e.node;if("expander"===i)r.isLoading()?r.debug("Got 2nd click while loading: ignored"):this._callHook("nodeToggleExpanded",e);else if("checkbox"===i)this._callHook("nodeToggleSelected",e),e.options.focusOnSelect&&this._callHook("nodeSetFocus",e,!0);else{if(t=!(n=!1),r.folder)switch(e.options.clickFolderMode){case 2:t=!(n=!0);break;case 3:n=t=!0}t&&(this.nodeSetFocus(e),this._callHook("nodeSetActive",e,!0)),n&&this._callHook("nodeToggleExpanded",e)}},nodeCollapseSiblings:function(e,t){var n,i,r,o=e.node;if(o.parent)for(i=0,r=(n=o.parent.children).length;i<r;i++)n[i]!==o&&n[i].expanded&&this._callHook("nodeSetExpanded",n[i],!1,t)},nodeDblclick:function(e){"title"===e.targetType&&4===e.options.clickFolderMode&&this._callHook("nodeToggleExpanded",e),"title"===e.targetType&&e.originalEvent.preventDefault()},nodeKeydown:function(e){var t=e.originalEvent,n=e.node,i=e.tree,r=e.options,o=t.which,s=t.key||String.fromCharCode(o),a=!!(t.altKey||t.ctrlKey||t.metaKey),l=!g[o]&&!u[o]&&!a,o=k(t.target),d=!0,c=!(t.ctrlKey||!r.autoActivate);if(n||(a=this.getActiveNode()||this.getFirstChild())&&(a.setFocus(),(n=e.node=this.focusNode).debug("Keydown force focus on active node")),r.quicksearch&&l&&!o.is(":input:enabled"))return 500<(o=Date.now())-i.lastQuicksearchTime&&(i.lastQuicksearchTerm=""),i.lastQuicksearchTime=o,i.lastQuicksearchTerm+=s,(s=i.findNextNode(i.lastQuicksearchTerm,i.getActiveNode()))&&s.setActive(),void t.preventDefault();switch(h.eventToString(t)){case"+":case"=":i.nodeSetExpanded(e,!0);break;case"-":i.nodeSetExpanded(e,!1);break;case"space":n.isPagingNode()?i._triggerNodeEvent("clickPaging",e,t):h.evalOption("checkbox",n,n,r,!1)?i.nodeToggleSelected(e):i.nodeSetActive(e,!0);break;case"return":i.nodeSetActive(e,!0);break;case"home":case"end":case"backspace":case"left":case"right":case"up":case"down":n.navigate(t.which,c);break;default:d=!1}d&&t.preventDefault()},nodeLoadChildren:function(o,s){var t,n,a,e=null,i=!0,l=o.tree,d=o.node,c=d.parent,r="nodeLoadChildren",u=Date.now();return w(s)&&_(!w(s=s.call(l,{type:"source"},o)),"source callback must not return another function"),w(s.then)?e=s:s.url?e=(t=k.extend({},o.options.ajax,s)).debugDelay?(n=t.debugDelay,delete t.debugDelay,N(n)&&(n=n[0]+Math.random()*(n[1]-n[0])),d.warn("nodeLoadChildren waiting debugDelay "+Math.round(n)+" ms ..."),k.Deferred(function(e){setTimeout(function(){k.ajax(t).done(function(){e.resolveWith(this,arguments)}).fail(function(){e.rejectWith(this,arguments)})},n)})):k.ajax(t):k.isPlainObject(s)||N(s)?i=!(e={then:function(e,t){e(s,null,null)}}):k.error("Invalid source type: "+s),d._requestId&&(d.warn("Recursive load request #"+u+" while #"+d._requestId+" is pending."),d._requestId=u),i&&(l.debugTime(r),l.nodeSetStatus(o,"loading")),a=new k.Deferred,e.then(function(e,t,n){var i,r;if("json"!==s.dataType&&"jsonp"!==s.dataType||"string"!=typeof e||k.error("Ajax request returned a string (did you get the JSON dataType wrong?)."),d._requestId&&d._requestId>u)a.rejectWith(this,[f]);else if(null!==d.parent||null===c){if(o.options.postProcess){try{(r=l._triggerNodeEvent("postProcess",o,o.originalEvent,{response:e,error:null,dataType:s.dataType})).error&&l.warn("postProcess returned error:",r)}catch(e){r={error:e,message:""+e,details:"postProcess failed"}}if(r.error)return i=k.isPlainObject(r.error)?r.error:{message:r.error},i=l._makeHookContext(d,null,i),void a.rejectWith(this,[i]);(N(r)||k.isPlainObject(r)&&N(r.children))&&(e=r)}else e&&C(e,"d")&&o.options.enableAspx&&(42===o.options.enableAspx&&l.warn("The default for enableAspx will change to `false` in the fututure. Pass `enableAspx: true` or implement postProcess to silence this warning."),e="string"==typeof e.d?k.parseJSON(e.d):e.d);a.resolveWith(this,[e])}else a.rejectWith(this,[p])},function(e,t,n){n=l._makeHookContext(d,null,{error:e,args:Array.prototype.slice.call(arguments),message:n,details:e.status+": "+n});a.rejectWith(this,[n])}),a.done(function(e){var t,n,i;l.nodeSetStatus(o,"ok"),k.isPlainObject(e)?(_(d.isRootNode(),"source may only be an object for root nodes (expecting an array of child objects otherwise)"),_(N(e.children),"if an object is passed as source, it must contain a 'children' array (all other properties are added to 'tree.data')"),t=(n=e).children,delete n.children,k.each(b,function(e,t){void 0!==n[t]&&(l[t]=n[t],delete n[t])}),k.extend(l.data,n)):t=e,_(N(t),"expected array of children"),d._setChildren(t),l.options.nodata&&0===t.length&&(w(l.options.nodata)?i=l.options.nodata.call(l,{type:"nodata"},o):!0===l.options.nodata&&d.isRootNode()?i=l.options.strings.noData:"string"==typeof l.options.nodata&&d.isRootNode()&&(i=l.options.nodata),i&&d.setStatus("nodata",i)),l._triggerNodeEvent("loadChildren",d)}).fail(function(e){var t;e!==f?e!==p?(e.node&&e.error&&e.message?t=e:"[object Object]"===(t=l._makeHookContext(d,null,{error:e,args:Array.prototype.slice.call(arguments),message:e?e.message||e.toString():""})).message&&(t.message=""),d.warn("Load children failed ("+t.message+")",t),!1!==l._triggerNodeEvent("loadError",t,null)&&l.nodeSetStatus(o,"error",t.message,t.details)):d.warn("Lazy parent node was removed while loading: discarding response."):d.warn("Ignored response for obsolete load request #"+u+" (expected #"+d._requestId+")")}).always(function(){d._requestId=null,i&&l.debugTimeEnd(r)}),a.promise()},nodeLoadKeyPath:function(e,t){},nodeRemoveChild:function(e,t){var n=e.node,i=k.extend({},e,{node:t}),r=n.children;if(1===r.length)return _(t===r[0],"invalid single child"),this.nodeRemoveChildren(e);this.activeNode&&(t===this.activeNode||this.activeNode.isDescendantOf(t))&&this.activeNode.setActive(!1),this.focusNode&&(t===this.focusNode||this.focusNode.isDescendantOf(t))&&(this.focusNode=null),this.nodeRemoveMarkup(i),this.nodeRemoveChildren(i),_(0<=(i=k.inArray(t,r)),"invalid child"),n.triggerModifyChild("remove",t),t.visit(function(e){e.parent=null},!0),this._callHook("treeRegisterNode",this,!1,t),r.splice(i,1)},nodeRemoveChildMarkup:function(e){e=e.node;e.ul&&(e.isRootNode()?k(e.ul).empty():(k(e.ul).remove(),e.ul=null),e.visit(function(e){e.li=e.ul=null}))},nodeRemoveChildren:function(e){var t=e.tree,n=e.node;n.children&&(this.activeNode&&this.activeNode.isDescendantOf(n)&&this.activeNode.setActive(!1),this.focusNode&&this.focusNode.isDescendantOf(n)&&(this.focusNode=null),this.nodeRemoveChildMarkup(e),n.triggerModifyChild("remove",null),n.visit(function(e){e.parent=null,t._callHook("treeRegisterNode",t,!1,e)}),n.lazy?n.children=[]:n.children=null,n.isRootNode()||(n.expanded=!1),this.nodeRenderStatus(e))},nodeRemoveMarkup:function(e){var t=e.node;t.li&&(k(t.li).remove(),t.li=null),this.nodeRemoveChildMarkup(e)},nodeRender:function(e,t,n,i,r){var o,s,a,l,d,c,u,h=e.node,f=e.tree,p=e.options,g=p.aria,v=!1,y=h.parent,b=!y,m=h.children,x=null;if(!1!==f._enableUpdate&&(b||y.ul)){if(_(b||y.ul,"parent UL must exist"),b||(h.li&&(t||h.li.parentNode!==h.parent.ul)&&(h.li.parentNode===h.parent.ul?x=h.li.nextSibling:this.debug("Unlinking "+h+" (must be child of "+h.parent+")"),this.nodeRemoveMarkup(e)),h.li?this.nodeRenderStatus(e):(v=!0,h.li=document.createElement("li"),(h.li.ftnode=h).key&&p.generateIds&&(h.li.id=p.idPrefix+h.key),h.span=document.createElement("span"),h.span.className="fancytree-node",g&&!h.tr&&k(h.li).attr("role","treeitem"),h.li.appendChild(h.span),this.nodeRenderTitle(e),p.createNode&&p.createNode.call(f,{type:"createNode"},e)),p.renderNode&&p.renderNode.call(f,{type:"renderNode"},e)),m){if(b||h.expanded||!0===n){for(h.ul||(h.ul=document.createElement("ul"),(!0!==i||r)&&h.expanded||(h.ul.style.display="none"),g&&k(h.ul).attr("role","group"),h.li?h.li.appendChild(h.ul):h.tree.$div.append(h.ul)),l=0,d=m.length;l<d;l++)u=k.extend({},e,{node:m[l]}),this.nodeRender(u,t,n,!1,!0);for(o=h.ul.firstChild;o;)o=(a=o.ftnode)&&a.parent!==h?(h.debug("_fixParent: remove missing "+a,o),c=o.nextSibling,o.parentNode.removeChild(o),c):o.nextSibling;for(o=h.ul.firstChild,l=0,d=m.length-1;l<d;l++)(s=m[l])===(a=o.ftnode)?o=o.nextSibling:h.ul.insertBefore(s.li,a.li)}}else h.ul&&(this.warn("remove child markup for "+h),this.nodeRemoveChildMarkup(e));b||v&&y.ul.insertBefore(h.li,x)}},nodeRenderTitle:function(e,t){var n,i,r=e.node,o=e.tree,s=e.options,a=s.aria,l=r.getLevel(),d=[];void 0!==t&&(r.title=t),r.span&&!1!==o._enableUpdate&&(t=a&&!1!==r.hasChildren()?" role='button'":"",l<s.minExpandLevel?(r.lazy||(r.expanded=!0),1<l&&d.push("<span "+t+" class='fancytree-expander fancytree-expander-fixed'></span>")):d.push("<span "+t+" class='fancytree-expander'></span>"),(l=h.evalOption("checkbox",r,r,s,!1))&&!r.isStatusNode()&&(n="fancytree-checkbox",("radio"===l||r.parent&&r.parent.radiogroup)&&(n+=" fancytree-radio"),d.push("<span "+(t=a?" role='checkbox'":"")+" class='"+n+"'></span>")),void 0!==r.data.iconClass&&(r.icon?k.error("'iconClass' node option is deprecated since v2.14.0: use 'icon' only instead"):(r.warn("'iconClass' node option is deprecated since v2.14.0: use 'icon' instead"),r.icon=r.data.iconClass)),!1!==(n=h.evalOption("icon",r,r,s,!0))&&(t=a?" role='presentation'":"",i=(i=h.evalOption("iconTooltip",r,r,s,null))?" title='"+P(i)+"'":"","string"==typeof n?c.test(n)?(n="/"===n.charAt(0)?n:(s.imagePath||"")+n,d.push("<img src='"+n+"' class='fancytree-icon'"+i+" alt='' />")):d.push("<span "+t+" class='fancytree-custom-icon "+n+"'"+i+"></span>"):n.text?d.push("<span "+t+" class='fancytree-custom-icon "+(n.addClass||"")+"'"+i+">"+h.escapeHtml(n.text)+"</span>"):n.html?d.push("<span "+t+" class='fancytree-custom-icon "+(n.addClass||"")+"'"+i+">"+n.html+"</span>"):d.push("<span "+t+" class='fancytree-icon'"+i+"></span>")),t="",t=(t=s.renderTitle?s.renderTitle.call(o,{type:"renderTitle"},e)||"":t)||"<span class='fancytree-title'"+(i=(i=!0===(i=h.evalOption("tooltip",r,r,s,null))?r.title:i)?" title='"+P(i)+"'":"")+(s.titlesTabbable?" tabindex='0'":"")+">"+(s.escapeTitles?h.escapeHtml(r.title):r.title)+"</span>",d.push(t),r.span.innerHTML=d.join(""),this.nodeRenderStatus(e),s.enhanceTitle&&(e.$title=k(">span.fancytree-title",r.span),t=s.enhanceTitle.call(o,{type:"enhanceTitle"},e)||""))},nodeRenderStatus:function(e){var t,n=e.node,i=e.tree,r=e.options,o=n.hasChildren(),s=n.isLastSibling(),a=r.aria,l=r._classNames,d=[],e=n[i.statusClassPropName];e&&!1!==i._enableUpdate&&(a&&(t=k(n.tr||n.li)),d.push(l.node),i.activeNode===n&&d.push(l.active),i.focusNode===n&&d.push(l.focused),n.expanded&&d.push(l.expanded),a&&(!1===o?t.removeAttr("aria-expanded"):t.attr("aria-expanded",Boolean(n.expanded))),n.folder&&d.push(l.folder),!1!==o&&d.push(l.hasChildren),s&&d.push(l.lastsib),n.lazy&&null==n.children&&d.push(l.lazy),n.partload&&d.push(l.partload),n.partsel&&d.push(l.partsel),h.evalOption("unselectable",n,n,r,!1)&&d.push(l.unselectable),n._isLoading&&d.push(l.loading),n._error&&d.push(l.error),n.statusNodeType&&d.push(l.statusNodePrefix+n.statusNodeType),n.selected?(d.push(l.selected),a&&t.attr("aria-selected",!0)):a&&t.attr("aria-selected",!1),n.extraClasses&&d.push(n.extraClasses),!1===o?d.push(l.combinedExpanderPrefix+"n"+(s?"l":"")):d.push(l.combinedExpanderPrefix+(n.expanded?"e":"c")+(n.lazy&&null==n.children?"d":"")+(s?"l":"")),d.push(l.combinedIconPrefix+(n.expanded?"e":"c")+(n.folder?"f":"")),e.className=d.join(" "),n.li&&k(n.li).toggleClass(l.lastsib,s))},nodeSetActive:function(e,t,n){var i=e.node,r=e.tree,o=e.options,s=!0===(n=n||{}).noEvents,a=!0===n.noFocus,n=!1!==n.scrollIntoView;return i===r.activeNode===(t=!1!==t)?T(i):(n&&e.originalEvent&&k(e.originalEvent.target).is("a,:checkbox")&&(i.info("Not scrolling while clicking an embedded link."),n=!1),t&&!s&&!1===this._triggerNodeEvent("beforeActivate",i,e.originalEvent)?L(i,["rejected"]):(t?(r.activeNode&&(_(r.activeNode!==i,"node was active (inconsistency)"),t=k.extend({},e,{node:r.activeNode}),r.nodeSetActive(t,!1),_(null===r.activeNode,"deactivate was out of sync?")),o.activeVisible&&i.makeVisible({scrollIntoView:n}),r.activeNode=i,r.nodeRenderStatus(e),a||r.nodeSetFocus(e),s||r._triggerNodeEvent("activate",i,e.originalEvent)):(_(r.activeNode===i,"node was not active (inconsistency)"),r.activeNode=null,this.nodeRenderStatus(e),s||e.tree._triggerNodeEvent("deactivate",i,e.originalEvent)),T(i)))},nodeSetExpanded:function(i,r,e){var t,n,o,s,a,l,d=i.node,c=i.tree,u=i.options,h=!0===(e=e||{}).noAnimation,f=!0===e.noEvents;if(r=!1!==r,k(d.li).hasClass(u._classNames.animating))return d.warn("setExpanded("+r+") while animating: ignored."),L(d,["recursion"]);if(d.expanded&&r||!d.expanded&&!r)return T(d);if(r&&!d.lazy&&!d.hasChildren())return T(d);if(!r&&d.getLevel()<u.minExpandLevel)return L(d,["locked"]);if(!f&&!1===this._triggerNodeEvent("beforeExpand",d,i.originalEvent))return L(d,["rejected"]);if(h||d.isVisible()||(h=e.noAnimation=!0),n=new k.Deferred,r&&!d.expanded&&u.autoCollapse){a=d.getParentList(!1,!0),l=u.autoCollapse;try{for(u.autoCollapse=!1,o=0,s=a.length;o<s;o++)this._callHook("nodeCollapseSiblings",a[o],e)}finally{u.autoCollapse=l}}return n.done(function(){var e=d.getLastChild();r&&u.autoScroll&&!h&&e&&c._enableUpdate?e.scrollIntoView(!0,{topNode:d}).always(function(){f||i.tree._triggerNodeEvent(r?"expand":"collapse",i)}):f||i.tree._triggerNodeEvent(r?"expand":"collapse",i)}),t=function(e){var t=u._classNames,n=u.toggleEffect;if(d.expanded=r,c._callHook("treeStructureChanged",i,r?"expand":"collapse"),c._callHook("nodeRender",i,!1,!1,!0),d.ul)if("none"!==d.ul.style.display==!!d.expanded)d.warn("nodeSetExpanded: UL.style.display already set");else{if(n&&!h)return k(d.li).addClass(t.animating),void(w(k(d.ul)[n.effect])?k(d.ul)[n.effect]({duration:n.duration,always:function(){k(this).removeClass(t.animating),k(d.li).removeClass(t.animating),e()}}):(k(d.ul).stop(!0,!0),k(d.ul).parent().find(".ui-effects-placeholder").remove(),k(d.ul).toggle(n.effect,n.options,n.duration,function(){k(this).removeClass(t.animating),k(d.li).removeClass(t.animating),e()})));d.ul.style.display=d.expanded||!parent?"":"none"}e()},r&&d.lazy&&void 0===d.hasChildren()?d.load().done(function(){n.notifyWith&&n.notifyWith(d,["loaded"]),t(function(){n.resolveWith(d)})}).fail(function(e){t(function(){n.rejectWith(d,["load failed ("+e+")"])})}):t(function(){n.resolveWith(d)}),n.promise()},nodeSetFocus:function(e,t){var n,i=e.tree,r=e.node,o=i.options,s=!!e.originalEvent&&k(e.originalEvent.target).is(":input");if(t=!1!==t,i.focusNode){if(i.focusNode===r&&t)return;n=k.extend({},e,{node:i.focusNode}),i.focusNode=null,this._triggerNodeEvent("blur",n),this._callHook("nodeRenderStatus",n)}t&&(this.hasFocus()||(r.debug("nodeSetFocus: forcing container focus"),this._callHook("treeSetFocus",e,!0,{calledByNode:!0})),r.makeVisible({scrollIntoView:!1}),i.focusNode=r,o.titlesTabbable&&(s||k(r.span).find(".fancytree-title").focus()),o.aria&&k(i.$container).attr("aria-activedescendant",k(r.tr||r.li).uniqueId().attr("id")),this._triggerNodeEvent("focus",e),document.activeElement===i.$container.get(0)||1<=k(document.activeElement,i.$container).length||k(i.$container).focus(),o.autoScroll&&r.scrollIntoView(),this._callHook("nodeRenderStatus",e))},nodeSetSelected:function(e,t,n){var i=e.node,r=e.tree,o=e.options,s=!0===(n=n||{}).noEvents,a=i.parent;if(t=!1!==t,!h.evalOption("unselectable",i,i,o,!1))return i._lastSelectIntent=t,!!i.selected!==t||3===o.selectMode&&i.partsel&&!t?s||!1!==this._triggerNodeEvent("beforeSelect",i,e.originalEvent)?(t&&1===o.selectMode?(r.lastSelectedNode&&r.lastSelectedNode.setSelected(!1),i.selected=t):3!==o.selectMode||!a||a.radiogroup||i.radiogroup?a&&a.radiogroup?i.visitSiblings(function(e){e._changeSelectStatusAttrs(t&&e===i)},!0):i.selected=t:(i.selected=t,i.fixSelection3AfterClick(n)),this.nodeRenderStatus(e),r.lastSelectedNode=t?i:null,void(s||r._triggerNodeEvent("select",e))):!!i.selected:t},nodeSetStatus:function(i,e,t,n){var r=i.node,o=i.tree;function s(e,t){var n=r.children?r.children[0]:null;return n&&n.isStatusNode()?(k.extend(n,e),n.statusNodeType=t,o._callHook("nodeRenderTitle",n)):(r._setChildren([e]),o._callHook("treeStructureChanged",i,"setStatusNode"),r.children[0].statusNodeType=t,o.render()),r.children[0]}switch(e){case"ok":!function(){var e=r.children?r.children[0]:null;if(e&&e.isStatusNode()){try{r.ul&&(r.ul.removeChild(e.li),e.li=null)}catch(e){}1===r.children.length?r.children=[]:r.children.shift(),o._callHook("treeStructureChanged",i,"clearStatusNode")}}(),r._isLoading=!1,r._error=null,r.renderStatus();break;case"loading":r.parent||s({title:o.options.strings.loading+(t?" ("+t+")":""),checkbox:!1,tooltip:n},e),r._isLoading=!0,r._error=null,r.renderStatus();break;case"error":s({title:o.options.strings.loadError+(t?" ("+t+")":""),checkbox:!1,tooltip:n},e),r._isLoading=!1,r._error={message:t,details:n},r.renderStatus();break;case"nodata":s({title:t||o.options.strings.noData,checkbox:!1,tooltip:n},e),r._isLoading=!1,r._error=null,r.renderStatus();break;default:k.error("invalid node status "+e)}},nodeToggleExpanded:function(e){return this.nodeSetExpanded(e,!e.node.expanded)},nodeToggleSelected:function(e){var t=e.node,n=!t.selected;return t.partsel&&!t.selected&&!0===t._lastSelectIntent&&(t.selected=!(n=!1)),t._lastSelectIntent=n,this.nodeSetSelected(e,n)},treeClear:function(e){var t=e.tree;t.activeNode=null,t.focusNode=null,t.$div.find(">ul.fancytree-container").empty(),t.rootNode.children=null,t._callHook("treeStructureChanged",e,"clear")},treeCreate:function(e){},treeDestroy:function(e){this.$div.find(">ul.fancytree-container").remove(),this.$source&&this.$source.removeClass("fancytree-helper-hidden")},treeInit:function(e){var n=e.tree,i=n.options;n.$container.attr("tabindex",i.tabindex),k.each(b,function(e,t){void 0!==i[t]&&(n.info("Move option "+t+" to tree"),n[t]=i[t],delete i[t])}),i.checkboxAutoHide&&n.$container.addClass("fancytree-checkbox-auto-hide"),i.rtl?n.$container.attr("DIR","RTL").addClass("fancytree-rtl"):n.$container.removeAttr("DIR").removeClass("fancytree-rtl"),i.aria&&(n.$container.attr("role","tree"),1!==i.selectMode&&n.$container.attr("aria-multiselectable",!0)),this.treeLoad(e)},treeLoad:function(e,t){var n,i,r,o=e.tree,s=e.widget.element,a=k.extend({},e,{node:this.rootNode});if(o.rootNode.children&&this.treeClear(e),t=t||this.options.source)"string"==typeof t&&k.error("Not implemented");else switch(i=s.data("type")||"html"){case"html":(r=s.find(">ul").not(".fancytree-container").first()).length?(r.addClass("ui-fancytree-source fancytree-helper-hidden"),t=k.ui.fancytree.parseHtml(r),this.data=k.extend(this.data,H(r))):(h.warn("No `source` option was passed and container does not contain `<ul>`: assuming `source: []`."),t=[]);break;case"json":t=k.parseJSON(s.text()),s.contents().filter(function(){return 3===this.nodeType}).remove(),k.isPlainObject(t)&&(_(N(t.children),"if an object is passed as source, it must contain a 'children' array (all other properties are added to 'tree.data')"),t=(n=t).children,delete n.children,k.each(b,function(e,t){void 0!==n[t]&&(o[t]=n[t],delete n[t])}),k.extend(o.data,n));break;default:k.error("Invalid data-type: "+i)}return o._triggerTreeEvent("preInit",null),this.nodeLoadChildren(a,t).done(function(){o._callHook("treeStructureChanged",e,"loadChildren"),o.render(),3===e.options.selectMode&&o.rootNode.fixSelection3FromEndNodes(),o.activeNode&&o.options.activeVisible&&o.activeNode.makeVisible(),o._triggerTreeEvent("init",null,{status:!0})}).fail(function(){o.render(),o._triggerTreeEvent("init",null,{status:!1})})},treeRegisterNode:function(e,t,n){e.tree._callHook("treeStructureChanged",e,t?"addNode":"removeNode")},treeSetFocus:function(e,t,n){var i;(t=!1!==t)!==this.hasFocus()&&(!(this._hasFocus=t)&&this.focusNode?this.focusNode.setFocus(!1):!t||n&&n.calledByNode||k(this.$container).focus(),this.$container.toggleClass("fancytree-treefocus",t),this._triggerTreeEvent(t?"focusTree":"blurTree"),t&&!this.activeNode&&(i=this._lastMousedownNode||this.getFirstChild())&&i.setFocus())},treeSetOption:function(e,t,n){var i=e.tree,r=!0,o=!1,s=!1;switch(t){case"aria":case"checkbox":case"icon":case"minExpandLevel":case"tabindex":s=o=!0;break;case"checkboxAutoHide":i.$container.toggleClass("fancytree-checkbox-auto-hide",!!n);break;case"escapeTitles":case"tooltip":s=!0;break;case"rtl":!1===n?i.$container.removeAttr("DIR").removeClass("fancytree-rtl"):i.$container.attr("DIR","RTL").addClass("fancytree-rtl"),s=!0;break;case"source":r=!1,i._callHook("treeLoad",i,n),s=!0}i.debug("set option "+t+"="+n+" <"+typeof n+">"),r&&(this.widget._super||k.Widget.prototype._setOption).call(this.widget,t,n),o&&i._callHook("treeCreate",i),s&&i.render(!0,!1)},treeStructureChanged:function(e,t){}}),k.widget("ui.fancytree",{options:{activeVisible:!0,ajax:{type:"GET",cache:!1,dataType:"json"},aria:!0,autoActivate:!0,autoCollapse:!1,autoScroll:!1,checkbox:!1,clickFolderMode:4,copyFunctionsToData:!1,debugLevel:null,disabled:!1,enableAspx:42,escapeTitles:!1,extensions:[],focusOnSelect:!1,generateIds:!1,icon:!0,idPrefix:"ft_",keyboard:!0,keyPathSeparator:"/",minExpandLevel:1,nodata:!0,quicksearch:!1,rtl:!1,scrollOfs:{top:0,bottom:0},scrollParent:null,selectMode:2,strings:{loading:"Loading...",loadError:"Load error!",moreData:"More...",noData:"No data."},tabindex:"0",titlesTabbable:!1,toggleEffect:{effect:"slideToggle",duration:200},tooltip:!1,treeId:null,_classNames:{active:"fancytree-active",animating:"fancytree-animating",combinedExpanderPrefix:"fancytree-exp-",combinedIconPrefix:"fancytree-ico-",error:"fancytree-error",expanded:"fancytree-expanded",focused:"fancytree-focused",folder:"fancytree-folder",hasChildren:"fancytree-has-children",lastsib:"fancytree-lastsib",lazy:"fancytree-lazy",loading:"fancytree-loading",node:"fancytree-node",partload:"fancytree-partload",partsel:"fancytree-partsel",radio:"fancytree-radio",selected:"fancytree-selected",statusNodePrefix:"fancytree-statusnode-",unselectable:"fancytree-unselectable"},lazyLoad:null,postProcess:null},_deprecationWarning:function(e){var t=this.tree;t&&3<=t.options.debugLevel&&t.warn("$().fancytree('"+e+"') is deprecated (see https://wwwendt.de/tech/fancytree/doc/jsdoc/Fancytree_Widget.html")},_create:function(){this.tree=new F(this),this.$source=this.source||"json"===this.element.data("type")?this.element:this.element.find(">ul").first();for(var e,t,n=this.options,i=n.extensions,r=(this.tree,0);r<i.length;r++)t=i[r],(e=k.ui.fancytree._extensions[t])||k.error("Could not apply extension '"+t+"' (it is not registered, did you forget to include it?)"),this.tree.options[t]=function e(t){var n,i,r,o,s=t||{},a=1,l=arguments.length;if("object"==typeof s||w(s)||(s={}),a===l)throw Error("need at least two args");for(;a<l;a++)if(null!=(n=arguments[a]))for(i in n)C(n,i)&&(o=s[i],s!==(r=n[i])&&(r&&k.isPlainObject(r)?(o=o&&k.isPlainObject(o)?o:{},s[i]=e(o,r)):void 0!==r&&(s[i]=r)));return s}({},e.options,this.tree.options[t]),_(void 0===this.tree.ext[t],"Extension name must not exist as Fancytree.ext attribute: '"+t+"'"),this.tree.ext[t]={},function(e,t,n){for(var i in t)"function"==typeof t[i]?"function"==typeof e[i]?e[i]=E(i,e,0,t,n):"_"===i.charAt(0)?e.ext[n][i]=E(i,e,0,t,n):k.error("Could not override tree."+i+". Use prefix '_' to create tree."+n+"._"+i):"options"!==i&&(e.ext[n][i]=t[i])}(this.tree,e,t),0;void 0!==n.icons&&(!0===n.icon?(this.tree.warn("'icons' tree option is deprecated since v2.14.0: use 'icon' instead"),n.icon=n.icons):k.error("'icons' tree option is deprecated since v2.14.0: use 'icon' only instead")),void 0!==n.iconClass&&(n.icon?k.error("'iconClass' tree option is deprecated since v2.14.0: use 'icon' only instead"):(this.tree.warn("'iconClass' tree option is deprecated since v2.14.0: use 'icon' instead"),n.icon=n.iconClass)),void 0!==n.tabbable&&(n.tabindex=n.tabbable?"0":"-1",this.tree.warn("'tabbable' tree option is deprecated since v2.17.0: use 'tabindex='"+n.tabindex+"' instead")),this.tree._callHook("treeCreate",this.tree)},_init:function(){this.tree._callHook("treeInit",this.tree),this._bind()},_setOption:function(e,t){return this.tree._callHook("treeSetOption",this.tree,e,t)},_destroy:function(){this._unbind(),this.tree._callHook("treeDestroy",this.tree)},_unbind:function(){var e=this.tree._ns;this.element.off(e),this.tree.$container.off(e),k(document).off(e)},_bind:function(){var s=this,a=this.options,o=this.tree,e=o._ns;this._unbind(),o.$container.on("focusin"+e+" focusout"+e,function(e){var t=h.getNode(e),n="focusin"===e.type;if(!n&&t&&k(e.target).is("a"))t.debug("Ignored focusout on embedded <a> element.");else{if(n){if(o._getExpiringValue("focusin"))return void o.debug("Ignored double focusin.");o._setExpiringValue("focusin",!0,50),t||(t=o._getExpiringValue("mouseDownNode"))&&o.debug("Reconstruct mouse target for focusin from recent event.")}t?o._callHook("nodeSetFocus",o._makeHookContext(t,e),n):o.tbody&&k(e.target).parents("table.fancytree-container > thead").length?o.debug("Ignore focus event outside table body.",e):o._callHook("treeSetFocus",o,n)}}).on("selectstart"+e,"span.fancytree-title",function(e){e.preventDefault()}).on("keydown"+e,function(e){if(a.disabled||!1===a.keyboard)return!0;var t,n=o.focusNode,i=o._makeHookContext(n||o,e),r=o.phase;try{return o.phase="userEvent","preventNav"===(t=n?o._triggerNodeEvent("keydown",n,e):o._triggerTreeEvent("keydown",e))?t=!0:!1!==t&&(t=o._callHook("nodeKeydown",i)),t}finally{o.phase=r}}).on("mousedown"+e,function(e){e=h.getEventTarget(e);o._lastMousedownNode=e?e.node:null,o._setExpiringValue("mouseDownNode",o._lastMousedownNode)}).on("click"+e+" dblclick"+e,function(e){if(a.disabled)return!0;var t,n=h.getEventTarget(e),i=n.node,r=s.tree,o=r.phase;if(!i)return!0;t=r._makeHookContext(i,e);try{switch(r.phase="userEvent",e.type){case"click":return t.targetType=n.type,i.isPagingNode()?!0===r._triggerNodeEvent("clickPaging",t,e):!1!==r._triggerNodeEvent("click",t,e)&&r._callHook("nodeClick",t);case"dblclick":return t.targetType=n.type,!1!==r._triggerNodeEvent("dblclick",t,e)&&r._callHook("nodeDblclick",t)}}finally{r.phase=o}})},getActiveNode:function(){return this._deprecationWarning("getActiveNode"),this.tree.activeNode},getNodeByKey:function(e){return this._deprecationWarning("getNodeByKey"),this.tree.getNodeByKey(e)},getRootNode:function(){return this._deprecationWarning("getRootNode"),this.tree.rootNode},getTree:function(){return this._deprecationWarning("getTree"),this.tree}}),h=k.ui.fancytree,k.extend(k.ui.fancytree,{version:"2.38.3",buildType: "production",debugLevel: 3,_nextId:1,_nextNodeKey:1,_extensions:{},_FancytreeClass:F,_FancytreeNodeClass:I,jquerySupports:{positionMyOfs:function(e){for(var t,n,i=k.map(S(e).split("."),function(e){return parseInt(e,10)}),r=k.map(Array.prototype.slice.call(arguments,1),function(e){return parseInt(e,10)}),o=0;o<r.length;o++)if((t=i[o]||0)!==(n=r[o]||0))return n<t;return!0}(k.ui.version,1,9)},assert:_,createTree:function(e,t){t=k(e).fancytree(t);return h.getTree(t)},debounce:function(t,n,i,r){var o;return 3===arguments.length&&"boolean"!=typeof i&&(r=i,i=!1),function(){var e=arguments;r=r||this,i&&!o&&n.apply(r,e),clearTimeout(o),o=setTimeout(function(){i||n.apply(r,e),o=null},t)}},debug:function(e){4<=k.ui.fancytree.debugLevel&&d("log",arguments)},error:function(e){1<=k.ui.fancytree.debugLevel&&d("error",arguments)},escapeHtml:function(e){return(""+e).replace(t,function(e){return i[e]})},fixPositionOptions:function(e){var t,n,i,r;return(e.offset||0<=(""+e.my+e.at).indexOf("%"))&&k.error("expected new position syntax (but '%' is not supported)"),k.ui.fancytree.jquerySupports.positionMyOfs||(t=/(\w+)([+-]?\d+)?\s+(\w+)([+-]?\d+)?/.exec(e.my),n=/(\w+)([+-]?\d+)?\s+(\w+)([+-]?\d+)?/.exec(e.at),i=(t[2]?+t[2]:0)+(n[2]?+n[2]:0),r=(t[4]?+t[4]:0)+(n[4]?+n[4]:0),e=k.extend({},e,{my:t[1]+" "+t[3],at:n[1]+" "+n[3]}),(i||r)&&(e.offset=i+" "+r)),e},getEventTarget:function(e){var t=e&&e.target?e.target.className:"",n={node:this.getNode(e.target),type:void 0};return/\bfancytree-title\b/.test(t)?n.type="title":/\bfancytree-expander\b/.test(t)?n.type=!1===n.node.hasChildren()?"prefix":"expander":/\bfancytree-checkbox\b/.test(t)?n.type="checkbox":/\bfancytree(-custom)?-icon\b/.test(t)?n.type="icon":/\bfancytree-node\b/.test(t)?n.type="title":e&&e.target&&((e=k(e.target)).is("ul[role=group]")?((n.node&&n.node.tree||h).debug("Ignoring click on outer UL."),n.node=null):e.closest(".fancytree-title").length?n.type="title":e.closest(".fancytree-checkbox").length?n.type="checkbox":e.closest(".fancytree-expander").length&&(n.type="expander")),n},getEventTargetType:function(e){return this.getEventTarget(e).type},getNode:function(e){if(e instanceof I)return e;for(e instanceof k?e=e[0]:void 0!==e.originalEvent&&(e=e.target);e;){if(e.ftnode)return e.ftnode;e=e.parentNode}return null},getTree:function(e){var t=e;return e instanceof F?e:("number"==typeof(e=void 0===e?0:e)?e=k(".fancytree-container").eq(e):"string"==typeof e?(e=k("#ft-id-"+t).eq(0)).length||(e=k(t).eq(0)):e instanceof Element||e instanceof HTMLDocument?e=k(e):e instanceof k?e=e.eq(0):void 0!==e.originalEvent&&(e=k(e.target)),(e=(e=e.closest(":ui-fancytree")).data("ui-fancytree")||e.data("fancytree"))?e.tree:null)},evalOption:function(e,t,n,i,r){var o,s=t.tree,i=i[e],n=n[e];return w(i)?(o={node:t,tree:s,widget:s.widget,options:s.widget.options,typeInfo:s.types[t.type]||{}},null==(o=i.call(s,{type:e},o))&&(o=n)):o=null==n?i:n,o=null==o?r:o},setSpanIcon:function(e,t,n){var i=k(e);"string"==typeof n?i.attr("class",t+" "+n):(n.text?i.text(""+n.text):n.html&&(e.innerHTML=n.html),i.attr("class",t+" "+(n.addClass||"")))},eventToString:function(e){var t=e.which,n=e.type,i=[];return e.altKey&&i.push("alt"),e.ctrlKey&&i.push("ctrl"),e.metaKey&&i.push("meta"),e.shiftKey&&i.push("shift"),"click"===n||"dblclick"===n?i.push(o[e.button]+n):"wheel"===n?i.push(n):r[t]||i.push(u[t]||String.fromCharCode(t).toLowerCase()),i.join("+")},info:function(e){3<=k.ui.fancytree.debugLevel&&d("info",arguments)},keyEventToString:function(e){return this.warn("keyEventToString() is deprecated: use eventToString()"),this.eventToString(e)},overrideMethod:function(e,t,n,i){var r,o=e[t]||k.noop;e[t]=function(){var e=i||this;try{return r=e._super,e._super=o,n.apply(e,arguments)}finally{e._super=r}}},parseHtml:function(s){var a,l,d,c,u,h,f,p,e=s.find(">li"),g=[];return e.each(function(){var e,t,n=k(this),i=n.find(">span",this).first(),r=i.length?null:n.find(">a").first(),o={tooltip:null,data:{}};for(i.length?o.title=i.html():r&&r.length?(o.title=r.html(),o.data.href=r.attr("href"),o.data.target=r.attr("target"),o.tooltip=r.attr("title")):(o.title=n.html(),0<=(u=o.title.search(/<ul/i))&&(o.title=o.title.substring(0,u))),o.title=S(o.title),c=0,h=v.length;c<h;c++)o[v[c]]=void 0;for(a=this.className.split(" "),d=[],c=0,h=a.length;c<h;c++)l=a[c],y[l]?o[l]=!0:d.push(l);if(o.extraClasses=d.join(" "),(f=n.attr("title"))&&(o.tooltip=f),(f=n.attr("id"))&&(o.key=f),n.attr("hideCheckbox")&&(o.checkbox=!1),(e=H(n))&&!k.isEmptyObject(e)){for(t in x)C(e,t)&&(e[x[t]]=e[t],delete e[t]);for(c=0,h=m.length;c<h;c++)f=m[c],null!=(p=e[f])&&(delete e[f],o[f]=p);k.extend(o.data,e)}(s=n.find(">ul").first()).length?o.children=k.ui.fancytree.parseHtml(s):o.children=o.lazy?void 0:null,g.push(o)}),g},registerExtension:function(e){_(null!=e.name,"extensions must have a `name` property."),_(null!=e.version,"extensions must have a `version` property."),k.ui.fancytree._extensions[e.name]=e},trim:S,unescapeHtml:function(e){var t=document.createElement("div");return t.innerHTML=e,0===t.childNodes.length?"":t.childNodes[0].nodeValue},warn:function(e){2<=k.ui.fancytree.debugLevel&&d("warn",arguments)}}),k.ui.fancytree}function _(e,t){e||(k.ui.fancytree.error(t="Fancytree assertion failed"+(t=t?": "+t:"")),k.error(t))}function C(e,t){return Object.prototype.hasOwnProperty.call(e,t)}function w(e){return"function"==typeof e}function S(e){return null==e?"":e.trim()}function d(t,n){var i,r,t=window.console?window.console[t]:null;if(t)try{t.apply(window.console,n)}catch(e){for(r="",i=0;i<n.length;i++)r+=n[i];t(r)}}function E(e,i,t,n,r){var o,s,a;function l(){return o.apply(i,arguments)}function d(e){return o.apply(i,e)}return o=i[e],s=n[e],a=i.ext[r],function(){var e=i._local,t=i._super,n=i._superApply;try{return i._local=a,i._super=l,i._superApply=d,s.apply(i,arguments)}finally{i._local=e,i._super=t,i._superApply=n}}}function T(e,t){return(void 0===e?k.Deferred(function(){this.resolve()}):k.Deferred(function(){this.resolveWith(e,t)})).promise()}function L(e,t){return(void 0===e?k.Deferred(function(){this.reject()}):k.Deferred(function(){this.rejectWith(e,t)})).promise()}function A(e,t){return function(){e.resolveWith(t)}}function H(e){var t=k.extend({},e.data()),e=t.json;return delete t.fancytree,delete t.uiFancytree,e&&(delete t.json,t=k.extend(t,e)),t}function P(e){return(""+e).replace(n,function(e){return i[e]})}function R(t){return t=t.toLowerCase(),function(e){return 0<=e.title.toLowerCase().indexOf(t)}}function I(e,t){var n,i,r;for(this.parent=e,this.tree=e.tree,this.ul=null,this.li=null,this.statusNodeType=null,this._isLoading=!1,this._error=null,this.data={},n=0,i=m.length;n<i;n++)this[r=m[n]]=t[r];for(r in null==this.unselectableIgnore&&null==this.unselectableStatus||(this.unselectable=!0),t.hideCheckbox&&k.error("'hideCheckbox' node option was removed in v2.23.0: use 'checkbox: false'"),t.data&&k.extend(this.data,t.data),t)s[r]||!this.tree.options.copyFunctionsToData&&w(t[r])||a[r]||(this.data[r]=t[r]);null==this.key?this.tree.options.defaultKey?(this.key=""+this.tree.options.defaultKey(this),_(this.key,"defaultKey() must return a unique key")):this.key="_"+h._nextNodeKey++:this.key=""+this.key,t.active&&(_(null===this.tree.activeNode,"only one active node allowed"),this.tree.activeNode=this),t.selected&&(this.tree.lastSelectedNode=this),(e=t.children)?e.length?this._setChildren(e):this.children=this.lazy?[]:null:this.children=null,this.tree._callHook("treeRegisterNode",this.tree,!0,this)}function F(e){this.widget=e,this.$div=e.element,this.options=e.options,this.options&&(void 0!==this.options.lazyload&&k.error("The 'lazyload' event is deprecated since 2014-02-25. Use 'lazyLoad' (with uppercase L) instead."),void 0!==this.options.loaderror&&k.error("The 'loaderror' event was renamed since 2014-07-03. Use 'loadError' (with uppercase E) instead."),void 0!==this.options.fx&&k.error("The 'fx' option was replaced by 'toggleEffect' since 2014-11-30."),void 0!==this.options.removeNode&&k.error("The 'removeNode' event was replaced by 'modifyChild' since 2.20 (2016-09-10).")),this.ext={},this.types={},this.columns={},this.data=H(this.$div),this._id=""+(this.options.treeId||k.ui.fancytree._nextId++),this._ns=".fancytree-"+this._id,this.activeNode=null,this.focusNode=null,this._hasFocus=null,this._tempCache={},this._lastMousedownNode=null,this._enableUpdate=!0,this.lastSelectedNode=null,this.systemFocusElement=null,this.lastQuicksearchTerm="",this.lastQuicksearchTime=0,this.viewport=null,this.statusClassPropName="span",this.ariaPropName="li",this.nodeContainerAttrName="li",this.$div.find(">ul.fancytree-container").remove(),this.rootNode=new I({tree:this},{title:"root",key:"root_"+this._id,children:null,expanded:!0}),this.rootNode.parent=null,e=k("<ul>",{id:"ft-id-"+this._id,class:"ui-fancytree fancytree-container fancytree-plain"}).appendTo(this.$div),this.$container=e,this.rootNode.ul=e[0],null==this.options.debugLevel&&(this.options.debugLevel=h.debugLevel)}k.ui.fancytree.warn("Fancytree: ignored duplicate include")});
\ No newline at end of file diff --git a/plugins/55/indexmenu/scripts/fancytree/modules/jquery.fancytree.ariagrid.js b/plugins/55/indexmenu/scripts/fancytree/modules/jquery.fancytree.ariagrid.js new file mode 100644 index 0000000..37ff6d9 --- /dev/null +++ b/plugins/55/indexmenu/scripts/fancytree/modules/jquery.fancytree.ariagrid.js @@ -0,0 +1,714 @@ +/*! + * jquery.fancytree.ariagrid.js + * + * Support ARIA compliant markup and keyboard navigation for tree grids with + * embedded input controls. + * (Extension module for jquery.fancytree.js: https://github.com/mar10/fancytree/) + * + * @requires ext-table + * + * Copyright (c) 2008-2023, Martin Wendt (https://wwWendt.de) + * + * Released under the MIT license + * https://github.com/mar10/fancytree/wiki/LicenseInfo + * + * @version 2.38.3 + * @date 2023-02-01T20:52:50Z + */ + +(function (factory) { + if (typeof define === "function" && define.amd) { + // AMD. Register as an anonymous module. + define([ + "jquery", + "./jquery.fancytree", + "./jquery.fancytree.table", + ], factory); + } else if (typeof module === "object" && module.exports) { + // Node/CommonJS + require("./jquery.fancytree.table"); // core + table + module.exports = factory(require("jquery")); + } else { + // Browser globals + factory(jQuery); + } +})(function ($) { + "use strict"; + + /******************************************************************************* + * Private functions and variables + */ + + // Allow these navigation keys even when input controls are focused + + var FT = $.ui.fancytree, + clsFancytreeActiveCell = "fancytree-active-cell", + clsFancytreeCellMode = "fancytree-cell-mode", + clsFancytreeCellNavMode = "fancytree-cell-nav-mode", + VALID_MODES = ["allow", "force", "start", "off"], + // Define which keys are handled by embedded <input> control, and should + // *not* be passed to tree navigation handler in cell-edit mode: + INPUT_KEYS = { + text: ["left", "right", "home", "end", "backspace"], + number: ["up", "down", "left", "right", "home", "end", "backspace"], + checkbox: [], + link: [], + radiobutton: ["up", "down"], + "select-one": ["up", "down"], + "select-multiple": ["up", "down"], + }, + NAV_KEYS = ["up", "down", "left", "right", "home", "end"]; + + /* Set aria-activedescendant on container to active cell's ID (generate one if required).*/ + function setActiveDescendant(tree, $target) { + var id = $target ? $target.uniqueId().attr("id") : ""; + + tree.$container.attr("aria-activedescendant", id); + } + + /* Calculate TD column index (considering colspans).*/ + function getColIdx($tr, $td) { + var colspan, + td = $td.get(0), + idx = 0; + + $tr.children().each(function () { + if (this === td) { + return false; + } + colspan = $(this).prop("colspan"); + idx += colspan ? colspan : 1; + }); + return idx; + } + + /* Find TD at given column index (considering colspans).*/ + function findTdAtColIdx($tr, colIdx) { + var colspan, + res = null, + idx = 0; + + $tr.children().each(function () { + if (idx >= colIdx) { + res = $(this); + return false; + } + colspan = $(this).prop("colspan"); + idx += colspan ? colspan : 1; + }); + return res; + } + + /* Find adjacent cell for a given direction. Skip empty cells and consider merged cells */ + function findNeighbourTd(tree, $target, keyCode) { + var nextNode, + node, + navMap = { "ctrl+home": "first", "ctrl+end": "last" }, + $td = $target.closest("td"), + $tr = $td.parent(), + treeOpts = tree.options, + colIdx = getColIdx($tr, $td), + $tdNext = null; + + keyCode = navMap[keyCode] || keyCode; + + switch (keyCode) { + case "left": + $tdNext = treeOpts.rtl ? $td.next() : $td.prev(); + break; + case "right": + $tdNext = treeOpts.rtl ? $td.prev() : $td.next(); + break; + case "up": + case "down": + case "ctrl+home": + case "ctrl+end": + node = $tr[0].ftnode; + nextNode = tree.findRelatedNode(node, keyCode); + if (nextNode) { + nextNode.makeVisible(); + nextNode.setActive(); + $tdNext = findTdAtColIdx($(nextNode.tr), colIdx); + } + break; + case "home": + $tdNext = treeOpts.rtl + ? $tr.children("td").last() + : $tr.children("td").first(); + break; + case "end": + $tdNext = treeOpts.rtl + ? $tr.children("td").first() + : $tr.children("td").last(); + break; + } + return $tdNext && $tdNext.length ? $tdNext : null; + } + + /* Return a descriptive string of the current mode. */ + function getGridNavMode(tree) { + if (tree.$activeTd) { + return tree.forceNavMode ? "cell-nav" : "cell-edit"; + } + return "row"; + } + + /* .*/ + function activateEmbeddedLink($td) { + // $td.find( "a" )[ 0 ].trigger("click"); // does not work (always)? + // $td.find( "a" ).trigger("click"); + var event = document.createEvent("MouseEvent"), + a = $td.find("a")[0]; // document.getElementById('nameOfID'); + + event = new CustomEvent("click"); + a.dispatchEvent(event); + } + + /** + * [ext-ariagrid] Set active cell and activate cell-nav or cell-edit mode if needed. + * Pass $td=null to enter row-mode. + * + * See also FancytreeNode#setActive(flag, {cell: idx}) + * + * @param {jQuery | Element | integer} [$td] + * @param {Event|null} [orgEvent=null] + * @alias Fancytree#activateCell + * @requires jquery.fancytree.ariagrid.js + * @since 2.23 + */ + $.ui.fancytree._FancytreeClass.prototype.activateCell = function ( + $td, + orgEvent + ) { + var colIdx, + $input, + $tr, + res, + tree = this, + $prevTd = this.$activeTd || null, + newNode = $td ? FT.getNode($td) : null, + prevNode = $prevTd ? FT.getNode($prevTd) : null, + anyNode = newNode || prevNode, + $prevTr = $prevTd ? $prevTd.closest("tr") : null; + + anyNode.debug( + "activateCell(" + + ($prevTd ? $prevTd.text() : "null") + + ") -> " + + ($td ? $td.text() : "OFF") + ); + + // Make available as event + + if ($td) { + FT.assert($td.length, "Invalid active cell"); + colIdx = getColIdx($(newNode.tr), $td); + res = this._triggerNodeEvent("activateCell", newNode, orgEvent, { + activeTd: tree.$activeTd, + colIdx: colIdx, + mode: null, // editMode ? "cell-edit" : "cell-nav" + }); + if (res === false) { + return false; + } + this.$container.addClass(clsFancytreeCellMode); + this.$container.toggleClass( + clsFancytreeCellNavMode, + !!this.forceNavMode + ); + $tr = $td.closest("tr"); + if ($prevTd) { + // cell-mode => cell-mode + if ($prevTd.is($td)) { + return; + } + $prevTd + .removeAttr("tabindex") + .removeClass(clsFancytreeActiveCell); + + if (!$prevTr.is($tr)) { + // We are moving to a different row: only the inputs in the + // active row should be tabbable + $prevTr.find(">td :input,a").attr("tabindex", "-1"); + } + } + $tr.find(">td :input:enabled,a").attr("tabindex", "0"); + newNode.setActive(); + $td.addClass(clsFancytreeActiveCell); + this.$activeTd = $td; + + $input = $td.find(":input:enabled,a"); + this.debug("Focus input", $input); + if ($input.length) { + $input.focus(); + setActiveDescendant(this, $input); + } else { + $td.attr("tabindex", "-1").focus(); + setActiveDescendant(this, $td); + } + } else { + res = this._triggerNodeEvent("activateCell", prevNode, orgEvent, { + activeTd: null, + colIdx: null, + mode: "row", + }); + if (res === false) { + return false; + } + // $td == null: switch back to row-mode + this.$container.removeClass( + clsFancytreeCellMode + " " + clsFancytreeCellNavMode + ); + // console.log("activateCell: set row-mode for " + this.activeNode, $prevTd); + if ($prevTd) { + // cell-mode => row-mode + $prevTd + .removeAttr("tabindex") + .removeClass(clsFancytreeActiveCell); + // In row-mode, only embedded inputs of the active row are tabbable + $prevTr + .find("td") + .blur() // we need to blur first, because otherwise the focus frame is not reliably removed(?) + .removeAttr("tabindex"); + $prevTr.find(">td :input,a").attr("tabindex", "-1"); + this.$activeTd = null; + // The cell lost focus, but the tree still needs to capture keys: + this.activeNode.setFocus(); + setActiveDescendant(this, $tr); + } else { + // row-mode => row-mode (nothing to do) + } + } + }; + + /******************************************************************************* + * Extension code + */ + $.ui.fancytree.registerExtension({ + name: "ariagrid", + version: "2.38.3", + // Default options for this extension. + options: { + // Internal behavior flags + activateCellOnDoubelclick: true, + cellFocus: "allow", + // TODO: use a global tree option `name` or `title` instead?: + label: "Tree Grid", // Added as `aria-label` attribute + }, + + treeInit: function (ctx) { + var tree = ctx.tree, + treeOpts = ctx.options, + opts = treeOpts.ariagrid; + + // ariagrid requires the table extension to be loaded before itself + if (tree.ext.grid) { + this._requireExtension("grid", true, true); + } else { + this._requireExtension("table", true, true); + } + if (!treeOpts.aria) { + $.error("ext-ariagrid requires `aria: true`"); + } + if ($.inArray(opts.cellFocus, VALID_MODES) < 0) { + $.error("Invalid `cellFocus` option"); + } + this._superApply(arguments); + + // The combination of $activeTd and forceNavMode determines the current + // navigation mode: + this.$activeTd = null; // active cell (null in row-mode) + this.forceNavMode = true; + + this.$container + .addClass("fancytree-ext-ariagrid") + .toggleClass(clsFancytreeCellNavMode, !!this.forceNavMode) + .attr("aria-label", "" + opts.label); + this.$container + .find("thead > tr > th") + .attr("role", "columnheader"); + + // Store table options for easier evaluation of default actions + // depending of active cell column + this.nodeColumnIdx = treeOpts.table.nodeColumnIdx; + this.checkboxColumnIdx = treeOpts.table.checkboxColumnIdx; + if (this.checkboxColumnIdx == null) { + this.checkboxColumnIdx = this.nodeColumnIdx; + } + + this.$container + .on("focusin", function (event) { + // Activate node if embedded input gets focus (due to a click) + var node = FT.getNode(event.target), + $td = $(event.target).closest("td"); + + // tree.debug( "focusin: " + ( node ? node.title : "null" ) + + // ", target: " + ( $td ? $td.text() : null ) + + // ", node was active: " + ( node && node.isActive() ) + + // ", last cell: " + ( tree.$activeTd ? tree.$activeTd.text() : null ) ); + // tree.debug( "focusin: target", event.target ); + + // TODO: add ":input" as delegate filter instead of testing here + if ( + node && + !$td.is(tree.$activeTd) && + $(event.target).is(":input") + ) { + node.debug("Activate cell on INPUT focus event"); + tree.activateCell($td); + } + }) + .on("fancytreeinit", function (event, data) { + if ( + opts.cellFocus === "start" || + opts.cellFocus === "force" + ) { + tree.debug("Enforce cell-mode on init"); + tree.debug( + "init", + tree.getActiveNode() || tree.getFirstChild() + ); + ( + tree.getActiveNode() || tree.getFirstChild() + ).setActive(true, { cell: tree.nodeColumnIdx }); + tree.debug( + "init2", + tree.getActiveNode() || tree.getFirstChild() + ); + } + }) + .on("fancytreefocustree", function (event, data) { + // Enforce cell-mode when container gets focus + if (opts.cellFocus === "force" && !tree.$activeTd) { + var node = tree.getActiveNode() || tree.getFirstChild(); + tree.debug("Enforce cell-mode on focusTree event"); + node.setActive(true, { cell: 0 }); + } + }) + // .on("fancytreeupdateviewport", function(event, data) { + // tree.debug(event.type, data); + // }) + .on("fancytreebeforeupdateviewport", function (event, data) { + // When scrolling, the TR may be re-used by another node, so the + // active cell marker an + // tree.debug(event.type, data); + if (tree.viewport && tree.$activeTd) { + tree.info("Cancel cell-mode due to scroll event."); + tree.activateCell(null); + } + }); + }, + nodeClick: function (ctx) { + var targetType = ctx.targetType, + tree = ctx.tree, + node = ctx.node, + event = ctx.originalEvent, + $target = $(event.target), + $td = $target.closest("td"); + + tree.debug( + "nodeClick: node: " + + (node ? node.title : "null") + + ", targetType: " + + targetType + + ", target: " + + ($td.length ? $td.text() : null) + + ", node was active: " + + (node && node.isActive()) + + ", last cell: " + + (tree.$activeTd ? tree.$activeTd.text() : null) + ); + + if (tree.$activeTd) { + // If already in cell-mode, activate new cell + tree.activateCell($td); + if ($target.is(":input")) { + return; + } else if ( + $target.is(".fancytree-checkbox") || + $target.is(".fancytree-expander") + ) { + return this._superApply(arguments); + } + return false; + } + return this._superApply(arguments); + }, + nodeDblclick: function (ctx) { + var tree = ctx.tree, + treeOpts = ctx.options, + opts = treeOpts.ariagrid, + event = ctx.originalEvent, + $td = $(event.target).closest("td"); + + // console.log("nodeDblclick", tree.$activeTd, ctx.options.ariagrid.cellFocus) + if ( + opts.activateCellOnDoubelclick && + !tree.$activeTd && + opts.cellFocus === "allow" + ) { + // If in row-mode, activate new cell + tree.activateCell($td); + return false; + } + return this._superApply(arguments); + }, + nodeRenderStatus: function (ctx) { + // Set classes for current status + var res, + node = ctx.node, + $tr = $(node.tr); + + res = this._super(ctx); + + if (node.parent) { + $tr.attr("aria-level", node.getLevel()) + .attr("aria-setsize", node.parent.children.length) + .attr("aria-posinset", node.getIndex() + 1); + + // 2018-06-24: not required according to + // https://github.com/w3c/aria-practices/issues/132#issuecomment-397698250 + // if ( $tr.is( ":hidden" ) ) { + // $tr.attr( "aria-hidden", true ); + // } else { + // $tr.removeAttr( "aria-hidden" ); + // } + + // this.debug("nodeRenderStatus: " + this.$activeTd + ", " + $tr.attr("aria-expanded")); + // In cell-mode, move aria-expanded attribute from TR to first child TD + if (this.$activeTd && $tr.attr("aria-expanded") != null) { + $tr.remove("aria-expanded"); + $tr.find("td") + .eq(this.nodeColumnIdx) + .attr("aria-expanded", node.isExpanded()); + } else { + $tr.find("td") + .eq(this.nodeColumnIdx) + .removeAttr("aria-expanded"); + } + } + return res; + }, + nodeSetActive: function (ctx, flag, callOpts) { + var $td, + node = ctx.node, + tree = ctx.tree, + $tr = $(node.tr); + + flag = flag !== false; + node.debug("nodeSetActive(" + flag + ")", callOpts); + // Support custom `cell` option + if (flag && callOpts && callOpts.cell != null) { + // `cell` may be a col-index, <td>, or `$(td)` + if (typeof callOpts.cell === "number") { + $td = findTdAtColIdx($tr, callOpts.cell); + } else { + $td = $(callOpts.cell); + } + tree.activateCell($td); + return; + } + // tree.debug( "nodeSetActive: activeNode " + this.activeNode ); + return this._superApply(arguments); + }, + nodeKeydown: function (ctx) { + var handleKeys, + inputType, + res, + $td, + $embeddedCheckbox = null, + tree = ctx.tree, + node = ctx.node, + treeOpts = ctx.options, + opts = treeOpts.ariagrid, + event = ctx.originalEvent, + eventString = FT.eventToString(event), + $target = $(event.target), + $activeTd = this.$activeTd, + $activeTr = $activeTd ? $activeTd.closest("tr") : null, + colIdx = $activeTd ? getColIdx($activeTr, $activeTd) : -1, + forceNav = + $activeTd && + tree.forceNavMode && + $.inArray(eventString, NAV_KEYS) >= 0; + + if (opts.cellFocus === "off") { + return this._superApply(arguments); + } + + if ($target.is(":input:enabled")) { + inputType = $target.prop("type"); + } else if ($target.is("a")) { + inputType = "link"; + } + if ($activeTd && $activeTd.find(":checkbox:enabled").length === 1) { + $embeddedCheckbox = $activeTd.find(":checkbox:enabled"); + inputType = "checkbox"; + } + tree.debug( + "nodeKeydown(" + + eventString + + "), activeTd: '" + + ($activeTd && $activeTd.text()) + + "', inputType: " + + inputType + ); + + if (inputType && eventString !== "esc" && !forceNav) { + handleKeys = INPUT_KEYS[inputType]; + if (handleKeys && $.inArray(eventString, handleKeys) >= 0) { + return; // Let input control handle the key + } + } + + switch (eventString) { + case "right": + if ($activeTd) { + // Cell mode: move to neighbour (stop on right border) + $td = findNeighbourTd(tree, $activeTd, eventString); + if ($td) { + tree.activateCell($td); + } + } else if ( + node && + !node.isExpanded() && + node.hasChildren() !== false + ) { + // Row mode and current node can be expanded: + // default handling will expand. + break; + } else { + // Row mode: switch to cell-mode + $td = $(node.tr).find(">td").first(); + tree.activateCell($td); + } + return false; // no default handling + + case "left": + case "home": + case "end": + case "ctrl+home": + case "ctrl+end": + case "up": + case "down": + if ($activeTd) { + // Cell mode: move to neighbour + $td = findNeighbourTd(tree, $activeTd, eventString); + // Note: $td may be null if we move outside bounds. In this case + // we switch back to row-mode (i.e. call activateCell(null) ). + if (!$td && "left right".indexOf(eventString) < 0) { + // Only switch to row-mode if left/right hits the bounds + return false; + } + if ($td || opts.cellFocus !== "force") { + tree.activateCell($td); + } + return false; + } + break; + + case "esc": + if ($activeTd && !tree.forceNavMode) { + // Switch from cell-edit-mode to cell-nav-mode + // $target.closest( "td" ).focus(); + tree.forceNavMode = true; + tree.debug("Enter cell-nav-mode"); + tree.$container.toggleClass( + clsFancytreeCellNavMode, + !!tree.forceNavMode + ); + return false; + } else if ($activeTd && opts.cellFocus !== "force") { + // Switch back from cell-mode to row-mode + tree.activateCell(null); + return false; + } + // tree.$container.toggleClass( clsFancytreeCellNavMode, !!tree.forceNavMode ); + break; + + case "return": + // Let user override the default action. + // This event is triggered in row-mode and cell-mode + res = tree._triggerNodeEvent( + "defaultGridAction", + node, + event, + { + activeTd: tree.$activeTd ? tree.$activeTd[0] : null, + colIdx: colIdx, + mode: getGridNavMode(tree), + } + ); + if (res === false) { + return false; + } + // Implement default actions (for cell-mode only). + if ($activeTd) { + // Apply 'default action' for embedded cell control + if (colIdx === this.nodeColumnIdx) { + node.toggleExpanded(); + } else if (colIdx === this.checkboxColumnIdx) { + // TODO: only in checkbox mode! + node.toggleSelected(); + } else if ($embeddedCheckbox) { + // Embedded checkboxes are always toggled (ignoring `autoFocusInput`) + $embeddedCheckbox.prop( + "checked", + !$embeddedCheckbox.prop("checked") + ); + } else if (tree.forceNavMode && $target.is(":input")) { + tree.forceNavMode = false; + tree.$container.removeClass( + clsFancytreeCellNavMode + ); + tree.debug("enable cell-edit-mode"); + } else if ($activeTd.find("a").length === 1) { + activateEmbeddedLink($activeTd); + } + } else { + // ENTER in row-mode: Switch from row-mode to cell-mode + // TODO: it was also suggested to expand/collapse instead + // https://github.com/w3c/aria-practices/issues/132#issuecomment-407634891 + $td = $(node.tr).find(">td").nth(this.nodeColumnIdx); + tree.activateCell($td); + } + return false; // no default handling + + case "space": + if ($activeTd) { + if (colIdx === this.checkboxColumnIdx) { + node.toggleSelected(); + } else if ($embeddedCheckbox) { + $embeddedCheckbox.prop( + "checked", + !$embeddedCheckbox.prop("checked") + ); + } + return false; // no default handling + } + break; + + default: + // Allow to focus input by typing alphanum keys + } + return this._superApply(arguments); + }, + treeSetOption: function (ctx, key, value) { + var tree = ctx.tree, + opts = tree.options.ariagrid; + + if (key === "ariagrid") { + // User called `$().fancytree("option", "ariagrid.SUBKEY", VALUE)` + if (value.cellFocus !== opts.cellFocus) { + if ($.inArray(value.cellFocus, VALID_MODES) < 0) { + $.error("Invalid `cellFocus` option"); + } + // TODO: fix current focus and mode + } + } + return this._superApply(arguments); + }, + }); + // Value returned by `require('jquery.fancytree..')` + return $.ui.fancytree; +}); // End of closure diff --git a/plugins/55/indexmenu/scripts/fancytree/modules/jquery.fancytree.childcounter.js b/plugins/55/indexmenu/scripts/fancytree/modules/jquery.fancytree.childcounter.js new file mode 100644 index 0000000..216b124 --- /dev/null +++ b/plugins/55/indexmenu/scripts/fancytree/modules/jquery.fancytree.childcounter.js @@ -0,0 +1,241 @@ +// Extending Fancytree +// =================== +// +// See also the [live demo](https://wwWendt.de/tech/fancytree/demo/sample-ext-childcounter.html) of this code. +// +// Every extension should have a comment header containing some information +// about the author, copyright and licensing. Also a pointer to the latest +// source code. +// Prefix with `/*!` so the comment is not removed by the minifier. + +/*! + * jquery.fancytree.childcounter.js + * + * Add a child counter bubble to tree nodes. + * (Extension module for jquery.fancytree.js: https://github.com/mar10/fancytree/) + * + * Copyright (c) 2008-2023, Martin Wendt (https://wwWendt.de) + * + * Released under the MIT license + * https://github.com/mar10/fancytree/wiki/LicenseInfo + * + * @version 2.38.3 + * @date 2023-02-01T20:52:50Z + */ + +// To keep the global namespace clean, we wrap everything in a closure. +// The UMD wrapper pattern defines the dependencies on jQuery and the +// Fancytree core module, and makes sure that we can use the `require()` +// syntax with package loaders. + +(function (factory) { + if (typeof define === "function" && define.amd) { + // AMD. Register as an anonymous module. + define(["jquery", "./jquery.fancytree"], factory); + } else if (typeof module === "object" && module.exports) { + // Node/CommonJS + require("./jquery.fancytree"); + module.exports = factory(require("jquery")); + } else { + // Browser globals + factory(jQuery); + } +})(function ($) { + // Consider to use [strict mode](http://ejohn.org/blog/ecmascript-5-strict-mode-json-and-more/) + "use strict"; + + // The [coding guidelines](http://contribute.jquery.org/style-guide/js/) + // require jshint /eslint compliance. + // But for this sample, we want to allow unused variables for demonstration purpose. + + /*eslint-disable no-unused-vars */ + + // Adding methods + // -------------- + + // New member functions can be added to the `Fancytree` class. + // This function will be available for every tree instance: + // + // var tree = $.ui.fancytree.getTree("#tree"); + // tree.countSelected(false); + + $.ui.fancytree._FancytreeClass.prototype.countSelected = function ( + topOnly + ) { + var tree = this, + treeOptions = tree.options; + + return tree.getSelectedNodes(topOnly).length; + }; + + // The `FancytreeNode` class can also be easily extended. This would be called + // like + // node.updateCounters(); + // + // It is also good practice to add a docstring comment. + /** + * [ext-childcounter] Update counter badges for `node` and its parents. + * May be called in the `loadChildren` event, to update parents of lazy loaded + * nodes. + * @alias FancytreeNode#updateCounters + * @requires jquery.fancytree.childcounters.js + */ + $.ui.fancytree._FancytreeNodeClass.prototype.updateCounters = function () { + var node = this, + $badge = $("span.fancytree-childcounter", node.span), + extOpts = node.tree.options.childcounter, + count = node.countChildren(extOpts.deep); + + node.data.childCounter = count; + if ( + (count || !extOpts.hideZeros) && + (!node.isExpanded() || !extOpts.hideExpanded) + ) { + if (!$badge.length) { + $badge = $("<span class='fancytree-childcounter'/>").appendTo( + $( + "span.fancytree-icon,span.fancytree-custom-icon", + node.span + ) + ); + } + $badge.text(count); + } else { + $badge.remove(); + } + if (extOpts.deep && !node.isTopLevel() && !node.isRootNode()) { + node.parent.updateCounters(); + } + }; + + // Finally, we can extend the widget API and create functions that are called + // like so: + // + // $("#tree").fancytree("widgetMethod1", "abc"); + + $.ui.fancytree.prototype.widgetMethod1 = function (arg1) { + var tree = this.tree; + return arg1; + }; + + // Register a Fancytree extension + // ------------------------------ + // A full blown extension, extension is available for all trees and can be + // enabled like so (see also the [live demo](https://wwWendt.de/tech/fancytree/demo/sample-ext-childcounter.html)): + // + // <script src="../src/jquery.fancytree.js"></script> + // <script src="../src/jquery.fancytree.childcounter.js"></script> + // ... + // + // $("#tree").fancytree({ + // extensions: ["childcounter"], + // childcounter: { + // hideExpanded: true + // }, + // ... + // }); + // + + /* 'childcounter' extension */ + $.ui.fancytree.registerExtension({ + // Every extension must be registered by a unique name. + name: "childcounter", + // Version information should be compliant with [semver](http://semver.org) + version: "2.38.3", + + // Extension specific options and their defaults. + // This options will be available as `tree.options.childcounter.hideExpanded` + + options: { + deep: true, + hideZeros: true, + hideExpanded: false, + }, + + // Attributes other than `options` (or functions) can be defined here, and + // will be added to the tree.ext.EXTNAME namespace, in this case `tree.ext.childcounter.foo`. + // They can also be accessed as `this._local.foo` from within the extension + // methods. + foo: 42, + + // Local functions are prefixed with an underscore '_'. + // Callable as `this._local._appendCounter()`. + + _appendCounter: function (bar) { + var tree = this; + }, + + // **Override virtual methods for this extension.** + // + // Fancytree implements a number of 'hook methods', prefixed by 'node...' or 'tree...'. + // with a `ctx` argument (see [EventData](https://wwWendt.de/tech/fancytree/doc/jsdoc/global.html#EventData) + // for details) and an extended calling context:<br> + // `this` : the Fancytree instance<br> + // `this._local`: the namespace that contains extension attributes and private methods (same as this.ext.EXTNAME)<br> + // `this._super`: the virtual function that was overridden (member of previous extension or Fancytree) + // + // See also the [complete list of available hook functions](https://wwWendt.de/tech/fancytree/doc/jsdoc/Fancytree_Hooks.html). + + /* Init */ + // `treeInit` is triggered when a tree is initalized. We can set up classes or + // bind event handlers here... + treeInit: function (ctx) { + var tree = this, // same as ctx.tree, + opts = ctx.options, + extOpts = ctx.options.childcounter; + // Optionally check for dependencies with other extensions + /* this._requireExtension("glyph", false, false); */ + // Call the base implementation + this._superApply(arguments); + // Add a class to the tree container + this.$container.addClass("fancytree-ext-childcounter"); + }, + + // Destroy this tree instance (we only call the default implementation, so + // this method could as well be omitted). + + treeDestroy: function (ctx) { + this._superApply(arguments); + }, + + // Overload the `renderTitle` hook, to append a counter badge + nodeRenderTitle: function (ctx, title) { + var node = ctx.node, + extOpts = ctx.options.childcounter, + count = + node.data.childCounter == null + ? node.countChildren(extOpts.deep) + : +node.data.childCounter; + // Let the base implementation render the title + // We use `_super()` instead of `_superApply()` here, since it is a little bit + // more performant when called often + this._super(ctx, title); + // Append a counter badge + if ( + (count || !extOpts.hideZeros) && + (!node.isExpanded() || !extOpts.hideExpanded) + ) { + $( + "span.fancytree-icon,span.fancytree-custom-icon", + node.span + ).append( + $("<span class='fancytree-childcounter'/>").text(count) + ); + } + }, + // Overload the `setExpanded` hook, so the counters are updated + nodeSetExpanded: function (ctx, flag, callOpts) { + var tree = ctx.tree, + node = ctx.node; + // Let the base implementation expand/collapse the node, then redraw the title + // after the animation has finished + return this._superApply(arguments).always(function () { + tree.nodeRenderTitle(ctx); + }); + }, + + // End of extension definition + }); + // Value returned by `require('jquery.fancytree..')` + return $.ui.fancytree; +}); // End of closure diff --git a/plugins/55/indexmenu/scripts/fancytree/modules/jquery.fancytree.clones.js b/plugins/55/indexmenu/scripts/fancytree/modules/jquery.fancytree.clones.js new file mode 100644 index 0000000..08f8f2b --- /dev/null +++ b/plugins/55/indexmenu/scripts/fancytree/modules/jquery.fancytree.clones.js @@ -0,0 +1,514 @@ +/*! + * + * jquery.fancytree.clones.js + * Support faster lookup of nodes by key and shared ref-ids. + * (Extension module for jquery.fancytree.js: https://github.com/mar10/fancytree/) + * + * Copyright (c) 2008-2023, Martin Wendt (https://wwWendt.de) + * + * Released under the MIT license + * https://github.com/mar10/fancytree/wiki/LicenseInfo + * + * @version 2.38.3 + * @date 2023-02-01T20:52:50Z + */ + +(function (factory) { + if (typeof define === "function" && define.amd) { + // AMD. Register as an anonymous module. + define(["jquery", "./jquery.fancytree"], factory); + } else if (typeof module === "object" && module.exports) { + // Node/CommonJS + require("./jquery.fancytree"); + module.exports = factory(require("jquery")); + } else { + // Browser globals + factory(jQuery); + } +})(function ($) { + "use strict"; + + /******************************************************************************* + * Private functions and variables + */ + + var _assert = $.ui.fancytree.assert; + + /* Return first occurrence of member from array. */ + function _removeArrayMember(arr, elem) { + // TODO: use Array.indexOf for IE >= 9 + var i; + for (i = arr.length - 1; i >= 0; i--) { + if (arr[i] === elem) { + arr.splice(i, 1); + return true; + } + } + return false; + } + + /** + * JS Implementation of MurmurHash3 (r136) (as of May 20, 2011) + * + * @author <a href="mailto:gary.court@gmail.com">Gary Court</a> + * @see http://github.com/garycourt/murmurhash-js + * @author <a href="mailto:aappleby@gmail.com">Austin Appleby</a> + * @see http://sites.google.com/site/murmurhash/ + * + * @param {string} key ASCII only + * @param {boolean} [asString=false] + * @param {number} seed Positive integer only + * @return {number} 32-bit positive integer hash + */ + function hashMurmur3(key, asString, seed) { + /*eslint-disable no-bitwise */ + var h1b, + k1, + remainder = key.length & 3, + bytes = key.length - remainder, + h1 = seed, + c1 = 0xcc9e2d51, + c2 = 0x1b873593, + i = 0; + + while (i < bytes) { + k1 = + (key.charCodeAt(i) & 0xff) | + ((key.charCodeAt(++i) & 0xff) << 8) | + ((key.charCodeAt(++i) & 0xff) << 16) | + ((key.charCodeAt(++i) & 0xff) << 24); + ++i; + + k1 = + ((k1 & 0xffff) * c1 + ((((k1 >>> 16) * c1) & 0xffff) << 16)) & + 0xffffffff; + k1 = (k1 << 15) | (k1 >>> 17); + k1 = + ((k1 & 0xffff) * c2 + ((((k1 >>> 16) * c2) & 0xffff) << 16)) & + 0xffffffff; + + h1 ^= k1; + h1 = (h1 << 13) | (h1 >>> 19); + h1b = + ((h1 & 0xffff) * 5 + ((((h1 >>> 16) * 5) & 0xffff) << 16)) & + 0xffffffff; + h1 = + (h1b & 0xffff) + + 0x6b64 + + ((((h1b >>> 16) + 0xe654) & 0xffff) << 16); + } + + k1 = 0; + + switch (remainder) { + case 3: + k1 ^= (key.charCodeAt(i + 2) & 0xff) << 16; + // fall through + case 2: + k1 ^= (key.charCodeAt(i + 1) & 0xff) << 8; + // fall through + case 1: + k1 ^= key.charCodeAt(i) & 0xff; + + k1 = + ((k1 & 0xffff) * c1 + + ((((k1 >>> 16) * c1) & 0xffff) << 16)) & + 0xffffffff; + k1 = (k1 << 15) | (k1 >>> 17); + k1 = + ((k1 & 0xffff) * c2 + + ((((k1 >>> 16) * c2) & 0xffff) << 16)) & + 0xffffffff; + h1 ^= k1; + } + + h1 ^= key.length; + + h1 ^= h1 >>> 16; + h1 = + ((h1 & 0xffff) * 0x85ebca6b + + ((((h1 >>> 16) * 0x85ebca6b) & 0xffff) << 16)) & + 0xffffffff; + h1 ^= h1 >>> 13; + h1 = + ((h1 & 0xffff) * 0xc2b2ae35 + + ((((h1 >>> 16) * 0xc2b2ae35) & 0xffff) << 16)) & + 0xffffffff; + h1 ^= h1 >>> 16; + + if (asString) { + // Convert to 8 digit hex string + return ("0000000" + (h1 >>> 0).toString(16)).substr(-8); + } + return h1 >>> 0; + /*eslint-enable no-bitwise */ + } + + /* + * Return a unique key for node by calculating the hash of the parents refKey-list. + */ + function calcUniqueKey(node) { + var key, + h1, + path = $.map(node.getParentList(false, true), function (e) { + return e.refKey || e.key; + }); + + path = path.join("/"); + // 32-bit has a high probability of collisions, so we pump up to 64-bit + // https://security.stackexchange.com/q/209882/207588 + + h1 = hashMurmur3(path, true); + key = "id_" + h1 + hashMurmur3(h1 + path, true); + + return key; + } + + /** + * [ext-clones] Return a list of clone-nodes (i.e. same refKey) or null. + * @param {boolean} [includeSelf=false] + * @returns {FancytreeNode[] | null} + * + * @alias FancytreeNode#getCloneList + * @requires jquery.fancytree.clones.js + */ + $.ui.fancytree._FancytreeNodeClass.prototype.getCloneList = function ( + includeSelf + ) { + var key, + tree = this.tree, + refList = tree.refMap[this.refKey] || null, + keyMap = tree.keyMap; + + if (refList) { + key = this.key; + // Convert key list to node list + if (includeSelf) { + refList = $.map(refList, function (val) { + return keyMap[val]; + }); + } else { + refList = $.map(refList, function (val) { + return val === key ? null : keyMap[val]; + }); + if (refList.length < 1) { + refList = null; + } + } + } + return refList; + }; + + /** + * [ext-clones] Return true if this node has at least another clone with same refKey. + * @returns {boolean} + * + * @alias FancytreeNode#isClone + * @requires jquery.fancytree.clones.js + */ + $.ui.fancytree._FancytreeNodeClass.prototype.isClone = function () { + var refKey = this.refKey || null, + refList = (refKey && this.tree.refMap[refKey]) || null; + return !!(refList && refList.length > 1); + }; + + /** + * [ext-clones] Update key and/or refKey for an existing node. + * @param {string} key + * @param {string} refKey + * @returns {boolean} + * + * @alias FancytreeNode#reRegister + * @requires jquery.fancytree.clones.js + */ + $.ui.fancytree._FancytreeNodeClass.prototype.reRegister = function ( + key, + refKey + ) { + key = key == null ? null : "" + key; + refKey = refKey == null ? null : "" + refKey; + // this.debug("reRegister", key, refKey); + + var tree = this.tree, + prevKey = this.key, + prevRefKey = this.refKey, + keyMap = tree.keyMap, + refMap = tree.refMap, + refList = refMap[prevRefKey] || null, + // curCloneKeys = refList ? node.getCloneList(true), + modified = false; + + // Key has changed: update all references + if (key != null && key !== this.key) { + if (keyMap[key]) { + $.error( + "[ext-clones] reRegister(" + + key + + "): already exists: " + + this + ); + } + // Update keyMap + delete keyMap[prevKey]; + keyMap[key] = this; + // Update refMap + if (refList) { + refMap[prevRefKey] = $.map(refList, function (e) { + return e === prevKey ? key : e; + }); + } + this.key = key; + modified = true; + } + + // refKey has changed + if (refKey != null && refKey !== this.refKey) { + // Remove previous refKeys + if (refList) { + if (refList.length === 1) { + delete refMap[prevRefKey]; + } else { + refMap[prevRefKey] = $.map(refList, function (e) { + return e === prevKey ? null : e; + }); + } + } + // Add refKey + if (refMap[refKey]) { + refMap[refKey].append(key); + } else { + refMap[refKey] = [this.key]; + } + this.refKey = refKey; + modified = true; + } + return modified; + }; + + /** + * [ext-clones] Define a refKey for an existing node. + * @param {string} refKey + * @returns {boolean} + * + * @alias FancytreeNode#setRefKey + * @requires jquery.fancytree.clones.js + * @since 2.16 + */ + $.ui.fancytree._FancytreeNodeClass.prototype.setRefKey = function (refKey) { + return this.reRegister(null, refKey); + }; + + /** + * [ext-clones] Return all nodes with a given refKey (null if not found). + * @param {string} refKey + * @param {FancytreeNode} [rootNode] optionally restrict results to descendants of this node + * @returns {FancytreeNode[] | null} + * @alias Fancytree#getNodesByRef + * @requires jquery.fancytree.clones.js + */ + $.ui.fancytree._FancytreeClass.prototype.getNodesByRef = function ( + refKey, + rootNode + ) { + var keyMap = this.keyMap, + refList = this.refMap[refKey] || null; + + if (refList) { + // Convert key list to node list + if (rootNode) { + refList = $.map(refList, function (val) { + var node = keyMap[val]; + return node.isDescendantOf(rootNode) ? node : null; + }); + } else { + refList = $.map(refList, function (val) { + return keyMap[val]; + }); + } + if (refList.length < 1) { + refList = null; + } + } + return refList; + }; + + /** + * [ext-clones] Replace a refKey with a new one. + * @param {string} oldRefKey + * @param {string} newRefKey + * @alias Fancytree#changeRefKey + * @requires jquery.fancytree.clones.js + */ + $.ui.fancytree._FancytreeClass.prototype.changeRefKey = function ( + oldRefKey, + newRefKey + ) { + var i, + node, + keyMap = this.keyMap, + refList = this.refMap[oldRefKey] || null; + + if (refList) { + for (i = 0; i < refList.length; i++) { + node = keyMap[refList[i]]; + node.refKey = newRefKey; + } + delete this.refMap[oldRefKey]; + this.refMap[newRefKey] = refList; + } + }; + + /******************************************************************************* + * Extension code + */ + $.ui.fancytree.registerExtension({ + name: "clones", + version: "2.38.3", + // Default options for this extension. + options: { + highlightActiveClones: true, // set 'fancytree-active-clone' on active clones and all peers + highlightClones: false, // set 'fancytree-clone' class on any node that has at least one clone + }, + + treeCreate: function (ctx) { + this._superApply(arguments); + ctx.tree.refMap = {}; + ctx.tree.keyMap = {}; + }, + treeInit: function (ctx) { + this.$container.addClass("fancytree-ext-clones"); + _assert(ctx.options.defaultKey == null); + // Generate unique / reproducible default keys + ctx.options.defaultKey = function (node) { + return calcUniqueKey(node); + }; + // The default implementation loads initial data + this._superApply(arguments); + }, + treeClear: function (ctx) { + ctx.tree.refMap = {}; + ctx.tree.keyMap = {}; + return this._superApply(arguments); + }, + treeRegisterNode: function (ctx, add, node) { + var refList, + len, + tree = ctx.tree, + keyMap = tree.keyMap, + refMap = tree.refMap, + key = node.key, + refKey = node && node.refKey != null ? "" + node.refKey : null; + + // ctx.tree.debug("clones.treeRegisterNode", add, node); + + if (node.isStatusNode()) { + return this._super(ctx, add, node); + } + + if (add) { + if (keyMap[node.key] != null) { + var other = keyMap[node.key], + msg = + "clones.treeRegisterNode: duplicate key '" + + node.key + + "': /" + + node.getPath(true) + + " => " + + other.getPath(true); + // Sometimes this exception is not visible in the console, + // so we also write it: + tree.error(msg); + $.error(msg); + } + keyMap[key] = node; + + if (refKey) { + refList = refMap[refKey]; + if (refList) { + refList.push(key); + if ( + refList.length === 2 && + ctx.options.clones.highlightClones + ) { + // Mark peer node, if it just became a clone (no need to + // mark current node, since it will be rendered later anyway) + keyMap[refList[0]].renderStatus(); + } + } else { + refMap[refKey] = [key]; + } + // node.debug("clones.treeRegisterNode: add clone =>", refMap[refKey]); + } + } else { + if (keyMap[key] == null) { + $.error( + "clones.treeRegisterNode: node.key not registered: " + + node.key + ); + } + delete keyMap[key]; + if (refKey) { + refList = refMap[refKey]; + // node.debug("clones.treeRegisterNode: remove clone BEFORE =>", refMap[refKey]); + if (refList) { + len = refList.length; + if (len <= 1) { + _assert(len === 1); + _assert(refList[0] === key); + delete refMap[refKey]; + } else { + _removeArrayMember(refList, key); + // Unmark peer node, if this was the only clone + if ( + len === 2 && + ctx.options.clones.highlightClones + ) { + // node.debug("clones.treeRegisterNode: last =>", node.getCloneList()); + keyMap[refList[0]].renderStatus(); + } + } + // node.debug("clones.treeRegisterNode: remove clone =>", refMap[refKey]); + } + } + } + return this._super(ctx, add, node); + }, + nodeRenderStatus: function (ctx) { + var $span, + res, + node = ctx.node; + + res = this._super(ctx); + + if (ctx.options.clones.highlightClones) { + $span = $(node[ctx.tree.statusClassPropName]); + // Only if span already exists + if ($span.length && node.isClone()) { + // node.debug("clones.nodeRenderStatus: ", ctx.options.clones.highlightClones); + $span.addClass("fancytree-clone"); + } + } + return res; + }, + nodeSetActive: function (ctx, flag, callOpts) { + var res, + scpn = ctx.tree.statusClassPropName, + node = ctx.node; + + res = this._superApply(arguments); + + if (ctx.options.clones.highlightActiveClones && node.isClone()) { + $.each(node.getCloneList(true), function (idx, n) { + // n.debug("clones.nodeSetActive: ", flag !== false); + $(n[scpn]).toggleClass( + "fancytree-active-clone", + flag !== false + ); + }); + } + return res; + }, + }); + // Value returned by `require('jquery.fancytree..')` + return $.ui.fancytree; +}); // End of closure diff --git a/plugins/55/indexmenu/scripts/fancytree/modules/jquery.fancytree.columnview.js b/plugins/55/indexmenu/scripts/fancytree/modules/jquery.fancytree.columnview.js new file mode 100644 index 0000000..98afd52 --- /dev/null +++ b/plugins/55/indexmenu/scripts/fancytree/modules/jquery.fancytree.columnview.js @@ -0,0 +1,205 @@ +/*! + * jquery.fancytree.columnview.js + * + * Render tree like a Mac Finder's column view. + * (Extension module for jquery.fancytree.js: https://github.com/mar10/fancytree/) + * + * Copyright (c) 2008-2023, Martin Wendt (https://wwWendt.de) + * + * Released under the MIT license + * https://github.com/mar10/fancytree/wiki/LicenseInfo + * + * @version 2.38.3 + * @date 2023-02-01T20:52:50Z + */ + +(function (factory) { + if (typeof define === "function" && define.amd) { + // AMD. Register as an anonymous module. + define(["jquery", "./jquery.fancytree"], factory); + } else if (typeof module === "object" && module.exports) { + // Node/CommonJS + require("./jquery.fancytree"); + module.exports = factory(require("jquery")); + } else { + // Browser globals + factory(jQuery); + } +})(function ($) { + "use strict"; + + /******************************************************************************* + * Private functions and variables + */ + var _assert = $.ui.fancytree.assert, + FT = $.ui.fancytree; + + /******************************************************************************* + * Private functions and variables + */ + $.ui.fancytree.registerExtension({ + name: "columnview", + version: "2.38.3", + // Default options for this extension. + options: {}, + // Overide virtual methods for this extension. + // `this` : is this extension object + // `this._base` : the Fancytree instance + // `this._super`: the virtual function that was overriden (member of prev. extension or Fancytree) + treeInit: function (ctx) { + var $tdFirst, + $ul, + tree = ctx.tree, + $table = tree.widget.element; + + tree.tr = $("tbody tr", $table)[0]; + tree.$tdList = $(">td", tree.tr); + tree.columnCount = tree.$tdList.length; + // Perform default behavior + this._superApply(arguments); + // Standard Fancytree created a root <ul>. Now move this into first table cell + $ul = $(tree.rootNode.ul); + $tdFirst = tree.$tdList.eq(0); + + _assert( + $.inArray("table", this.options.extensions) < 0, + "columnview extensions must not use ext-table" + ); + _assert( + tree.columnCount >= 2, + "columnview target must be a table with at least two columns" + ); + + $ul.removeClass("fancytree-container").removeAttr("tabindex"); + tree.$container = $table; + $table + .addClass("fancytree-container fancytree-ext-columnview") + .attr("tabindex", "0"); + + $tdFirst.empty(); + $ul.detach().appendTo($tdFirst); + + // Force some required options + tree.widget.options.autoCollapse = true; + // tree.widget.options.autoActivate = true; + tree.widget.options.toggleEffect = false; + tree.widget.options.clickFolderMode = 1; + + $table + // Make sure that only active path is expanded when a node is activated: + .on("fancytreeactivate", function (event, data) { + var node = data.node, + tree = data.tree, + level = node.getLevel(); + + tree._callHook("nodeCollapseSiblings", node); + // Clear right neighbours + if (!node.expanded) { + tree.$tdList.eq(level).nextAll().empty(); + } + // Expand nodes on activate, so we populate the right neighbor cell + if (!node.expanded && (node.children || node.lazy)) { + node.setExpanded(); + } + }) + // Adjust keyboard behaviour: + .on("fancytreekeydown", function (event, data) { + var next = null, + handled = true, + node = data.node || data.tree.getFirstChild(); + + if (node.getLevel() >= tree.columnCount) { + return; + } + switch (FT.eventToString(event)) { + case "down": + next = node.getNextSibling(); + break; + case "left": + if (!node.isTopLevel()) { + next = node.getParent(); + } + break; + case "right": + next = node.getFirstChild(); + if (!next) { + // default processing: expand or ignore + return; + } + // Prefer an expanded child if any + next.visitSiblings(function (n) { + if (n.expanded) { + next = n; + return false; + } + }, true); + break; + case "up": + next = node.getPrevSibling(); + break; + default: + handled = false; + } + if (next) { + next.setActive(); + } + return !handled; + }); + }, + nodeSetExpanded: function (ctx, flag, callOpts) { + var $wait, + node = ctx.node, + tree = ctx.tree, + level = node.getLevel(); + + if (flag !== false && !node.expanded && node.isUndefined()) { + $wait = $( + "<span class='fancytree-icon fancytree-icon-loading'>" + ); + tree.$tdList.eq(level).empty().append($wait); + } + return this._superApply(arguments); + }, + nodeRemoveChildren: function (ctx) { + // #899: node's children removed: remove child marker... + $(ctx.node.span).find("span.fancytree-cv-right").remove(); + // ...and clear right columns + ctx.tree.$tdList.eq(ctx.node.getLevel()).nextAll().empty(); + return this._superApply(arguments); + }, + nodeRender: function (ctx, force, deep, collapsed, _recursive) { + // Render standard nested <ul> - <li> hierarchy + this._super(ctx, force, deep, collapsed, _recursive); + // Remove expander and add a trailing triangle instead + var level, + $tdChild, + $ul, + tree = ctx.tree, + node = ctx.node, + $span = $(node.span); + + $span.find("span.fancytree-expander").remove(); + if ( + node.hasChildren() !== false && + !$span.find("span.fancytree-cv-right").length + ) { + $span.append( + $("<span class='fancytree-icon fancytree-cv-right'>") + ); + } + // Move <ul> with children into the appropriate <td> + if (node.ul && node.expanded) { + node.ul.style.display = ""; // might be hidden if RIGHT was pressed + level = node.getLevel(); + if (level < tree.columnCount) { + // only if we are not in the last column + $tdChild = tree.$tdList.eq(level); + $ul = $(node.ul).detach(); + $tdChild.empty().append($ul); + } + } + }, + }); + // Value returned by `require('jquery.fancytree..')` + return $.ui.fancytree; +}); // End of closure diff --git a/plugins/55/indexmenu/scripts/fancytree/modules/jquery.fancytree.dnd.js b/plugins/55/indexmenu/scripts/fancytree/modules/jquery.fancytree.dnd.js new file mode 100644 index 0000000..e9f68ad --- /dev/null +++ b/plugins/55/indexmenu/scripts/fancytree/modules/jquery.fancytree.dnd.js @@ -0,0 +1,798 @@ +/*! + * jquery.fancytree.dnd.js + * + * Drag-and-drop support (jQuery UI draggable/droppable). + * (Extension module for jquery.fancytree.js: https://github.com/mar10/fancytree/) + * + * Copyright (c) 2008-2023, Martin Wendt (https://wwWendt.de) + * + * Released under the MIT license + * https://github.com/mar10/fancytree/wiki/LicenseInfo + * + * @version 2.38.3 + * @date 2023-02-01T20:52:50Z + */ + +(function (factory) { + if (typeof define === "function" && define.amd) { + // AMD. Register as an anonymous module. + define([ + "jquery", + "jquery-ui/ui/widgets/draggable", + "jquery-ui/ui/widgets/droppable", + "./jquery.fancytree", + ], factory); + } else if (typeof module === "object" && module.exports) { + // Node/CommonJS + require("./jquery.fancytree"); + module.exports = factory(require("jquery")); + } else { + // Browser globals + factory(jQuery); + } +})(function ($) { + "use strict"; + + /****************************************************************************** + * Private functions and variables + */ + var didRegisterDnd = false, + classDropAccept = "fancytree-drop-accept", + classDropAfter = "fancytree-drop-after", + classDropBefore = "fancytree-drop-before", + classDropOver = "fancytree-drop-over", + classDropReject = "fancytree-drop-reject", + classDropTarget = "fancytree-drop-target"; + + /* Convert number to string and prepend +/-; return empty string for 0.*/ + function offsetString(n) { + // eslint-disable-next-line no-nested-ternary + return n === 0 ? "" : n > 0 ? "+" + n : "" + n; + } + + //--- Extend ui.draggable event handling -------------------------------------- + + function _registerDnd() { + if (didRegisterDnd) { + return; + } + + // Register proxy-functions for draggable.start/drag/stop + + $.ui.plugin.add("draggable", "connectToFancytree", { + start: function (event, ui) { + // 'draggable' was renamed to 'ui-draggable' since jQueryUI 1.10 + var draggable = + $(this).data("ui-draggable") || + $(this).data("draggable"), + sourceNode = ui.helper.data("ftSourceNode") || null; + + if (sourceNode) { + // Adjust helper offset, so cursor is slightly outside top/left corner + draggable.offset.click.top = -2; + draggable.offset.click.left = +16; + // Trigger dragStart event + // TODO: when called as connectTo..., the return value is ignored(?) + return sourceNode.tree.ext.dnd._onDragEvent( + "start", + sourceNode, + null, + event, + ui, + draggable + ); + } + }, + drag: function (event, ui) { + var ctx, + isHelper, + logObject, + // 'draggable' was renamed to 'ui-draggable' since jQueryUI 1.10 + draggable = + $(this).data("ui-draggable") || + $(this).data("draggable"), + sourceNode = ui.helper.data("ftSourceNode") || null, + prevTargetNode = ui.helper.data("ftTargetNode") || null, + targetNode = $.ui.fancytree.getNode(event.target), + dndOpts = sourceNode && sourceNode.tree.options.dnd; + + // logObject = sourceNode || prevTargetNode || $.ui.fancytree; + // logObject.debug("Drag event:", event, event.shiftKey); + if (event.target && !targetNode) { + // We got a drag event, but the targetNode could not be found + // at the event location. This may happen, + // 1. if the mouse jumped over the drag helper, + // 2. or if a non-fancytree element is dragged + // We ignore it: + isHelper = + $(event.target).closest( + "div.fancytree-drag-helper,#fancytree-drop-marker" + ).length > 0; + if (isHelper) { + logObject = + sourceNode || prevTargetNode || $.ui.fancytree; + logObject.debug("Drag event over helper: ignored."); + return; + } + } + ui.helper.data("ftTargetNode", targetNode); + + if (dndOpts && dndOpts.updateHelper) { + ctx = sourceNode.tree._makeHookContext(sourceNode, event, { + otherNode: targetNode, + ui: ui, + draggable: draggable, + dropMarker: $("#fancytree-drop-marker"), + }); + dndOpts.updateHelper.call(sourceNode.tree, sourceNode, ctx); + } + + // Leaving a tree node + if (prevTargetNode && prevTargetNode !== targetNode) { + prevTargetNode.tree.ext.dnd._onDragEvent( + "leave", + prevTargetNode, + sourceNode, + event, + ui, + draggable + ); + } + if (targetNode) { + if (!targetNode.tree.options.dnd.dragDrop) { + // not enabled as drop target + } else if (targetNode === prevTargetNode) { + // Moving over same node + targetNode.tree.ext.dnd._onDragEvent( + "over", + targetNode, + sourceNode, + event, + ui, + draggable + ); + } else { + // Entering this node first time + targetNode.tree.ext.dnd._onDragEvent( + "enter", + targetNode, + sourceNode, + event, + ui, + draggable + ); + targetNode.tree.ext.dnd._onDragEvent( + "over", + targetNode, + sourceNode, + event, + ui, + draggable + ); + } + } + // else go ahead with standard event handling + }, + stop: function (event, ui) { + var logObject, + // 'draggable' was renamed to 'ui-draggable' since jQueryUI 1.10: + draggable = + $(this).data("ui-draggable") || + $(this).data("draggable"), + sourceNode = ui.helper.data("ftSourceNode") || null, + targetNode = ui.helper.data("ftTargetNode") || null, + dropped = event.type === "mouseup" && event.which === 1; + + if (!dropped) { + logObject = sourceNode || targetNode || $.ui.fancytree; + logObject.debug("Drag was cancelled"); + } + if (targetNode) { + if (dropped) { + targetNode.tree.ext.dnd._onDragEvent( + "drop", + targetNode, + sourceNode, + event, + ui, + draggable + ); + } + targetNode.tree.ext.dnd._onDragEvent( + "leave", + targetNode, + sourceNode, + event, + ui, + draggable + ); + } + if (sourceNode) { + sourceNode.tree.ext.dnd._onDragEvent( + "stop", + sourceNode, + null, + event, + ui, + draggable + ); + } + }, + }); + + didRegisterDnd = true; + } + + /****************************************************************************** + * Drag and drop support + */ + function _initDragAndDrop(tree) { + var dnd = tree.options.dnd || null, + glyph = tree.options.glyph || null; + + // Register 'connectToFancytree' option with ui.draggable + if (dnd) { + _registerDnd(); + } + // Attach ui.draggable to this Fancytree instance + if (dnd && dnd.dragStart) { + tree.widget.element.draggable( + $.extend( + { + addClasses: false, + // DT issue 244: helper should be child of scrollParent: + appendTo: tree.$container, + // appendTo: "body", + containment: false, + // containment: "parent", + delay: 0, + distance: 4, + revert: false, + scroll: true, // to disable, also set css 'position: inherit' on ul.fancytree-container + scrollSpeed: 7, + scrollSensitivity: 10, + // Delegate draggable.start, drag, and stop events to our handler + connectToFancytree: true, + // Let source tree create the helper element + helper: function (event) { + var $helper, + $nodeTag, + opts, + sourceNode = $.ui.fancytree.getNode( + event.target + ); + + if (!sourceNode) { + // #405, DT issue 211: might happen, if dragging a table *header* + return "<div>ERROR?: helper requested but sourceNode not found</div>"; + } + opts = sourceNode.tree.options.dnd; + $nodeTag = $(sourceNode.span); + // Only event and node argument is available + $helper = $( + "<div class='fancytree-drag-helper'><span class='fancytree-drag-helper-img' /></div>" + ) + .css({ zIndex: 3, position: "relative" }) // so it appears above ext-wide selection bar + .append( + $nodeTag + .find("span.fancytree-title") + .clone() + ); + + // Attach node reference to helper object + $helper.data("ftSourceNode", sourceNode); + + // Support glyph symbols instead of icons + if (glyph) { + $helper + .find(".fancytree-drag-helper-img") + .addClass( + glyph.map._addClass + + " " + + glyph.map.dragHelper + ); + } + // Allow to modify the helper, e.g. to add multi-node-drag feedback + if (opts.initHelper) { + opts.initHelper.call( + sourceNode.tree, + sourceNode, + { + node: sourceNode, + tree: sourceNode.tree, + originalEvent: event, + ui: { helper: $helper }, + } + ); + } + // We return an unconnected element, so `draggable` will add this + // to the parent specified as `appendTo` option + return $helper; + }, + start: function (event, ui) { + var sourceNode = ui.helper.data("ftSourceNode"); + return !!sourceNode; // Abort dragging if no node could be found + }, + }, + tree.options.dnd.draggable + ) + ); + } + // Attach ui.droppable to this Fancytree instance + if (dnd && dnd.dragDrop) { + tree.widget.element.droppable( + $.extend( + { + addClasses: false, + tolerance: "intersect", + greedy: false, + /* + activate: function(event, ui) { + tree.debug("droppable - activate", event, ui, this); + }, + create: function(event, ui) { + tree.debug("droppable - create", event, ui); + }, + deactivate: function(event, ui) { + tree.debug("droppable - deactivate", event, ui); + }, + drop: function(event, ui) { + tree.debug("droppable - drop", event, ui); + }, + out: function(event, ui) { + tree.debug("droppable - out", event, ui); + }, + over: function(event, ui) { + tree.debug("droppable - over", event, ui); + } +*/ + }, + tree.options.dnd.droppable + ) + ); + } + } + + /****************************************************************************** + * + */ + + $.ui.fancytree.registerExtension({ + name: "dnd", + version: "2.38.3", + // Default options for this extension. + options: { + // Make tree nodes accept draggables + autoExpandMS: 1000, // Expand nodes after n milliseconds of hovering. + draggable: null, // Additional options passed to jQuery draggable + droppable: null, // Additional options passed to jQuery droppable + focusOnClick: false, // Focus, although draggable cancels mousedown event (#270) + preventVoidMoves: true, // Prevent dropping nodes 'before self', etc. + preventRecursiveMoves: true, // Prevent dropping nodes on own descendants + smartRevert: true, // set draggable.revert = true if drop was rejected + dropMarkerOffsetX: -24, // absolute position offset for .fancytree-drop-marker relatively to ..fancytree-title (icon/img near a node accepting drop) + dropMarkerInsertOffsetX: -16, // additional offset for drop-marker with hitMode = "before"/"after" + // Events (drag support) + dragStart: null, // Callback(sourceNode, data), return true, to enable dnd + dragStop: null, // Callback(sourceNode, data) + initHelper: null, // Callback(sourceNode, data) + updateHelper: null, // Callback(sourceNode, data) + // Events (drop support) + dragEnter: null, // Callback(targetNode, data) + dragOver: null, // Callback(targetNode, data) + dragExpand: null, // Callback(targetNode, data), return false to prevent autoExpand + dragDrop: null, // Callback(targetNode, data) + dragLeave: null, // Callback(targetNode, data) + }, + + treeInit: function (ctx) { + var tree = ctx.tree; + this._superApply(arguments); + // issue #270: draggable eats mousedown events + if (tree.options.dnd.dragStart) { + tree.$container.on("mousedown", function (event) { + // if( !tree.hasFocus() && ctx.options.dnd.focusOnClick ) { + if (ctx.options.dnd.focusOnClick) { + // #270 + var node = $.ui.fancytree.getNode(event); + if (node) { + node.debug( + "Re-enable focus that was prevented by jQuery UI draggable." + ); + // node.setFocus(); + // $(node.span).closest(":tabbable").focus(); + // $(event.target).trigger("focus"); + // $(event.target).closest(":tabbable").trigger("focus"); + } + setTimeout(function () { + // #300 + $(event.target).closest(":tabbable").focus(); + }, 10); + } + }); + } + _initDragAndDrop(tree); + }, + /* Display drop marker according to hitMode ('after', 'before', 'over'). */ + _setDndStatus: function ( + sourceNode, + targetNode, + helper, + hitMode, + accept + ) { + var markerOffsetX, + pos, + markerAt = "center", + instData = this._local, + dndOpt = this.options.dnd, + glyphOpt = this.options.glyph, + $source = sourceNode ? $(sourceNode.span) : null, + $target = $(targetNode.span), + $targetTitle = $target.find("span.fancytree-title"); + + if (!instData.$dropMarker) { + instData.$dropMarker = $( + "<div id='fancytree-drop-marker'></div>" + ) + .hide() + .css({ "z-index": 1000 }) + .prependTo($(this.$div).parent()); + // .prependTo("body"); + + if (glyphOpt) { + instData.$dropMarker.addClass( + glyphOpt.map._addClass + " " + glyphOpt.map.dropMarker + ); + } + } + if ( + hitMode === "after" || + hitMode === "before" || + hitMode === "over" + ) { + markerOffsetX = dndOpt.dropMarkerOffsetX || 0; + switch (hitMode) { + case "before": + markerAt = "top"; + markerOffsetX += dndOpt.dropMarkerInsertOffsetX || 0; + break; + case "after": + markerAt = "bottom"; + markerOffsetX += dndOpt.dropMarkerInsertOffsetX || 0; + break; + } + + pos = { + my: "left" + offsetString(markerOffsetX) + " center", + at: "left " + markerAt, + of: $targetTitle, + }; + if (this.options.rtl) { + pos.my = "right" + offsetString(-markerOffsetX) + " center"; + pos.at = "right " + markerAt; + } + instData.$dropMarker + .toggleClass(classDropAfter, hitMode === "after") + .toggleClass(classDropOver, hitMode === "over") + .toggleClass(classDropBefore, hitMode === "before") + .toggleClass("fancytree-rtl", !!this.options.rtl) + .show() + .position($.ui.fancytree.fixPositionOptions(pos)); + } else { + instData.$dropMarker.hide(); + } + if ($source) { + $source + .toggleClass(classDropAccept, accept === true) + .toggleClass(classDropReject, accept === false); + } + $target + .toggleClass( + classDropTarget, + hitMode === "after" || + hitMode === "before" || + hitMode === "over" + ) + .toggleClass(classDropAfter, hitMode === "after") + .toggleClass(classDropBefore, hitMode === "before") + .toggleClass(classDropAccept, accept === true) + .toggleClass(classDropReject, accept === false); + + helper + .toggleClass(classDropAccept, accept === true) + .toggleClass(classDropReject, accept === false); + }, + + /* + * Handles drag'n'drop functionality. + * + * A standard jQuery drag-and-drop process may generate these calls: + * + * start: + * _onDragEvent("start", sourceNode, null, event, ui, draggable); + * drag: + * _onDragEvent("leave", prevTargetNode, sourceNode, event, ui, draggable); + * _onDragEvent("over", targetNode, sourceNode, event, ui, draggable); + * _onDragEvent("enter", targetNode, sourceNode, event, ui, draggable); + * stop: + * _onDragEvent("drop", targetNode, sourceNode, event, ui, draggable); + * _onDragEvent("leave", targetNode, sourceNode, event, ui, draggable); + * _onDragEvent("stop", sourceNode, null, event, ui, draggable); + */ + _onDragEvent: function ( + eventName, + node, + otherNode, + event, + ui, + draggable + ) { + // if(eventName !== "over"){ + // this.debug("tree.ext.dnd._onDragEvent(%s, %o, %o) - %o", eventName, node, otherNode, this); + // } + var accept, + nodeOfs, + parentRect, + rect, + relPos, + relPos2, + enterResponse, + hitMode, + r, + opts = this.options, + dnd = opts.dnd, + ctx = this._makeHookContext(node, event, { + otherNode: otherNode, + ui: ui, + draggable: draggable, + }), + res = null, + self = this, + $nodeTag = $(node.span); + + if (dnd.smartRevert) { + draggable.options.revert = "invalid"; + } + + switch (eventName) { + case "start": + if (node.isStatusNode()) { + res = false; + } else if (dnd.dragStart) { + res = dnd.dragStart(node, ctx); + } + if (res === false) { + this.debug("tree.dragStart() cancelled"); + //draggable._clear(); + // NOTE: the return value seems to be ignored (drag is not cancelled, when false is returned) + // TODO: call this._cancelDrag()? + ui.helper.trigger("mouseup").hide(); + } else { + if (dnd.smartRevert) { + // #567, #593: fix revert position + // rect = node.li.getBoundingClientRect(); + rect = + node[ + ctx.tree.nodeContainerAttrName + ].getBoundingClientRect(); + parentRect = $( + draggable.options.appendTo + )[0].getBoundingClientRect(); + draggable.originalPosition.left = Math.max( + 0, + rect.left - parentRect.left + ); + draggable.originalPosition.top = Math.max( + 0, + rect.top - parentRect.top + ); + } + $nodeTag.addClass("fancytree-drag-source"); + // Register global handlers to allow cancel + $(document).on( + "keydown.fancytree-dnd,mousedown.fancytree-dnd", + function (event) { + // node.tree.debug("dnd global event", event.type, event.which); + if ( + event.type === "keydown" && + event.which === $.ui.keyCode.ESCAPE + ) { + self.ext.dnd._cancelDrag(); + } else if (event.type === "mousedown") { + self.ext.dnd._cancelDrag(); + } + } + ); + } + break; + + case "enter": + if ( + dnd.preventRecursiveMoves && + node.isDescendantOf(otherNode) + ) { + r = false; + } else { + r = dnd.dragEnter ? dnd.dragEnter(node, ctx) : null; + } + if (!r) { + // convert null, undefined, false to false + res = false; + } else if (Array.isArray(r)) { + // TODO: also accept passing an object of this format directly + res = { + over: $.inArray("over", r) >= 0, + before: $.inArray("before", r) >= 0, + after: $.inArray("after", r) >= 0, + }; + } else { + res = { + over: r === true || r === "over", + before: r === true || r === "before", + after: r === true || r === "after", + }; + } + ui.helper.data("enterResponse", res); + // this.debug("helper.enterResponse: %o", res); + break; + + case "over": + enterResponse = ui.helper.data("enterResponse"); + hitMode = null; + if (enterResponse === false) { + // Don't call dragOver if onEnter returned false. + // break; + } else if (typeof enterResponse === "string") { + // Use hitMode from onEnter if provided. + hitMode = enterResponse; + } else { + // Calculate hitMode from relative cursor position. + nodeOfs = $nodeTag.offset(); + relPos = { + x: event.pageX - nodeOfs.left, + y: event.pageY - nodeOfs.top, + }; + relPos2 = { + x: relPos.x / $nodeTag.width(), + y: relPos.y / $nodeTag.height(), + }; + + if (enterResponse.after && relPos2.y > 0.75) { + hitMode = "after"; + } else if ( + !enterResponse.over && + enterResponse.after && + relPos2.y > 0.5 + ) { + hitMode = "after"; + } else if (enterResponse.before && relPos2.y <= 0.25) { + hitMode = "before"; + } else if ( + !enterResponse.over && + enterResponse.before && + relPos2.y <= 0.5 + ) { + hitMode = "before"; + } else if (enterResponse.over) { + hitMode = "over"; + } + // Prevent no-ops like 'before source node' + // TODO: these are no-ops when moving nodes, but not in copy mode + if (dnd.preventVoidMoves) { + if (node === otherNode) { + this.debug( + " drop over source node prevented" + ); + hitMode = null; + } else if ( + hitMode === "before" && + otherNode && + node === otherNode.getNextSibling() + ) { + this.debug( + " drop after source node prevented" + ); + hitMode = null; + } else if ( + hitMode === "after" && + otherNode && + node === otherNode.getPrevSibling() + ) { + this.debug( + " drop before source node prevented" + ); + hitMode = null; + } else if ( + hitMode === "over" && + otherNode && + otherNode.parent === node && + otherNode.isLastSibling() + ) { + this.debug( + " drop last child over own parent prevented" + ); + hitMode = null; + } + } + // this.debug("hitMode: %s - %s - %s", hitMode, (node.parent === otherNode), node.isLastSibling()); + ui.helper.data("hitMode", hitMode); + } + // Auto-expand node (only when 'over' the node, not 'before', or 'after') + if ( + hitMode !== "before" && + hitMode !== "after" && + dnd.autoExpandMS && + node.hasChildren() !== false && + !node.expanded && + (!dnd.dragExpand || dnd.dragExpand(node, ctx) !== false) + ) { + node.scheduleAction("expand", dnd.autoExpandMS); + } + if (hitMode && dnd.dragOver) { + // TODO: http://code.google.com/p/dynatree/source/detail?r=625 + ctx.hitMode = hitMode; + res = dnd.dragOver(node, ctx); + } + accept = res !== false && hitMode !== null; + if (dnd.smartRevert) { + draggable.options.revert = !accept; + } + this._local._setDndStatus( + otherNode, + node, + ui.helper, + hitMode, + accept + ); + break; + + case "drop": + hitMode = ui.helper.data("hitMode"); + if (hitMode && dnd.dragDrop) { + ctx.hitMode = hitMode; + dnd.dragDrop(node, ctx); + } + break; + + case "leave": + // Cancel pending expand request + node.scheduleAction("cancel"); + ui.helper.data("enterResponse", null); + ui.helper.data("hitMode", null); + this._local._setDndStatus( + otherNode, + node, + ui.helper, + "out", + undefined + ); + if (dnd.dragLeave) { + dnd.dragLeave(node, ctx); + } + break; + + case "stop": + $nodeTag.removeClass("fancytree-drag-source"); + $(document).off(".fancytree-dnd"); + if (dnd.dragStop) { + dnd.dragStop(node, ctx); + } + break; + + default: + $.error("Unsupported drag event: " + eventName); + } + return res; + }, + + _cancelDrag: function () { + var dd = $.ui.ddmanager.current; + if (dd) { + dd.cancel(); + } + }, + }); + // Value returned by `require('jquery.fancytree..')` + return $.ui.fancytree; +}); // End of closure diff --git a/plugins/55/indexmenu/scripts/fancytree/modules/jquery.fancytree.dnd5.js b/plugins/55/indexmenu/scripts/fancytree/modules/jquery.fancytree.dnd5.js new file mode 100644 index 0000000..328cef5 --- /dev/null +++ b/plugins/55/indexmenu/scripts/fancytree/modules/jquery.fancytree.dnd5.js @@ -0,0 +1,1157 @@ +/*! + * jquery.fancytree.dnd5.js + * + * Drag-and-drop support (native HTML5). + * (Extension module for jquery.fancytree.js: https://github.com/mar10/fancytree/) + * + * Copyright (c) 2008-2023, Martin Wendt (https://wwWendt.de) + * + * Released under the MIT license + * https://github.com/mar10/fancytree/wiki/LicenseInfo + * + * @version 2.38.3 + * @date 2023-02-01T20:52:50Z + */ + +/* + #TODO + Compatiblity when dragging between *separate* windows: + + Drag from Chrome Edge FF IE11 Safari + To Chrome ok ok ok NO ? + Edge ok ok ok NO ? + FF ok ok ok NO ? + IE 11 ok ok ok ok ? + Safari ? ? ? ? ok + + */ + +(function (factory) { + if (typeof define === "function" && define.amd) { + // AMD. Register as an anonymous module. + define(["jquery", "./jquery.fancytree"], factory); + } else if (typeof module === "object" && module.exports) { + // Node/CommonJS + require("./jquery.fancytree"); + module.exports = factory(require("jquery")); + } else { + // Browser globals + factory(jQuery); + } +})(function ($) { + "use strict"; + + /****************************************************************************** + * Private functions and variables + */ + var FT = $.ui.fancytree, + isMac = /Mac/.test(navigator.platform), + classDragSource = "fancytree-drag-source", + classDragRemove = "fancytree-drag-remove", + classDropAccept = "fancytree-drop-accept", + classDropAfter = "fancytree-drop-after", + classDropBefore = "fancytree-drop-before", + classDropOver = "fancytree-drop-over", + classDropReject = "fancytree-drop-reject", + classDropTarget = "fancytree-drop-target", + nodeMimeType = "application/x-fancytree-node", + $dropMarker = null, + $dragImage, + $extraHelper, + SOURCE_NODE = null, + SOURCE_NODE_LIST = null, + $sourceList = null, + DRAG_ENTER_RESPONSE = null, + // SESSION_DATA = null, // plain object passed to events as `data` + SUGGESTED_DROP_EFFECT = null, + REQUESTED_DROP_EFFECT = null, + REQUESTED_EFFECT_ALLOWED = null, + LAST_HIT_MODE = null, + DRAG_OVER_STAMP = null; // Time when a node entered the 'over' hitmode + + /* */ + function _clearGlobals() { + DRAG_ENTER_RESPONSE = null; + DRAG_OVER_STAMP = null; + REQUESTED_DROP_EFFECT = null; + REQUESTED_EFFECT_ALLOWED = null; + SUGGESTED_DROP_EFFECT = null; + SOURCE_NODE = null; + SOURCE_NODE_LIST = null; + if ($sourceList) { + $sourceList.removeClass(classDragSource + " " + classDragRemove); + } + $sourceList = null; + if ($dropMarker) { + $dropMarker.hide(); + } + // Take this badge off of me - I can't use it anymore: + if ($extraHelper) { + $extraHelper.remove(); + $extraHelper = null; + } + } + + /* Convert number to string and prepend +/-; return empty string for 0.*/ + function offsetString(n) { + // eslint-disable-next-line no-nested-ternary + return n === 0 ? "" : n > 0 ? "+" + n : "" + n; + } + + /* Convert a dragEnter() or dragOver() response to a canonical form. + * Return false or plain object + * @param {string|object|boolean} r + * @return {object|false} + */ + function normalizeDragEnterResponse(r) { + var res; + + if (!r) { + return false; + } + if ($.isPlainObject(r)) { + res = { + over: !!r.over, + before: !!r.before, + after: !!r.after, + }; + } else if (Array.isArray(r)) { + res = { + over: $.inArray("over", r) >= 0, + before: $.inArray("before", r) >= 0, + after: $.inArray("after", r) >= 0, + }; + } else { + res = { + over: r === true || r === "over", + before: r === true || r === "before", + after: r === true || r === "after", + }; + } + if (Object.keys(res).length === 0) { + return false; + } + // if( Object.keys(res).length === 1 ) { + // res.unique = res[0]; + // } + return res; + } + + /* Convert a dataTransfer.effectAllowed to a canonical form. + * Return false or plain object + * @param {string|boolean} r + * @return {object|false} + */ + // function normalizeEffectAllowed(r) { + // if (!r || r === "none") { + // return false; + // } + // var all = r === "all", + // res = { + // copy: all || /copy/i.test(r), + // link: all || /link/i.test(r), + // move: all || /move/i.test(r), + // }; + + // return res; + // } + + /* Implement auto scrolling when drag cursor is in top/bottom area of scroll parent. */ + function autoScroll(tree, event) { + var spOfs, + scrollTop, + delta, + dndOpts = tree.options.dnd5, + sp = tree.$scrollParent[0], + sensitivity = dndOpts.scrollSensitivity, + speed = dndOpts.scrollSpeed, + scrolled = 0; + + if (sp !== document && sp.tagName !== "HTML") { + spOfs = tree.$scrollParent.offset(); + scrollTop = sp.scrollTop; + if (spOfs.top + sp.offsetHeight - event.pageY < sensitivity) { + delta = + sp.scrollHeight - + tree.$scrollParent.innerHeight() - + scrollTop; + // console.log ("sp.offsetHeight: " + sp.offsetHeight + // + ", spOfs.top: " + spOfs.top + // + ", scrollTop: " + scrollTop + // + ", innerHeight: " + tree.$scrollParent.innerHeight() + // + ", scrollHeight: " + sp.scrollHeight + // + ", delta: " + delta + // ); + if (delta > 0) { + sp.scrollTop = scrolled = scrollTop + speed; + } + } else if (scrollTop > 0 && event.pageY - spOfs.top < sensitivity) { + sp.scrollTop = scrolled = scrollTop - speed; + } + } else { + scrollTop = $(document).scrollTop(); + if (scrollTop > 0 && event.pageY - scrollTop < sensitivity) { + scrolled = scrollTop - speed; + $(document).scrollTop(scrolled); + } else if ( + $(window).height() - (event.pageY - scrollTop) < + sensitivity + ) { + scrolled = scrollTop + speed; + $(document).scrollTop(scrolled); + } + } + if (scrolled) { + tree.debug("autoScroll: " + scrolled + "px"); + } + return scrolled; + } + + /* Guess dropEffect from modifier keys. + * Using rules suggested here: + * https://ux.stackexchange.com/a/83769 + * @returns + * 'copy', 'link', 'move', or 'none' + */ + function evalEffectModifiers(tree, event, effectDefault) { + var res = effectDefault; + + if (isMac) { + if (event.metaKey && event.altKey) { + // Mac: [Control] + [Option] + res = "link"; + } else if (event.ctrlKey) { + // Chrome on Mac: [Control] + res = "link"; + } else if (event.metaKey) { + // Mac: [Command] + res = "move"; + } else if (event.altKey) { + // Mac: [Option] + res = "copy"; + } + } else { + if (event.ctrlKey) { + // Windows: [Ctrl] + res = "copy"; + } else if (event.shiftKey) { + // Windows: [Shift] + res = "move"; + } else if (event.altKey) { + // Windows: [Alt] + res = "link"; + } + } + if (res !== SUGGESTED_DROP_EFFECT) { + tree.info( + "evalEffectModifiers: " + + event.type + + " - evalEffectModifiers(): " + + SUGGESTED_DROP_EFFECT + + " -> " + + res + ); + } + SUGGESTED_DROP_EFFECT = res; + // tree.debug("evalEffectModifiers: " + res); + return res; + } + /* + * Check if the previous callback (dragEnter, dragOver, ...) has changed + * the `data` object and apply those settings. + * + * Safari: + * It seems that `dataTransfer.dropEffect` can only be set on dragStart, and will remain + * even if the cursor changes when [Alt] or [Ctrl] are pressed (?) + * Using rules suggested here: + * https://ux.stackexchange.com/a/83769 + * @returns + * 'copy', 'link', 'move', or 'none' + */ + function prepareDropEffectCallback(event, data) { + var tree = data.tree, + dataTransfer = data.dataTransfer; + + if (event.type === "dragstart") { + data.effectAllowed = tree.options.dnd5.effectAllowed; + data.dropEffect = tree.options.dnd5.dropEffectDefault; + } else { + data.effectAllowed = REQUESTED_EFFECT_ALLOWED; + data.dropEffect = REQUESTED_DROP_EFFECT; + } + data.dropEffectSuggested = evalEffectModifiers( + tree, + event, + tree.options.dnd5.dropEffectDefault + ); + data.isMove = data.dropEffect === "move"; + data.files = dataTransfer.files || []; + + // if (REQUESTED_EFFECT_ALLOWED !== dataTransfer.effectAllowed) { + // tree.warn( + // "prepareDropEffectCallback(" + + // event.type + + // "): dataTransfer.effectAllowed changed from " + + // REQUESTED_EFFECT_ALLOWED + + // " -> " + + // dataTransfer.effectAllowed + // ); + // } + // if (REQUESTED_DROP_EFFECT !== dataTransfer.dropEffect) { + // tree.warn( + // "prepareDropEffectCallback(" + + // event.type + + // "): dataTransfer.dropEffect changed from requested " + + // REQUESTED_DROP_EFFECT + + // " to " + + // dataTransfer.dropEffect + // ); + // } + } + + function applyDropEffectCallback(event, data, allowDrop) { + var tree = data.tree, + dataTransfer = data.dataTransfer; + + if ( + event.type !== "dragstart" && + REQUESTED_EFFECT_ALLOWED !== data.effectAllowed + ) { + tree.warn( + "effectAllowed should only be changed in dragstart event: " + + event.type + + ": data.effectAllowed changed from " + + REQUESTED_EFFECT_ALLOWED + + " -> " + + data.effectAllowed + ); + } + + if (allowDrop === false) { + tree.info("applyDropEffectCallback: allowDrop === false"); + data.effectAllowed = "none"; + data.dropEffect = "none"; + } + // if (REQUESTED_DROP_EFFECT !== data.dropEffect) { + // tree.debug( + // "applyDropEffectCallback(" + + // event.type + + // "): data.dropEffect changed from previous " + + // REQUESTED_DROP_EFFECT + + // " to " + + // data.dropEffect + // ); + // } + + data.isMove = data.dropEffect === "move"; + // data.isMove = data.dropEffectSuggested === "move"; + + // `effectAllowed` must only be defined in dragstart event, so we + // store it in a global variable for reference + if (event.type === "dragstart") { + REQUESTED_EFFECT_ALLOWED = data.effectAllowed; + REQUESTED_DROP_EFFECT = data.dropEffect; + } + + // if (REQUESTED_DROP_EFFECT !== dataTransfer.dropEffect) { + // data.tree.info( + // "applyDropEffectCallback(" + + // event.type + + // "): dataTransfer.dropEffect changed from " + + // REQUESTED_DROP_EFFECT + + // " -> " + + // dataTransfer.dropEffect + // ); + // } + dataTransfer.effectAllowed = REQUESTED_EFFECT_ALLOWED; + dataTransfer.dropEffect = REQUESTED_DROP_EFFECT; + + // tree.debug( + // "applyDropEffectCallback(" + + // event.type + + // "): set " + + // dataTransfer.dropEffect + + // "/" + + // dataTransfer.effectAllowed + // ); + // if (REQUESTED_DROP_EFFECT !== dataTransfer.dropEffect) { + // data.tree.warn( + // "applyDropEffectCallback(" + + // event.type + + // "): could not set dataTransfer.dropEffect to " + + // REQUESTED_DROP_EFFECT + + // ": got " + + // dataTransfer.dropEffect + // ); + // } + return REQUESTED_DROP_EFFECT; + } + + /* Handle dragover event (fired every x ms) on valid drop targets. + * + * - Auto-scroll when cursor is in border regions + * - Apply restrictioan like 'preventVoidMoves' + * - Calculate hit mode + * - Calculate drop effect + * - Trigger dragOver() callback to let user modify hit mode and drop effect + * - Adjust the drop marker accordingly + * + * @returns hitMode + */ + function handleDragOver(event, data) { + // Implement auto-scrolling + if (data.options.dnd5.scroll) { + autoScroll(data.tree, event); + } + // Bail out with previous response if we get an invalid dragover + if (!data.node) { + data.tree.warn("Ignored dragover for non-node"); //, event, data); + return LAST_HIT_MODE; + } + + var markerOffsetX, + nodeOfs, + pos, + relPosY, + hitMode = null, + tree = data.tree, + options = tree.options, + dndOpts = options.dnd5, + targetNode = data.node, + sourceNode = data.otherNode, + markerAt = "center", + $target = $(targetNode.span), + $targetTitle = $target.find("span.fancytree-title"); + + if (DRAG_ENTER_RESPONSE === false) { + tree.debug("Ignored dragover, since dragenter returned false."); + return false; + } else if (typeof DRAG_ENTER_RESPONSE === "string") { + $.error("assert failed: dragenter returned string"); + } + // Calculate hitMode from relative cursor position. + nodeOfs = $target.offset(); + relPosY = (event.pageY - nodeOfs.top) / $target.height(); + if (event.pageY === undefined) { + tree.warn("event.pageY is undefined: see issue #1013."); + } + + if (DRAG_ENTER_RESPONSE.after && relPosY > 0.75) { + hitMode = "after"; + } else if ( + !DRAG_ENTER_RESPONSE.over && + DRAG_ENTER_RESPONSE.after && + relPosY > 0.5 + ) { + hitMode = "after"; + } else if (DRAG_ENTER_RESPONSE.before && relPosY <= 0.25) { + hitMode = "before"; + } else if ( + !DRAG_ENTER_RESPONSE.over && + DRAG_ENTER_RESPONSE.before && + relPosY <= 0.5 + ) { + hitMode = "before"; + } else if (DRAG_ENTER_RESPONSE.over) { + hitMode = "over"; + } + // Prevent no-ops like 'before source node' + // TODO: these are no-ops when moving nodes, but not in copy mode + if (dndOpts.preventVoidMoves && data.dropEffect === "move") { + if (targetNode === sourceNode) { + targetNode.debug("Drop over source node prevented."); + hitMode = null; + } else if ( + hitMode === "before" && + sourceNode && + targetNode === sourceNode.getNextSibling() + ) { + targetNode.debug("Drop after source node prevented."); + hitMode = null; + } else if ( + hitMode === "after" && + sourceNode && + targetNode === sourceNode.getPrevSibling() + ) { + targetNode.debug("Drop before source node prevented."); + hitMode = null; + } else if ( + hitMode === "over" && + sourceNode && + sourceNode.parent === targetNode && + sourceNode.isLastSibling() + ) { + targetNode.debug("Drop last child over own parent prevented."); + hitMode = null; + } + } + // Let callback modify the calculated hitMode + data.hitMode = hitMode; + if (hitMode && dndOpts.dragOver) { + prepareDropEffectCallback(event, data); + dndOpts.dragOver(targetNode, data); + var allowDrop = !!hitMode; + applyDropEffectCallback(event, data, allowDrop); + hitMode = data.hitMode; + } + LAST_HIT_MODE = hitMode; + // + if (hitMode === "after" || hitMode === "before" || hitMode === "over") { + markerOffsetX = dndOpts.dropMarkerOffsetX || 0; + switch (hitMode) { + case "before": + markerAt = "top"; + markerOffsetX += dndOpts.dropMarkerInsertOffsetX || 0; + break; + case "after": + markerAt = "bottom"; + markerOffsetX += dndOpts.dropMarkerInsertOffsetX || 0; + break; + } + + pos = { + my: "left" + offsetString(markerOffsetX) + " center", + at: "left " + markerAt, + of: $targetTitle, + }; + if (options.rtl) { + pos.my = "right" + offsetString(-markerOffsetX) + " center"; + pos.at = "right " + markerAt; + // console.log("rtl", pos); + } + $dropMarker + .toggleClass(classDropAfter, hitMode === "after") + .toggleClass(classDropOver, hitMode === "over") + .toggleClass(classDropBefore, hitMode === "before") + .show() + .position(FT.fixPositionOptions(pos)); + } else { + $dropMarker.hide(); + // console.log("hide dropmarker") + } + + $(targetNode.span) + .toggleClass( + classDropTarget, + hitMode === "after" || + hitMode === "before" || + hitMode === "over" + ) + .toggleClass(classDropAfter, hitMode === "after") + .toggleClass(classDropBefore, hitMode === "before") + .toggleClass(classDropAccept, hitMode === "over") + .toggleClass(classDropReject, hitMode === false); + + return hitMode; + } + + /* + * Handle dragstart drag dragend events on the container + */ + function onDragEvent(event) { + var json, + tree = this, + dndOpts = tree.options.dnd5, + node = FT.getNode(event), + dataTransfer = + event.dataTransfer || event.originalEvent.dataTransfer, + data = { + tree: tree, + node: node, + options: tree.options, + originalEvent: event.originalEvent, + widget: tree.widget, + dataTransfer: dataTransfer, + useDefaultImage: true, + dropEffect: undefined, + dropEffectSuggested: undefined, + effectAllowed: undefined, // set by dragstart + files: undefined, // only for drop events + isCancelled: undefined, // set by dragend + isMove: undefined, + }; + + switch (event.type) { + case "dragstart": + if (!node) { + tree.info("Ignored dragstart on a non-node."); + return false; + } + // Store current source node in different formats + SOURCE_NODE = node; + + // Also optionally store selected nodes + if (dndOpts.multiSource === false) { + SOURCE_NODE_LIST = [node]; + } else if (dndOpts.multiSource === true) { + if (node.isSelected()) { + SOURCE_NODE_LIST = tree.getSelectedNodes(); + } else { + SOURCE_NODE_LIST = [node]; + } + } else { + SOURCE_NODE_LIST = dndOpts.multiSource(node, data); + } + // Cache as array of jQuery objects for faster access: + $sourceList = $( + $.map(SOURCE_NODE_LIST, function (n) { + return n.span; + }) + ); + // Set visual feedback + $sourceList.addClass(classDragSource); + + // Set payload + // Note: + // Transfer data is only accessible on dragstart and drop! + // For all other events the formats and kinds in the drag + // data store list of items representing dragged data can be + // enumerated, but the data itself is unavailable and no new + // data can be added. + var nodeData = node.toDict(true, dndOpts.sourceCopyHook); + nodeData.treeId = node.tree._id; + json = JSON.stringify(nodeData); + try { + dataTransfer.setData(nodeMimeType, json); + dataTransfer.setData("text/html", $(node.span).html()); + dataTransfer.setData("text/plain", node.title); + } catch (ex) { + // IE only accepts 'text' type + tree.warn( + "Could not set data (IE only accepts 'text') - " + ex + ); + } + // We always need to set the 'text' type if we want to drag + // Because IE 11 only accepts this single type. + // If we pass JSON here, IE can can access all node properties, + // even when the source lives in another window. (D'n'd inside + // the same window will always work.) + // The drawback is, that in this case ALL browsers will see + // the JSON representation as 'text', so dragging + // to a text field will insert the JSON string instead of + // the node title. + if (dndOpts.setTextTypeJson) { + dataTransfer.setData("text", json); + } else { + dataTransfer.setData("text", node.title); + } + + // Set the allowed drag modes (combinations of move, copy, and link) + // (effectAllowed can only be set in the dragstart event.) + // This can be overridden in the dragStart() callback + prepareDropEffectCallback(event, data); + + // Let user cancel or modify above settings + // Realize potential changes by previous callback + if (dndOpts.dragStart(node, data) === false) { + // Cancel dragging + // dataTransfer.dropEffect = "none"; + _clearGlobals(); + return false; + } + applyDropEffectCallback(event, data); + + // Unless user set `data.useDefaultImage` to false in dragStart, + // generata a default drag image now: + $extraHelper = null; + + if (data.useDefaultImage) { + // Set the title as drag image (otherwise it would contain the expander) + $dragImage = $(node.span).find(".fancytree-title"); + + if (SOURCE_NODE_LIST && SOURCE_NODE_LIST.length > 1) { + // Add a counter badge to node title if dragging more than one node. + // We want this, because the element that is used as drag image + // must be *visible* in the DOM, so we cannot create some hidden + // custom markup. + // See https://kryogenix.org/code/browser/custom-drag-image.html + // Also, since IE 11 and Edge don't support setDragImage() alltogether, + // it gives som feedback to the user. + // The badge will be removed later on drag end. + $extraHelper = $( + "<span class='fancytree-childcounter'/>" + ) + .text("+" + (SOURCE_NODE_LIST.length - 1)) + .appendTo($dragImage); + } + if (dataTransfer.setDragImage) { + // IE 11 and Edge do not support this + dataTransfer.setDragImage($dragImage[0], -10, -10); + } + } + return true; + + case "drag": + // Called every few milliseconds (no matter if the + // cursor is over a valid drop target) + // data.tree.info("drag", SOURCE_NODE) + prepareDropEffectCallback(event, data); + dndOpts.dragDrag(node, data); + applyDropEffectCallback(event, data); + + $sourceList.toggleClass(classDragRemove, data.isMove); + break; + + case "dragend": + // Called at the end of a d'n'd process (after drop) + // Note caveat: If drop removed the dragged source element, + // we may not get this event, since the target does not exist + // anymore + prepareDropEffectCallback(event, data); + + _clearGlobals(); + + data.isCancelled = !LAST_HIT_MODE; + dndOpts.dragEnd(node, data, !LAST_HIT_MODE); + // applyDropEffectCallback(event, data); + break; + } + } + /* + * Handle dragenter dragover dragleave drop events on the container + */ + function onDropEvent(event) { + var json, + allowAutoExpand, + nodeData, + isSourceFtNode, + r, + res, + tree = this, + dndOpts = tree.options.dnd5, + allowDrop = null, + node = FT.getNode(event), + dataTransfer = + event.dataTransfer || event.originalEvent.dataTransfer, + data = { + tree: tree, + node: node, + options: tree.options, + originalEvent: event.originalEvent, + widget: tree.widget, + hitMode: DRAG_ENTER_RESPONSE, + dataTransfer: dataTransfer, + otherNode: SOURCE_NODE || null, + otherNodeList: SOURCE_NODE_LIST || null, + otherNodeData: null, // set by drop event + useDefaultImage: true, + dropEffect: undefined, + dropEffectSuggested: undefined, + effectAllowed: undefined, // set by dragstart + files: null, // list of File objects (may be []) + isCancelled: undefined, // set by drop event + isMove: undefined, + }; + + // data.isMove = dropEffect === "move"; + + switch (event.type) { + case "dragenter": + // The dragenter event is fired when a dragged element or + // text selection enters a valid drop target. + + DRAG_OVER_STAMP = null; + if (!node) { + // Sometimes we get dragenter for the container element + tree.debug( + "Ignore non-node " + + event.type + + ": " + + event.target.tagName + + "." + + event.target.className + ); + DRAG_ENTER_RESPONSE = false; + break; + } + + $(node.span) + .addClass(classDropOver) + .removeClass(classDropAccept + " " + classDropReject); + + // Data is only readable in the dragstart and drop event, + // but we can check for the type: + isSourceFtNode = + $.inArray(nodeMimeType, dataTransfer.types) >= 0; + + if (dndOpts.preventNonNodes && !isSourceFtNode) { + node.debug("Reject dropping a non-node."); + DRAG_ENTER_RESPONSE = false; + break; + } else if ( + dndOpts.preventForeignNodes && + (!SOURCE_NODE || SOURCE_NODE.tree !== node.tree) + ) { + node.debug("Reject dropping a foreign node."); + DRAG_ENTER_RESPONSE = false; + break; + } else if ( + dndOpts.preventSameParent && + data.otherNode && + data.otherNode.tree === node.tree && + node.parent === data.otherNode.parent + ) { + node.debug("Reject dropping as sibling (same parent)."); + DRAG_ENTER_RESPONSE = false; + break; + } else if ( + dndOpts.preventRecursion && + data.otherNode && + data.otherNode.tree === node.tree && + node.isDescendantOf(data.otherNode) + ) { + node.debug("Reject dropping below own ancestor."); + DRAG_ENTER_RESPONSE = false; + break; + } else if (dndOpts.preventLazyParents && !node.isLoaded()) { + node.warn("Drop over unloaded target node prevented."); + DRAG_ENTER_RESPONSE = false; + break; + } + $dropMarker.show(); + + // Call dragEnter() to figure out if (and where) dropping is allowed + prepareDropEffectCallback(event, data); + r = dndOpts.dragEnter(node, data); + + res = normalizeDragEnterResponse(r); + // alert("res:" + JSON.stringify(res)) + DRAG_ENTER_RESPONSE = res; + + allowDrop = res && (res.over || res.before || res.after); + + applyDropEffectCallback(event, data, allowDrop); + break; + + case "dragover": + if (!node) { + tree.debug( + "Ignore non-node " + + event.type + + ": " + + event.target.tagName + + "." + + event.target.className + ); + break; + } + // The dragover event is fired when an element or text + // selection is being dragged over a valid drop target + // (every few hundred milliseconds). + // tree.debug( + // event.type + + // ": dropEffect: " + + // dataTransfer.dropEffect + // ); + prepareDropEffectCallback(event, data); + LAST_HIT_MODE = handleDragOver(event, data); + + // The flag controls the preventDefault() below: + allowDrop = !!LAST_HIT_MODE; + allowAutoExpand = + LAST_HIT_MODE === "over" || LAST_HIT_MODE === false; + + if ( + allowAutoExpand && + !node.expanded && + node.hasChildren() !== false + ) { + if (!DRAG_OVER_STAMP) { + DRAG_OVER_STAMP = Date.now(); + } else if ( + dndOpts.autoExpandMS && + Date.now() - DRAG_OVER_STAMP > dndOpts.autoExpandMS && + !node.isLoading() && + (!dndOpts.dragExpand || + dndOpts.dragExpand(node, data) !== false) + ) { + node.setExpanded(); + } + } else { + DRAG_OVER_STAMP = null; + } + break; + + case "dragleave": + // NOTE: dragleave is fired AFTER the dragenter event of the + // FOLLOWING element. + if (!node) { + tree.debug( + "Ignore non-node " + + event.type + + ": " + + event.target.tagName + + "." + + event.target.className + ); + break; + } + if (!$(node.span).hasClass(classDropOver)) { + node.debug("Ignore dragleave (multi)."); + break; + } + $(node.span).removeClass( + classDropOver + + " " + + classDropAccept + + " " + + classDropReject + ); + node.scheduleAction("cancel"); + dndOpts.dragLeave(node, data); + $dropMarker.hide(); + break; + + case "drop": + // Data is only readable in the (dragstart and) drop event: + + if ($.inArray(nodeMimeType, dataTransfer.types) >= 0) { + nodeData = dataTransfer.getData(nodeMimeType); + tree.info( + event.type + + ": getData('application/x-fancytree-node'): '" + + nodeData + + "'" + ); + } + if (!nodeData) { + // 1. Source is not a Fancytree node, or + // 2. If the FT mime type was set, but returns '', this + // is probably IE 11 (which only supports 'text') + nodeData = dataTransfer.getData("text"); + tree.info( + event.type + ": getData('text'): '" + nodeData + "'" + ); + } + if (nodeData) { + try { + // 'text' type may contain JSON if IE is involved + // and setTextTypeJson option was set + json = JSON.parse(nodeData); + if (json.title !== undefined) { + data.otherNodeData = json; + } + } catch (ex) { + // assume 'text' type contains plain text, so `otherNodeData` + // should not be set + } + } + tree.debug( + event.type + + ": nodeData: '" + + nodeData + + "', otherNodeData: ", + data.otherNodeData + ); + + $(node.span).removeClass( + classDropOver + + " " + + classDropAccept + + " " + + classDropReject + ); + + // Let user implement the actual drop operation + data.hitMode = LAST_HIT_MODE; + prepareDropEffectCallback(event, data, !LAST_HIT_MODE); + data.isCancelled = !LAST_HIT_MODE; + + var orgSourceElem = SOURCE_NODE && SOURCE_NODE.span, + orgSourceTree = SOURCE_NODE && SOURCE_NODE.tree; + + dndOpts.dragDrop(node, data); + // applyDropEffectCallback(event, data); + + // Prevent browser's default drop handling, i.e. open as link, ... + event.preventDefault(); + + if (orgSourceElem && !document.body.contains(orgSourceElem)) { + // The drop handler removed the original drag source from + // the DOM, so the dragend event will probaly not fire. + if (orgSourceTree === tree) { + tree.debug( + "Drop handler removed source element: generating dragEnd." + ); + dndOpts.dragEnd(SOURCE_NODE, data); + } else { + tree.warn( + "Drop handler removed source element: dragend event may be lost." + ); + } + } + + _clearGlobals(); + + break; + } + // Dnd API madness: we must PREVENT default handling to enable dropping + if (allowDrop) { + event.preventDefault(); + return false; + } + } + + /** [ext-dnd5] Return a Fancytree instance, from element, index, event, or jQueryObject. + * + * @returns {FancytreeNode[]} List of nodes (empty if no drag operation) + * @example + * $.ui.fancytree.getDragNodeList(); + * + * @alias Fancytree_Static#getDragNodeList + * @requires jquery.fancytree.dnd5.js + * @since 2.31 + */ + $.ui.fancytree.getDragNodeList = function () { + return SOURCE_NODE_LIST || []; + }; + + /** [ext-dnd5] Return the FancytreeNode that is currently being dragged. + * + * If multiple nodes are dragged, only the first is returned. + * + * @returns {FancytreeNode | null} dragged nodes or null if no drag operation + * @example + * $.ui.fancytree.getDragNode(); + * + * @alias Fancytree_Static#getDragNode + * @requires jquery.fancytree.dnd5.js + * @since 2.31 + */ + $.ui.fancytree.getDragNode = function () { + return SOURCE_NODE; + }; + + /****************************************************************************** + * + */ + + $.ui.fancytree.registerExtension({ + name: "dnd5", + version: "2.38.3", + // Default options for this extension. + options: { + autoExpandMS: 1500, // Expand nodes after n milliseconds of hovering + dropMarkerInsertOffsetX: -16, // Additional offset for drop-marker with hitMode = "before"/"after" + dropMarkerOffsetX: -24, // Absolute position offset for .fancytree-drop-marker relatively to ..fancytree-title (icon/img near a node accepting drop) + // #1021 `document.body` is not available yet + dropMarkerParent: "body", // Root Container used for drop marker (could be a shadow root) + multiSource: false, // true: Drag multiple (i.e. selected) nodes. Also a callback() is allowed + effectAllowed: "all", // Restrict the possible cursor shapes and modifier operations (can also be set in the dragStart event) + // dropEffect: "auto", // 'copy'|'link'|'move'|'auto'(calculate from `effectAllowed`+modifier keys) or callback(node, data) that returns such string. + dropEffectDefault: "move", // Default dropEffect ('copy', 'link', or 'move') when no modifier is pressed (overide in dragDrag, dragOver). + preventForeignNodes: false, // Prevent dropping nodes from different Fancytrees + preventLazyParents: true, // Prevent dropping items on unloaded lazy Fancytree nodes + preventNonNodes: false, // Prevent dropping items other than Fancytree nodes + preventRecursion: true, // Prevent dropping nodes on own descendants + preventSameParent: false, // Prevent dropping nodes under same direct parent + preventVoidMoves: true, // Prevent dropping nodes 'before self', etc. + scroll: true, // Enable auto-scrolling while dragging + scrollSensitivity: 20, // Active top/bottom margin in pixel + scrollSpeed: 5, // Pixel per event + setTextTypeJson: false, // Allow dragging of nodes to different IE windows + sourceCopyHook: null, // Optional callback passed to `toDict` on dragStart @since 2.38 + // Events (drag support) + dragStart: null, // Callback(sourceNode, data), return true, to enable dnd drag + dragDrag: $.noop, // Callback(sourceNode, data) + dragEnd: $.noop, // Callback(sourceNode, data) + // Events (drop support) + dragEnter: null, // Callback(targetNode, data), return true, to enable dnd drop + dragOver: $.noop, // Callback(targetNode, data) + dragExpand: $.noop, // Callback(targetNode, data), return false to prevent autoExpand + dragDrop: $.noop, // Callback(targetNode, data) + dragLeave: $.noop, // Callback(targetNode, data) + }, + + treeInit: function (ctx) { + var $temp, + tree = ctx.tree, + opts = ctx.options, + glyph = opts.glyph || null, + dndOpts = opts.dnd5; + + if ($.inArray("dnd", opts.extensions) >= 0) { + $.error("Extensions 'dnd' and 'dnd5' are mutually exclusive."); + } + if (dndOpts.dragStop) { + $.error( + "dragStop is not used by ext-dnd5. Use dragEnd instead." + ); + } + if (dndOpts.preventRecursiveMoves != null) { + $.error( + "preventRecursiveMoves was renamed to preventRecursion." + ); + } + + // Implement `opts.createNode` event to add the 'draggable' attribute + // #680: this must happen before calling super.treeInit() + if (dndOpts.dragStart) { + FT.overrideMethod( + ctx.options, + "createNode", + function (event, data) { + // Default processing if any + this._super.apply(this, arguments); + if (data.node.span) { + data.node.span.draggable = true; + } else { + data.node.warn( + "Cannot add `draggable`: no span tag" + ); + } + } + ); + } + this._superApply(arguments); + + this.$container.addClass("fancytree-ext-dnd5"); + + // Store the current scroll parent, which may be the tree + // container, any enclosing div, or the document. + // #761: scrollParent() always needs a container child + $temp = $("<span>").appendTo(this.$container); + this.$scrollParent = $temp.scrollParent(); + $temp.remove(); + + $dropMarker = $("#fancytree-drop-marker"); + if (!$dropMarker.length) { + $dropMarker = $("<div id='fancytree-drop-marker'></div>") + .hide() + .css({ + "z-index": 1000, + // Drop marker should not steal dragenter/dragover events: + "pointer-events": "none", + }) + .prependTo(dndOpts.dropMarkerParent); + if (glyph) { + FT.setSpanIcon( + $dropMarker[0], + glyph.map._addClass, + glyph.map.dropMarker + ); + } + } + $dropMarker.toggleClass("fancytree-rtl", !!opts.rtl); + + // Enable drag support if dragStart() is specified: + if (dndOpts.dragStart) { + // Bind drag event handlers + tree.$container.on( + "dragstart drag dragend", + onDragEvent.bind(tree) + ); + } + // Enable drop support if dragEnter() is specified: + if (dndOpts.dragEnter) { + // Bind drop event handlers + tree.$container.on( + "dragenter dragover dragleave drop", + onDropEvent.bind(tree) + ); + } + }, + }); + // Value returned by `require('jquery.fancytree..')` + return $.ui.fancytree; +}); // End of closure diff --git a/plugins/55/indexmenu/scripts/fancytree/modules/jquery.fancytree.edit.js b/plugins/55/indexmenu/scripts/fancytree/modules/jquery.fancytree.edit.js new file mode 100644 index 0000000..7ccd5df --- /dev/null +++ b/plugins/55/indexmenu/scripts/fancytree/modules/jquery.fancytree.edit.js @@ -0,0 +1,403 @@ +/*! + * jquery.fancytree.edit.js + * + * Make node titles editable. + * (Extension module for jquery.fancytree.js: https://github.com/mar10/fancytree/) + * + * Copyright (c) 2008-2023, Martin Wendt (https://wwWendt.de) + * + * Released under the MIT license + * https://github.com/mar10/fancytree/wiki/LicenseInfo + * + * @version 2.38.3 + * @date 2023-02-01T20:52:50Z + */ + +(function (factory) { + if (typeof define === "function" && define.amd) { + // AMD. Register as an anonymous module. + define(["jquery", "./jquery.fancytree"], factory); + } else if (typeof module === "object" && module.exports) { + // Node/CommonJS + require("./jquery.fancytree"); + module.exports = factory(require("jquery")); + } else { + // Browser globals + factory(jQuery); + } +})(function ($) { + "use strict"; + + /******************************************************************************* + * Private functions and variables + */ + + var isMac = /Mac/.test(navigator.platform), + escapeHtml = $.ui.fancytree.escapeHtml, + trim = $.ui.fancytree.trim, + unescapeHtml = $.ui.fancytree.unescapeHtml; + + /** + * [ext-edit] Start inline editing of current node title. + * + * @alias FancytreeNode#editStart + * @requires Fancytree + */ + $.ui.fancytree._FancytreeNodeClass.prototype.editStart = function () { + var $input, + node = this, + tree = this.tree, + local = tree.ext.edit, + instOpts = tree.options.edit, + $title = $(".fancytree-title", node.span), + eventData = { + node: node, + tree: tree, + options: tree.options, + isNew: $(node[tree.statusClassPropName]).hasClass( + "fancytree-edit-new" + ), + orgTitle: node.title, + input: null, + dirty: false, + }; + + // beforeEdit may want to modify the title before editing + if ( + instOpts.beforeEdit.call( + node, + { type: "beforeEdit" }, + eventData + ) === false + ) { + return false; + } + $.ui.fancytree.assert(!local.currentNode, "recursive edit"); + local.currentNode = this; + local.eventData = eventData; + + // Disable standard Fancytree mouse- and key handling + tree.widget._unbind(); + + local.lastDraggableAttrValue = node.span.draggable; + if (local.lastDraggableAttrValue) { + node.span.draggable = false; + } + + // #116: ext-dnd prevents the blur event, so we have to catch outer clicks + $(document).on("mousedown.fancytree-edit", function (event) { + if (!$(event.target).hasClass("fancytree-edit-input")) { + node.editEnd(true, event); + } + }); + + // Replace node with <input> + $input = $("<input />", { + class: "fancytree-edit-input", + type: "text", + value: tree.options.escapeTitles + ? eventData.orgTitle + : unescapeHtml(eventData.orgTitle), + }); + local.eventData.input = $input; + if (instOpts.adjustWidthOfs != null) { + $input.width($title.width() + instOpts.adjustWidthOfs); + } + if (instOpts.inputCss != null) { + $input.css(instOpts.inputCss); + } + + $title.html($input); + + // Focus <input> and bind keyboard handler + $input + .focus() + .change(function (event) { + $input.addClass("fancytree-edit-dirty"); + }) + .on("keydown", function (event) { + switch (event.which) { + case $.ui.keyCode.ESCAPE: + node.editEnd(false, event); + break; + case $.ui.keyCode.ENTER: + node.editEnd(true, event); + return false; // so we don't start editmode on Mac + } + event.stopPropagation(); + }) + .blur(function (event) { + return node.editEnd(true, event); + }); + + instOpts.edit.call(node, { type: "edit" }, eventData); + }; + + /** + * [ext-edit] Stop inline editing. + * @param {Boolean} [applyChanges=false] false: cancel edit, true: save (if modified) + * @alias FancytreeNode#editEnd + * @requires jquery.fancytree.edit.js + */ + $.ui.fancytree._FancytreeNodeClass.prototype.editEnd = function ( + applyChanges, + _event + ) { + var newVal, + node = this, + tree = this.tree, + local = tree.ext.edit, + eventData = local.eventData, + instOpts = tree.options.edit, + $title = $(".fancytree-title", node.span), + $input = $title.find("input.fancytree-edit-input"); + + if (instOpts.trim) { + $input.val(trim($input.val())); + } + newVal = $input.val(); + + eventData.dirty = newVal !== node.title; + eventData.originalEvent = _event; + + // Find out, if saving is required + if (applyChanges === false) { + // If true/false was passed, honor this (except in rename mode, if unchanged) + eventData.save = false; + } else if (eventData.isNew) { + // In create mode, we save everything, except for empty text + eventData.save = newVal !== ""; + } else { + // In rename mode, we save everyting, except for empty or unchanged text + eventData.save = eventData.dirty && newVal !== ""; + } + // Allow to break (keep editor open), modify input, or re-define data.save + if ( + instOpts.beforeClose.call( + node, + { type: "beforeClose" }, + eventData + ) === false + ) { + return false; + } + if ( + eventData.save && + instOpts.save.call(node, { type: "save" }, eventData) === false + ) { + return false; + } + $input.removeClass("fancytree-edit-dirty").off(); + // Unbind outer-click handler + $(document).off(".fancytree-edit"); + + if (eventData.save) { + // # 171: escape user input (not required if global escaping is on) + node.setTitle( + tree.options.escapeTitles ? newVal : escapeHtml(newVal) + ); + node.setFocus(); + } else { + if (eventData.isNew) { + node.remove(); + node = eventData.node = null; + local.relatedNode.setFocus(); + } else { + node.renderTitle(); + node.setFocus(); + } + } + local.eventData = null; + local.currentNode = null; + local.relatedNode = null; + // Re-enable mouse and keyboard handling + tree.widget._bind(); + + if (node && local.lastDraggableAttrValue) { + node.span.draggable = true; + } + + // Set keyboard focus, even if setFocus() claims 'nothing to do' + tree.$container.get(0).focus({ preventScroll: true }); + eventData.input = null; + instOpts.close.call(node, { type: "close" }, eventData); + return true; + }; + + /** + * [ext-edit] Create a new child or sibling node and start edit mode. + * + * @param {String} [mode='child'] 'before', 'after', or 'child' + * @param {Object} [init] NodeData (or simple title string) + * @alias FancytreeNode#editCreateNode + * @requires jquery.fancytree.edit.js + * @since 2.4 + */ + $.ui.fancytree._FancytreeNodeClass.prototype.editCreateNode = function ( + mode, + init + ) { + var newNode, + tree = this.tree, + self = this; + + mode = mode || "child"; + if (init == null) { + init = { title: "" }; + } else if (typeof init === "string") { + init = { title: init }; + } else { + $.ui.fancytree.assert($.isPlainObject(init)); + } + // Make sure node is expanded (and loaded) in 'child' mode + if ( + mode === "child" && + !this.isExpanded() && + this.hasChildren() !== false + ) { + this.setExpanded().done(function () { + self.editCreateNode(mode, init); + }); + return; + } + newNode = this.addNode(init, mode); + + // #644: Don't filter new nodes. + newNode.match = true; + $(newNode[tree.statusClassPropName]) + .removeClass("fancytree-hide") + .addClass("fancytree-match"); + + newNode.makeVisible(/*{noAnimation: true}*/).done(function () { + $(newNode[tree.statusClassPropName]).addClass("fancytree-edit-new"); + self.tree.ext.edit.relatedNode = self; + newNode.editStart(); + }); + }; + + /** + * [ext-edit] Check if any node in this tree in edit mode. + * + * @returns {FancytreeNode | null} + * @alias Fancytree#isEditing + * @requires jquery.fancytree.edit.js + */ + $.ui.fancytree._FancytreeClass.prototype.isEditing = function () { + return this.ext.edit ? this.ext.edit.currentNode : null; + }; + + /** + * [ext-edit] Check if this node is in edit mode. + * @returns {Boolean} true if node is currently beeing edited + * @alias FancytreeNode#isEditing + * @requires jquery.fancytree.edit.js + */ + $.ui.fancytree._FancytreeNodeClass.prototype.isEditing = function () { + return this.tree.ext.edit + ? this.tree.ext.edit.currentNode === this + : false; + }; + + /******************************************************************************* + * Extension code + */ + $.ui.fancytree.registerExtension({ + name: "edit", + version: "2.38.3", + // Default options for this extension. + options: { + adjustWidthOfs: 4, // null: don't adjust input size to content + allowEmpty: false, // Prevent empty input + inputCss: { minWidth: "3em" }, + // triggerCancel: ["esc", "tab", "click"], + triggerStart: ["f2", "mac+enter", "shift+click"], + trim: true, // Trim whitespace before save + // Events: + beforeClose: $.noop, // Return false to prevent cancel/save (data.input is available) + beforeEdit: $.noop, // Return false to prevent edit mode + close: $.noop, // Editor was removed + edit: $.noop, // Editor was opened (available as data.input) + // keypress: $.noop, // Not yet implemented + save: $.noop, // Save data.input.val() or return false to keep editor open + }, + // Local attributes + currentNode: null, + + treeInit: function (ctx) { + var tree = ctx.tree; + + this._superApply(arguments); + + this.$container + .addClass("fancytree-ext-edit") + .on("fancytreebeforeupdateviewport", function (event, data) { + var editNode = tree.isEditing(); + // When scrolling, the TR may be re-used by another node, so the + // active cell marker an + if (editNode) { + editNode.info("Cancel edit due to scroll event."); + editNode.editEnd(false, event); + } + }); + }, + nodeClick: function (ctx) { + var eventStr = $.ui.fancytree.eventToString(ctx.originalEvent), + triggerStart = ctx.options.edit.triggerStart; + + if ( + eventStr === "shift+click" && + $.inArray("shift+click", triggerStart) >= 0 + ) { + if (ctx.originalEvent.shiftKey) { + ctx.node.editStart(); + return false; + } + } + if ( + eventStr === "click" && + $.inArray("clickActive", triggerStart) >= 0 + ) { + // Only when click was inside title text (not aynwhere else in the row) + if ( + ctx.node.isActive() && + !ctx.node.isEditing() && + $(ctx.originalEvent.target).hasClass("fancytree-title") + ) { + ctx.node.editStart(); + return false; + } + } + return this._superApply(arguments); + }, + nodeDblclick: function (ctx) { + if ($.inArray("dblclick", ctx.options.edit.triggerStart) >= 0) { + ctx.node.editStart(); + return false; + } + return this._superApply(arguments); + }, + nodeKeydown: function (ctx) { + switch (ctx.originalEvent.which) { + case 113: // [F2] + if ($.inArray("f2", ctx.options.edit.triggerStart) >= 0) { + ctx.node.editStart(); + return false; + } + break; + case $.ui.keyCode.ENTER: + if ( + $.inArray("mac+enter", ctx.options.edit.triggerStart) >= + 0 && + isMac + ) { + ctx.node.editStart(); + return false; + } + break; + } + return this._superApply(arguments); + }, + }); + // Value returned by `require('jquery.fancytree..')` + return $.ui.fancytree; +}); // End of closure diff --git a/plugins/55/indexmenu/scripts/fancytree/modules/jquery.fancytree.filter.js b/plugins/55/indexmenu/scripts/fancytree/modules/jquery.fancytree.filter.js new file mode 100644 index 0000000..5eb2e5e --- /dev/null +++ b/plugins/55/indexmenu/scripts/fancytree/modules/jquery.fancytree.filter.js @@ -0,0 +1,549 @@ +/*! + * jquery.fancytree.filter.js + * + * Remove or highlight tree nodes, based on a filter. + * (Extension module for jquery.fancytree.js: https://github.com/mar10/fancytree/) + * + * Copyright (c) 2008-2023, Martin Wendt (https://wwWendt.de) + * + * Released under the MIT license + * https://github.com/mar10/fancytree/wiki/LicenseInfo + * + * @version 2.38.3 + * @date 2023-02-01T20:52:50Z + */ + +(function (factory) { + if (typeof define === "function" && define.amd) { + // AMD. Register as an anonymous module. + define(["jquery", "./jquery.fancytree"], factory); + } else if (typeof module === "object" && module.exports) { + // Node/CommonJS + require("./jquery.fancytree"); + module.exports = factory(require("jquery")); + } else { + // Browser globals + factory(jQuery); + } +})(function ($) { + "use strict"; + + /******************************************************************************* + * Private functions and variables + */ + + var KeyNoData = "__not_found__", + escapeHtml = $.ui.fancytree.escapeHtml, + exoticStartChar = "\uFFF7", + exoticEndChar = "\uFFF8"; + function _escapeRegex(str) { + return (str + "").replace(/([.?*+^$[\]\\(){}|-])/g, "\\$1"); + } + + function extractHtmlText(s) { + if (s.indexOf(">") >= 0) { + return $("<div/>").html(s).text(); + } + return s; + } + + /** + * @description Marks the matching charecters of `text` either by `mark` or + * by exotic*Chars (if `escapeTitles` is `true`) based on `regexMatchArray` + * which is an array of matching groups. + * @param {string} text + * @param {RegExpMatchArray} regexMatchArray + */ + function _markFuzzyMatchedChars(text, regexMatchArray, escapeTitles) { + // It is extremely infuriating that we can not use `let` or `const` or arrow functions. + // Damn you IE!!! + var matchingIndices = []; + // get the indices of matched characters (Iterate through `RegExpMatchArray`) + for ( + var _matchingArrIdx = 1; + _matchingArrIdx < regexMatchArray.length; + _matchingArrIdx++ + ) { + var _mIdx = + // get matching char index by cumulatively adding + // the matched group length + regexMatchArray[_matchingArrIdx].length + + (_matchingArrIdx === 1 ? 0 : 1) + + (matchingIndices[matchingIndices.length - 1] || 0); + matchingIndices.push(_mIdx); + } + // Map each `text` char to its position and store in `textPoses`. + var textPoses = text.split(""); + if (escapeTitles) { + // If escaping the title, then wrap the matchng char within exotic chars + matchingIndices.forEach(function (v) { + textPoses[v] = exoticStartChar + textPoses[v] + exoticEndChar; + }); + } else { + // Otherwise, Wrap the matching chars within `mark`. + matchingIndices.forEach(function (v) { + textPoses[v] = "<mark>" + textPoses[v] + "</mark>"; + }); + } + // Join back the modified `textPoses` to create final highlight markup. + return textPoses.join(""); + } + $.ui.fancytree._FancytreeClass.prototype._applyFilterImpl = function ( + filter, + branchMode, + _opts + ) { + var match, + statusNode, + re, + reHighlight, + reExoticStartChar, + reExoticEndChar, + temp, + prevEnableUpdate, + count = 0, + treeOpts = this.options, + escapeTitles = treeOpts.escapeTitles, + prevAutoCollapse = treeOpts.autoCollapse, + opts = $.extend({}, treeOpts.filter, _opts), + hideMode = opts.mode === "hide", + leavesOnly = !!opts.leavesOnly && !branchMode; + + // Default to 'match title substring (not case sensitive)' + if (typeof filter === "string") { + if (filter === "") { + this.warn( + "Fancytree passing an empty string as a filter is handled as clearFilter()." + ); + this.clearFilter(); + return; + } + if (opts.fuzzy) { + // See https://codereview.stackexchange.com/questions/23899/faster-javascript-fuzzy-string-matching-function/23905#23905 + // and http://www.quora.com/How-is-the-fuzzy-search-algorithm-in-Sublime-Text-designed + // and http://www.dustindiaz.com/autocomplete-fuzzy-matching + match = filter + .split("") + // Escaping the `filter` will not work because, + // it gets further split into individual characters. So, + // escape each character after splitting + .map(_escapeRegex) + .reduce(function (a, b) { + // create capture groups for parts that comes before + // the character + return a + "([^" + b + "]*)" + b; + }, ""); + } else { + match = _escapeRegex(filter); // make sure a '.' is treated literally + } + re = new RegExp(match, "i"); + reHighlight = new RegExp(_escapeRegex(filter), "gi"); + if (escapeTitles) { + reExoticStartChar = new RegExp( + _escapeRegex(exoticStartChar), + "g" + ); + reExoticEndChar = new RegExp(_escapeRegex(exoticEndChar), "g"); + } + filter = function (node) { + if (!node.title) { + return false; + } + var text = escapeTitles + ? node.title + : extractHtmlText(node.title), + // `.match` instead of `.test` to get the capture groups + res = text.match(re); + if (res && opts.highlight) { + if (escapeTitles) { + if (opts.fuzzy) { + temp = _markFuzzyMatchedChars( + text, + res, + escapeTitles + ); + } else { + // #740: we must not apply the marks to escaped entity names, e.g. `"` + // Use some exotic characters to mark matches: + temp = text.replace(reHighlight, function (s) { + return exoticStartChar + s + exoticEndChar; + }); + } + // now we can escape the title... + node.titleWithHighlight = escapeHtml(temp) + // ... and finally insert the desired `<mark>` tags + .replace(reExoticStartChar, "<mark>") + .replace(reExoticEndChar, "</mark>"); + } else { + if (opts.fuzzy) { + node.titleWithHighlight = _markFuzzyMatchedChars( + text, + res + ); + } else { + node.titleWithHighlight = text.replace( + reHighlight, + function (s) { + return "<mark>" + s + "</mark>"; + } + ); + } + } + // node.debug("filter", escapeTitles, text, node.titleWithHighlight); + } + return !!res; + }; + } + + this.enableFilter = true; + this.lastFilterArgs = arguments; + + prevEnableUpdate = this.enableUpdate(false); + + this.$div.addClass("fancytree-ext-filter"); + if (hideMode) { + this.$div.addClass("fancytree-ext-filter-hide"); + } else { + this.$div.addClass("fancytree-ext-filter-dimm"); + } + this.$div.toggleClass( + "fancytree-ext-filter-hide-expanders", + !!opts.hideExpanders + ); + // Reset current filter + this.rootNode.subMatchCount = 0; + this.visit(function (node) { + delete node.match; + delete node.titleWithHighlight; + node.subMatchCount = 0; + }); + statusNode = this.getRootNode()._findDirectChild(KeyNoData); + if (statusNode) { + statusNode.remove(); + } + + // Adjust node.hide, .match, and .subMatchCount properties + treeOpts.autoCollapse = false; // #528 + + this.visit(function (node) { + if (leavesOnly && node.children != null) { + return; + } + var res = filter(node), + matchedByBranch = false; + + if (res === "skip") { + node.visit(function (c) { + c.match = false; + }, true); + return "skip"; + } + if (!res && (branchMode || res === "branch") && node.parent.match) { + res = true; + matchedByBranch = true; + } + if (res) { + count++; + node.match = true; + node.visitParents(function (p) { + if (p !== node) { + p.subMatchCount += 1; + } + // Expand match (unless this is no real match, but only a node in a matched branch) + if (opts.autoExpand && !matchedByBranch && !p.expanded) { + p.setExpanded(true, { + noAnimation: true, + noEvents: true, + scrollIntoView: false, + }); + p._filterAutoExpanded = true; + } + }, true); + } + }); + treeOpts.autoCollapse = prevAutoCollapse; + + if (count === 0 && opts.nodata && hideMode) { + statusNode = opts.nodata; + if (typeof statusNode === "function") { + statusNode = statusNode(); + } + if (statusNode === true) { + statusNode = {}; + } else if (typeof statusNode === "string") { + statusNode = { title: statusNode }; + } + statusNode = $.extend( + { + statusNodeType: "nodata", + key: KeyNoData, + title: this.options.strings.noData, + }, + statusNode + ); + + this.getRootNode().addNode(statusNode).match = true; + } + // Redraw whole tree + this._callHook("treeStructureChanged", this, "applyFilter"); + // this.render(); + this.enableUpdate(prevEnableUpdate); + return count; + }; + + /** + * [ext-filter] Dimm or hide nodes. + * + * @param {function | string} filter + * @param {boolean} [opts={autoExpand: false, leavesOnly: false}] + * @returns {integer} count + * @alias Fancytree#filterNodes + * @requires jquery.fancytree.filter.js + */ + $.ui.fancytree._FancytreeClass.prototype.filterNodes = function ( + filter, + opts + ) { + if (typeof opts === "boolean") { + opts = { leavesOnly: opts }; + this.warn( + "Fancytree.filterNodes() leavesOnly option is deprecated since 2.9.0 / 2015-04-19. Use opts.leavesOnly instead." + ); + } + return this._applyFilterImpl(filter, false, opts); + }; + + /** + * [ext-filter] Dimm or hide whole branches. + * + * @param {function | string} filter + * @param {boolean} [opts={autoExpand: false}] + * @returns {integer} count + * @alias Fancytree#filterBranches + * @requires jquery.fancytree.filter.js + */ + $.ui.fancytree._FancytreeClass.prototype.filterBranches = function ( + filter, + opts + ) { + return this._applyFilterImpl(filter, true, opts); + }; + + /** + * [ext-filter] Re-apply current filter. + * + * @returns {integer} count + * @alias Fancytree#updateFilter + * @requires jquery.fancytree.filter.js + * @since 2.38 + */ + $.ui.fancytree._FancytreeClass.prototype.updateFilter = function () { + if ( + this.enableFilter && + this.lastFilterArgs && + this.options.filter.autoApply + ) { + this._applyFilterImpl.apply(this, this.lastFilterArgs); + } else { + this.warn("updateFilter(): no filter active."); + } + }; + + /** + * [ext-filter] Reset the filter. + * + * @alias Fancytree#clearFilter + * @requires jquery.fancytree.filter.js + */ + $.ui.fancytree._FancytreeClass.prototype.clearFilter = function () { + var $title, + statusNode = this.getRootNode()._findDirectChild(KeyNoData), + escapeTitles = this.options.escapeTitles, + enhanceTitle = this.options.enhanceTitle, + prevEnableUpdate = this.enableUpdate(false); + + if (statusNode) { + statusNode.remove(); + } + // we also counted root node's subMatchCount + delete this.rootNode.match; + delete this.rootNode.subMatchCount; + + this.visit(function (node) { + if (node.match && node.span) { + // #491, #601 + $title = $(node.span).find(">span.fancytree-title"); + if (escapeTitles) { + $title.text(node.title); + } else { + $title.html(node.title); + } + if (enhanceTitle) { + enhanceTitle( + { type: "enhanceTitle" }, + { node: node, $title: $title } + ); + } + } + delete node.match; + delete node.subMatchCount; + delete node.titleWithHighlight; + if (node.$subMatchBadge) { + node.$subMatchBadge.remove(); + delete node.$subMatchBadge; + } + if (node._filterAutoExpanded && node.expanded) { + node.setExpanded(false, { + noAnimation: true, + noEvents: true, + scrollIntoView: false, + }); + } + delete node._filterAutoExpanded; + }); + this.enableFilter = false; + this.lastFilterArgs = null; + this.$div.removeClass( + "fancytree-ext-filter fancytree-ext-filter-dimm fancytree-ext-filter-hide" + ); + this._callHook("treeStructureChanged", this, "clearFilter"); + // this.render(); + this.enableUpdate(prevEnableUpdate); + }; + + /** + * [ext-filter] Return true if a filter is currently applied. + * + * @returns {Boolean} + * @alias Fancytree#isFilterActive + * @requires jquery.fancytree.filter.js + * @since 2.13 + */ + $.ui.fancytree._FancytreeClass.prototype.isFilterActive = function () { + return !!this.enableFilter; + }; + + /** + * [ext-filter] Return true if this node is matched by current filter (or no filter is active). + * + * @returns {Boolean} + * @alias FancytreeNode#isMatched + * @requires jquery.fancytree.filter.js + * @since 2.13 + */ + $.ui.fancytree._FancytreeNodeClass.prototype.isMatched = function () { + return !(this.tree.enableFilter && !this.match); + }; + + /******************************************************************************* + * Extension code + */ + $.ui.fancytree.registerExtension({ + name: "filter", + version: "2.38.3", + // Default options for this extension. + options: { + autoApply: true, // Re-apply last filter if lazy data is loaded + autoExpand: false, // Expand all branches that contain matches while filtered + counter: true, // Show a badge with number of matching child nodes near parent icons + fuzzy: false, // Match single characters in order, e.g. 'fb' will match 'FooBar' + hideExpandedCounter: true, // Hide counter badge if parent is expanded + hideExpanders: false, // Hide expanders if all child nodes are hidden by filter + highlight: true, // Highlight matches by wrapping inside <mark> tags + leavesOnly: false, // Match end nodes only + nodata: true, // Display a 'no data' status node if result is empty + mode: "dimm", // Grayout unmatched nodes (pass "hide" to remove unmatched node instead) + }, + nodeLoadChildren: function (ctx, source) { + var tree = ctx.tree; + + return this._superApply(arguments).done(function () { + if ( + tree.enableFilter && + tree.lastFilterArgs && + ctx.options.filter.autoApply + ) { + tree._applyFilterImpl.apply(tree, tree.lastFilterArgs); + } + }); + }, + nodeSetExpanded: function (ctx, flag, callOpts) { + var node = ctx.node; + + delete node._filterAutoExpanded; + // Make sure counter badge is displayed again, when node is beeing collapsed + if ( + !flag && + ctx.options.filter.hideExpandedCounter && + node.$subMatchBadge + ) { + node.$subMatchBadge.show(); + } + return this._superApply(arguments); + }, + nodeRenderStatus: function (ctx) { + // Set classes for current status + var res, + node = ctx.node, + tree = ctx.tree, + opts = ctx.options.filter, + $title = $(node.span).find("span.fancytree-title"), + $span = $(node[tree.statusClassPropName]), + enhanceTitle = ctx.options.enhanceTitle, + escapeTitles = ctx.options.escapeTitles; + + res = this._super(ctx); + // nothing to do, if node was not yet rendered + if (!$span.length || !tree.enableFilter) { + return res; + } + $span + .toggleClass("fancytree-match", !!node.match) + .toggleClass("fancytree-submatch", !!node.subMatchCount) + .toggleClass( + "fancytree-hide", + !(node.match || node.subMatchCount) + ); + // Add/update counter badge + if ( + opts.counter && + node.subMatchCount && + (!node.isExpanded() || !opts.hideExpandedCounter) + ) { + if (!node.$subMatchBadge) { + node.$subMatchBadge = $( + "<span class='fancytree-childcounter'/>" + ); + $( + "span.fancytree-icon, span.fancytree-custom-icon", + node.span + ).append(node.$subMatchBadge); + } + node.$subMatchBadge.show().text(node.subMatchCount); + } else if (node.$subMatchBadge) { + node.$subMatchBadge.hide(); + } + // node.debug("nodeRenderStatus", node.titleWithHighlight, node.title) + // #601: also check for $title.length, because we don't need to render + // if node.span is null (i.e. not rendered) + if (node.span && (!node.isEditing || !node.isEditing.call(node))) { + if (node.titleWithHighlight) { + $title.html(node.titleWithHighlight); + } else if (escapeTitles) { + $title.text(node.title); + } else { + $title.html(node.title); + } + if (enhanceTitle) { + enhanceTitle( + { type: "enhanceTitle" }, + { node: node, $title: $title } + ); + } + } + return res; + }, + }); + // Value returned by `require('jquery.fancytree..')` + return $.ui.fancytree; +}); // End of closure diff --git a/plugins/55/indexmenu/scripts/fancytree/modules/jquery.fancytree.fixed.js b/plugins/55/indexmenu/scripts/fancytree/modules/jquery.fancytree.fixed.js new file mode 100644 index 0000000..7372f24 --- /dev/null +++ b/plugins/55/indexmenu/scripts/fancytree/modules/jquery.fancytree.fixed.js @@ -0,0 +1,674 @@ +/*! + * jquery.fancytree.fixed.js + * + * Add fixed colums and headers to ext.table. + * (Extension module for jquery.fancytree.js: https://github.com/mar10/fancytree/) + * + * Copyright (c) 2008-2023, Martin Wendt (https://wwWendt.de) + * + * Released under the MIT license + * https://github.com/mar10/fancytree/wiki/LicenseInfo + * + * @version 2.38.3 + * @date 2023-02-01T20:52:50Z + */ + +// Allow to use multiple var statements inside a function + +(function (factory) { + if (typeof define === "function" && define.amd) { + // AMD. Register as an anonymous module. + define([ + "jquery", + "./jquery.fancytree", + "./jquery.fancytree.table", + ], factory); + } else if (typeof module === "object" && module.exports) { + // Node/CommonJS + require("./jquery.fancytree.table"); // core + table + module.exports = factory(require("jquery")); + } else { + // Browser globals + factory(jQuery); + } +})(function ($) { + "use strict"; + + /****************************************************************************** + * Private functions and variables + */ + + $.ui.fancytree.registerExtension({ + name: "fixed", + version: "0.0.1", + // Default options for this extension. + options: { + fixCol: 1, + fixColWidths: null, + fixRows: true, + scrollSpeed: 50, + resizable: true, + classNames: { + table: "fancytree-ext-fixed", + wrapper: "fancytree-ext-fixed-wrapper", + topLeft: "fancytree-ext-fixed-wrapper-tl", + topRight: "fancytree-ext-fixed-wrapper-tr", + bottomLeft: "fancytree-ext-fixed-wrapper-bl", + bottomRight: "fancytree-ext-fixed-wrapper-br", + hidden: "fancytree-ext-fixed-hidden", + counterpart: "fancytree-ext-fixed-node-counterpart", + scrollBorderBottom: "fancytree-ext-fixed-scroll-border-bottom", + scrollBorderRight: "fancytree-ext-fixed-scroll-border-right", + hover: "fancytree-ext-fixed-hover", + }, + }, + // Overide virtual methods for this extension. + // `this` : is this extension object + // `this._super`: the virtual function that was overriden (member of prev. extension or Fancytree) + treeInit: function (ctx) { + this._requireExtension("table", true, true); + // 'fixed' requires the table extension to be loaded before itself + + var res = this._superApply(arguments), + tree = ctx.tree, + options = this.options.fixed, + fcn = this.options.fixed.classNames, + $table = tree.widget.element, + fixedColCount = options.fixCols, + fixedRowCount = options.fixRows, + $tableWrapper = $table.parent(), + $topLeftWrapper = $("<div>").addClass(fcn.topLeft), + $topRightWrapper = $("<div>").addClass(fcn.topRight), + $bottomLeftWrapper = $("<div>").addClass(fcn.bottomLeft), + $bottomRightWrapper = $("<div>").addClass(fcn.bottomRight), + tableStyle = $table.attr("style"), + tableClass = $table.attr("class"), + $topLeftTable = $("<table>") + .attr("style", tableStyle) + .attr("class", tableClass), + $topRightTable = $("<table>") + .attr("style", tableStyle) + .attr("class", tableClass), + $bottomLeftTable = $table, + $bottomRightTable = $("<table>") + .attr("style", tableStyle) + .attr("class", tableClass), + $head = $table.find("thead"), + $colgroup = $table.find("colgroup"), + headRowCount = $head.find("tr").length; + + this.$fixedWrapper = $tableWrapper; + $table.addClass(fcn.table); + $tableWrapper.addClass(fcn.wrapper); + $bottomRightTable.append($("<tbody>")); + + if ($colgroup.length) { + $colgroup.remove(); + } + + if (typeof fixedRowCount === "boolean") { + fixedRowCount = fixedRowCount ? headRowCount : 0; + } else { + fixedRowCount = Math.max( + 0, + Math.min(fixedRowCount, headRowCount) + ); + } + + if (fixedRowCount) { + $topLeftTable.append($head.clone(true)); + $topRightTable.append($head.clone(true)); + $head.remove(); + } + + $topLeftTable.find("tr").each(function (idx) { + $(this).find("th").slice(fixedColCount).remove(); + }); + + $topRightTable.find("tr").each(function (idx) { + $(this).find("th").slice(0, fixedColCount).remove(); + }); + + this.$fixedWrapper = $tableWrapper; + + $tableWrapper.append( + $topLeftWrapper.append($topLeftTable), + $topRightWrapper.append($topRightTable), + $bottomLeftWrapper.append($bottomLeftTable), + $bottomRightWrapper.append($bottomRightTable) + ); + + $bottomRightTable.on("keydown", function (evt) { + var node = tree.focusNode, + ctx = tree._makeHookContext(node || tree, evt), + res = tree._callHook("nodeKeydown", ctx); + return res; + }); + + $bottomRightTable.on("click dblclick", "tr", function (evt) { + var $trLeft = $(this), + $trRight = $trLeft.data(fcn.counterpart), + node = $.ui.fancytree.getNode($trRight), + ctx = tree._makeHookContext(node, evt), + et = $.ui.fancytree.getEventTarget(evt), + prevPhase = tree.phase; + + try { + tree.phase = "userEvent"; + switch (evt.type) { + case "click": + ctx.targetType = et.type; + if (node.isPagingNode()) { + return ( + tree._triggerNodeEvent( + "clickPaging", + ctx, + evt + ) === true + ); + } + return tree._triggerNodeEvent("click", ctx, evt) === + false + ? false + : tree._callHook("nodeClick", ctx); + case "dblclick": + ctx.targetType = et.type; + return tree._triggerNodeEvent( + "dblclick", + ctx, + evt + ) === false + ? false + : tree._callHook("nodeDblclick", ctx); + } + } finally { + tree.phase = prevPhase; + } + }); + + $tableWrapper + .on( + "mouseenter", + "." + + fcn.bottomRight + + " table tr, ." + + fcn.bottomLeft + + " table tr", + function (evt) { + var $tr = $(this), + $trOther = $tr.data(fcn.counterpart); + $tr.addClass(fcn.hover); + $trOther.addClass(fcn.hover); + } + ) + .on( + "mouseleave", + "." + + fcn.bottomRight + + " table tr, ." + + fcn.bottomLeft + + " table tr", + function (evt) { + var $tr = $(this), + $trOther = $tr.data(fcn.counterpart); + $tr.removeClass(fcn.hover); + $trOther.removeClass(fcn.hover); + } + ); + + $bottomLeftWrapper.on( + "mousewheel DOMMouseScroll", + function (event) { + var $this = $(this), + newScroll = $this.scrollTop(), + scrollUp = + event.originalEvent.wheelDelta > 0 || + event.originalEvent.detail < 0; + + newScroll += scrollUp + ? -options.scrollSpeed + : options.scrollSpeed; + $this.scrollTop(newScroll); + $bottomRightWrapper.scrollTop(newScroll); + event.preventDefault(); + } + ); + + $bottomRightWrapper.scroll(function () { + var $this = $(this), + scrollLeft = $this.scrollLeft(), + scrollTop = $this.scrollTop(); + + $topLeftWrapper + .toggleClass(fcn.scrollBorderBottom, scrollTop > 0) + .toggleClass(fcn.scrollBorderRight, scrollLeft > 0); + $topRightWrapper + .toggleClass(fcn.scrollBorderBottom, scrollTop > 0) + .scrollLeft(scrollLeft); + $bottomLeftWrapper + .toggleClass(fcn.scrollBorderRight, scrollLeft > 0) + .scrollTop(scrollTop); + }); + + $.ui.fancytree.overrideMethod( + $.ui.fancytree._FancytreeNodeClass.prototype, + "scrollIntoView", + function (effects, options) { + var $prevContainer = tree.$container; + tree.$container = $bottomRightWrapper; + return this._super + .apply(this, arguments) + .always(function () { + tree.$container = $prevContainer; + }); + } + ); + return res; + }, + + treeLoad: function (ctx) { + var self = this, + res = this._superApply(arguments); + + res.done(function () { + self.ext.fixed._adjustLayout.call(self); + if (self.options.fixed.resizable) { + self.ext.fixed._makeTableResizable(); + } + }); + return res; + }, + + _makeTableResizable: function () { + var $wrapper = this.$fixedWrapper, + fcn = this.options.fixed.classNames, + $topLeftWrapper = $wrapper.find("div." + fcn.topLeft), + $topRightWrapper = $wrapper.find("div." + fcn.topRight), + $bottomLeftWrapper = $wrapper.find("div." + fcn.bottomLeft), + $bottomRightWrapper = $wrapper.find("div." + fcn.bottomRight); + + function _makeResizable($table) { + $table.resizable({ + handles: "e", + resize: function (evt, ui) { + var width = Math.max($table.width(), ui.size.width); + $bottomLeftWrapper.css("width", width); + $topLeftWrapper.css("width", width); + $bottomRightWrapper.css("left", width); + $topRightWrapper.css("left", width); + }, + stop: function () { + $table.css("width", "100%"); + }, + }); + } + + _makeResizable($topLeftWrapper.find("table")); + _makeResizable($bottomLeftWrapper.find("table")); + }, + + /* Called by nodeRender to sync node order with tag order.*/ + // nodeFixOrder: function(ctx) { + // }, + + nodeLoadChildren: function (ctx, source) { + return this._superApply(arguments); + }, + + nodeRemoveChildMarkup: function (ctx) { + var node = ctx.node; + + function _removeChild(elem) { + var i, + child, + children = elem.children; + if (children) { + for (i = 0; i < children.length; i++) { + child = children[i]; + if (child.trRight) { + $(child.trRight).remove(); + } + _removeChild(child); + } + } + } + + _removeChild(node); + return this._superApply(arguments); + }, + + nodeRemoveMarkup: function (ctx) { + var node = ctx.node; + + if (node.trRight) { + $(node.trRight).remove(); + } + return this._superApply(arguments); + }, + + nodeSetActive: function (ctx, flag, callOpts) { + var node = ctx.node, + cn = this.options._classNames; + + if (node.trRight) { + $(node.trRight) + .toggleClass(cn.active, flag) + .toggleClass(cn.focused, flag); + } + return this._superApply(arguments); + }, + + nodeKeydown: function (ctx) { + return this._superApply(arguments); + }, + + nodeSetFocus: function (ctx, flag) { + var node = ctx.node, + cn = this.options._classNames; + + if (node.trRight) { + $(node.trRight).toggleClass(cn.focused, flag); + } + return this._superApply(arguments); + }, + + nodeRender: function (ctx, force, deep, collapsed, _recursive) { + var res = this._superApply(arguments), + node = ctx.node, + isRootNode = !node.parent; + + if (!isRootNode && this.$fixedWrapper) { + var $trLeft = $(node.tr), + fcn = this.options.fixed.classNames, + $trRight = $trLeft.data(fcn.counterpart); + + if (!$trRight && $trLeft.length) { + var idx = $trLeft.index(), + fixedColCount = this.options.fixed.fixCols, + $blTableBody = this.$fixedWrapper.find( + "div." + fcn.bottomLeft + " table tbody" + ), + $brTableBody = this.$fixedWrapper.find( + "div." + fcn.bottomRight + " table tbody" + ), + $prevLeftNode = $blTableBody + .find("tr") + .eq(Math.max(idx + 1, 0)), + prevRightNode = $prevLeftNode.data(fcn.counterpart); + + $trRight = $trLeft.clone(true); + var trRight = $trRight.get(0); + + if (prevRightNode) { + $(prevRightNode).before($trRight); + } else { + $brTableBody.append($trRight); + } + $trRight.show(); + trRight.ftnode = node; + node.trRight = trRight; + + $trLeft.find("td").slice(fixedColCount).remove(); + $trRight.find("td").slice(0, fixedColCount).remove(); + $trLeft.data(fcn.counterpart, $trRight); + $trRight.data(fcn.counterpart, $trLeft); + } + } + + return res; + }, + + nodeRenderTitle: function (ctx, title) { + return this._superApply(arguments); + }, + + nodeRenderStatus: function (ctx) { + var res = this._superApply(arguments), + node = ctx.node; + + if (node.trRight) { + var $trRight = $(node.trRight), + $trLeft = $(node.tr), + fcn = this.options.fixed.classNames, + hovering = $trRight.hasClass(fcn.hover), + trClasses = $trLeft.attr("class"); + + $trRight.attr("class", trClasses); + if (hovering) { + $trRight.addClass(fcn.hover); + $trLeft.addClass(fcn.hover); + } + } + return res; + }, + + nodeSetExpanded: function (ctx, flag, callOpts) { + var res, + self = this, + node = ctx.node, + $leftTr = $(node.tr), + fcn = this.options.fixed.classNames, + cn = this.options._classNames, + $rightTr = $leftTr.data(fcn.counterpart); + + flag = typeof flag === "undefined" ? true : flag; + + if (!$rightTr) { + return this._superApply(arguments); + } + $rightTr.toggleClass(cn.expanded, !!flag); + if (flag && !node.isExpanded()) { + res = this._superApply(arguments); + res.done(function () { + node.visit(function (child) { + var $trLeft = $(child.tr), + $trRight = $trLeft.data(fcn.counterpart); + + self.ext.fixed._adjustRowHeight($trLeft, $trRight); + if (!child.expanded) { + return "skip"; + } + }); + + self.ext.fixed._adjustColWidths(); + self.ext.fixed._adjustWrapperLayout(); + }); + } else if (!flag && node.isExpanded()) { + node.visit(function (child) { + var $trLeft = $(child.tr), + $trRight = $trLeft.data(fcn.counterpart); + if ($trRight) { + if (!child.expanded) { + return "skip"; + } + } + }); + + self.ext.fixed._adjustColWidths(); + self.ext.fixed._adjustWrapperLayout(); + res = this._superApply(arguments); + } else { + res = this._superApply(arguments); + } + return res; + }, + + nodeSetStatus: function (ctx, status, message, details) { + return this._superApply(arguments); + }, + + treeClear: function (ctx) { + var tree = ctx.tree, + $table = tree.widget.element, + $wrapper = this.$fixedWrapper, + fcn = this.options.fixed.classNames; + + $table.find("tr, td, th, thead").removeClass(fcn.hidden).css({ + "min-width": "auto", + height: "auto", + }); + $wrapper.empty().append($table); + return this._superApply(arguments); + }, + + treeRegisterNode: function (ctx, add, node) { + return this._superApply(arguments); + }, + + treeDestroy: function (ctx) { + var tree = ctx.tree, + $table = tree.widget.element, + $wrapper = this.$fixedWrapper, + fcn = this.options.fixed.classNames; + + $table.find("tr, td, th, thead").removeClass(fcn.hidden).css({ + "min-width": "auto", + height: "auto", + }); + $wrapper.empty().append($table); + return this._superApply(arguments); + }, + + _adjustColWidths: function () { + if (this.options.fixed.adjustColWidths) { + this.options.fixed.adjustColWidths.call(this); + return; + } + + var $wrapper = this.$fixedWrapper, + fcn = this.options.fixed.classNames, + $tlWrapper = $wrapper.find("div." + fcn.topLeft), + $blWrapper = $wrapper.find("div." + fcn.bottomLeft), + $trWrapper = $wrapper.find("div." + fcn.topRight), + $brWrapper = $wrapper.find("div." + fcn.bottomRight); + + function _adjust($topWrapper, $bottomWrapper) { + var $trTop = $topWrapper.find("thead tr").first(), + $trBottom = $bottomWrapper.find("tbody tr").first(); + + $trTop.find("th").each(function (idx) { + var $thTop = $(this), + $tdBottom = $trBottom.find("td").eq(idx), + thTopWidth = $thTop.width(), + thTopOuterWidth = $thTop.outerWidth(), + tdBottomWidth = $tdBottom.width(), + tdBottomOuterWidth = $tdBottom.outerWidth(), + newWidth = Math.max( + thTopOuterWidth, + tdBottomOuterWidth + ); + + $thTop.css( + "min-width", + newWidth - (thTopOuterWidth - thTopWidth) + ); + $tdBottom.css( + "min-width", + newWidth - (tdBottomOuterWidth - tdBottomWidth) + ); + }); + } + + _adjust($tlWrapper, $blWrapper); + _adjust($trWrapper, $brWrapper); + }, + + _adjustRowHeight: function ($tr1, $tr2) { + var fcn = this.options.fixed.classNames; + if (!$tr2) { + $tr2 = $tr1.data(fcn.counterpart); + } + $tr1.css("height", "auto"); + $tr2.css("height", "auto"); + var row1Height = $tr1.outerHeight(), + row2Height = $tr2.outerHeight(), + newHeight = Math.max(row1Height, row2Height); + $tr1.css("height", newHeight + 1); + $tr2.css("height", newHeight + 1); + }, + + _adjustWrapperLayout: function () { + var $wrapper = this.$fixedWrapper, + fcn = this.options.fixed.classNames, + $topLeftWrapper = $wrapper.find("div." + fcn.topLeft), + $topRightWrapper = $wrapper.find("div." + fcn.topRight), + $bottomLeftWrapper = $wrapper.find("div." + fcn.bottomLeft), + $bottomRightWrapper = $wrapper.find("div." + fcn.bottomRight), + $topLeftTable = $topLeftWrapper.find("table"), + $topRightTable = $topRightWrapper.find("table"), + // $bottomLeftTable = $bottomLeftWrapper.find("table"), + wrapperWidth = $wrapper.width(), + wrapperHeight = $wrapper.height(), + fixedWidth = Math.min(wrapperWidth, $topLeftTable.width()), + fixedHeight = Math.min( + wrapperHeight, + Math.max($topLeftTable.height(), $topRightTable.height()) + ); + // vScrollbar = $bottomRightWrapper.get(0).scrollHeight > (wrapperHeight - fixedHeight), + // hScrollbar = $bottomRightWrapper.get(0).scrollWidth > (wrapperWidth - fixedWidth); + + $topLeftWrapper.css({ + width: fixedWidth, + height: fixedHeight, + }); + $topRightWrapper.css({ + // width: wrapperWidth - fixedWidth - (vScrollbar ? 17 : 0), + // width: "calc(100% - " + (fixedWidth + (vScrollbar ? 17 : 0)) + "px)", + width: "calc(100% - " + (fixedWidth + 17) + "px)", + height: fixedHeight, + left: fixedWidth, + }); + $bottomLeftWrapper.css({ + width: fixedWidth, + // height: vScrollbar ? wrapperHeight - fixedHeight - (hScrollbar ? 17 : 0) : "auto", + // height: vScrollbar ? ("calc(100% - " + (fixedHeight + (hScrollbar ? 17 : 0)) + "px)") : "auto", + // height: vScrollbar ? ("calc(100% - " + (fixedHeight + 17) + "px)") : "auto", + height: "calc(100% - " + (fixedHeight + 17) + "px)", + top: fixedHeight, + }); + $bottomRightWrapper.css({ + // width: wrapperWidth - fixedWidth, + // height: vScrollbar ? wrapperHeight - fixedHeight : "auto", + width: "calc(100% - " + fixedWidth + "px)", + // height: vScrollbar ? ("calc(100% - " + fixedHeight + "px)") : "auto", + height: "calc(100% - " + fixedHeight + "px)", + top: fixedHeight, + left: fixedWidth, + }); + }, + + _adjustLayout: function () { + var self = this, + $wrapper = this.$fixedWrapper, + fcn = this.options.fixed.classNames, + $topLeftWrapper = $wrapper.find("div." + fcn.topLeft), + $topRightWrapper = $wrapper.find("div." + fcn.topRight), + $bottomLeftWrapper = $wrapper.find("div." + fcn.bottomLeft); + // $bottomRightWrapper = $wrapper.find("div." + fcn.bottomRight) + + $topLeftWrapper.find("table tr").each(function (idx) { + var $trRight = $topRightWrapper.find("tr").eq(idx); + self.ext.fixed._adjustRowHeight($(this), $trRight); + }); + + $bottomLeftWrapper + .find("table tbody") + .find("tr") + .each(function (idx) { + // var $trRight = $bottomRightWrapper.find("tbody").find("tr").eq(idx); + self.ext.fixed._adjustRowHeight($(this)); + }); + + self.ext.fixed._adjustColWidths.call(this); + self.ext.fixed._adjustWrapperLayout.call(this); + }, + + // treeSetFocus: function(ctx, flag) { + //// alert("treeSetFocus" + ctx.tree.$container); + // ctx.tree.$container.focus(); + // $.ui.fancytree.focusTree = ctx.tree; + // } + }); + // Value returned by `require('jquery.fancytree..')` + return $.ui.fancytree; +}); // End of closure diff --git a/plugins/55/indexmenu/scripts/fancytree/modules/jquery.fancytree.glyph.js b/plugins/55/indexmenu/scripts/fancytree/modules/jquery.fancytree.glyph.js new file mode 100644 index 0000000..4771bee --- /dev/null +++ b/plugins/55/indexmenu/scripts/fancytree/modules/jquery.fancytree.glyph.js @@ -0,0 +1,354 @@ +/*! + * jquery.fancytree.glyph.js + * + * Use glyph-fonts, ligature-fonts, or SVG icons instead of icon sprites. + * (Extension module for jquery.fancytree.js: https://github.com/mar10/fancytree/) + * + * Copyright (c) 2008-2023, Martin Wendt (https://wwWendt.de) + * + * Released under the MIT license + * https://github.com/mar10/fancytree/wiki/LicenseInfo + * + * @version 2.38.3 + * @date 2023-02-01T20:52:50Z + */ + +(function (factory) { + if (typeof define === "function" && define.amd) { + // AMD. Register as an anonymous module. + define(["jquery", "./jquery.fancytree"], factory); + } else if (typeof module === "object" && module.exports) { + // Node/CommonJS + require("./jquery.fancytree"); + module.exports = factory(require("jquery")); + } else { + // Browser globals + factory(jQuery); + } +})(function ($) { + "use strict"; + + /****************************************************************************** + * Private functions and variables + */ + + var FT = $.ui.fancytree, + PRESETS = { + awesome3: { + // Outdated! + _addClass: "", + checkbox: "icon-check-empty", + checkboxSelected: "icon-check", + checkboxUnknown: "icon-check icon-muted", + dragHelper: "icon-caret-right", + dropMarker: "icon-caret-right", + error: "icon-exclamation-sign", + expanderClosed: "icon-caret-right", + expanderLazy: "icon-angle-right", + expanderOpen: "icon-caret-down", + loading: "icon-refresh icon-spin", + nodata: "icon-meh", + noExpander: "", + radio: "icon-circle-blank", + radioSelected: "icon-circle", + // radioUnknown: "icon-circle icon-muted", + // Default node icons. + // (Use tree.options.icon callback to define custom icons based on node data) + doc: "icon-file-alt", + docOpen: "icon-file-alt", + folder: "icon-folder-close-alt", + folderOpen: "icon-folder-open-alt", + }, + awesome4: { + _addClass: "fa", + checkbox: "fa-square-o", + checkboxSelected: "fa-check-square-o", + checkboxUnknown: "fa-square fancytree-helper-indeterminate-cb", + dragHelper: "fa-arrow-right", + dropMarker: "fa-long-arrow-right", + error: "fa-warning", + expanderClosed: "fa-caret-right", + expanderLazy: "fa-angle-right", + expanderOpen: "fa-caret-down", + // We may prevent wobbling rotations on FF by creating a separate sub element: + loading: { html: "<span class='fa fa-spinner fa-pulse' />" }, + nodata: "fa-meh-o", + noExpander: "", + radio: "fa-circle-thin", // "fa-circle-o" + radioSelected: "fa-circle", + // radioUnknown: "fa-dot-circle-o", + // Default node icons. + // (Use tree.options.icon callback to define custom icons based on node data) + doc: "fa-file-o", + docOpen: "fa-file-o", + folder: "fa-folder-o", + folderOpen: "fa-folder-open-o", + }, + awesome5: { + // fontawesome 5 have several different base classes + // "far, fas, fal and fab" The rendered svg puts that prefix + // in a different location so we have to keep them separate here + _addClass: "", + checkbox: "far fa-square", + checkboxSelected: "far fa-check-square", + // checkboxUnknown: "far fa-window-close", + checkboxUnknown: + "fas fa-square fancytree-helper-indeterminate-cb", + radio: "far fa-circle", + radioSelected: "fas fa-circle", + radioUnknown: "far fa-dot-circle", + dragHelper: "fas fa-arrow-right", + dropMarker: "fas fa-long-arrow-alt-right", + error: "fas fa-exclamation-triangle", + expanderClosed: "fas fa-caret-right", + expanderLazy: "fas fa-angle-right", + expanderOpen: "fas fa-caret-down", + loading: "fas fa-spinner fa-pulse", + nodata: "far fa-meh", + noExpander: "", + // Default node icons. + // (Use tree.options.icon callback to define custom icons based on node data) + doc: "far fa-file", + docOpen: "far fa-file", + folder: "far fa-folder", + folderOpen: "far fa-folder-open", + }, + bootstrap3: { + _addClass: "glyphicon", + checkbox: "glyphicon-unchecked", + checkboxSelected: "glyphicon-check", + checkboxUnknown: + "glyphicon-expand fancytree-helper-indeterminate-cb", // "glyphicon-share", + dragHelper: "glyphicon-play", + dropMarker: "glyphicon-arrow-right", + error: "glyphicon-warning-sign", + expanderClosed: "glyphicon-menu-right", // glyphicon-plus-sign + expanderLazy: "glyphicon-menu-right", // glyphicon-plus-sign + expanderOpen: "glyphicon-menu-down", // glyphicon-minus-sign + loading: "glyphicon-refresh fancytree-helper-spin", + nodata: "glyphicon-info-sign", + noExpander: "", + radio: "glyphicon-remove-circle", // "glyphicon-unchecked", + radioSelected: "glyphicon-ok-circle", // "glyphicon-check", + // radioUnknown: "glyphicon-ban-circle", + // Default node icons. + // (Use tree.options.icon callback to define custom icons based on node data) + doc: "glyphicon-file", + docOpen: "glyphicon-file", + folder: "glyphicon-folder-close", + folderOpen: "glyphicon-folder-open", + }, + material: { + _addClass: "material-icons", + checkbox: { text: "check_box_outline_blank" }, + checkboxSelected: { text: "check_box" }, + checkboxUnknown: { text: "indeterminate_check_box" }, + dragHelper: { text: "play_arrow" }, + dropMarker: { text: "arrow-forward" }, + error: { text: "warning" }, + expanderClosed: { text: "chevron_right" }, + expanderLazy: { text: "last_page" }, + expanderOpen: { text: "expand_more" }, + loading: { + text: "autorenew", + addClass: "fancytree-helper-spin", + }, + nodata: { text: "info" }, + noExpander: { text: "" }, + radio: { text: "radio_button_unchecked" }, + radioSelected: { text: "radio_button_checked" }, + // Default node icons. + // (Use tree.options.icon callback to define custom icons based on node data) + doc: { text: "insert_drive_file" }, + docOpen: { text: "insert_drive_file" }, + folder: { text: "folder" }, + folderOpen: { text: "folder_open" }, + }, + }; + + function setIcon(node, span, baseClass, opts, type) { + var map = opts.map, + icon = map[type], + $span = $(span), + $counter = $span.find(".fancytree-childcounter"), + setClass = baseClass + " " + (map._addClass || ""); + + // #871 Allow a callback + if (typeof icon === "function") { + icon = icon.call(this, node, span, type); + } + // node.debug( "setIcon(" + baseClass + ", " + type + "): " + "oldIcon" + " -> " + icon ); + // #871: propsed this, but I am not sure how robust this is, e.g. + // the prefix (fas, far) class changes are not considered? + // if (span.tagName === "svg" && opts.preset === "awesome5") { + // // fa5 script converts <i> to <svg> so call a specific handler. + // var oldIcon = "fa-" + $span.data("icon"); + // // node.debug( "setIcon(" + baseClass + ", " + type + "): " + oldIcon + " -> " + icon ); + // if (typeof oldIcon === "string") { + // $span.removeClass(oldIcon); + // } + // if (typeof icon === "string") { + // $span.addClass(icon); + // } + // return; + // } + if (typeof icon === "string") { + // #883: remove inner html that may be added by prev. mode + span.innerHTML = ""; + $span.attr("class", setClass + " " + icon).append($counter); + } else if (icon) { + if (icon.text) { + span.textContent = "" + icon.text; + } else if (icon.html) { + span.innerHTML = icon.html; + } else { + span.innerHTML = ""; + } + $span + .attr("class", setClass + " " + (icon.addClass || "")) + .append($counter); + } + } + + $.ui.fancytree.registerExtension({ + name: "glyph", + version: "2.38.3", + // Default options for this extension. + options: { + preset: null, // 'awesome3', 'awesome4', 'bootstrap3', 'material' + map: {}, + }, + + treeInit: function (ctx) { + var tree = ctx.tree, + opts = ctx.options.glyph; + + if (opts.preset) { + FT.assert( + !!PRESETS[opts.preset], + "Invalid value for `options.glyph.preset`: " + opts.preset + ); + opts.map = $.extend({}, PRESETS[opts.preset], opts.map); + } else { + tree.warn("ext-glyph: missing `preset` option."); + } + this._superApply(arguments); + tree.$container.addClass("fancytree-ext-glyph"); + }, + nodeRenderStatus: function (ctx) { + var checkbox, + icon, + res, + span, + node = ctx.node, + $span = $(node.span), + opts = ctx.options.glyph; + + res = this._super(ctx); + + if (node.isRootNode()) { + return res; + } + span = $span.children(".fancytree-expander").get(0); + if (span) { + // if( node.isLoading() ){ + // icon = "loading"; + if (node.expanded && node.hasChildren()) { + icon = "expanderOpen"; + } else if (node.isUndefined()) { + icon = "expanderLazy"; + } else if (node.hasChildren()) { + icon = "expanderClosed"; + } else { + icon = "noExpander"; + } + // span.className = "fancytree-expander " + map[icon]; + setIcon(node, span, "fancytree-expander", opts, icon); + } + + if (node.tr) { + span = $("td", node.tr).find(".fancytree-checkbox").get(0); + } else { + span = $span.children(".fancytree-checkbox").get(0); + } + if (span) { + checkbox = FT.evalOption("checkbox", node, node, opts, false); + if ( + (node.parent && node.parent.radiogroup) || + checkbox === "radio" + ) { + icon = node.selected ? "radioSelected" : "radio"; + setIcon( + node, + span, + "fancytree-checkbox fancytree-radio", + opts, + icon + ); + } else { + // eslint-disable-next-line no-nested-ternary + icon = node.selected + ? "checkboxSelected" + : node.partsel + ? "checkboxUnknown" + : "checkbox"; + // span.className = "fancytree-checkbox " + map[icon]; + setIcon(node, span, "fancytree-checkbox", opts, icon); + } + } + + // Standard icon (note that this does not match .fancytree-custom-icon, + // that might be set by opts.icon callbacks) + span = $span.children(".fancytree-icon").get(0); + if (span) { + if (node.statusNodeType) { + icon = node.statusNodeType; // loading, error + } else if (node.folder) { + icon = + node.expanded && node.hasChildren() + ? "folderOpen" + : "folder"; + } else { + icon = node.expanded ? "docOpen" : "doc"; + } + setIcon(node, span, "fancytree-icon", opts, icon); + } + return res; + }, + nodeSetStatus: function (ctx, status, message, details) { + var res, + span, + opts = ctx.options.glyph, + node = ctx.node; + + res = this._superApply(arguments); + + if ( + status === "error" || + status === "loading" || + status === "nodata" + ) { + if (node.parent) { + span = $(".fancytree-expander", node.span).get(0); + if (span) { + setIcon(node, span, "fancytree-expander", opts, status); + } + } else { + // + span = $( + ".fancytree-statusnode-" + status, + node[this.nodeContainerAttrName] + ) + .find(".fancytree-icon") + .get(0); + if (span) { + setIcon(node, span, "fancytree-icon", opts, status); + } + } + } + return res; + }, + }); + // Value returned by `require('jquery.fancytree..')` + return $.ui.fancytree; +}); // End of closure diff --git a/plugins/55/indexmenu/scripts/fancytree/modules/jquery.fancytree.grid.js b/plugins/55/indexmenu/scripts/fancytree/modules/jquery.fancytree.grid.js new file mode 100644 index 0000000..73e53cd --- /dev/null +++ b/plugins/55/indexmenu/scripts/fancytree/modules/jquery.fancytree.grid.js @@ -0,0 +1,1014 @@ +/*! + * jquery.fancytree.grid.js + * + * Render tree as table (aka 'tree grid', 'table tree'). + * (Extension module for jquery.fancytree.js: https://github.com/mar10/fancytree/) + * + * Copyright (c) 2008-2023, Martin Wendt (http://wwWendt.de) + * + * Released under the MIT license + * https://github.com/mar10/fancytree/wiki/LicenseInfo + * + * @version 2.38.3 + * @date 2023-02-01T20:52:50Z + */ + +(function (factory) { + if (typeof define === "function" && define.amd) { + // AMD. Register as an anonymous module. + define(["jquery", "./jquery.fancytree"], factory); + } else if (typeof module === "object" && module.exports) { + // Node/CommonJS + require("./jquery.fancytree"); + module.exports = factory(require("jquery")); + } else { + // Browser globals + factory(jQuery); + } +})(function ($) { + "use strict"; + + /****************************************************************************** + * Private functions and variables + */ + var FT = $.ui.fancytree, + _assert = FT.assert, + SCROLL_MODE = "wheel"; // 'wheel' | 'scroll' + // EPS = 1.0; + + /* + * [ext-grid] ... + * + * @alias Fancytree#_addScrollbar + * @requires jquery.fancytree.grid.js + */ + function _addScrollbar(table) { + var sbWidth = 10, + $table = $(table), + position = $table.position(), + // top = $table.find("tbody").position().top, + + $sb = $("<div>", { + class: "fancytree-scrollbar", + css: { + border: "1px solid gray", + position: "absolute", + top: position.top, + left: position.left + $table.width(), + width: sbWidth, + height: $table.find("tbody").height(), + }, + }); + + $table + .css({ + "margin-right": sbWidth, + }) + .after($sb); + + return $sb; + } + + /* + * [ext-grid] Invalidate renumber status, i.e. trigger renumber next time. + * + * @alias Fancytree#_renumberReset + * @requires jquery.fancytree.grid.js + */ + $.ui.fancytree._FancytreeClass.prototype._renumberReset = function () { + // this.debug("_renumberReset()"); + this.visibleNodeList = null; + }; + + /* + * [ext-grid] Adjust the start value if the content would be outside otherwise. + * + * @alias Fancytree#_fixStart + * @requires jquery.fancytree.grid.js + */ + $.ui.fancytree._FancytreeClass.prototype._fixStart = function ( + start, + apply + ) { + var vp = this.viewport, + nodeList = this.visibleNodeList; + + start = start == null ? vp.start : start; + // this.debug("_fixStart(" + start + ", " + !!apply + ")"); + var orgStart = start; + // Don't scroll down below bottom node + if (nodeList) { + start = Math.min(start, this.visibleNodeList.length - vp.count); + start = Math.max(start, 0, start); + if (start !== orgStart) { + this.debug("Adjust start " + orgStart + " => " + start); + if (apply) { + vp.start = start; + } + } + } + return start; + }; + + /* + * [ext-grid] ... + * + * @alias Fancytree#_shiftViewport + * @requires jquery.fancytree.grid.js + */ + $.ui.fancytree._FancytreeClass.prototype._shiftViewport = function ( + mode, + ofs + ) { + this.debug("_shiftViewport", mode, ofs); + switch (mode) { + case "vscroll": + if (ofs) { + this.setViewport({ + start: this.viewport.start + (ofs > 0 ? 1 : -1), + }); + } + break; + + default: + throw Error("Invalid mode: " + mode); + } + }; + + /** + * [ext-grid] Return true if viewport cannot be scrolled down any further. + * + * @alias Fancytree#isViewportBottom + * @requires jquery.fancytree.grid.js + */ + $.ui.fancytree._FancytreeClass.prototype.isViewportBottom = function () { + return ( + this.viewport.start + this.viewport.count >= + this.visibleNodeList.length + ); + }; + + /** + * [ext-grid] Define a subset of rows/columns to display and redraw. + * + * @param {object | boolean} options viewport boundaries and status. + * + * @alias Fancytree#setViewport + * @requires jquery.fancytree.grid.js + */ + $.ui.fancytree._FancytreeClass.prototype.setViewport = function (opts) { + if (typeof opts === "boolean") { + this.debug("setViewport( " + opts + ")"); + return this.setViewport({ enabled: opts }); + } + opts = opts || {}; + var i, + count, + start, + newRow, + redrawReason = "", + vp = this.viewport, + diffVp = { start: 0, count: 0, enabled: null, force: null }, + newVp = $.extend({}, vp), + trList = this.tbody.children, + trCount = trList.length; + + // Sanitize viewport settings and check if we need to redraw + this.debug("setViewport(" + opts.start + ", +" + opts.count + ")"); + if (opts.force) { + redrawReason += "force"; + diffVp.force = true; + } + + opts.enabled = opts.enabled !== false; // default to true + if (vp.enabled !== opts.enabled) { + redrawReason += "enable"; + newVp.enabled = diffVp.enabled = opts.enabled; + } + + start = opts.start == null ? vp.start : Math.max(0, +opts.start); + // Adjust start value to assure the current content is inside vp + start = this._fixStart(start, false); + + if (vp.start !== +start) { + redrawReason += "start"; + newVp.start = start; + diffVp.start = start - vp.start; + } + + count = opts.count == null ? vp.count : Math.max(1, +opts.count); + if (vp.count !== +count) { + redrawReason += "count"; + newVp.count = count; + diffVp.count = count - vp.count; + } + // if (vp.left !== +opts.left) { + // diffVp.left = left - vp.left; + // newVp.left = opts.left; + // redrawReason += "left"; + // } + // if (vp.right !== +opts.right) { + // diffVp.right = right - vp.right; + // newVp.right = opts.right; + // redrawReason += "right"; + // } + + if (!redrawReason) { + return false; + } + // Let user cancel or modify the update + var info = { + next: newVp, + diff: diffVp, + reason: redrawReason, + scrollOnly: redrawReason === "start", + }; + if ( + !opts.noEvents && + this._triggerTreeEvent("beforeUpdateViewport", null, info) === false + ) { + return false; + } + info.prev = $.extend({}, vp); + delete info.next; + // vp.enabled = newVp.enabled; + vp.start = newVp.start; + vp.count = newVp.count; + + // Make sure we have the correct count of TRs + var prevPhase = this.isVpUpdating; + + if (trCount > count) { + for (i = 0; i < trCount - count; i++) { + delete this.tbody.lastChild.ftnode; + this.tbody.removeChild(this.tbody.lastChild); + } + } else if (trCount < count) { + for (i = 0; i < count - trCount; i++) { + newRow = this.rowFragment.firstChild.cloneNode(true); + this.tbody.appendChild(newRow); + } + } + trCount = trList.length; + + // Update visible node cache if needed + var force = opts.force; + this.redrawViewport(force); + + if (!opts.noEvents) { + this._triggerTreeEvent("updateViewport", null, info); + } + + this.isVpUpdating = prevPhase; + return true; + }; + + /** + * [ext-grid] Calculate the viewport count from current scroll wrapper height. + * + * @alias Fancytree#adjustViewportSize + * @requires jquery.fancytree.grid.js + */ + $.ui.fancytree._FancytreeClass.prototype.adjustViewportSize = function () { + _assert( + this.scrollWrapper, + "No parent div.fancytree-grid-container found." + ); + if (this.isVpUpdating) { + this.debug("Ignoring adjustViewportSize() during VP update."); + return; + } + // Calculate how many rows fit into current container height + var $table = this.$container, + wrapper = this.scrollWrapper, + trHeight = $table.find(">tbody>tr").first().height() || 0, + tableHeight = $table.height(), + headHeight = tableHeight - this.viewport.count * trHeight, + wrapperHeight = wrapper.offsetHeight, + free = wrapperHeight - headHeight, + newCount = trHeight ? Math.floor(free / trHeight) : 0; + + // console.info( + // "set container height", + // $(this) + // .parent(".fancytree-grid-container") + // .height() + // ); + + this.setViewport({ count: newCount }); + // if (SCROLL_MODE === "scroll") { + // // Add bottom margin to the table, to make sure the wrapper becomes + // // scrollable + // var mb = wrapperHeight - $table.height() - 2.0 * EPS; + // this.debug("margin-bottom=" + mb); + // $table.css("margin-bottom", mb); + // } + }; + + /* + * [ext-grid] Calculate the scroll container dimension from the current tree table. + * + * @alias Fancytree#initViewportWrapper + * @requires jquery.fancytree.grid.js + */ + $.ui.fancytree._FancytreeClass.prototype._initViewportWrapper = + function () { + var // wrapper = this.scrollWrapper, + // $wrapper = $(wrapper), + tree = this; + + // if (SCROLL_MODE === "scroll") { + // $wrapper.on("scroll", function(e) { + // var viewport = tree.viewport, + // curTop = wrapper.scrollTop, + // homeTop = viewport.start === 0 ? 0 : EPS, + // dy = viewport.start === 0 ? 1 : curTop - EPS; //homeTop; + + // tree.debug( + // "Got 'scroll' event: scrollTop=" + + // curTop + + // ", homeTop=" + + // homeTop + + // ", start=" + + // viewport.start + + // ", dy=" + + // dy + // ); + // if (tree.isVpUpdating) { + // tree.debug("Ignoring scroll during VP update."); + // return; + // } else if (curTop === homeTop) { + // tree.debug("Ignoring scroll to neutral " + homeTop + "."); + // return; + // } + // tree._shiftViewport("vscroll", dy); + // homeTop = viewport.start === 0 ? 0 : EPS; + // setTimeout(function() { + // tree.debug( + // "scrollTop(" + + // wrapper.scrollTop + + // " -> " + + // homeTop + + // ")..." + // ); + // wrapper.scrollTop = homeTop; + // }, 0); + // }); + // } + if (SCROLL_MODE === "wheel") { + this.$container.on("wheel", function (e) { + var orgEvent = e.originalEvent, + viewport = tree.viewport, + dy = orgEvent.deltaY; // * orgEvent.wheelDeltaY; + + if ( + !dy || + e.altKey || + e.ctrlKey || + e.metaKey || + e.shiftKey + ) { + return true; + } + if (dy < 0 && viewport.start === 0) { + return true; + } + if (dy > 0 && tree.isViewportBottom()) { + return true; + } + tree.debug( + "Got 'wheel' event: dy=" + + dy + + ", mode=" + + orgEvent.deltaMode + ); + tree._shiftViewport("vscroll", dy); + return false; + }); + } + }; + + /* + * [ext-grid] Renumber and collect all visible rows. + * + * @param {bool} [force=false] + * @param {FancytreeNode | int} [startIdx=0] + * @alias Fancytree#_renumberVisibleNodes + * @requires jquery.fancytree.grid.js + */ + $.ui.fancytree._FancytreeClass.prototype._renumberVisibleNodes = function ( + force, + startIdx + ) { + if ( + (!this.options.viewport.enabled || this.visibleNodeList != null) && + force !== true + ) { + // this.debug("_renumberVisibleNodes() ignored."); + return false; + } + this.debugTime("_renumberVisibleNodes()"); + var i = 0, + prevLength = this.visibleNodeList ? this.visibleNodeList.length : 0, + visibleNodeList = (this.visibleNodeList = []); + + // Reset previous data + this.visit(function (node) { + node._rowIdx = null; + // node.span = null; + // if (node.tr) { + // delete node.tr.ftnode; + // node.tr = null; + // } + }); + // Iterate over all *visible* nodes + this.visitRows(function (node) { + node._rowIdx = i++; + visibleNodeList.push(node); + }); + this.debugTimeEnd("_renumberVisibleNodes()"); + if (i !== prevLength) { + this._triggerTreeEvent("updateViewport", null, { + reason: "renumber", + diff: { start: 0, count: 0, enabled: null, force: null }, + next: $.extend({}, this.viewport), + // visibleCount: prevLength, + // cur: i, + }); + } + }; + + /** + * [ext-grid] Render all visible nodes into the viweport. + * + * @param {bool} [force=false] + * @alias Fancytree#redrawViewport + * @requires jquery.fancytree.grid.js + */ + $.ui.fancytree._FancytreeClass.prototype.redrawViewport = function (force) { + if (this._enableUpdate === false) { + // tree.debug("no render", tree._enableUpdate); + return; + } + this.debugTime("redrawViewport()"); + this._renumberVisibleNodes(force); + // Adjust vp.start value to assure the current content is inside: + this._fixStart(null, true); + + var i = 0, + vp = this.viewport, + visibleNodeList = this.visibleNodeList, + start = vp.start, + bottom = start + vp.count, + tr, + _renderCount = 0, + trIdx = 0, + trList = this.tbody.children, + prevPhase = this.isVpUpdating; + + // Reset previous data + this.visit(function (node) { + // node.debug("redrawViewport(): _rowIdx=" + node._rowIdx); + node.span = null; + if (node.tr) { + delete node.tr.ftnode; + node.tr = null; + } + }); + + // Redraw the whole tree, erasing all node markup before and after + // the viewport + + for (i = start; i < bottom; i++) { + var node = visibleNodeList[i]; + + tr = trList[trIdx]; + + if (!node) { + // TODO: make trailing empty rows configurable (custom template or remove TRs) + var newRow = this.rowFragment.firstChild.cloneNode(true); + this.tbody.replaceChild(newRow, tr); + trIdx++; + continue; + } + if (tr !== node.tr) { + node.tr = tr; + node.render(); + _renderCount++; + + // TODO: + // Implement scrolling by re-using existing markup + // e.g. shifting TRs or TR child elements instead of + // re-creating all the time + } + trIdx++; + } + this.isVpUpdating = prevPhase; + this.debugTimeEnd("redrawViewport()"); + }; + + $.ui.fancytree.registerExtension({ + name: "grid", + version: "2.38.3", + // Default options for this extension. + options: { + checkboxColumnIdx: null, // render the checkboxes into the this column index (default: nodeColumnIdx) + indentation: 16, // indent every node level by 16px + mergeStatusColumns: true, // display 'nodata', 'loading', 'error' centered in a single, merged TR + nodeColumnIdx: 0, // render node expander, icon, and title to this column (default: #0) + }, + // Overide virtual methods for this extension. + // `this` : is this extension object + // `this._super`: the virtual function that was overriden (member of prev. extension or Fancytree) + treeInit: function (ctx) { + var i, + columnCount, + n, + $row, + $tbody, + tree = ctx.tree, + opts = ctx.options, + tableOpts = opts.table, + $table = tree.widget.element, + $scrollWrapper = $table.parent(".fancytree-grid-container"); + + if ($.inArray("table", opts.extensions) >= 0) { + $.error("ext-grid and ext-table are mutually exclusive."); + } + if (opts.renderStatusColumns === true) { + opts.renderStatusColumns = opts.renderColumns; + } + // Note: we also re-use CSS rules from ext-table + $table.addClass( + "fancytree-container fancytree-ext-grid fancytree-ext-table" + ); + $tbody = $table.find(">tbody"); + if (!$tbody.length) { + // TODO: not sure if we can rely on browsers to insert missing <tbody> before <tr>s: + if ($table.find(">tr").length) { + $.error( + "Expected table > tbody > tr. If you see this, please open an issue." + ); + } + $tbody = $("<tbody>").appendTo($table); + } + + tree.tbody = $tbody[0]; + + // Prepare row templates: + // Determine column count from table header if any + columnCount = $("thead >tr", $table).last().find(">th").length; + // Read TR templates from tbody if any + $row = $tbody.children("tr").first(); + if ($row.length) { + n = $row.children("td").length; + if (columnCount && n !== columnCount) { + tree.warn( + "Column count mismatch between thead (" + + columnCount + + ") and tbody (" + + n + + "): using tbody." + ); + columnCount = n; + } + $row = $row.clone(); + } else { + // Only thead is defined: create default row markup + _assert( + columnCount >= 1, + "Need either <thead> or <tbody> with <td> elements to determine column count." + ); + $row = $("<tr />"); + for (i = 0; i < columnCount; i++) { + $row.append("<td />"); + } + } + $row.find(">td") + .eq(tableOpts.nodeColumnIdx) + .html("<span class='fancytree-node' />"); + if (opts.aria) { + $row.attr("role", "row"); + $row.find("td").attr("role", "gridcell"); + } + tree.rowFragment = document.createDocumentFragment(); + tree.rowFragment.appendChild($row.get(0)); + + $tbody.empty(); + + // Make sure that status classes are set on the node's <tr> elements + tree.statusClassPropName = "tr"; + tree.ariaPropName = "tr"; + this.nodeContainerAttrName = "tr"; + + // #489: make sure $container is set to <table>, even if ext-dnd is listed before ext-grid + tree.$container = $table; + if ($scrollWrapper.length) { + tree.scrollWrapper = $scrollWrapper[0]; + this._initViewportWrapper(); + } else { + tree.scrollWrapper = null; + } + + // Scrolling is implemented completely differently here + $.ui.fancytree.overrideMethod( + $.ui.fancytree._FancytreeNodeClass.prototype, + "scrollIntoView", + function (effects, options) { + var node = this, + tree = node.tree, + topNode = options && options.topNode, + vp = tree.viewport, + start = vp ? vp.start : null; + + if (!tree.viewport) { + return node._super.apply(this, arguments); + } + if (node._rowIdx < vp.start) { + start = node._rowIdx; + } else if (node._rowIdx >= vp.start + vp.count) { + start = node._rowIdx - vp.count + 1; + } + if (topNode && topNode._rowIdx < start) { + start = topNode._rowIdx; + } + tree.setViewport({ start: start }); + // Return a resolved promise + return $.Deferred(function () { + this.resolveWith(node); + }).promise(); + } + ); + + tree.visibleNodeList = null; // Set by _renumberVisibleNodes() + tree.viewport = { + enabled: true, + start: 0, + count: 10, + left: 0, + right: 0, + }; + this.setViewport( + $.extend( + { + // enabled: true, + autoSize: true, + start: 0, + count: 10, + left: 0, + right: 0, + keepEmptyRows: true, + noEvents: true, + }, + opts.viewport + ) + ); + // tree.$scrollbar = _addScrollbar($table); + + this._superApply(arguments); + + // standard Fancytree created a root UL + $(tree.rootNode.ul).remove(); + tree.rootNode.ul = null; + + // Add container to the TAB chain + // #577: Allow to set tabindex to "0", "-1" and "" + this.$container.attr("tabindex", opts.tabindex); + // this.$container.attr("tabindex", opts.tabbable ? "0" : "-1"); + if (opts.aria) { + tree.$container + .attr("role", "treegrid") + .attr("aria-readonly", true); + } + }, + nodeKeydown: function (ctx) { + var nextNode = null, + nextIdx = null, + tree = ctx.tree, + node = ctx.node, + nodeList = tree.visibleNodeList, + // treeOpts = ctx.options, + viewport = tree.viewport, + event = ctx.originalEvent, + eventString = FT.eventToString(event); + + tree.debug("nodeKeydown(" + eventString + ")"); + + switch (eventString) { + case "home": + case "meta+up": + nextIdx = 0; + break; + case "end": + case "meta+down": + nextIdx = nodeList.length - 1; + break; + case "pageup": + nextIdx = node._rowIdx - viewport.count; + break; + case "pagedown": + nextIdx = node._rowIdx + viewport.count; + break; + } + if (nextIdx != null) { + nextIdx = Math.min(Math.max(0, nextIdx), nodeList.length - 1); + nextNode = nodeList[nextIdx]; + nextNode.makeVisible(); + nextNode.setActive(); + return false; + } + return this._superApply(arguments); + }, + nodeRemoveChildMarkup: function (ctx) { + var node = ctx.node; + + node.visit(function (n) { + if (n.tr) { + delete n.tr.ftnode; + n.tr = null; + n.span = null; + } + }); + }, + nodeRemoveMarkup: function (ctx) { + var node = ctx.node; + + if (node.tr) { + delete node.tr.ftnode; + node.tr = null; + node.span = null; + } + this.nodeRemoveChildMarkup(ctx); + }, + /* Override standard render. */ + nodeRender: function (ctx, force, deep, collapsed, _recursive) { + var children, + i, + l, + outsideViewport, + subCtx, + tree = ctx.tree, + node = ctx.node; + + if (tree._enableUpdate === false) { + node.debug("nodeRender(): _enableUpdate: false"); + return; + } + var opts = ctx.options, + viewport = tree.viewport.enabled ? tree.viewport : null, + start = viewport && viewport.start > 0 ? +viewport.start : 0, + bottom = viewport ? start + viewport.count - 1 : 0, + isRootNode = !node.parent; + + _assert(viewport); + + // node.debug("nodeRender(): " + node + ", isRoot=" + isRootNode, "tr=" + node.tr, "hcp=" + ctx.hasCollapsedParents, "parent.tr=" + (node.parent && node.parent.tr)); + if (!_recursive) { + // node.debug("nodeRender(): start top node"); + if (isRootNode && viewport) { + node.debug("nodeRender(): redrawViewport() instead"); + return ctx.tree.redrawViewport(); + } + ctx.hasCollapsedParents = node.parent && !node.parent.expanded; + // Make sure visible row indices are up-to-date + if (viewport) { + tree._renumberVisibleNodes(); + } + } + + if (!isRootNode) { + outsideViewport = + viewport && + (node._rowIdx < start || + node._rowIdx >= start + viewport.count); + + // node.debug( + // "nodeRender(): idx=" + + // node._rowIdx + + // ", outside=" + + // outsideViewport + + // ", TR count=" + + // tree.tbody.rows.length + // ); + if (outsideViewport) { + // node.debug("nodeRender(): outsideViewport: ignored"); + return; + } + if (!node.tr) { + if (node._rowIdx == null) { + // node.warn("nodeRender(): ignoring hidden"); + return; + } + node.debug("nodeRender(): creating new TR."); + node.tr = tree.tbody.rows[node._rowIdx - start]; + } + // _assert( + // node.tr, + // "nodeRender() called for node.tr == null: " + node + // ); + node.tr.ftnode = node; + + if (node.key && opts.generateIds) { + node.tr.id = opts.idPrefix + node.key; + } + node.span = $("span.fancytree-node", node.tr).get(0); + + // Set icon, link, and title (normally this is only required on initial render) + // var ctx = this._makeHookContext(node); + this.nodeRenderTitle(ctx); // triggers renderColumns() + + // Allow tweaking, binding, after node was created for the first time + if (opts.createNode) { + opts.createNode.call(this, { type: "createNode" }, ctx); + } + } + // Allow tweaking after node state was rendered + if (opts.renderNode) { + opts.renderNode.call(tree, { type: "renderNode" }, ctx); + } + // Visit child nodes + // Add child markup + children = node.children; + _assert(!deep, "deep is not supported"); + + if (children && (isRootNode || deep || node.expanded)) { + for (i = 0, l = children.length; i < l; i++) { + var child = children[i]; + + if (viewport && child._rowIdx > bottom) { + children[i].debug("BREAK render children loop"); + return false; + } + subCtx = $.extend({}, ctx, { node: child }); + subCtx.hasCollapsedParents = + subCtx.hasCollapsedParents || !node.expanded; + this.nodeRender(subCtx, force, deep, collapsed, true); + } + } + }, + nodeRenderTitle: function (ctx, title) { + var $cb, + res, + tree = ctx.tree, + node = ctx.node, + opts = ctx.options, + isStatusNode = node.isStatusNode(); + + res = this._super(ctx, title); + + if (node.isRootNode()) { + return res; + } + // Move checkbox to custom column + if ( + opts.checkbox && + !isStatusNode && + opts.table.checkboxColumnIdx != null + ) { + $cb = $("span.fancytree-checkbox", node.span); //.detach(); + $(node.tr) + .find("td") + .eq(+opts.table.checkboxColumnIdx) + .html($cb); + } + // Update element classes according to node state + this.nodeRenderStatus(ctx); + + if (isStatusNode) { + if (opts.renderStatusColumns) { + // Let user code write column content + opts.renderStatusColumns.call( + tree, + { type: "renderStatusColumns" }, + ctx + ); + } else if (opts.grid.mergeStatusColumns && node.isTopLevel()) { + node.warn("mergeStatusColumns is not yet implemented."); + // This approach would not work, since the roe may be re-used: + // $(node.tr) + // .find(">td") + // .eq(0) + // .prop("colspan", tree.columnCount) + // .text(node.title) + // .addClass("fancytree-status-merged") + // .nextAll() + // .remove(); + } // else: default rendering for status node: leave other cells empty + } else if (opts.renderColumns) { + opts.renderColumns.call(tree, { type: "renderColumns" }, ctx); + } + return res; + }, + nodeRenderStatus: function (ctx) { + var indent, + node = ctx.node, + opts = ctx.options; + + this._super(ctx); + + $(node.tr).removeClass("fancytree-node"); + // indent + indent = (node.getLevel() - 1) * opts.table.indentation; + if (opts.rtl) { + $(node.span).css({ paddingRight: indent + "px" }); + } else { + $(node.span).css({ paddingLeft: indent + "px" }); + } + }, + /* Expand node, return Deferred.promise. */ + nodeSetExpanded: function (ctx, flag, callOpts) { + var node = ctx.node, + tree = ctx.tree; + + // flag defaults to true + flag = flag !== false; + + if ((node.expanded && flag) || (!node.expanded && !flag)) { + // Expanded state isn't changed - just call base implementation + return this._superApply(arguments); + } + + var dfd = new $.Deferred(), + subOpts = $.extend({}, callOpts, { + noEvents: true, + noAnimation: true, + }); + + callOpts = callOpts || {}; + + function _afterExpand(ok) { + tree.redrawViewport(true); + + if (ok) { + if ( + flag && + ctx.options.autoScroll && + !callOpts.noAnimation && + node.hasChildren() + ) { + // Scroll down to last child, but keep current node visible + node.getLastChild() + .scrollIntoView(true, { topNode: node }) + .always(function () { + if (!callOpts.noEvents) { + tree._triggerNodeEvent( + flag ? "expand" : "collapse", + ctx + ); + } + dfd.resolveWith(node); + }); + } else { + if (!callOpts.noEvents) { + tree._triggerNodeEvent( + flag ? "expand" : "collapse", + ctx + ); + } + dfd.resolveWith(node); + } + } else { + if (!callOpts.noEvents) { + tree._triggerNodeEvent( + flag ? "expand" : "collapse", + ctx + ); + } + dfd.rejectWith(node); + } + } + // Call base-expand with disabled events and animation + this._super(ctx, flag, subOpts) + .done(function () { + _afterExpand(true); + }) + .fail(function () { + _afterExpand(false); + }); + return dfd.promise(); + }, + treeClear: function (ctx) { + // this.nodeRemoveChildMarkup(this._makeHookContext(this.rootNode)); + // this._renumberReset(); // Invalidate visible row cache + return this._superApply(arguments); + }, + treeDestroy: function (ctx) { + this.$container.find("tbody").empty(); + this.$container.off("wheel"); + if (this.$source) { + this.$source.removeClass("fancytree-helper-hidden"); + } + this._renumberReset(); // Invalidate visible row cache + return this._superApply(arguments); + }, + treeStructureChanged: function (ctx, type) { + // debugger; + if (type !== "addNode" || ctx.tree.visibleNodeList) { + // this.debug("treeStructureChanged(" + type + ")"); + this._renumberReset(); // Invalidate visible row cache + } + }, + }); + // Value returned by `require('jquery.fancytree..')` + return $.ui.fancytree; +}); // End of closure diff --git a/plugins/55/indexmenu/scripts/fancytree/modules/jquery.fancytree.gridnav.js b/plugins/55/indexmenu/scripts/fancytree/modules/jquery.fancytree.gridnav.js new file mode 100644 index 0000000..7ffbb67 --- /dev/null +++ b/plugins/55/indexmenu/scripts/fancytree/modules/jquery.fancytree.gridnav.js @@ -0,0 +1,218 @@ +/*! + * jquery.fancytree.gridnav.js + * + * Support keyboard navigation for trees with embedded input controls. + * (Extension module for jquery.fancytree.js: https://github.com/mar10/fancytree/) + * + * Copyright (c) 2008-2023, Martin Wendt (https://wwWendt.de) + * + * Released under the MIT license + * https://github.com/mar10/fancytree/wiki/LicenseInfo + * + * @version 2.38.3 + * @date 2023-02-01T20:52:50Z + */ + +(function (factory) { + if (typeof define === "function" && define.amd) { + // AMD. Register as an anonymous module. + define([ + "jquery", + "./jquery.fancytree", + "./jquery.fancytree.table", + ], factory); + } else if (typeof module === "object" && module.exports) { + // Node/CommonJS + require("./jquery.fancytree.table"); // core + table + module.exports = factory(require("jquery")); + } else { + // Browser globals + factory(jQuery); + } +})(function ($) { + "use strict"; + + /******************************************************************************* + * Private functions and variables + */ + + // Allow these navigation keys even when input controls are focused + + var KC = $.ui.keyCode, + // which keys are *not* handled by embedded control, but passed to tree + // navigation handler: + NAV_KEYS = { + text: [KC.UP, KC.DOWN], + checkbox: [KC.UP, KC.DOWN, KC.LEFT, KC.RIGHT], + link: [KC.UP, KC.DOWN, KC.LEFT, KC.RIGHT], + radiobutton: [KC.UP, KC.DOWN, KC.LEFT, KC.RIGHT], + "select-one": [KC.LEFT, KC.RIGHT], + "select-multiple": [KC.LEFT, KC.RIGHT], + }; + + /* Calculate TD column index (considering colspans).*/ + function getColIdx($tr, $td) { + var colspan, + td = $td.get(0), + idx = 0; + + $tr.children().each(function () { + if (this === td) { + return false; + } + colspan = $(this).prop("colspan"); + idx += colspan ? colspan : 1; + }); + return idx; + } + + /* Find TD at given column index (considering colspans).*/ + function findTdAtColIdx($tr, colIdx) { + var colspan, + res = null, + idx = 0; + + $tr.children().each(function () { + if (idx >= colIdx) { + res = $(this); + return false; + } + colspan = $(this).prop("colspan"); + idx += colspan ? colspan : 1; + }); + return res; + } + + /* Find adjacent cell for a given direction. Skip empty cells and consider merged cells */ + function findNeighbourTd($target, keyCode) { + var $tr, + colIdx, + $td = $target.closest("td"), + $tdNext = null; + + switch (keyCode) { + case KC.LEFT: + $tdNext = $td.prev(); + break; + case KC.RIGHT: + $tdNext = $td.next(); + break; + case KC.UP: + case KC.DOWN: + $tr = $td.parent(); + colIdx = getColIdx($tr, $td); + while (true) { + $tr = keyCode === KC.UP ? $tr.prev() : $tr.next(); + if (!$tr.length) { + break; + } + // Skip hidden rows + if ($tr.is(":hidden")) { + continue; + } + // Find adjacent cell in the same column + $tdNext = findTdAtColIdx($tr, colIdx); + // Skip cells that don't conatain a focusable element + if ($tdNext && $tdNext.find(":input,a").length) { + break; + } + } + break; + } + return $tdNext; + } + + /******************************************************************************* + * Extension code + */ + $.ui.fancytree.registerExtension({ + name: "gridnav", + version: "2.38.3", + // Default options for this extension. + options: { + autofocusInput: false, // Focus first embedded input if node gets activated + handleCursorKeys: true, // Allow UP/DOWN in inputs to move to prev/next node + }, + + treeInit: function (ctx) { + // gridnav requires the table extension to be loaded before itself + this._requireExtension("table", true, true); + this._superApply(arguments); + + this.$container.addClass("fancytree-ext-gridnav"); + + // Activate node if embedded input gets focus (due to a click) + this.$container.on("focusin", function (event) { + var ctx2, + node = $.ui.fancytree.getNode(event.target); + + if (node && !node.isActive()) { + // Call node.setActive(), but also pass the event + ctx2 = ctx.tree._makeHookContext(node, event); + ctx.tree._callHook("nodeSetActive", ctx2, true); + } + }); + }, + nodeSetActive: function (ctx, flag, callOpts) { + var $outer, + opts = ctx.options.gridnav, + node = ctx.node, + event = ctx.originalEvent || {}, + triggeredByInput = $(event.target).is(":input"); + + flag = flag !== false; + + this._superApply(arguments); + + if (flag) { + if (ctx.options.titlesTabbable) { + if (!triggeredByInput) { + $(node.span).find("span.fancytree-title").focus(); + node.setFocus(); + } + // If one node is tabbable, the container no longer needs to be + ctx.tree.$container.attr("tabindex", "-1"); + // ctx.tree.$container.removeAttr("tabindex"); + } else if (opts.autofocusInput && !triggeredByInput) { + // Set focus to input sub input (if node was clicked, but not + // when TAB was pressed ) + $outer = $(node.tr || node.span); + $outer.find(":input:enabled").first().focus(); + } + } + }, + nodeKeydown: function (ctx) { + var inputType, + handleKeys, + $td, + opts = ctx.options.gridnav, + event = ctx.originalEvent, + $target = $(event.target); + + if ($target.is(":input:enabled")) { + inputType = $target.prop("type"); + } else if ($target.is("a")) { + inputType = "link"; + } + // ctx.tree.debug("ext-gridnav nodeKeydown", event, inputType); + + if (inputType && opts.handleCursorKeys) { + handleKeys = NAV_KEYS[inputType]; + if (handleKeys && $.inArray(event.which, handleKeys) >= 0) { + $td = findNeighbourTd($target, event.which); + if ($td && $td.length) { + // ctx.node.debug("ignore keydown in input", event.which, handleKeys); + $td.find(":input:enabled,a").focus(); + // Prevent Fancytree default navigation + return false; + } + } + return true; + } + // ctx.tree.debug("ext-gridnav NOT HANDLED", event, inputType); + return this._superApply(arguments); + }, + }); + // Value returned by `require('jquery.fancytree..')` + return $.ui.fancytree; +}); // End of closure diff --git a/plugins/55/indexmenu/scripts/fancytree/modules/jquery.fancytree.js b/plugins/55/indexmenu/scripts/fancytree/modules/jquery.fancytree.js new file mode 100644 index 0000000..ada9aeb --- /dev/null +++ b/plugins/55/indexmenu/scripts/fancytree/modules/jquery.fancytree.js @@ -0,0 +1,7374 @@ +/*! + * jquery.fancytree.js + * Tree view control with support for lazy loading and much more. + * https://github.com/mar10/fancytree/ + * + * Copyright (c) 2008-2023, Martin Wendt (https://wwWendt.de) + * Released under the MIT license + * https://github.com/mar10/fancytree/wiki/LicenseInfo + * + * @version 2.38.3 + * @date 2023-02-01T20:52:50Z + */ + +/** Core Fancytree module. + */ + +// UMD wrapper for the Fancytree core module +(function (factory) { + if (typeof define === "function" && define.amd) { + // AMD. Register as an anonymous module. + define(["jquery", "./jquery.fancytree.ui-deps"], factory); + } else if (typeof module === "object" && module.exports) { + // Node/CommonJS + require("./jquery.fancytree.ui-deps"); + module.exports = factory(require("jquery")); + } else { + // Browser globals + factory(jQuery); + } +})(function ($) { + "use strict"; + + // prevent duplicate loading + if ($.ui && $.ui.fancytree) { + $.ui.fancytree.warn("Fancytree: ignored duplicate include"); + return; + } + + /****************************************************************************** + * Private functions and variables + */ + + var i, + attr, + FT = null, // initialized below + TEST_IMG = new RegExp(/\.|\//), // strings are considered image urls if they contain '.' or '/' + REX_HTML = /[&<>"'/]/g, // Escape those characters + REX_TOOLTIP = /[<>"'/]/g, // Don't escape `&` in tooltips + RECURSIVE_REQUEST_ERROR = "$recursive_request", + INVALID_REQUEST_TARGET_ERROR = "$request_target_invalid", + ENTITY_MAP = { + "&": "&", + "<": "<", + ">": ">", + '"': """, + "'": "'", + "/": "/", + }, + IGNORE_KEYCODES = { 16: true, 17: true, 18: true }, + SPECIAL_KEYCODES = { + 8: "backspace", + 9: "tab", + 10: "return", + 13: "return", + // 16: null, 17: null, 18: null, // ignore shift, ctrl, alt + 19: "pause", + 20: "capslock", + 27: "esc", + 32: "space", + 33: "pageup", + 34: "pagedown", + 35: "end", + 36: "home", + 37: "left", + 38: "up", + 39: "right", + 40: "down", + 45: "insert", + 46: "del", + 59: ";", + 61: "=", + // 91: null, 93: null, // ignore left and right meta + 96: "0", + 97: "1", + 98: "2", + 99: "3", + 100: "4", + 101: "5", + 102: "6", + 103: "7", + 104: "8", + 105: "9", + 106: "*", + 107: "+", + 109: "-", + 110: ".", + 111: "/", + 112: "f1", + 113: "f2", + 114: "f3", + 115: "f4", + 116: "f5", + 117: "f6", + 118: "f7", + 119: "f8", + 120: "f9", + 121: "f10", + 122: "f11", + 123: "f12", + 144: "numlock", + 145: "scroll", + 173: "-", + 186: ";", + 187: "=", + 188: ",", + 189: "-", + 190: ".", + 191: "/", + 192: "`", + 219: "[", + 220: "\\", + 221: "]", + 222: "'", + }, + MODIFIERS = { + 16: "shift", + 17: "ctrl", + 18: "alt", + 91: "meta", + 93: "meta", + }, + MOUSE_BUTTONS = { 0: "", 1: "left", 2: "middle", 3: "right" }, + // Boolean attributes that can be set with equivalent class names in the LI tags + // Note: v2.23: checkbox and hideCheckbox are *not* in this list + CLASS_ATTRS = + "active expanded focus folder lazy radiogroup selected unselectable unselectableIgnore".split( + " " + ), + CLASS_ATTR_MAP = {}, + // Top-level Fancytree attributes, that can be set by dict + TREE_ATTRS = "columns types".split(" "), + // TREE_ATTR_MAP = {}, + // Top-level FancytreeNode attributes, that can be set by dict + NODE_ATTRS = + "checkbox expanded extraClasses folder icon iconTooltip key lazy partsel radiogroup refKey selected statusNodeType title tooltip type unselectable unselectableIgnore unselectableStatus".split( + " " + ), + NODE_ATTR_MAP = {}, + // Mapping of lowercase -> real name (because HTML5 data-... attribute only supports lowercase) + NODE_ATTR_LOWERCASE_MAP = {}, + // Attribute names that should NOT be added to node.data + NONE_NODE_DATA_MAP = { + active: true, + children: true, + data: true, + focus: true, + }; + + for (i = 0; i < CLASS_ATTRS.length; i++) { + CLASS_ATTR_MAP[CLASS_ATTRS[i]] = true; + } + for (i = 0; i < NODE_ATTRS.length; i++) { + attr = NODE_ATTRS[i]; + NODE_ATTR_MAP[attr] = true; + if (attr !== attr.toLowerCase()) { + NODE_ATTR_LOWERCASE_MAP[attr.toLowerCase()] = attr; + } + } + // for(i=0; i<TREE_ATTRS.length; i++) { + // TREE_ATTR_MAP[TREE_ATTRS[i]] = true; + // } + + function _assert(cond, msg) { + // TODO: see qunit.js extractStacktrace() + if (!cond) { + msg = msg ? ": " + msg : ""; + msg = "Fancytree assertion failed" + msg; + + // consoleApply("assert", [!!cond, msg]); + + // #1041: Raised exceptions may not be visible in the browser + // console if inside promise chains, so we also print directly: + $.ui.fancytree.error(msg); + + // Throw exception: + $.error(msg); + } + } + + function _hasProp(object, property) { + return Object.prototype.hasOwnProperty.call(object, property); + } + + /* Replacement for the deprecated `jQuery.isFunction()`. */ + function _isFunction(obj) { + return typeof obj === "function"; + } + + /* Replacement for the deprecated `jQuery.trim()`. */ + function _trim(text) { + return text == null ? "" : text.trim(); + } + + /* Replacement for the deprecated `jQuery.isArray()`. */ + var _isArray = Array.isArray; + + _assert($.ui, "Fancytree requires jQuery UI (http://jqueryui.com)"); + + function consoleApply(method, args) { + var i, + s, + fn = window.console ? window.console[method] : null; + + if (fn) { + try { + fn.apply(window.console, args); + } catch (e) { + // IE 8? + s = ""; + for (i = 0; i < args.length; i++) { + s += args[i]; + } + fn(s); + } + } + } + + /* support: IE8 Polyfil for Date.now() */ + if (!Date.now) { + Date.now = function now() { + return new Date().getTime(); + }; + } + + /*Return true if x is a FancytreeNode.*/ + function _isNode(x) { + return !!(x.tree && x.statusNodeType !== undefined); + } + + /** Return true if dotted version string is equal or higher than requested version. + * + * See http://jsfiddle.net/mar10/FjSAN/ + */ + function isVersionAtLeast(dottedVersion, major, minor, patch) { + var i, + v, + t, + verParts = $.map(_trim(dottedVersion).split("."), function (e) { + return parseInt(e, 10); + }), + testParts = $.map( + Array.prototype.slice.call(arguments, 1), + function (e) { + return parseInt(e, 10); + } + ); + + for (i = 0; i < testParts.length; i++) { + v = verParts[i] || 0; + t = testParts[i] || 0; + if (v !== t) { + return v > t; + } + } + return true; + } + + /** + * Deep-merge a list of objects (but replace array-type options). + * + * jQuery's $.extend(true, ...) method does a deep merge, that also merges Arrays. + * This variant is used to merge extension defaults with user options, and should + * merge objects, but override arrays (for example the `triggerStart: [...]` option + * of ext-edit). Also `null` values are copied over and not skipped. + * + * See issue #876 + * + * Example: + * _simpleDeepMerge({}, o1, o2); + */ + function _simpleDeepMerge() { + var options, + name, + src, + copy, + clone, + target = arguments[0] || {}, + i = 1, + length = arguments.length; + + // Handle case when target is a string or something (possible in deep copy) + if (typeof target !== "object" && !_isFunction(target)) { + target = {}; + } + if (i === length) { + throw Error("need at least two args"); + } + for (; i < length; i++) { + // Only deal with non-null/undefined values + if ((options = arguments[i]) != null) { + // Extend the base object + for (name in options) { + if (_hasProp(options, name)) { + src = target[name]; + copy = options[name]; + // Prevent never-ending loop + if (target === copy) { + continue; + } + // Recurse if we're merging plain objects + // (NOTE: unlike $.extend, we don't merge arrays, but replace them) + if (copy && $.isPlainObject(copy)) { + clone = src && $.isPlainObject(src) ? src : {}; + // Never move original objects, clone them + target[name] = _simpleDeepMerge(clone, copy); + // Don't bring in undefined values + } else if (copy !== undefined) { + target[name] = copy; + } + } + } + } + } + // Return the modified object + return target; + } + + /** Return a wrapper that calls sub.methodName() and exposes + * this : tree + * this._local : tree.ext.EXTNAME + * this._super : base.methodName.call() + * this._superApply : base.methodName.apply() + */ + function _makeVirtualFunction(methodName, tree, base, extension, extName) { + // $.ui.fancytree.debug("_makeVirtualFunction", methodName, tree, base, extension, extName); + // if(rexTestSuper && !rexTestSuper.test(func)){ + // // extension.methodName() doesn't call _super(), so no wrapper required + // return func; + // } + // Use an immediate function as closure + var proxy = (function () { + var prevFunc = tree[methodName], // org. tree method or prev. proxy + baseFunc = extension[methodName], // + _local = tree.ext[extName], + _super = function () { + return prevFunc.apply(tree, arguments); + }, + _superApply = function (args) { + return prevFunc.apply(tree, args); + }; + + // Return the wrapper function + return function () { + var prevLocal = tree._local, + prevSuper = tree._super, + prevSuperApply = tree._superApply; + + try { + tree._local = _local; + tree._super = _super; + tree._superApply = _superApply; + return baseFunc.apply(tree, arguments); + } finally { + tree._local = prevLocal; + tree._super = prevSuper; + tree._superApply = prevSuperApply; + } + }; + })(); // end of Immediate Function + return proxy; + } + + /** + * Subclass `base` by creating proxy functions + */ + function _subclassObject(tree, base, extension, extName) { + // $.ui.fancytree.debug("_subclassObject", tree, base, extension, extName); + for (var attrName in extension) { + if (typeof extension[attrName] === "function") { + if (typeof tree[attrName] === "function") { + // override existing method + tree[attrName] = _makeVirtualFunction( + attrName, + tree, + base, + extension, + extName + ); + } else if (attrName.charAt(0) === "_") { + // Create private methods in tree.ext.EXTENSION namespace + tree.ext[extName][attrName] = _makeVirtualFunction( + attrName, + tree, + base, + extension, + extName + ); + } else { + $.error( + "Could not override tree." + + attrName + + ". Use prefix '_' to create tree." + + extName + + "._" + + attrName + ); + } + } else { + // Create member variables in tree.ext.EXTENSION namespace + if (attrName !== "options") { + tree.ext[extName][attrName] = extension[attrName]; + } + } + } + } + + function _getResolvedPromise(context, argArray) { + if (context === undefined) { + return $.Deferred(function () { + this.resolve(); + }).promise(); + } + return $.Deferred(function () { + this.resolveWith(context, argArray); + }).promise(); + } + + function _getRejectedPromise(context, argArray) { + if (context === undefined) { + return $.Deferred(function () { + this.reject(); + }).promise(); + } + return $.Deferred(function () { + this.rejectWith(context, argArray); + }).promise(); + } + + function _makeResolveFunc(deferred, context) { + return function () { + deferred.resolveWith(context); + }; + } + + function _getElementDataAsDict($el) { + // Evaluate 'data-NAME' attributes with special treatment for 'data-json'. + var d = $.extend({}, $el.data()), + json = d.json; + + delete d.fancytree; // added to container by widget factory (old jQuery UI) + delete d.uiFancytree; // added to container by widget factory + + if (json) { + delete d.json; + // <li data-json='...'> is already returned as object (http://api.jquery.com/data/#data-html5) + d = $.extend(d, json); + } + return d; + } + + function _escapeTooltip(s) { + return ("" + s).replace(REX_TOOLTIP, function (s) { + return ENTITY_MAP[s]; + }); + } + + // TODO: use currying + function _makeNodeTitleMatcher(s) { + s = s.toLowerCase(); + return function (node) { + return node.title.toLowerCase().indexOf(s) >= 0; + }; + } + + function _makeNodeTitleStartMatcher(s) { + var reMatch = new RegExp("^" + s, "i"); + return function (node) { + return reMatch.test(node.title); + }; + } + + /****************************************************************************** + * FancytreeNode + */ + + /** + * Creates a new FancytreeNode + * + * @class FancytreeNode + * @classdesc A FancytreeNode represents the hierarchical data model and operations. + * + * @param {FancytreeNode} parent + * @param {NodeData} obj + * + * @property {Fancytree} tree The tree instance + * @property {FancytreeNode} parent The parent node + * @property {string} key Node id (must be unique inside the tree) + * @property {string} title Display name (may contain HTML) + * @property {object} data Contains all extra data that was passed on node creation + * @property {FancytreeNode[] | null | undefined} children Array of child nodes.<br> + * For lazy nodes, null or undefined means 'not yet loaded'. Use an empty array + * to define a node that has no children. + * @property {boolean} expanded Use isExpanded(), setExpanded() to access this property. + * @property {string} extraClasses Additional CSS classes, added to the node's `<span>`.<br> + * Note: use `node.add/remove/toggleClass()` to modify. + * @property {boolean} folder Folder nodes have different default icons and click behavior.<br> + * Note: Also non-folders may have children. + * @property {string} statusNodeType null for standard nodes. Otherwise type of special system node: 'error', 'loading', 'nodata', or 'paging'. + * @property {boolean} lazy True if this node is loaded on demand, i.e. on first expansion. + * @property {boolean} selected Use isSelected(), setSelected() to access this property. + * @property {string} tooltip Alternative description used as hover popup + * @property {string} iconTooltip Description used as hover popup for icon. @since 2.27 + * @property {string} type Node type, used with tree.types map. @since 2.27 + */ + function FancytreeNode(parent, obj) { + var i, l, name, cl; + + this.parent = parent; + this.tree = parent.tree; + this.ul = null; + this.li = null; // <li id='key' ftnode=this> tag + this.statusNodeType = null; // if this is a temp. node to display the status of its parent + this._isLoading = false; // if this node itself is loading + this._error = null; // {message: '...'} if a load error occurred + this.data = {}; + + // TODO: merge this code with node.toDict() + // copy attributes from obj object + for (i = 0, l = NODE_ATTRS.length; i < l; i++) { + name = NODE_ATTRS[i]; + this[name] = obj[name]; + } + // unselectableIgnore and unselectableStatus imply unselectable + if ( + this.unselectableIgnore != null || + this.unselectableStatus != null + ) { + this.unselectable = true; + } + if (obj.hideCheckbox) { + $.error( + "'hideCheckbox' node option was removed in v2.23.0: use 'checkbox: false'" + ); + } + // node.data += obj.data + if (obj.data) { + $.extend(this.data, obj.data); + } + // Copy all other attributes to this.data.NAME + for (name in obj) { + if ( + !NODE_ATTR_MAP[name] && + (this.tree.options.copyFunctionsToData || + !_isFunction(obj[name])) && + !NONE_NODE_DATA_MAP[name] + ) { + // node.data.NAME = obj.NAME + this.data[name] = obj[name]; + } + } + + // Fix missing key + if (this.key == null) { + // test for null OR undefined + if (this.tree.options.defaultKey) { + this.key = "" + this.tree.options.defaultKey(this); + _assert(this.key, "defaultKey() must return a unique key"); + } else { + this.key = "_" + FT._nextNodeKey++; + } + } else { + this.key = "" + this.key; // Convert to string (#217) + } + + // Fix tree.activeNode + // TODO: not elegant: we use obj.active as marker to set tree.activeNode + // when loading from a dictionary. + if (obj.active) { + _assert( + this.tree.activeNode === null, + "only one active node allowed" + ); + this.tree.activeNode = this; + } + if (obj.selected) { + // #186 + this.tree.lastSelectedNode = this; + } + // TODO: handle obj.focus = true + + // Create child nodes + cl = obj.children; + if (cl) { + if (cl.length) { + this._setChildren(cl); + } else { + // if an empty array was passed for a lazy node, keep it, in order to mark it 'loaded' + this.children = this.lazy ? [] : null; + } + } else { + this.children = null; + } + // Add to key/ref map (except for root node) + // if( parent ) { + this.tree._callHook("treeRegisterNode", this.tree, true, this); + // } + } + + FancytreeNode.prototype = /** @lends FancytreeNode# */ { + /* Return the direct child FancytreeNode with a given key, index. */ + _findDirectChild: function (ptr) { + var i, + l, + cl = this.children; + + if (cl) { + if (typeof ptr === "string") { + for (i = 0, l = cl.length; i < l; i++) { + if (cl[i].key === ptr) { + return cl[i]; + } + } + } else if (typeof ptr === "number") { + return this.children[ptr]; + } else if (ptr.parent === this) { + return ptr; + } + } + return null; + }, + // TODO: activate() + // TODO: activateSilently() + /* Internal helper called in recursive addChildren sequence.*/ + _setChildren: function (children) { + _assert( + children && (!this.children || this.children.length === 0), + "only init supported" + ); + this.children = []; + for (var i = 0, l = children.length; i < l; i++) { + this.children.push(new FancytreeNode(this, children[i])); + } + this.tree._callHook( + "treeStructureChanged", + this.tree, + "setChildren" + ); + }, + /** + * Append (or insert) a list of child nodes. + * + * @param {NodeData[]} children array of child node definitions (also single child accepted) + * @param {FancytreeNode | string | Integer} [insertBefore] child node (or key or index of such). + * If omitted, the new children are appended. + * @returns {FancytreeNode} first child added + * + * @see FancytreeNode#applyPatch + */ + addChildren: function (children, insertBefore) { + var i, + l, + pos, + origFirstChild = this.getFirstChild(), + origLastChild = this.getLastChild(), + firstNode = null, + nodeList = []; + + if ($.isPlainObject(children)) { + children = [children]; + } + if (!this.children) { + this.children = []; + } + for (i = 0, l = children.length; i < l; i++) { + nodeList.push(new FancytreeNode(this, children[i])); + } + firstNode = nodeList[0]; + if (insertBefore == null) { + this.children = this.children.concat(nodeList); + } else { + // Returns null if insertBefore is not a direct child: + insertBefore = this._findDirectChild(insertBefore); + pos = $.inArray(insertBefore, this.children); + _assert(pos >= 0, "insertBefore must be an existing child"); + // insert nodeList after children[pos] + this.children.splice.apply( + this.children, + [pos, 0].concat(nodeList) + ); + } + if (origFirstChild && !insertBefore) { + // #708: Fast path -- don't render every child of root, just the new ones! + // #723, #729: but only if it's appended to an existing child list + for (i = 0, l = nodeList.length; i < l; i++) { + nodeList[i].render(); // New nodes were never rendered before + } + // Adjust classes where status may have changed + // Has a first child + if (origFirstChild !== this.getFirstChild()) { + // Different first child -- recompute classes + origFirstChild.renderStatus(); + } + if (origLastChild !== this.getLastChild()) { + // Different last child -- recompute classes + origLastChild.renderStatus(); + } + } else if (!this.parent || this.parent.ul || this.tr) { + // render if the parent was rendered (or this is a root node) + this.render(); + } + if (this.tree.options.selectMode === 3) { + this.fixSelection3FromEndNodes(); + } + this.triggerModifyChild( + "add", + nodeList.length === 1 ? nodeList[0] : null + ); + return firstNode; + }, + /** + * Add class to node's span tag and to .extraClasses. + * + * @param {string} className class name + * + * @since 2.17 + */ + addClass: function (className) { + return this.toggleClass(className, true); + }, + /** + * Append or prepend a node, or append a child node. + * + * This a convenience function that calls addChildren() + * + * @param {NodeData} node node definition + * @param {string} [mode=child] 'before', 'after', 'firstChild', or 'child' ('over' is a synonym for 'child') + * @returns {FancytreeNode} new node + */ + addNode: function (node, mode) { + if (mode === undefined || mode === "over") { + mode = "child"; + } + switch (mode) { + case "after": + return this.getParent().addChildren( + node, + this.getNextSibling() + ); + case "before": + return this.getParent().addChildren(node, this); + case "firstChild": + // Insert before the first child if any + var insertBefore = this.children ? this.children[0] : null; + return this.addChildren(node, insertBefore); + case "child": + case "over": + return this.addChildren(node); + } + _assert(false, "Invalid mode: " + mode); + }, + /**Add child status nodes that indicate 'More...', etc. + * + * This also maintains the node's `partload` property. + * @param {boolean|object} node optional node definition. Pass `false` to remove all paging nodes. + * @param {string} [mode='child'] 'child'|firstChild' + * @since 2.15 + */ + addPagingNode: function (node, mode) { + var i, n; + + mode = mode || "child"; + if (node === false) { + for (i = this.children.length - 1; i >= 0; i--) { + n = this.children[i]; + if (n.statusNodeType === "paging") { + this.removeChild(n); + } + } + this.partload = false; + return; + } + node = $.extend( + { + title: this.tree.options.strings.moreData, + statusNodeType: "paging", + icon: false, + }, + node + ); + this.partload = true; + return this.addNode(node, mode); + }, + /** + * Append new node after this. + * + * This a convenience function that calls addNode(node, 'after') + * + * @param {NodeData} node node definition + * @returns {FancytreeNode} new node + */ + appendSibling: function (node) { + return this.addNode(node, "after"); + }, + /** + * (experimental) Apply a modification (or navigation) operation. + * + * @param {string} cmd + * @param {object} [opts] + * @see Fancytree#applyCommand + * @since 2.32 + */ + applyCommand: function (cmd, opts) { + return this.tree.applyCommand(cmd, this, opts); + }, + /** + * Modify existing child nodes. + * + * @param {NodePatch} patch + * @returns {$.Promise} + * @see FancytreeNode#addChildren + */ + applyPatch: function (patch) { + // patch [key, null] means 'remove' + if (patch === null) { + this.remove(); + return _getResolvedPromise(this); + } + // TODO: make sure that root node is not collapsed or modified + // copy (most) attributes to node.ATTR or node.data.ATTR + var name, + promise, + v, + IGNORE_MAP = { children: true, expanded: true, parent: true }; // TODO: should be global + + for (name in patch) { + if (_hasProp(patch, name)) { + v = patch[name]; + if (!IGNORE_MAP[name] && !_isFunction(v)) { + if (NODE_ATTR_MAP[name]) { + this[name] = v; + } else { + this.data[name] = v; + } + } + } + } + // Remove and/or create children + if (_hasProp(patch, "children")) { + this.removeChildren(); + if (patch.children) { + // only if not null and not empty list + // TODO: addChildren instead? + this._setChildren(patch.children); + } + // TODO: how can we APPEND or INSERT child nodes? + } + if (this.isVisible()) { + this.renderTitle(); + this.renderStatus(); + } + // Expand collapse (final step, since this may be async) + if (_hasProp(patch, "expanded")) { + promise = this.setExpanded(patch.expanded); + } else { + promise = _getResolvedPromise(this); + } + return promise; + }, + /** Collapse all sibling nodes. + * @returns {$.Promise} + */ + collapseSiblings: function () { + return this.tree._callHook("nodeCollapseSiblings", this); + }, + /** Copy this node as sibling or child of `node`. + * + * @param {FancytreeNode} node source node + * @param {string} [mode=child] 'before' | 'after' | 'child' + * @param {Function} [map] callback function(NodeData, FancytreeNode) that could modify the new node + * @returns {FancytreeNode} new + */ + copyTo: function (node, mode, map) { + return node.addNode(this.toDict(true, map), mode); + }, + /** Count direct and indirect children. + * + * @param {boolean} [deep=true] pass 'false' to only count direct children + * @returns {int} number of child nodes + */ + countChildren: function (deep) { + var cl = this.children, + i, + l, + n; + if (!cl) { + return 0; + } + n = cl.length; + if (deep !== false) { + for (i = 0, l = n; i < l; i++) { + n += cl[i].countChildren(); + } + } + return n; + }, + // TODO: deactivate() + /** Write to browser console if debugLevel >= 4 (prepending node info) + * + * @param {*} msg string or object or array of such + */ + debug: function (msg) { + if (this.tree.options.debugLevel >= 4) { + Array.prototype.unshift.call(arguments, this.toString()); + consoleApply("log", arguments); + } + }, + /** Deprecated. + * @deprecated since 2014-02-16. Use resetLazy() instead. + */ + discard: function () { + this.warn( + "FancytreeNode.discard() is deprecated since 2014-02-16. Use .resetLazy() instead." + ); + return this.resetLazy(); + }, + /** Remove DOM elements for all descendents. May be called on .collapse event + * to keep the DOM small. + * @param {boolean} [includeSelf=false] + */ + discardMarkup: function (includeSelf) { + var fn = includeSelf ? "nodeRemoveMarkup" : "nodeRemoveChildMarkup"; + this.tree._callHook(fn, this); + }, + /** Write error to browser console if debugLevel >= 1 (prepending tree info) + * + * @param {*} msg string or object or array of such + */ + error: function (msg) { + if (this.tree.options.debugLevel >= 1) { + Array.prototype.unshift.call(arguments, this.toString()); + consoleApply("error", arguments); + } + }, + /**Find all nodes that match condition (excluding self). + * + * @param {string | function(node)} match title string to search for, or a + * callback function that returns `true` if a node is matched. + * @returns {FancytreeNode[]} array of nodes (may be empty) + */ + findAll: function (match) { + match = _isFunction(match) ? match : _makeNodeTitleMatcher(match); + var res = []; + this.visit(function (n) { + if (match(n)) { + res.push(n); + } + }); + return res; + }, + /**Find first node that matches condition (excluding self). + * + * @param {string | function(node)} match title string to search for, or a + * callback function that returns `true` if a node is matched. + * @returns {FancytreeNode} matching node or null + * @see FancytreeNode#findAll + */ + findFirst: function (match) { + match = _isFunction(match) ? match : _makeNodeTitleMatcher(match); + var res = null; + this.visit(function (n) { + if (match(n)) { + res = n; + return false; + } + }); + return res; + }, + /** Find a node relative to self. + * + * @param {number|string} where The keyCode that would normally trigger this move, + * or a keyword ('down', 'first', 'last', 'left', 'parent', 'right', 'up'). + * @returns {FancytreeNode} + * @since v2.31 + */ + findRelatedNode: function (where, includeHidden) { + return this.tree.findRelatedNode(this, where, includeHidden); + }, + /* Apply selection state (internal use only) */ + _changeSelectStatusAttrs: function (state) { + var changed = false, + opts = this.tree.options, + unselectable = FT.evalOption( + "unselectable", + this, + this, + opts, + false + ), + unselectableStatus = FT.evalOption( + "unselectableStatus", + this, + this, + opts, + undefined + ); + + if (unselectable && unselectableStatus != null) { + state = unselectableStatus; + } + switch (state) { + case false: + changed = this.selected || this.partsel; + this.selected = false; + this.partsel = false; + break; + case true: + changed = !this.selected || !this.partsel; + this.selected = true; + this.partsel = true; + break; + case undefined: + changed = this.selected || !this.partsel; + this.selected = false; + this.partsel = true; + break; + default: + _assert(false, "invalid state: " + state); + } + // this.debug("fixSelection3AfterLoad() _changeSelectStatusAttrs()", state, changed); + if (changed) { + this.renderStatus(); + } + return changed; + }, + /** + * Fix selection status, after this node was (de)selected in multi-hier mode. + * This includes (de)selecting all children. + */ + fixSelection3AfterClick: function (callOpts) { + var flag = this.isSelected(); + + // this.debug("fixSelection3AfterClick()"); + + this.visit(function (node) { + node._changeSelectStatusAttrs(flag); + if (node.radiogroup) { + // #931: don't (de)select this branch + return "skip"; + } + }); + this.fixSelection3FromEndNodes(callOpts); + }, + /** + * Fix selection status for multi-hier mode. + * Only end-nodes are considered to update the descendants branch and parents. + * Should be called after this node has loaded new children or after + * children have been modified using the API. + */ + fixSelection3FromEndNodes: function (callOpts) { + var opts = this.tree.options; + + // this.debug("fixSelection3FromEndNodes()"); + _assert(opts.selectMode === 3, "expected selectMode 3"); + + // Visit all end nodes and adjust their parent's `selected` and `partsel` + // attributes. Return selection state true, false, or undefined. + function _walk(node) { + var i, + l, + child, + s, + state, + allSelected, + someSelected, + unselIgnore, + unselState, + children = node.children; + + if (children && children.length) { + // check all children recursively + allSelected = true; + someSelected = false; + + for (i = 0, l = children.length; i < l; i++) { + child = children[i]; + // the selection state of a node is not relevant; we need the end-nodes + s = _walk(child); + // if( !child.unselectableIgnore ) { + unselIgnore = FT.evalOption( + "unselectableIgnore", + child, + child, + opts, + false + ); + if (!unselIgnore) { + if (s !== false) { + someSelected = true; + } + if (s !== true) { + allSelected = false; + } + } + } + // eslint-disable-next-line no-nested-ternary + state = allSelected + ? true + : someSelected + ? undefined + : false; + } else { + // This is an end-node: simply report the status + unselState = FT.evalOption( + "unselectableStatus", + node, + node, + opts, + undefined + ); + state = unselState == null ? !!node.selected : !!unselState; + } + // #939: Keep a `partsel` flag that was explicitly set on a lazy node + if ( + node.partsel && + !node.selected && + node.lazy && + node.children == null + ) { + state = undefined; + } + node._changeSelectStatusAttrs(state); + return state; + } + _walk(this); + + // Update parent's state + this.visitParents(function (node) { + var i, + l, + child, + state, + unselIgnore, + unselState, + children = node.children, + allSelected = true, + someSelected = false; + + for (i = 0, l = children.length; i < l; i++) { + child = children[i]; + unselIgnore = FT.evalOption( + "unselectableIgnore", + child, + child, + opts, + false + ); + if (!unselIgnore) { + unselState = FT.evalOption( + "unselectableStatus", + child, + child, + opts, + undefined + ); + state = + unselState == null + ? !!child.selected + : !!unselState; + // When fixing the parents, we trust the sibling status (i.e. + // we don't recurse) + if (state || child.partsel) { + someSelected = true; + } + if (!state) { + allSelected = false; + } + } + } + // eslint-disable-next-line no-nested-ternary + state = allSelected ? true : someSelected ? undefined : false; + node._changeSelectStatusAttrs(state); + }); + }, + // TODO: focus() + /** + * Update node data. If dict contains 'children', then also replace + * the hole sub tree. + * @param {NodeData} dict + * + * @see FancytreeNode#addChildren + * @see FancytreeNode#applyPatch + */ + fromDict: function (dict) { + // copy all other attributes to this.data.xxx + for (var name in dict) { + if (NODE_ATTR_MAP[name]) { + // node.NAME = dict.NAME + this[name] = dict[name]; + } else if (name === "data") { + // node.data += dict.data + $.extend(this.data, dict.data); + } else if ( + !_isFunction(dict[name]) && + !NONE_NODE_DATA_MAP[name] + ) { + // node.data.NAME = dict.NAME + this.data[name] = dict[name]; + } + } + if (dict.children) { + // recursively set children and render + this.removeChildren(); + this.addChildren(dict.children); + } + this.renderTitle(); + /* + var children = dict.children; + if(children === undefined){ + this.data = $.extend(this.data, dict); + this.render(); + return; + } + dict = $.extend({}, dict); + dict.children = undefined; + this.data = $.extend(this.data, dict); + this.removeChildren(); + this.addChild(children); + */ + }, + /** Return the list of child nodes (undefined for unexpanded lazy nodes). + * @returns {FancytreeNode[] | undefined} + */ + getChildren: function () { + if (this.hasChildren() === undefined) { + // TODO: only required for lazy nodes? + return undefined; // Lazy node: unloaded, currently loading, or load error + } + return this.children; + }, + /** Return the first child node or null. + * @returns {FancytreeNode | null} + */ + getFirstChild: function () { + return this.children ? this.children[0] : null; + }, + /** Return the 0-based child index. + * @returns {int} + */ + getIndex: function () { + // return this.parent.children.indexOf(this); + return $.inArray(this, this.parent.children); // indexOf doesn't work in IE7 + }, + /** Return the hierarchical child index (1-based, e.g. '3.2.4'). + * @param {string} [separator="."] + * @param {int} [digits=1] + * @returns {string} + */ + getIndexHier: function (separator, digits) { + separator = separator || "."; + var s, + res = []; + $.each(this.getParentList(false, true), function (i, o) { + s = "" + (o.getIndex() + 1); + if (digits) { + // prepend leading zeroes + s = ("0000000" + s).substr(-digits); + } + res.push(s); + }); + return res.join(separator); + }, + /** Return the parent keys separated by options.keyPathSeparator, e.g. "/id_1/id_17/id_32". + * + * (Unlike `node.getPath()`, this method prepends a "/" and inverts the first argument.) + * + * @see FancytreeNode#getPath + * @param {boolean} [excludeSelf=false] + * @returns {string} + */ + getKeyPath: function (excludeSelf) { + var sep = this.tree.options.keyPathSeparator; + + return sep + this.getPath(!excludeSelf, "key", sep); + }, + /** Return the last child of this node or null. + * @returns {FancytreeNode | null} + */ + getLastChild: function () { + return this.children + ? this.children[this.children.length - 1] + : null; + }, + /** Return node depth. 0: System root node, 1: visible top-level node, 2: first sub-level, ... . + * @returns {int} + */ + getLevel: function () { + var level = 0, + dtn = this.parent; + while (dtn) { + level++; + dtn = dtn.parent; + } + return level; + }, + /** Return the successor node (under the same parent) or null. + * @returns {FancytreeNode | null} + */ + getNextSibling: function () { + // TODO: use indexOf, if available: (not in IE6) + if (this.parent) { + var i, + l, + ac = this.parent.children; + + for (i = 0, l = ac.length - 1; i < l; i++) { + // up to length-2, so next(last) = null + if (ac[i] === this) { + return ac[i + 1]; + } + } + } + return null; + }, + /** Return the parent node (null for the system root node). + * @returns {FancytreeNode | null} + */ + getParent: function () { + // TODO: return null for top-level nodes? + return this.parent; + }, + /** Return an array of all parent nodes (top-down). + * @param {boolean} [includeRoot=false] Include the invisible system root node. + * @param {boolean} [includeSelf=false] Include the node itself. + * @returns {FancytreeNode[]} + */ + getParentList: function (includeRoot, includeSelf) { + var l = [], + dtn = includeSelf ? this : this.parent; + while (dtn) { + if (includeRoot || dtn.parent) { + l.unshift(dtn); + } + dtn = dtn.parent; + } + return l; + }, + /** Return a string representing the hierachical node path, e.g. "a/b/c". + * @param {boolean} [includeSelf=true] + * @param {string | function} [part="title"] node property name or callback + * @param {string} [separator="/"] + * @returns {string} + * @since v2.31 + */ + getPath: function (includeSelf, part, separator) { + includeSelf = includeSelf !== false; + part = part || "title"; + separator = separator || "/"; + + var val, + path = [], + isFunc = _isFunction(part); + + this.visitParents(function (n) { + if (n.parent) { + val = isFunc ? part(n) : n[part]; + path.unshift(val); + } + }, includeSelf); + return path.join(separator); + }, + /** Return the predecessor node (under the same parent) or null. + * @returns {FancytreeNode | null} + */ + getPrevSibling: function () { + if (this.parent) { + var i, + l, + ac = this.parent.children; + + for (i = 1, l = ac.length; i < l; i++) { + // start with 1, so prev(first) = null + if (ac[i] === this) { + return ac[i - 1]; + } + } + } + return null; + }, + /** + * Return an array of selected descendant nodes. + * @param {boolean} [stopOnParents=false] only return the topmost selected + * node (useful with selectMode 3) + * @returns {FancytreeNode[]} + */ + getSelectedNodes: function (stopOnParents) { + var nodeList = []; + this.visit(function (node) { + if (node.selected) { + nodeList.push(node); + if (stopOnParents === true) { + return "skip"; // stop processing this branch + } + } + }); + return nodeList; + }, + /** Return true if node has children. Return undefined if not sure, i.e. the node is lazy and not yet loaded). + * @returns {boolean | undefined} + */ + hasChildren: function () { + if (this.lazy) { + if (this.children == null) { + // null or undefined: Not yet loaded + return undefined; + } else if (this.children.length === 0) { + // Loaded, but response was empty + return false; + } else if ( + this.children.length === 1 && + this.children[0].isStatusNode() + ) { + // Currently loading or load error + return undefined; + } + return true; + } + return !!(this.children && this.children.length); + }, + /** + * Return true if node has `className` defined in .extraClasses. + * + * @param {string} className class name (separate multiple classes by space) + * @returns {boolean} + * + * @since 2.32 + */ + hasClass: function (className) { + return ( + (" " + (this.extraClasses || "") + " ").indexOf( + " " + className + " " + ) >= 0 + ); + }, + /** Return true if node has keyboard focus. + * @returns {boolean} + */ + hasFocus: function () { + return this.tree.hasFocus() && this.tree.focusNode === this; + }, + /** Write to browser console if debugLevel >= 3 (prepending node info) + * + * @param {*} msg string or object or array of such + */ + info: function (msg) { + if (this.tree.options.debugLevel >= 3) { + Array.prototype.unshift.call(arguments, this.toString()); + consoleApply("info", arguments); + } + }, + /** Return true if node is active (see also FancytreeNode#isSelected). + * @returns {boolean} + */ + isActive: function () { + return this.tree.activeNode === this; + }, + /** Return true if node is vertically below `otherNode`, i.e. rendered in a subsequent row. + * @param {FancytreeNode} otherNode + * @returns {boolean} + * @since 2.28 + */ + isBelowOf: function (otherNode) { + return this.getIndexHier(".", 5) > otherNode.getIndexHier(".", 5); + }, + /** Return true if node is a direct child of otherNode. + * @param {FancytreeNode} otherNode + * @returns {boolean} + */ + isChildOf: function (otherNode) { + return this.parent && this.parent === otherNode; + }, + /** Return true, if node is a direct or indirect sub node of otherNode. + * @param {FancytreeNode} otherNode + * @returns {boolean} + */ + isDescendantOf: function (otherNode) { + if (!otherNode || otherNode.tree !== this.tree) { + return false; + } + var p = this.parent; + while (p) { + if (p === otherNode) { + return true; + } + if (p === p.parent) { + $.error("Recursive parent link: " + p); + } + p = p.parent; + } + return false; + }, + /** Return true if node is expanded. + * @returns {boolean} + */ + isExpanded: function () { + return !!this.expanded; + }, + /** Return true if node is the first node of its parent's children. + * @returns {boolean} + */ + isFirstSibling: function () { + var p = this.parent; + return !p || p.children[0] === this; + }, + /** Return true if node is a folder, i.e. has the node.folder attribute set. + * @returns {boolean} + */ + isFolder: function () { + return !!this.folder; + }, + /** Return true if node is the last node of its parent's children. + * @returns {boolean} + */ + isLastSibling: function () { + var p = this.parent; + return !p || p.children[p.children.length - 1] === this; + }, + /** Return true if node is lazy (even if data was already loaded) + * @returns {boolean} + */ + isLazy: function () { + return !!this.lazy; + }, + /** Return true if node is lazy and loaded. For non-lazy nodes always return true. + * @returns {boolean} + */ + isLoaded: function () { + return !this.lazy || this.hasChildren() !== undefined; // Also checks if the only child is a status node + }, + /** Return true if children are currently beeing loaded, i.e. a Ajax request is pending. + * @returns {boolean} + */ + isLoading: function () { + return !!this._isLoading; + }, + /* + * @deprecated since v2.4.0: Use isRootNode() instead + */ + isRoot: function () { + return this.isRootNode(); + }, + /** Return true if node is partially selected (tri-state). + * @returns {boolean} + * @since 2.23 + */ + isPartsel: function () { + return !this.selected && !!this.partsel; + }, + /** (experimental) Return true if this is partially loaded. + * @returns {boolean} + * @since 2.15 + */ + isPartload: function () { + return !!this.partload; + }, + /** Return true if this is the (invisible) system root node. + * @returns {boolean} + * @since 2.4 + */ + isRootNode: function () { + return this.tree.rootNode === this; + }, + /** Return true if node is selected, i.e. has a checkmark set (see also FancytreeNode#isActive). + * @returns {boolean} + */ + isSelected: function () { + return !!this.selected; + }, + /** Return true if this node is a temporarily generated system node like + * 'loading', 'paging', or 'error' (node.statusNodeType contains the type). + * @returns {boolean} + */ + isStatusNode: function () { + return !!this.statusNodeType; + }, + /** Return true if this node is a status node of type 'paging'. + * @returns {boolean} + * @since 2.15 + */ + isPagingNode: function () { + return this.statusNodeType === "paging"; + }, + /** Return true if this a top level node, i.e. a direct child of the (invisible) system root node. + * @returns {boolean} + * @since 2.4 + */ + isTopLevel: function () { + return this.tree.rootNode === this.parent; + }, + /** Return true if node is lazy and not yet loaded. For non-lazy nodes always return false. + * @returns {boolean} + */ + isUndefined: function () { + return this.hasChildren() === undefined; // also checks if the only child is a status node + }, + /** Return true if all parent nodes are expanded. Note: this does not check + * whether the node is scrolled into the visible part of the screen. + * @returns {boolean} + */ + isVisible: function () { + var i, + l, + n, + hasFilter = this.tree.enableFilter, + parents = this.getParentList(false, false); + + // TODO: check $(n.span).is(":visible") + // i.e. return false for nodes (but not parents) that are hidden + // by a filter + if (hasFilter && !this.match && !this.subMatchCount) { + // this.debug( "isVisible: HIDDEN (" + hasFilter + ", " + this.match + ", " + this.match + ")" ); + return false; + } + + for (i = 0, l = parents.length; i < l; i++) { + n = parents[i]; + + if (!n.expanded) { + // this.debug("isVisible: HIDDEN (parent collapsed)"); + return false; + } + // if (hasFilter && !n.match && !n.subMatchCount) { + // this.debug("isVisible: HIDDEN (" + hasFilter + ", " + this.match + ", " + this.match + ")"); + // return false; + // } + } + // this.debug("isVisible: VISIBLE"); + return true; + }, + /** Deprecated. + * @deprecated since 2014-02-16: use load() instead. + */ + lazyLoad: function (discard) { + $.error( + "FancytreeNode.lazyLoad() is deprecated since 2014-02-16. Use .load() instead." + ); + }, + /** + * Load all children of a lazy node if neccessary. The <i>expanded</i> state is maintained. + * @param {boolean} [forceReload=false] Pass true to discard any existing nodes before. Otherwise this method does nothing if the node was already loaded. + * @returns {$.Promise} + */ + load: function (forceReload) { + var res, + source, + self = this, + wasExpanded = this.isExpanded(); + + _assert(this.isLazy(), "load() requires a lazy node"); + // _assert( forceReload || this.isUndefined(), "Pass forceReload=true to re-load a lazy node" ); + if (!forceReload && !this.isUndefined()) { + return _getResolvedPromise(this); + } + if (this.isLoaded()) { + this.resetLazy(); // also collapses + } + // This method is also called by setExpanded() and loadKeyPath(), so we + // have to avoid recursion. + source = this.tree._triggerNodeEvent("lazyLoad", this); + if (source === false) { + // #69 + return _getResolvedPromise(this); + } + _assert( + typeof source !== "boolean", + "lazyLoad event must return source in data.result" + ); + res = this.tree._callHook("nodeLoadChildren", this, source); + if (wasExpanded) { + this.expanded = true; + res.always(function () { + self.render(); + }); + } else { + res.always(function () { + self.renderStatus(); // fix expander icon to 'loaded' + }); + } + return res; + }, + /** Expand all parents and optionally scroll into visible area as neccessary. + * Promise is resolved, when lazy loading and animations are done. + * @param {object} [opts] passed to `setExpanded()`. + * Defaults to {noAnimation: false, noEvents: false, scrollIntoView: true} + * @returns {$.Promise} + */ + makeVisible: function (opts) { + var i, + self = this, + deferreds = [], + dfd = new $.Deferred(), + parents = this.getParentList(false, false), + len = parents.length, + effects = !(opts && opts.noAnimation === true), + scroll = !(opts && opts.scrollIntoView === false); + + // Expand bottom-up, so only the top node is animated + for (i = len - 1; i >= 0; i--) { + // self.debug("pushexpand" + parents[i]); + deferreds.push(parents[i].setExpanded(true, opts)); + } + $.when.apply($, deferreds).done(function () { + // All expands have finished + // self.debug("expand DONE", scroll); + if (scroll) { + self.scrollIntoView(effects).done(function () { + // self.debug("scroll DONE"); + dfd.resolve(); + }); + } else { + dfd.resolve(); + } + }); + return dfd.promise(); + }, + /** Move this node to targetNode. + * @param {FancytreeNode} targetNode + * @param {string} mode <pre> + * 'child': append this node as last child of targetNode. + * This is the default. To be compatble with the D'n'd + * hitMode, we also accept 'over'. + * 'firstChild': add this node as first child of targetNode. + * 'before': add this node as sibling before targetNode. + * 'after': add this node as sibling after targetNode.</pre> + * @param {function} [map] optional callback(FancytreeNode) to allow modifcations + */ + moveTo: function (targetNode, mode, map) { + if (mode === undefined || mode === "over") { + mode = "child"; + } else if (mode === "firstChild") { + if (targetNode.children && targetNode.children.length) { + mode = "before"; + targetNode = targetNode.children[0]; + } else { + mode = "child"; + } + } + var pos, + tree = this.tree, + prevParent = this.parent, + targetParent = + mode === "child" ? targetNode : targetNode.parent; + + if (this === targetNode) { + return; + } else if (!this.parent) { + $.error("Cannot move system root"); + } else if (targetParent.isDescendantOf(this)) { + $.error("Cannot move a node to its own descendant"); + } + if (targetParent !== prevParent) { + prevParent.triggerModifyChild("remove", this); + } + // Unlink this node from current parent + if (this.parent.children.length === 1) { + if (this.parent === targetParent) { + return; // #258 + } + this.parent.children = this.parent.lazy ? [] : null; + this.parent.expanded = false; + } else { + pos = $.inArray(this, this.parent.children); + _assert(pos >= 0, "invalid source parent"); + this.parent.children.splice(pos, 1); + } + // Remove from source DOM parent + // if(this.parent.ul){ + // this.parent.ul.removeChild(this.li); + // } + + // Insert this node to target parent's child list + this.parent = targetParent; + if (targetParent.hasChildren()) { + switch (mode) { + case "child": + // Append to existing target children + targetParent.children.push(this); + break; + case "before": + // Insert this node before target node + pos = $.inArray(targetNode, targetParent.children); + _assert(pos >= 0, "invalid target parent"); + targetParent.children.splice(pos, 0, this); + break; + case "after": + // Insert this node after target node + pos = $.inArray(targetNode, targetParent.children); + _assert(pos >= 0, "invalid target parent"); + targetParent.children.splice(pos + 1, 0, this); + break; + default: + $.error("Invalid mode " + mode); + } + } else { + targetParent.children = [this]; + } + // Parent has no <ul> tag yet: + // if( !targetParent.ul ) { + // // This is the parent's first child: create UL tag + // // (Hidden, because it will be + // targetParent.ul = document.createElement("ul"); + // targetParent.ul.style.display = "none"; + // targetParent.li.appendChild(targetParent.ul); + // } + // // Issue 319: Add to target DOM parent (only if node was already rendered(expanded)) + // if(this.li){ + // targetParent.ul.appendChild(this.li); + // } + + // Let caller modify the nodes + if (map) { + targetNode.visit(map, true); + } + if (targetParent === prevParent) { + targetParent.triggerModifyChild("move", this); + } else { + // prevParent.triggerModifyChild("remove", this); + targetParent.triggerModifyChild("add", this); + } + // Handle cross-tree moves + if (tree !== targetNode.tree) { + // Fix node.tree for all source nodes + // _assert(false, "Cross-tree move is not yet implemented."); + this.warn("Cross-tree moveTo is experimental!"); + this.visit(function (n) { + // TODO: fix selection state and activation, ... + n.tree = targetNode.tree; + }, true); + } + + // A collaposed node won't re-render children, so we have to remove it manually + // if( !targetParent.expanded ){ + // prevParent.ul.removeChild(this.li); + // } + tree._callHook("treeStructureChanged", tree, "moveTo"); + + // Update HTML markup + if (!prevParent.isDescendantOf(targetParent)) { + prevParent.render(); + } + if ( + !targetParent.isDescendantOf(prevParent) && + targetParent !== prevParent + ) { + targetParent.render(); + } + // TODO: fix selection state + // TODO: fix active state + + /* + var tree = this.tree; + var opts = tree.options; + var pers = tree.persistence; + + // Always expand, if it's below minExpandLevel + // tree.logDebug ("%s._addChildNode(%o), l=%o", this, ftnode, ftnode.getLevel()); + if ( opts.minExpandLevel >= ftnode.getLevel() ) { + // tree.logDebug ("Force expand for %o", ftnode); + this.bExpanded = true; + } + + // In multi-hier mode, update the parents selection state + // DT issue #82: only if not initializing, because the children may not exist yet + // if( !ftnode.data.isStatusNode() && opts.selectMode==3 && !isInitializing ) + // ftnode._fixSelectionState(); + + // In multi-hier mode, update the parents selection state + if( ftnode.bSelected && opts.selectMode==3 ) { + var p = this; + while( p ) { + if( !p.hasSubSel ) + p._setSubSel(true); + p = p.parent; + } + } + // render this node and the new child + if ( tree.bEnableUpdate ) + this.render(); + return ftnode; + */ + }, + /** Set focus relative to this node and optionally activate. + * + * 'left' collapses the node if it is expanded, or move to the parent + * otherwise. + * 'right' expands the node if it is collapsed, or move to the first + * child otherwise. + * + * @param {string|number} where 'down', 'first', 'last', 'left', 'parent', 'right', or 'up'. + * (Alternatively the keyCode that would normally trigger this move, + * e.g. `$.ui.keyCode.LEFT` = 'left'. + * @param {boolean} [activate=true] + * @returns {$.Promise} + */ + navigate: function (where, activate) { + var node, + KC = $.ui.keyCode; + + // Handle optional expand/collapse action for LEFT/RIGHT + switch (where) { + case "left": + case KC.LEFT: + if (this.expanded) { + return this.setExpanded(false); + } + break; + case "right": + case KC.RIGHT: + if (!this.expanded && (this.children || this.lazy)) { + return this.setExpanded(); + } + break; + } + // Otherwise activate or focus the related node + node = this.findRelatedNode(where); + if (node) { + // setFocus/setActive will scroll later (if autoScroll is specified) + try { + node.makeVisible({ scrollIntoView: false }); + } catch (e) {} // #272 + if (activate === false) { + node.setFocus(); + return _getResolvedPromise(); + } + return node.setActive(); + } + this.warn("Could not find related node '" + where + "'."); + return _getResolvedPromise(); + }, + /** + * Remove this node (not allowed for system root). + */ + remove: function () { + return this.parent.removeChild(this); + }, + /** + * Remove childNode from list of direct children. + * @param {FancytreeNode} childNode + */ + removeChild: function (childNode) { + return this.tree._callHook("nodeRemoveChild", this, childNode); + }, + /** + * Remove all child nodes and descendents. This converts the node into a leaf.<br> + * If this was a lazy node, it is still considered 'loaded'; call node.resetLazy() + * in order to trigger lazyLoad on next expand. + */ + removeChildren: function () { + return this.tree._callHook("nodeRemoveChildren", this); + }, + /** + * Remove class from node's span tag and .extraClasses. + * + * @param {string} className class name + * + * @since 2.17 + */ + removeClass: function (className) { + return this.toggleClass(className, false); + }, + /** + * This method renders and updates all HTML markup that is required + * to display this node in its current state.<br> + * Note: + * <ul> + * <li>It should only be neccessary to call this method after the node object + * was modified by direct access to its properties, because the common + * API methods (node.setTitle(), moveTo(), addChildren(), remove(), ...) + * already handle this. + * <li> {@link FancytreeNode#renderTitle} and {@link FancytreeNode#renderStatus} + * are implied. If changes are more local, calling only renderTitle() or + * renderStatus() may be sufficient and faster. + * </ul> + * + * @param {boolean} [force=false] re-render, even if html markup was already created + * @param {boolean} [deep=false] also render all descendants, even if parent is collapsed + */ + render: function (force, deep) { + return this.tree._callHook("nodeRender", this, force, deep); + }, + /** Create HTML markup for the node's outer `<span>` (expander, checkbox, icon, and title). + * Implies {@link FancytreeNode#renderStatus}. + * @see Fancytree_Hooks#nodeRenderTitle + */ + renderTitle: function () { + return this.tree._callHook("nodeRenderTitle", this); + }, + /** Update element's CSS classes according to node state. + * @see Fancytree_Hooks#nodeRenderStatus + */ + renderStatus: function () { + return this.tree._callHook("nodeRenderStatus", this); + }, + /** + * (experimental) Replace this node with `source`. + * (Currently only available for paging nodes.) + * @param {NodeData[]} source List of child node definitions + * @since 2.15 + */ + replaceWith: function (source) { + var res, + parent = this.parent, + pos = $.inArray(this, parent.children), + self = this; + + _assert( + this.isPagingNode(), + "replaceWith() currently requires a paging status node" + ); + + res = this.tree._callHook("nodeLoadChildren", this, source); + res.done(function (data) { + // New nodes are currently children of `this`. + var children = self.children; + // Prepend newly loaded child nodes to `this` + // Move new children after self + for (i = 0; i < children.length; i++) { + children[i].parent = parent; + } + parent.children.splice.apply( + parent.children, + [pos + 1, 0].concat(children) + ); + + // Remove self + self.children = null; + self.remove(); + // Redraw new nodes + parent.render(); + // TODO: set node.partload = false if this was tha last paging node? + // parent.addPagingNode(false); + }).fail(function () { + self.setExpanded(); + }); + return res; + // $.error("Not implemented: replaceWith()"); + }, + /** + * Remove all children, collapse, and set the lazy-flag, so that the lazyLoad + * event is triggered on next expand. + */ + resetLazy: function () { + this.removeChildren(); + this.expanded = false; + this.lazy = true; + this.children = undefined; + this.renderStatus(); + }, + /** Schedule activity for delayed execution (cancel any pending request). + * scheduleAction('cancel') will only cancel a pending request (if any). + * @param {string} mode + * @param {number} ms + */ + scheduleAction: function (mode, ms) { + if (this.tree.timer) { + clearTimeout(this.tree.timer); + this.tree.debug("clearTimeout(%o)", this.tree.timer); + } + this.tree.timer = null; + var self = this; // required for closures + switch (mode) { + case "cancel": + // Simply made sure that timer was cleared + break; + case "expand": + this.tree.timer = setTimeout(function () { + self.tree.debug("setTimeout: trigger expand"); + self.setExpanded(true); + }, ms); + break; + case "activate": + this.tree.timer = setTimeout(function () { + self.tree.debug("setTimeout: trigger activate"); + self.setActive(true); + }, ms); + break; + default: + $.error("Invalid mode " + mode); + } + // this.tree.debug("setTimeout(%s, %s): %s", mode, ms, this.tree.timer); + }, + /** + * + * @param {boolean | PlainObject} [effects=false] animation options. + * @param {object} [options=null] {topNode: null, effects: ..., parent: ...} this node will remain visible in + * any case, even if `this` is outside the scroll pane. + * @returns {$.Promise} + */ + scrollIntoView: function (effects, options) { + if (options !== undefined && _isNode(options)) { + throw Error( + "scrollIntoView() with 'topNode' option is deprecated since 2014-05-08. Use 'options.topNode' instead." + ); + } + // The scroll parent is typically the plain tree's <UL> container. + // For ext-table, we choose the nearest parent that has `position: relative` + // and `overflow` set. + // (This default can be overridden by the local or global `scrollParent` option.) + var opts = $.extend( + { + effects: + effects === true + ? { duration: 200, queue: false } + : effects, + scrollOfs: this.tree.options.scrollOfs, + scrollParent: this.tree.options.scrollParent, + topNode: null, + }, + options + ), + $scrollParent = opts.scrollParent, + $container = this.tree.$container, + overflowY = $container.css("overflow-y"); + + if (!$scrollParent) { + if (this.tree.tbody) { + $scrollParent = $container.scrollParent(); + } else if (overflowY === "scroll" || overflowY === "auto") { + $scrollParent = $container; + } else { + // #922 plain tree in a non-fixed-sized UL scrolls inside its parent + $scrollParent = $container.scrollParent(); + } + } else if (!$scrollParent.jquery) { + // Make sure we have a jQuery object + $scrollParent = $($scrollParent); + } + if ( + $scrollParent[0] === document || + $scrollParent[0] === document.body + ) { + // `document` may be returned by $().scrollParent(), if nothing is found, + // but would not work: (see #894) + this.debug( + "scrollIntoView(): normalizing scrollParent to 'window':", + $scrollParent[0] + ); + $scrollParent = $(window); + } + // eslint-disable-next-line one-var + var topNodeY, + nodeY, + horzScrollbarHeight, + containerOffsetTop, + dfd = new $.Deferred(), + self = this, + nodeHeight = $(this.span).height(), + topOfs = opts.scrollOfs.top || 0, + bottomOfs = opts.scrollOfs.bottom || 0, + containerHeight = $scrollParent.height(), + scrollTop = $scrollParent.scrollTop(), + $animateTarget = $scrollParent, + isParentWindow = $scrollParent[0] === window, + topNode = opts.topNode || null, + newScrollTop = null; + + // this.debug("scrollIntoView(), scrollTop=" + scrollTop, opts.scrollOfs); + // _assert($(this.span).is(":visible"), "scrollIntoView node is invisible"); // otherwise we cannot calc offsets + if (this.isRootNode() || !this.isVisible()) { + // We cannot calc offsets for hidden elements + this.info("scrollIntoView(): node is invisible."); + return _getResolvedPromise(); + } + if (isParentWindow) { + nodeY = $(this.span).offset().top; + topNodeY = + topNode && topNode.span ? $(topNode.span).offset().top : 0; + $animateTarget = $("html,body"); + } else { + _assert( + $scrollParent[0] !== document && + $scrollParent[0] !== document.body, + "scrollParent should be a simple element or `window`, not document or body." + ); + + containerOffsetTop = $scrollParent.offset().top; + nodeY = + $(this.span).offset().top - containerOffsetTop + scrollTop; // relative to scroll parent + topNodeY = topNode + ? $(topNode.span).offset().top - + containerOffsetTop + + scrollTop + : 0; + horzScrollbarHeight = Math.max( + 0, + $scrollParent.innerHeight() - $scrollParent[0].clientHeight + ); + containerHeight -= horzScrollbarHeight; + } + + // this.debug(" scrollIntoView(), nodeY=" + nodeY + ", containerHeight=" + containerHeight); + if (nodeY < scrollTop + topOfs) { + // Node is above visible container area + newScrollTop = nodeY - topOfs; + // this.debug(" scrollIntoView(), UPPER newScrollTop=" + newScrollTop); + } else if ( + nodeY + nodeHeight > + scrollTop + containerHeight - bottomOfs + ) { + newScrollTop = nodeY + nodeHeight - containerHeight + bottomOfs; + // this.debug(" scrollIntoView(), LOWER newScrollTop=" + newScrollTop); + // If a topNode was passed, make sure that it is never scrolled + // outside the upper border + if (topNode) { + _assert( + topNode.isRootNode() || topNode.isVisible(), + "topNode must be visible" + ); + if (topNodeY < newScrollTop) { + newScrollTop = topNodeY - topOfs; + // this.debug(" scrollIntoView(), TOP newScrollTop=" + newScrollTop); + } + } + } + + if (newScrollTop === null) { + dfd.resolveWith(this); + } else { + // this.debug(" scrollIntoView(), SET newScrollTop=" + newScrollTop); + if (opts.effects) { + opts.effects.complete = function () { + dfd.resolveWith(self); + }; + $animateTarget.stop(true).animate( + { + scrollTop: newScrollTop, + }, + opts.effects + ); + } else { + $animateTarget[0].scrollTop = newScrollTop; + dfd.resolveWith(this); + } + } + return dfd.promise(); + }, + + /**Activate this node. + * + * The `cell` option requires the ext-table and ext-ariagrid extensions. + * + * @param {boolean} [flag=true] pass false to deactivate + * @param {object} [opts] additional options. Defaults to {noEvents: false, noFocus: false, cell: null} + * @returns {$.Promise} + */ + setActive: function (flag, opts) { + return this.tree._callHook("nodeSetActive", this, flag, opts); + }, + /**Expand or collapse this node. Promise is resolved, when lazy loading and animations are done. + * @param {boolean} [flag=true] pass false to collapse + * @param {object} [opts] additional options. Defaults to {noAnimation: false, noEvents: false} + * @returns {$.Promise} + */ + setExpanded: function (flag, opts) { + return this.tree._callHook("nodeSetExpanded", this, flag, opts); + }, + /**Set keyboard focus to this node. + * @param {boolean} [flag=true] pass false to blur + * @see Fancytree#setFocus + */ + setFocus: function (flag) { + return this.tree._callHook("nodeSetFocus", this, flag); + }, + /**Select this node, i.e. check the checkbox. + * @param {boolean} [flag=true] pass false to deselect + * @param {object} [opts] additional options. Defaults to {noEvents: false, p + * propagateDown: null, propagateUp: null, callback: null } + */ + setSelected: function (flag, opts) { + return this.tree._callHook("nodeSetSelected", this, flag, opts); + }, + /**Mark a lazy node as 'error', 'loading', 'nodata', or 'ok'. + * @param {string} status 'error'|'loading'|'nodata'|'ok' + * @param {string} [message] + * @param {string} [details] + */ + setStatus: function (status, message, details) { + return this.tree._callHook( + "nodeSetStatus", + this, + status, + message, + details + ); + }, + /**Rename this node. + * @param {string} title + */ + setTitle: function (title) { + this.title = title; + this.renderTitle(); + this.triggerModify("rename"); + }, + /**Sort child list by title. + * @param {function} [cmp] custom compare function(a, b) that returns -1, 0, or 1 (defaults to sort by title). + * @param {boolean} [deep=false] pass true to sort all descendant nodes + */ + sortChildren: function (cmp, deep) { + var i, + l, + cl = this.children; + + if (!cl) { + return; + } + cmp = + cmp || + function (a, b) { + var x = a.title.toLowerCase(), + y = b.title.toLowerCase(); + + // eslint-disable-next-line no-nested-ternary + return x === y ? 0 : x > y ? 1 : -1; + }; + cl.sort(cmp); + if (deep) { + for (i = 0, l = cl.length; i < l; i++) { + if (cl[i].children) { + cl[i].sortChildren(cmp, "$norender$"); + } + } + } + if (deep !== "$norender$") { + this.render(); + } + this.triggerModifyChild("sort"); + }, + /** Convert node (or whole branch) into a plain object. + * + * The result is compatible with node.addChildren(). + * + * @param {boolean} [recursive=false] include child nodes + * @param {function} [callback] callback(dict, node) is called for every node, in order to allow modifications. + * Return `false` to ignore this node or `"skip"` to include this node without its children. + * @returns {NodeData} + */ + toDict: function (recursive, callback) { + var i, + l, + node, + res, + dict = {}, + self = this; + + $.each(NODE_ATTRS, function (i, a) { + if (self[a] || self[a] === false) { + dict[a] = self[a]; + } + }); + if (!$.isEmptyObject(this.data)) { + dict.data = $.extend({}, this.data); + if ($.isEmptyObject(dict.data)) { + delete dict.data; + } + } + if (callback) { + res = callback(dict, self); + if (res === false) { + return false; // Don't include this node nor its children + } + if (res === "skip") { + recursive = false; // Include this node, but not the children + } + } + if (recursive) { + if (_isArray(this.children)) { + dict.children = []; + for (i = 0, l = this.children.length; i < l; i++) { + node = this.children[i]; + if (!node.isStatusNode()) { + res = node.toDict(true, callback); + if (res !== false) { + dict.children.push(res); + } + } + } + } + } + return dict; + }, + /** + * Set, clear, or toggle class of node's span tag and .extraClasses. + * + * @param {string} className class name (separate multiple classes by space) + * @param {boolean} [flag] true/false to add/remove class. If omitted, class is toggled. + * @returns {boolean} true if a class was added + * + * @since 2.17 + */ + toggleClass: function (value, flag) { + var className, + hasClass, + rnotwhite = /\S+/g, + classNames = value.match(rnotwhite) || [], + i = 0, + wasAdded = false, + statusElem = this[this.tree.statusClassPropName], + curClasses = " " + (this.extraClasses || "") + " "; + + // this.info("toggleClass('" + value + "', " + flag + ")", curClasses); + // Modify DOM element directly if it already exists + if (statusElem) { + $(statusElem).toggleClass(value, flag); + } + // Modify node.extraClasses to make this change persistent + // Toggle if flag was not passed + while ((className = classNames[i++])) { + hasClass = curClasses.indexOf(" " + className + " ") >= 0; + flag = flag === undefined ? !hasClass : !!flag; + if (flag) { + if (!hasClass) { + curClasses += className + " "; + wasAdded = true; + } + } else { + while (curClasses.indexOf(" " + className + " ") > -1) { + curClasses = curClasses.replace( + " " + className + " ", + " " + ); + } + } + } + this.extraClasses = _trim(curClasses); + // this.info("-> toggleClass('" + value + "', " + flag + "): '" + this.extraClasses + "'"); + return wasAdded; + }, + /** Flip expanded status. */ + toggleExpanded: function () { + return this.tree._callHook("nodeToggleExpanded", this); + }, + /** Flip selection status. */ + toggleSelected: function () { + return this.tree._callHook("nodeToggleSelected", this); + }, + toString: function () { + return "FancytreeNode@" + this.key + "[title='" + this.title + "']"; + // return "<FancytreeNode(#" + this.key + ", '" + this.title + "')>"; + }, + /** + * Trigger `modifyChild` event on a parent to signal that a child was modified. + * @param {string} operation Type of change: 'add', 'remove', 'rename', 'move', 'data', ... + * @param {FancytreeNode} [childNode] + * @param {object} [extra] + */ + triggerModifyChild: function (operation, childNode, extra) { + var data, + modifyChild = this.tree.options.modifyChild; + + if (modifyChild) { + if (childNode && childNode.parent !== this) { + $.error( + "childNode " + childNode + " is not a child of " + this + ); + } + data = { + node: this, + tree: this.tree, + operation: operation, + childNode: childNode || null, + }; + if (extra) { + $.extend(data, extra); + } + modifyChild({ type: "modifyChild" }, data); + } + }, + /** + * Trigger `modifyChild` event on node.parent(!). + * @param {string} operation Type of change: 'add', 'remove', 'rename', 'move', 'data', ... + * @param {object} [extra] + */ + triggerModify: function (operation, extra) { + this.parent.triggerModifyChild(operation, this, extra); + }, + /** Call fn(node) for all child nodes in hierarchical order (depth-first).<br> + * Stop iteration, if fn() returns false. Skip current branch, if fn() returns "skip".<br> + * Return false if iteration was stopped. + * + * @param {function} fn the callback function. + * Return false to stop iteration, return "skip" to skip this node and + * its children only. + * @param {boolean} [includeSelf=false] + * @returns {boolean} + */ + visit: function (fn, includeSelf) { + var i, + l, + res = true, + children = this.children; + + if (includeSelf === true) { + res = fn(this); + if (res === false || res === "skip") { + return res; + } + } + if (children) { + for (i = 0, l = children.length; i < l; i++) { + res = children[i].visit(fn, true); + if (res === false) { + break; + } + } + } + return res; + }, + /** Call fn(node) for all child nodes and recursively load lazy children.<br> + * <b>Note:</b> If you need this method, you probably should consider to review + * your architecture! Recursivley loading nodes is a perfect way for lazy + * programmers to flood the server with requests ;-) + * + * @param {function} [fn] optional callback function. + * Return false to stop iteration, return "skip" to skip this node and + * its children only. + * @param {boolean} [includeSelf=false] + * @returns {$.Promise} + * @since 2.4 + */ + visitAndLoad: function (fn, includeSelf, _recursion) { + var dfd, + res, + loaders, + node = this; + + // node.debug("visitAndLoad"); + if (fn && includeSelf === true) { + res = fn(node); + if (res === false || res === "skip") { + return _recursion ? res : _getResolvedPromise(); + } + } + if (!node.children && !node.lazy) { + return _getResolvedPromise(); + } + dfd = new $.Deferred(); + loaders = []; + // node.debug("load()..."); + node.load().done(function () { + // node.debug("load()... done."); + for (var i = 0, l = node.children.length; i < l; i++) { + res = node.children[i].visitAndLoad(fn, true, true); + if (res === false) { + dfd.reject(); + break; + } else if (res !== "skip") { + loaders.push(res); // Add promise to the list + } + } + $.when.apply(this, loaders).then(function () { + dfd.resolve(); + }); + }); + return dfd.promise(); + }, + /** Call fn(node) for all parent nodes, bottom-up, including invisible system root.<br> + * Stop iteration, if fn() returns false.<br> + * Return false if iteration was stopped. + * + * @param {function} fn the callback function. + * Return false to stop iteration, return "skip" to skip this node and children only. + * @param {boolean} [includeSelf=false] + * @returns {boolean} + */ + visitParents: function (fn, includeSelf) { + // Visit parent nodes (bottom up) + if (includeSelf && fn(this) === false) { + return false; + } + var p = this.parent; + while (p) { + if (fn(p) === false) { + return false; + } + p = p.parent; + } + return true; + }, + /** Call fn(node) for all sibling nodes.<br> + * Stop iteration, if fn() returns false.<br> + * Return false if iteration was stopped. + * + * @param {function} fn the callback function. + * Return false to stop iteration. + * @param {boolean} [includeSelf=false] + * @returns {boolean} + */ + visitSiblings: function (fn, includeSelf) { + var i, + l, + n, + ac = this.parent.children; + + for (i = 0, l = ac.length; i < l; i++) { + n = ac[i]; + if (includeSelf || n !== this) { + if (fn(n) === false) { + return false; + } + } + } + return true; + }, + /** Write warning to browser console if debugLevel >= 2 (prepending node info) + * + * @param {*} msg string or object or array of such + */ + warn: function (msg) { + if (this.tree.options.debugLevel >= 2) { + Array.prototype.unshift.call(arguments, this.toString()); + consoleApply("warn", arguments); + } + }, + }; + + /****************************************************************************** + * Fancytree + */ + /** + * Construct a new tree object. + * + * @class Fancytree + * @classdesc The controller behind a fancytree. + * This class also contains 'hook methods': see {@link Fancytree_Hooks}. + * + * @param {Widget} widget + * + * @property {string} _id Automatically generated unique tree instance ID, e.g. "1". + * @property {string} _ns Automatically generated unique tree namespace, e.g. ".fancytree-1". + * @property {FancytreeNode} activeNode Currently active node or null. + * @property {string} ariaPropName Property name of FancytreeNode that contains the element which will receive the aria attributes. + * Typically "li", but "tr" for table extension. + * @property {jQueryObject} $container Outer `<ul>` element (or `<table>` element for ext-table). + * @property {jQueryObject} $div A jQuery object containing the element used to instantiate the tree widget (`widget.element`) + * @property {object|array} columns Recommended place to store shared column meta data. @since 2.27 + * @property {object} data Metadata, i.e. properties that may be passed to `source` in addition to a children array. + * @property {object} ext Hash of all active plugin instances. + * @property {FancytreeNode} focusNode Currently focused node or null. + * @property {FancytreeNode} lastSelectedNode Used to implement selectMode 1 (single select) + * @property {string} nodeContainerAttrName Property name of FancytreeNode that contains the outer element of single nodes. + * Typically "li", but "tr" for table extension. + * @property {FancytreeOptions} options Current options, i.e. default options + options passed to constructor. + * @property {FancytreeNode} rootNode Invisible system root node. + * @property {string} statusClassPropName Property name of FancytreeNode that contains the element which will receive the status classes. + * Typically "span", but "tr" for table extension. + * @property {object} types Map for shared type specific meta data, used with node.type attribute. @since 2.27 + * @property {object} viewport See ext-vieport. @since v2.31 + * @property {object} widget Base widget instance. + */ + function Fancytree(widget) { + this.widget = widget; + this.$div = widget.element; + this.options = widget.options; + if (this.options) { + if (this.options.lazyload !== undefined) { + $.error( + "The 'lazyload' event is deprecated since 2014-02-25. Use 'lazyLoad' (with uppercase L) instead." + ); + } + if (this.options.loaderror !== undefined) { + $.error( + "The 'loaderror' event was renamed since 2014-07-03. Use 'loadError' (with uppercase E) instead." + ); + } + if (this.options.fx !== undefined) { + $.error( + "The 'fx' option was replaced by 'toggleEffect' since 2014-11-30." + ); + } + if (this.options.removeNode !== undefined) { + $.error( + "The 'removeNode' event was replaced by 'modifyChild' since 2.20 (2016-09-10)." + ); + } + } + this.ext = {}; // Active extension instances + this.types = {}; + this.columns = {}; + // allow to init tree.data.foo from <div data-foo=''> + this.data = _getElementDataAsDict(this.$div); + // TODO: use widget.uuid instead? + this._id = "" + (this.options.treeId || $.ui.fancytree._nextId++); + // TODO: use widget.eventNamespace instead? + this._ns = ".fancytree-" + this._id; // append for namespaced events + this.activeNode = null; + this.focusNode = null; + this._hasFocus = null; + this._tempCache = {}; + this._lastMousedownNode = null; + this._enableUpdate = true; + this.lastSelectedNode = null; + this.systemFocusElement = null; + this.lastQuicksearchTerm = ""; + this.lastQuicksearchTime = 0; + this.viewport = null; // ext-grid + + this.statusClassPropName = "span"; + this.ariaPropName = "li"; + this.nodeContainerAttrName = "li"; + + // Remove previous markup if any + this.$div.find(">ul.fancytree-container").remove(); + + // Create a node without parent. + var fakeParent = { tree: this }, + $ul; + this.rootNode = new FancytreeNode(fakeParent, { + title: "root", + key: "root_" + this._id, + children: null, + expanded: true, + }); + this.rootNode.parent = null; + + // Create root markup + $ul = $("<ul>", { + id: "ft-id-" + this._id, + class: "ui-fancytree fancytree-container fancytree-plain", + }).appendTo(this.$div); + this.$container = $ul; + this.rootNode.ul = $ul[0]; + + if (this.options.debugLevel == null) { + this.options.debugLevel = FT.debugLevel; + } + // // Add container to the TAB chain + // // See http://www.w3.org/TR/wai-aria-practices/#focus_activedescendant + // // #577: Allow to set tabindex to "0", "-1" and "" + // this.$container.attr("tabindex", this.options.tabindex); + + // if( this.options.rtl ) { + // this.$container.attr("DIR", "RTL").addClass("fancytree-rtl"); + // // }else{ + // // this.$container.attr("DIR", null).removeClass("fancytree-rtl"); + // } + // if(this.options.aria){ + // this.$container.attr("role", "tree"); + // if( this.options.selectMode !== 1 ) { + // this.$container.attr("aria-multiselectable", true); + // } + // } + } + + Fancytree.prototype = /** @lends Fancytree# */ { + /* Return a context object that can be re-used for _callHook(). + * @param {Fancytree | FancytreeNode | EventData} obj + * @param {Event} originalEvent + * @param {Object} extra + * @returns {EventData} + */ + _makeHookContext: function (obj, originalEvent, extra) { + var ctx, tree; + if (obj.node !== undefined) { + // obj is already a context object + if (originalEvent && obj.originalEvent !== originalEvent) { + $.error("invalid args"); + } + ctx = obj; + } else if (obj.tree) { + // obj is a FancytreeNode + tree = obj.tree; + ctx = { + node: obj, + tree: tree, + widget: tree.widget, + options: tree.widget.options, + originalEvent: originalEvent, + typeInfo: tree.types[obj.type] || {}, + }; + } else if (obj.widget) { + // obj is a Fancytree + ctx = { + node: null, + tree: obj, + widget: obj.widget, + options: obj.widget.options, + originalEvent: originalEvent, + }; + } else { + $.error("invalid args"); + } + if (extra) { + $.extend(ctx, extra); + } + return ctx; + }, + /* Trigger a hook function: funcName(ctx, [...]). + * + * @param {string} funcName + * @param {Fancytree|FancytreeNode|EventData} contextObject + * @param {any} [_extraArgs] optional additional arguments + * @returns {any} + */ + _callHook: function (funcName, contextObject, _extraArgs) { + var ctx = this._makeHookContext(contextObject), + fn = this[funcName], + args = Array.prototype.slice.call(arguments, 2); + if (!_isFunction(fn)) { + $.error("_callHook('" + funcName + "') is not a function"); + } + args.unshift(ctx); + // this.debug("_hook", funcName, ctx.node && ctx.node.toString() || ctx.tree.toString(), args); + return fn.apply(this, args); + }, + _setExpiringValue: function (key, value, ms) { + this._tempCache[key] = { + value: value, + expire: Date.now() + (+ms || 50), + }; + }, + _getExpiringValue: function (key) { + var entry = this._tempCache[key]; + if (entry && entry.expire > Date.now()) { + return entry.value; + } + delete this._tempCache[key]; + return null; + }, + /* Check if this tree has extension `name` enabled. + * + * @param {string} name name of the required extension + */ + _usesExtension: function (name) { + return $.inArray(name, this.options.extensions) >= 0; + }, + /* Check if current extensions dependencies are met and throw an error if not. + * + * This method may be called inside the `treeInit` hook for custom extensions. + * + * @param {string} name name of the required extension + * @param {boolean} [required=true] pass `false` if the extension is optional, but we want to check for order if it is present + * @param {boolean} [before] `true` if `name` must be included before this, `false` otherwise (use `null` if order doesn't matter) + * @param {string} [message] optional error message (defaults to a descriptve error message) + */ + _requireExtension: function (name, required, before, message) { + if (before != null) { + before = !!before; + } + var thisName = this._local.name, + extList = this.options.extensions, + isBefore = + $.inArray(name, extList) < $.inArray(thisName, extList), + isMissing = required && this.ext[name] == null, + badOrder = !isMissing && before != null && before !== isBefore; + + _assert( + thisName && thisName !== name, + "invalid or same name '" + thisName + "' (require yourself?)" + ); + + if (isMissing || badOrder) { + if (!message) { + if (isMissing || required) { + message = + "'" + + thisName + + "' extension requires '" + + name + + "'"; + if (badOrder) { + message += + " to be registered " + + (before ? "before" : "after") + + " itself"; + } + } else { + message = + "If used together, `" + + name + + "` must be registered " + + (before ? "before" : "after") + + " `" + + thisName + + "`"; + } + } + $.error(message); + return false; + } + return true; + }, + /** Activate node with a given key and fire focus and activate events. + * + * A previously activated node will be deactivated. + * If activeVisible option is set, all parents will be expanded as necessary. + * Pass key = false, to deactivate the current node only. + * @param {string} key + * @param {object} [opts] additional options. Defaults to {noEvents: false, noFocus: false} + * @returns {FancytreeNode} activated node (null, if not found) + */ + activateKey: function (key, opts) { + var node = this.getNodeByKey(key); + if (node) { + node.setActive(true, opts); + } else if (this.activeNode) { + this.activeNode.setActive(false, opts); + } + return node; + }, + /** (experimental) Add child status nodes that indicate 'More...', .... + * @param {boolean|object} node optional node definition. Pass `false` to remove all paging nodes. + * @param {string} [mode='append'] 'child'|firstChild' + * @since 2.15 + */ + addPagingNode: function (node, mode) { + return this.rootNode.addPagingNode(node, mode); + }, + /** + * (experimental) Apply a modification (or navigation) operation. + * + * Valid commands: + * - 'moveUp', 'moveDown' + * - 'indent', 'outdent' + * - 'remove' + * - 'edit', 'addChild', 'addSibling': (reqires ext-edit extension) + * - 'cut', 'copy', 'paste': (use an internal singleton 'clipboard') + * - 'down', 'first', 'last', 'left', 'parent', 'right', 'up': navigate + * + * @param {string} cmd + * @param {FancytreeNode} [node=active_node] + * @param {object} [opts] Currently unused + * + * @since 2.32 + */ + applyCommand: function (cmd, node, opts_) { + var // clipboard, + refNode; + // opts = $.extend( + // { setActive: true, clipboard: CLIPBOARD }, + // opts_ + // ); + + node = node || this.getActiveNode(); + // clipboard = opts.clipboard; + + switch (cmd) { + // Sorting and indentation: + case "moveUp": + refNode = node.getPrevSibling(); + if (refNode) { + node.moveTo(refNode, "before"); + node.setActive(); + } + break; + case "moveDown": + refNode = node.getNextSibling(); + if (refNode) { + node.moveTo(refNode, "after"); + node.setActive(); + } + break; + case "indent": + refNode = node.getPrevSibling(); + if (refNode) { + node.moveTo(refNode, "child"); + refNode.setExpanded(); + node.setActive(); + } + break; + case "outdent": + if (!node.isTopLevel()) { + node.moveTo(node.getParent(), "after"); + node.setActive(); + } + break; + // Remove: + case "remove": + refNode = node.getPrevSibling() || node.getParent(); + node.remove(); + if (refNode) { + refNode.setActive(); + } + break; + // Add, edit (requires ext-edit): + case "addChild": + node.editCreateNode("child", ""); + break; + case "addSibling": + node.editCreateNode("after", ""); + break; + case "rename": + node.editStart(); + break; + // Simple clipboard simulation: + // case "cut": + // clipboard = { mode: cmd, data: node }; + // break; + // case "copy": + // clipboard = { + // mode: cmd, + // data: node.toDict(function(d, n) { + // delete d.key; + // }), + // }; + // break; + // case "clear": + // clipboard = null; + // break; + // case "paste": + // if (clipboard.mode === "cut") { + // // refNode = node.getPrevSibling(); + // clipboard.data.moveTo(node, "child"); + // clipboard.data.setActive(); + // } else if (clipboard.mode === "copy") { + // node.addChildren(clipboard.data).setActive(); + // } + // break; + // Navigation commands: + case "down": + case "first": + case "last": + case "left": + case "parent": + case "right": + case "up": + return node.navigate(cmd); + default: + $.error("Unhandled command: '" + cmd + "'"); + } + }, + /** (experimental) Modify existing data model. + * + * @param {Array} patchList array of [key, NodePatch] arrays + * @returns {$.Promise} resolved, when all patches have been applied + * @see TreePatch + */ + applyPatch: function (patchList) { + var dfd, + i, + p2, + key, + patch, + node, + patchCount = patchList.length, + deferredList = []; + + for (i = 0; i < patchCount; i++) { + p2 = patchList[i]; + _assert( + p2.length === 2, + "patchList must be an array of length-2-arrays" + ); + key = p2[0]; + patch = p2[1]; + node = key === null ? this.rootNode : this.getNodeByKey(key); + if (node) { + dfd = new $.Deferred(); + deferredList.push(dfd); + node.applyPatch(patch).always(_makeResolveFunc(dfd, node)); + } else { + this.warn("could not find node with key '" + key + "'"); + } + } + // Return a promise that is resolved, when ALL patches were applied + return $.when.apply($, deferredList).promise(); + }, + /* TODO: implement in dnd extension + cancelDrag: function() { + var dd = $.ui.ddmanager.current; + if(dd){ + dd.cancel(); + } + }, + */ + /** Remove all nodes. + * @since 2.14 + */ + clear: function (source) { + this._callHook("treeClear", this); + }, + /** Return the number of nodes. + * @returns {integer} + */ + count: function () { + return this.rootNode.countChildren(); + }, + /** Write to browser console if debugLevel >= 4 (prepending tree name) + * + * @param {*} msg string or object or array of such + */ + debug: function (msg) { + if (this.options.debugLevel >= 4) { + Array.prototype.unshift.call(arguments, this.toString()); + consoleApply("log", arguments); + } + }, + /** Destroy this widget, restore previous markup and cleanup resources. + * + * @since 2.34 + */ + destroy: function () { + this.widget.destroy(); + }, + /** Enable (or disable) the tree control. + * + * @param {boolean} [flag=true] pass false to disable + * @since 2.30 + */ + enable: function (flag) { + if (flag === false) { + this.widget.disable(); + } else { + this.widget.enable(); + } + }, + /** Temporarily suppress rendering to improve performance on bulk-updates. + * + * @param {boolean} flag + * @returns {boolean} previous status + * @since 2.19 + */ + enableUpdate: function (flag) { + flag = flag !== false; + if (!!this._enableUpdate === !!flag) { + return flag; + } + this._enableUpdate = flag; + if (flag) { + this.debug("enableUpdate(true): redraw "); //, this._dirtyRoots); + this._callHook("treeStructureChanged", this, "enableUpdate"); + this.render(); + } else { + // this._dirtyRoots = null; + this.debug("enableUpdate(false)..."); + } + return !flag; // return previous value + }, + /** Write error to browser console if debugLevel >= 1 (prepending tree info) + * + * @param {*} msg string or object or array of such + */ + error: function (msg) { + if (this.options.debugLevel >= 1) { + Array.prototype.unshift.call(arguments, this.toString()); + consoleApply("error", arguments); + } + }, + /** Expand (or collapse) all parent nodes. + * + * This convenience method uses `tree.visit()` and `tree.setExpanded()` + * internally. + * + * @param {boolean} [flag=true] pass false to collapse + * @param {object} [opts] passed to setExpanded() + * @since 2.30 + */ + expandAll: function (flag, opts) { + var prev = this.enableUpdate(false); + + flag = flag !== false; + this.visit(function (node) { + if ( + node.hasChildren() !== false && + node.isExpanded() !== flag + ) { + node.setExpanded(flag, opts); + } + }); + this.enableUpdate(prev); + }, + /**Find all nodes that matches condition. + * + * @param {string | function(node)} match title string to search for, or a + * callback function that returns `true` if a node is matched. + * @returns {FancytreeNode[]} array of nodes (may be empty) + * @see FancytreeNode#findAll + * @since 2.12 + */ + findAll: function (match) { + return this.rootNode.findAll(match); + }, + /**Find first node that matches condition. + * + * @param {string | function(node)} match title string to search for, or a + * callback function that returns `true` if a node is matched. + * @returns {FancytreeNode} matching node or null + * @see FancytreeNode#findFirst + * @since 2.12 + */ + findFirst: function (match) { + return this.rootNode.findFirst(match); + }, + /** Find the next visible node that starts with `match`, starting at `startNode` + * and wrap-around at the end. + * + * @param {string|function} match + * @param {FancytreeNode} [startNode] defaults to first node + * @returns {FancytreeNode} matching node or null + */ + findNextNode: function (match, startNode) { + //, visibleOnly) { + var res = null, + firstNode = this.getFirstChild(); + + match = + typeof match === "string" + ? _makeNodeTitleStartMatcher(match) + : match; + startNode = startNode || firstNode; + + function _checkNode(n) { + // console.log("_check " + n) + if (match(n)) { + res = n; + } + if (res || n === startNode) { + return false; + } + } + this.visitRows(_checkNode, { + start: startNode, + includeSelf: false, + }); + // Wrap around search + if (!res && startNode !== firstNode) { + this.visitRows(_checkNode, { + start: firstNode, + includeSelf: true, + }); + } + return res; + }, + /** Find a node relative to another node. + * + * @param {FancytreeNode} node + * @param {string|number} where 'down', 'first', 'last', 'left', 'parent', 'right', or 'up'. + * (Alternatively the keyCode that would normally trigger this move, + * e.g. `$.ui.keyCode.LEFT` = 'left'. + * @param {boolean} [includeHidden=false] Not yet implemented + * @returns {FancytreeNode|null} + * @since v2.31 + */ + findRelatedNode: function (node, where, includeHidden) { + var res = null, + KC = $.ui.keyCode; + + switch (where) { + case "parent": + case KC.BACKSPACE: + if (node.parent && node.parent.parent) { + res = node.parent; + } + break; + case "first": + case KC.HOME: + // First visible node + this.visit(function (n) { + if (n.isVisible()) { + res = n; + return false; + } + }); + break; + case "last": + case KC.END: + this.visit(function (n) { + // last visible node + if (n.isVisible()) { + res = n; + } + }); + break; + case "left": + case KC.LEFT: + if (node.expanded) { + node.setExpanded(false); + } else if (node.parent && node.parent.parent) { + res = node.parent; + } + break; + case "right": + case KC.RIGHT: + if (!node.expanded && (node.children || node.lazy)) { + node.setExpanded(); + res = node; + } else if (node.children && node.children.length) { + res = node.children[0]; + } + break; + case "up": + case KC.UP: + this.visitRows( + function (n) { + res = n; + return false; + }, + { start: node, reverse: true, includeSelf: false } + ); + break; + case "down": + case KC.DOWN: + this.visitRows( + function (n) { + res = n; + return false; + }, + { start: node, includeSelf: false } + ); + break; + default: + this.tree.warn("Unknown relation '" + where + "'."); + } + return res; + }, + // TODO: fromDict + /** + * Generate INPUT elements that can be submitted with html forms. + * + * In selectMode 3 only the topmost selected nodes are considered, unless + * `opts.stopOnParents: false` is passed. + * + * @example + * // Generate input elements for active and selected nodes + * tree.generateFormElements(); + * // Generate input elements selected nodes, using a custom `name` attribute + * tree.generateFormElements("cust_sel", false); + * // Generate input elements using a custom filter + * tree.generateFormElements(true, true, { filter: function(node) { + * return node.isSelected() && node.data.yes; + * }}); + * + * @param {boolean | string} [selected=true] Pass false to disable, pass a string to override the field name (default: 'ft_ID[]') + * @param {boolean | string} [active=true] Pass false to disable, pass a string to override the field name (default: 'ft_ID_active') + * @param {object} [opts] default { filter: null, stopOnParents: true } + */ + generateFormElements: function (selected, active, opts) { + opts = opts || {}; + + var nodeList, + selectedName = + typeof selected === "string" + ? selected + : "ft_" + this._id + "[]", + activeName = + typeof active === "string" + ? active + : "ft_" + this._id + "_active", + id = "fancytree_result_" + this._id, + $result = $("#" + id), + stopOnParents = + this.options.selectMode === 3 && + opts.stopOnParents !== false; + + if ($result.length) { + $result.empty(); + } else { + $result = $("<div>", { + id: id, + }) + .hide() + .insertAfter(this.$container); + } + if (active !== false && this.activeNode) { + $result.append( + $("<input>", { + type: "radio", + name: activeName, + value: this.activeNode.key, + checked: true, + }) + ); + } + function _appender(node) { + $result.append( + $("<input>", { + type: "checkbox", + name: selectedName, + value: node.key, + checked: true, + }) + ); + } + if (opts.filter) { + this.visit(function (node) { + var res = opts.filter(node); + if (res === "skip") { + return res; + } + if (res !== false) { + _appender(node); + } + }); + } else if (selected !== false) { + nodeList = this.getSelectedNodes(stopOnParents); + $.each(nodeList, function (idx, node) { + _appender(node); + }); + } + }, + /** + * Return the currently active node or null. + * @returns {FancytreeNode} + */ + getActiveNode: function () { + return this.activeNode; + }, + /** Return the first top level node if any (not the invisible root node). + * @returns {FancytreeNode | null} + */ + getFirstChild: function () { + return this.rootNode.getFirstChild(); + }, + /** + * Return node that has keyboard focus or null. + * @returns {FancytreeNode} + */ + getFocusNode: function () { + return this.focusNode; + }, + /** + * Return current option value. + * (Note: this is the preferred variant of `$().fancytree("option", "KEY")`) + * + * @param {string} name option name (may contain '.') + * @returns {any} + */ + getOption: function (optionName) { + return this.widget.option(optionName); + }, + /** + * Return node with a given key or null if not found. + * + * @param {string} key + * @param {FancytreeNode} [searchRoot] only search below this node + * @returns {FancytreeNode | null} + */ + getNodeByKey: function (key, searchRoot) { + // Search the DOM by element ID (assuming this is faster than traversing all nodes). + var el, match; + // TODO: use tree.keyMap if available + // TODO: check opts.generateIds === true + if (!searchRoot) { + el = document.getElementById(this.options.idPrefix + key); + if (el) { + return el.ftnode ? el.ftnode : null; + } + } + // Not found in the DOM, but still may be in an unrendered part of tree + searchRoot = searchRoot || this.rootNode; + match = null; + key = "" + key; // Convert to string (#1005) + searchRoot.visit(function (node) { + if (node.key === key) { + match = node; + return false; // Stop iteration + } + }, true); + return match; + }, + /** Return the invisible system root node. + * @returns {FancytreeNode} + */ + getRootNode: function () { + return this.rootNode; + }, + /** + * Return an array of selected nodes. + * + * Note: you cannot send this result via Ajax directly. Instead the + * node object need to be converted to plain objects, for example + * by using `$.map()` and `node.toDict()`. + * @param {boolean} [stopOnParents=false] only return the topmost selected + * node (useful with selectMode 3) + * @returns {FancytreeNode[]} + */ + getSelectedNodes: function (stopOnParents) { + return this.rootNode.getSelectedNodes(stopOnParents); + }, + /** Return true if the tree control has keyboard focus + * @returns {boolean} + */ + hasFocus: function () { + // var ae = document.activeElement, + // hasFocus = !!( + // ae && $(ae).closest(".fancytree-container").length + // ); + + // if (hasFocus !== !!this._hasFocus) { + // this.warn( + // "hasFocus(): fix inconsistent container state, now: " + + // hasFocus + // ); + // this._hasFocus = hasFocus; + // this.$container.toggleClass("fancytree-treefocus", hasFocus); + // } + // return hasFocus; + return !!this._hasFocus; + }, + /** Write to browser console if debugLevel >= 3 (prepending tree name) + * @param {*} msg string or object or array of such + */ + info: function (msg) { + if (this.options.debugLevel >= 3) { + Array.prototype.unshift.call(arguments, this.toString()); + consoleApply("info", arguments); + } + }, + /** Return true if any node is currently beeing loaded, i.e. a Ajax request is pending. + * @returns {boolean} + * @since 2.32 + */ + isLoading: function () { + var res = false; + + this.rootNode.visit(function (n) { + // also visit rootNode + if (n._isLoading || n._requestId) { + res = true; + return false; + } + }, true); + return res; + }, + /* + TODO: isInitializing: function() { + return ( this.phase=="init" || this.phase=="postInit" ); + }, + TODO: isReloading: function() { + return ( this.phase=="init" || this.phase=="postInit" ) && this.options.persist && this.persistence.cookiesFound; + }, + TODO: isUserEvent: function() { + return ( this.phase=="userEvent" ); + }, + */ + + /** + * Make sure that a node with a given ID is loaded, by traversing - and + * loading - its parents. This method is meant for lazy hierarchies. + * A callback is executed for every node as we go. + * @example + * // Resolve using node.key: + * tree.loadKeyPath("/_3/_23/_26/_27", function(node, status){ + * if(status === "loaded") { + * console.log("loaded intermediate node " + node); + * }else if(status === "ok") { + * node.activate(); + * } + * }); + * // Use deferred promise: + * tree.loadKeyPath("/_3/_23/_26/_27").progress(function(data){ + * if(data.status === "loaded") { + * console.log("loaded intermediate node " + data.node); + * }else if(data.status === "ok") { + * node.activate(); + * } + * }).done(function(){ + * ... + * }); + * // Custom path segment resolver: + * tree.loadKeyPath("/321/431/21/2", { + * matchKey: function(node, key){ + * return node.data.refKey === key; + * }, + * callback: function(node, status){ + * if(status === "loaded") { + * console.log("loaded intermediate node " + node); + * }else if(status === "ok") { + * node.activate(); + * } + * } + * }); + * @param {string | string[]} keyPathList one or more key paths (e.g. '/3/2_1/7') + * @param {function | object} optsOrCallback callback(node, status) is called for every visited node ('loading', 'loaded', 'ok', 'error'). + * Pass an object to define custom key matchers for the path segments: {callback: function, matchKey: function}. + * @returns {$.Promise} + */ + loadKeyPath: function (keyPathList, optsOrCallback) { + var callback, + i, + path, + self = this, + dfd = new $.Deferred(), + parent = this.getRootNode(), + sep = this.options.keyPathSeparator, + pathSegList = [], + opts = $.extend({}, optsOrCallback); + + // Prepare options + if (typeof optsOrCallback === "function") { + callback = optsOrCallback; + } else if (optsOrCallback && optsOrCallback.callback) { + callback = optsOrCallback.callback; + } + opts.callback = function (ctx, node, status) { + if (callback) { + callback.call(ctx, node, status); + } + dfd.notifyWith(ctx, [{ node: node, status: status }]); + }; + if (opts.matchKey == null) { + opts.matchKey = function (node, key) { + return node.key === key; + }; + } + // Convert array of path strings to array of segment arrays + if (!_isArray(keyPathList)) { + keyPathList = [keyPathList]; + } + for (i = 0; i < keyPathList.length; i++) { + path = keyPathList[i]; + // strip leading slash + if (path.charAt(0) === sep) { + path = path.substr(1); + } + // segListMap[path] = { parent: parent, segList: path.split(sep) }; + pathSegList.push(path.split(sep)); + // targetList.push({ parent: parent, segList: path.split(sep)/* , path: path*/}); + } + // The timeout forces async behavior always (even if nodes are all loaded) + // This way a potential progress() event will fire. + setTimeout(function () { + self._loadKeyPathImpl(dfd, opts, parent, pathSegList).done( + function () { + dfd.resolve(); + } + ); + }, 0); + return dfd.promise(); + }, + /* + * Resolve a list of paths, relative to one parent node. + */ + _loadKeyPathImpl: function (dfd, opts, parent, pathSegList) { + var deferredList, + i, + key, + node, + nodeKey, + remain, + remainMap, + tmpParent, + segList, + subDfd, + self = this; + + function __findChild(parent, key) { + // console.log("__findChild", key, parent); + var i, + l, + cl = parent.children; + + if (cl) { + for (i = 0, l = cl.length; i < l; i++) { + if (opts.matchKey(cl[i], key)) { + return cl[i]; + } + } + } + return null; + } + + // console.log("_loadKeyPathImpl, parent=", parent, ", pathSegList=", pathSegList); + + // Pass 1: + // Handle all path segments for nodes that are already loaded. + // Collect distinct top-most lazy nodes in a map. + // Note that we can use node.key to de-dupe entries, even if a custom matcher would + // look for other node attributes. + // map[node.key] => {node: node, pathList: [list of remaining rest-paths]} + remainMap = {}; + + for (i = 0; i < pathSegList.length; i++) { + segList = pathSegList[i]; + // target = targetList[i]; + + // Traverse and pop path segments (i.e. keys), until we hit a lazy, unloaded node + tmpParent = parent; + while (segList.length) { + key = segList.shift(); + node = __findChild(tmpParent, key); + if (!node) { + this.warn( + "loadKeyPath: key not found: " + + key + + " (parent: " + + tmpParent + + ")" + ); + opts.callback(this, key, "error"); + break; + } else if (segList.length === 0) { + opts.callback(this, node, "ok"); + break; + } else if (!node.lazy || node.hasChildren() !== undefined) { + opts.callback(this, node, "loaded"); + tmpParent = node; + } else { + opts.callback(this, node, "loaded"); + key = node.key; //target.segList.join(sep); + if (remainMap[key]) { + remainMap[key].pathSegList.push(segList); + } else { + remainMap[key] = { + parent: node, + pathSegList: [segList], + }; + } + break; + } + } + } + // console.log("_loadKeyPathImpl AFTER pass 1, remainMap=", remainMap); + + // Now load all lazy nodes and continue iteration for remaining paths + deferredList = []; + + // Avoid jshint warning 'Don't make functions within a loop.': + function __lazyload(dfd, parent, pathSegList) { + // console.log("__lazyload", parent, "pathSegList=", pathSegList); + opts.callback(self, parent, "loading"); + parent + .load() + .done(function () { + self._loadKeyPathImpl + .call(self, dfd, opts, parent, pathSegList) + .always(_makeResolveFunc(dfd, self)); + }) + .fail(function (errMsg) { + self.warn("loadKeyPath: error loading lazy " + parent); + opts.callback(self, node, "error"); + dfd.rejectWith(self); + }); + } + // remainMap contains parent nodes, each with a list of relative sub-paths. + // We start loading all of them now, and pass the the list to each loader. + for (nodeKey in remainMap) { + if (_hasProp(remainMap, nodeKey)) { + remain = remainMap[nodeKey]; + // console.log("for(): remain=", remain, "remainMap=", remainMap); + // key = remain.segList.shift(); + // node = __findChild(remain.parent, key); + // if (node == null) { // #576 + // // Issue #576, refactored for v2.27: + // // The root cause was, that sometimes the wrong parent was used here + // // to find the next segment. + // // Falling back to getNodeByKey() was a hack that no longer works if a custom + // // matcher is used, because we cannot assume that a single segment-key is unique + // // throughout the tree. + // self.error("loadKeyPath: error loading child by key '" + key + "' (parent: " + target.parent + ")", target); + // // node = self.getNodeByKey(key); + // continue; + // } + subDfd = new $.Deferred(); + deferredList.push(subDfd); + __lazyload(subDfd, remain.parent, remain.pathSegList); + } + } + // Return a promise that is resolved, when ALL paths were loaded + return $.when.apply($, deferredList).promise(); + }, + /** Re-fire beforeActivate, activate, and (optional) focus events. + * Calling this method in the `init` event, will activate the node that + * was marked 'active' in the source data, and optionally set the keyboard + * focus. + * @param [setFocus=false] + */ + reactivate: function (setFocus) { + var res, + node = this.activeNode; + + if (!node) { + return _getResolvedPromise(); + } + this.activeNode = null; // Force re-activating + res = node.setActive(true, { noFocus: true }); + if (setFocus) { + node.setFocus(); + } + return res; + }, + /** Reload tree from source and return a promise. + * @param [source] optional new source (defaults to initial source data) + * @returns {$.Promise} + */ + reload: function (source) { + this._callHook("treeClear", this); + return this._callHook("treeLoad", this, source); + }, + /**Render tree (i.e. create DOM elements for all top-level nodes). + * @param {boolean} [force=false] create DOM elemnts, even if parent is collapsed + * @param {boolean} [deep=false] + */ + render: function (force, deep) { + return this.rootNode.render(force, deep); + }, + /**(De)select all nodes. + * @param {boolean} [flag=true] + * @since 2.28 + */ + selectAll: function (flag) { + this.visit(function (node) { + node.setSelected(flag); + }); + }, + // TODO: selectKey: function(key, select) + // TODO: serializeArray: function(stopOnParents) + /** + * @param {boolean} [flag=true] + */ + setFocus: function (flag) { + return this._callHook("treeSetFocus", this, flag); + }, + /** + * Set current option value. + * (Note: this is the preferred variant of `$().fancytree("option", "KEY", VALUE)`) + * @param {string} name option name (may contain '.') + * @param {any} new value + */ + setOption: function (optionName, value) { + return this.widget.option(optionName, value); + }, + /** + * Call console.time() when in debug mode (verbose >= 4). + * + * @param {string} label + */ + debugTime: function (label) { + if (this.options.debugLevel >= 4) { + window.console.time(this + " - " + label); + } + }, + /** + * Call console.timeEnd() when in debug mode (verbose >= 4). + * + * @param {string} label + */ + debugTimeEnd: function (label) { + if (this.options.debugLevel >= 4) { + window.console.timeEnd(this + " - " + label); + } + }, + /** + * Return all nodes as nested list of {@link NodeData}. + * + * @param {boolean} [includeRoot=false] Returns the hidden system root node (and its children) + * @param {function} [callback] callback(dict, node) is called for every node, in order to allow modifications. + * Return `false` to ignore this node or "skip" to include this node without its children. + * @returns {Array | object} + * @see FancytreeNode#toDict + */ + toDict: function (includeRoot, callback) { + var res = this.rootNode.toDict(true, callback); + return includeRoot ? res : res.children; + }, + /* Implicitly called for string conversions. + * @returns {string} + */ + toString: function () { + return "Fancytree@" + this._id; + // return "<Fancytree(#" + this._id + ")>"; + }, + /* _trigger a widget event with additional node ctx. + * @see EventData + */ + _triggerNodeEvent: function (type, node, originalEvent, extra) { + // this.debug("_trigger(" + type + "): '" + ctx.node.title + "'", ctx); + var ctx = this._makeHookContext(node, originalEvent, extra), + res = this.widget._trigger(type, originalEvent, ctx); + if (res !== false && ctx.result !== undefined) { + return ctx.result; + } + return res; + }, + /* _trigger a widget event with additional tree data. */ + _triggerTreeEvent: function (type, originalEvent, extra) { + // this.debug("_trigger(" + type + ")", ctx); + var ctx = this._makeHookContext(this, originalEvent, extra), + res = this.widget._trigger(type, originalEvent, ctx); + + if (res !== false && ctx.result !== undefined) { + return ctx.result; + } + return res; + }, + /** Call fn(node) for all nodes in hierarchical order (depth-first). + * + * @param {function} fn the callback function. + * Return false to stop iteration, return "skip" to skip this node and children only. + * @returns {boolean} false, if the iterator was stopped. + */ + visit: function (fn) { + return this.rootNode.visit(fn, false); + }, + /** Call fn(node) for all nodes in vertical order, top down (or bottom up).<br> + * Stop iteration, if fn() returns false.<br> + * Return false if iteration was stopped. + * + * @param {function} fn the callback function. + * Return false to stop iteration, return "skip" to skip this node and children only. + * @param {object} [options] + * Defaults: + * {start: First top node, reverse: false, includeSelf: true, includeHidden: false} + * @returns {boolean} false if iteration was cancelled + * @since 2.28 + */ + visitRows: function (fn, opts) { + if (!this.rootNode.hasChildren()) { + return false; + } + if (opts && opts.reverse) { + delete opts.reverse; + return this._visitRowsUp(fn, opts); + } + opts = opts || {}; + + var i, + nextIdx, + parent, + res, + siblings, + siblingOfs = 0, + skipFirstNode = opts.includeSelf === false, + includeHidden = !!opts.includeHidden, + checkFilter = !includeHidden && this.enableFilter, + node = opts.start || this.rootNode.children[0]; + + parent = node.parent; + while (parent) { + // visit siblings + siblings = parent.children; + nextIdx = siblings.indexOf(node) + siblingOfs; + _assert( + nextIdx >= 0, + "Could not find " + + node + + " in parent's children: " + + parent + ); + + for (i = nextIdx; i < siblings.length; i++) { + node = siblings[i]; + if (checkFilter && !node.match && !node.subMatchCount) { + continue; + } + if (!skipFirstNode && fn(node) === false) { + return false; + } + skipFirstNode = false; + // Dive into node's child nodes + if ( + node.children && + node.children.length && + (includeHidden || node.expanded) + ) { + // Disable warning: Functions declared within loops referencing an outer + // scoped variable may lead to confusing semantics: + /*jshint -W083 */ + res = node.visit(function (n) { + if (checkFilter && !n.match && !n.subMatchCount) { + return "skip"; + } + if (fn(n) === false) { + return false; + } + if (!includeHidden && n.children && !n.expanded) { + return "skip"; + } + }, false); + /*jshint +W083 */ + if (res === false) { + return false; + } + } + } + // Visit parent nodes (bottom up) + node = parent; + parent = parent.parent; + siblingOfs = 1; // + } + return true; + }, + /* Call fn(node) for all nodes in vertical order, bottom up. + */ + _visitRowsUp: function (fn, opts) { + var children, + idx, + parent, + includeHidden = !!opts.includeHidden, + node = opts.start || this.rootNode.children[0]; + + while (true) { + parent = node.parent; + children = parent.children; + + if (children[0] === node) { + // If this is already the first sibling, goto parent + node = parent; + if (!node.parent) { + break; // first node of the tree + } + children = parent.children; + } else { + // Otherwise, goto prev. sibling + idx = children.indexOf(node); + node = children[idx - 1]; + // If the prev. sibling has children, follow down to last descendant + while ( + // See: https://github.com/eslint/eslint/issues/11302 + // eslint-disable-next-line no-unmodified-loop-condition + (includeHidden || node.expanded) && + node.children && + node.children.length + ) { + children = node.children; + parent = node; + node = children[children.length - 1]; + } + } + // Skip invisible + if (!includeHidden && !node.isVisible()) { + continue; + } + if (fn(node) === false) { + return false; + } + } + }, + /** Write warning to browser console if debugLevel >= 2 (prepending tree info) + * + * @param {*} msg string or object or array of such + */ + warn: function (msg) { + if (this.options.debugLevel >= 2) { + Array.prototype.unshift.call(arguments, this.toString()); + consoleApply("warn", arguments); + } + }, + }; + + /** + * These additional methods of the {@link Fancytree} class are 'hook functions' + * that can be used and overloaded by extensions. + * + * @see [writing extensions](https://github.com/mar10/fancytree/wiki/TutorialExtensions) + * @mixin Fancytree_Hooks + */ + $.extend( + Fancytree.prototype, + /** @lends Fancytree_Hooks# */ + { + /** Default handling for mouse click events. + * + * @param {EventData} ctx + */ + nodeClick: function (ctx) { + var activate, + expand, + // event = ctx.originalEvent, + targetType = ctx.targetType, + node = ctx.node; + + // this.debug("ftnode.onClick(" + event.type + "): ftnode:" + this + ", button:" + event.button + ", which: " + event.which, ctx); + // TODO: use switch + // TODO: make sure clicks on embedded <input> doesn't steal focus (see table sample) + if (targetType === "expander") { + if (node.isLoading()) { + // #495: we probably got a click event while a lazy load is pending. + // The 'expanded' state is not yet set, so 'toggle' would expand + // and trigger lazyLoad again. + // It would be better to allow to collapse/expand the status node + // while loading (instead of ignoring), but that would require some + // more work. + node.debug("Got 2nd click while loading: ignored"); + return; + } + // Clicking the expander icon always expands/collapses + this._callHook("nodeToggleExpanded", ctx); + } else if (targetType === "checkbox") { + // Clicking the checkbox always (de)selects + this._callHook("nodeToggleSelected", ctx); + if (ctx.options.focusOnSelect) { + // #358 + this._callHook("nodeSetFocus", ctx, true); + } + } else { + // Honor `clickFolderMode` for + expand = false; + activate = true; + if (node.folder) { + switch (ctx.options.clickFolderMode) { + case 2: // expand only + expand = true; + activate = false; + break; + case 3: // expand and activate + activate = true; + expand = true; //!node.isExpanded(); + break; + // else 1 or 4: just activate + } + } + if (activate) { + this.nodeSetFocus(ctx); + this._callHook("nodeSetActive", ctx, true); + } + if (expand) { + if (!activate) { + // this._callHook("nodeSetFocus", ctx); + } + // this._callHook("nodeSetExpanded", ctx, true); + this._callHook("nodeToggleExpanded", ctx); + } + } + // Make sure that clicks stop, otherwise <a href='#'> jumps to the top + // if(event.target.localName === "a" && event.target.className === "fancytree-title"){ + // event.preventDefault(); + // } + // TODO: return promise? + }, + /** Collapse all other children of same parent. + * + * @param {EventData} ctx + * @param {object} callOpts + */ + nodeCollapseSiblings: function (ctx, callOpts) { + // TODO: return promise? + var ac, + i, + l, + node = ctx.node; + + if (node.parent) { + ac = node.parent.children; + for (i = 0, l = ac.length; i < l; i++) { + if (ac[i] !== node && ac[i].expanded) { + this._callHook( + "nodeSetExpanded", + ac[i], + false, + callOpts + ); + } + } + } + }, + /** Default handling for mouse douleclick events. + * @param {EventData} ctx + */ + nodeDblclick: function (ctx) { + // TODO: return promise? + if ( + ctx.targetType === "title" && + ctx.options.clickFolderMode === 4 + ) { + // this.nodeSetFocus(ctx); + // this._callHook("nodeSetActive", ctx, true); + this._callHook("nodeToggleExpanded", ctx); + } + // TODO: prevent text selection on dblclicks + if (ctx.targetType === "title") { + ctx.originalEvent.preventDefault(); + } + }, + /** Default handling for mouse keydown events. + * + * NOTE: this may be called with node == null if tree (but no node) has focus. + * @param {EventData} ctx + */ + nodeKeydown: function (ctx) { + // TODO: return promise? + var matchNode, + stamp, + _res, + focusNode, + event = ctx.originalEvent, + node = ctx.node, + tree = ctx.tree, + opts = ctx.options, + which = event.which, + // #909: Use event.key, to get unicode characters. + // We can't use `/\w/.test(key)`, because that would + // only detect plain ascii alpha-numerics. But we still need + // to ignore modifier-only, whitespace, cursor-keys, etc. + key = event.key || String.fromCharCode(which), + specialModifiers = !!( + event.altKey || + event.ctrlKey || + event.metaKey + ), + isAlnum = + !MODIFIERS[which] && + !SPECIAL_KEYCODES[which] && + !specialModifiers, + $target = $(event.target), + handled = true, + activate = !(event.ctrlKey || !opts.autoActivate); + + // (node || FT).debug("ftnode.nodeKeydown(" + event.type + "): ftnode:" + this + ", charCode:" + event.charCode + ", keyCode: " + event.keyCode + ", which: " + event.which); + // FT.debug( "eventToString(): " + FT.eventToString(event) + ", key='" + key + "', isAlnum: " + isAlnum ); + + // Set focus to active (or first node) if no other node has the focus yet + if (!node) { + focusNode = this.getActiveNode() || this.getFirstChild(); + if (focusNode) { + focusNode.setFocus(); + node = ctx.node = this.focusNode; + node.debug("Keydown force focus on active node"); + } + } + + if ( + opts.quicksearch && + isAlnum && + !$target.is(":input:enabled") + ) { + // Allow to search for longer streaks if typed in quickly + stamp = Date.now(); + if (stamp - tree.lastQuicksearchTime > 500) { + tree.lastQuicksearchTerm = ""; + } + tree.lastQuicksearchTime = stamp; + tree.lastQuicksearchTerm += key; + // tree.debug("quicksearch find", tree.lastQuicksearchTerm); + matchNode = tree.findNextNode( + tree.lastQuicksearchTerm, + tree.getActiveNode() + ); + if (matchNode) { + matchNode.setActive(); + } + event.preventDefault(); + return; + } + switch (FT.eventToString(event)) { + case "+": + case "=": // 187: '+' @ Chrome, Safari + tree.nodeSetExpanded(ctx, true); + break; + case "-": + tree.nodeSetExpanded(ctx, false); + break; + case "space": + if (node.isPagingNode()) { + tree._triggerNodeEvent("clickPaging", ctx, event); + } else if ( + FT.evalOption("checkbox", node, node, opts, false) + ) { + // #768 + tree.nodeToggleSelected(ctx); + } else { + tree.nodeSetActive(ctx, true); + } + break; + case "return": + tree.nodeSetActive(ctx, true); + break; + case "home": + case "end": + case "backspace": + case "left": + case "right": + case "up": + case "down": + _res = node.navigate(event.which, activate); + break; + default: + handled = false; + } + if (handled) { + event.preventDefault(); + } + }, + + // /** Default handling for mouse keypress events. */ + // nodeKeypress: function(ctx) { + // var event = ctx.originalEvent; + // }, + + // /** Trigger lazyLoad event (async). */ + // nodeLazyLoad: function(ctx) { + // var node = ctx.node; + // if(this._triggerNodeEvent()) + // }, + /** Load child nodes (async). + * + * @param {EventData} ctx + * @param {object[]|object|string|$.Promise|function} source + * @returns {$.Promise} The deferred will be resolved as soon as the (ajax) + * data was rendered. + */ + nodeLoadChildren: function (ctx, source) { + var ajax, + delay, + ajaxDfd = null, + resultDfd, + isAsync = true, + tree = ctx.tree, + node = ctx.node, + nodePrevParent = node.parent, + tag = "nodeLoadChildren", + requestId = Date.now(); + + // `source` is a callback: use the returned result instead: + if (_isFunction(source)) { + source = source.call(tree, { type: "source" }, ctx); + _assert( + !_isFunction(source), + "source callback must not return another function" + ); + } + // `source` is already a promise: + if (_isFunction(source.then)) { + // _assert(_isFunction(source.always), "Expected jQuery?"); + ajaxDfd = source; + } else if (source.url) { + // `source` is an Ajax options object + ajax = $.extend({}, ctx.options.ajax, source); + if (ajax.debugDelay) { + // Simulate a slow server + delay = ajax.debugDelay; + delete ajax.debugDelay; // remove debug option + if (_isArray(delay)) { + // random delay range [min..max] + delay = + delay[0] + + Math.random() * (delay[1] - delay[0]); + } + node.warn( + "nodeLoadChildren waiting debugDelay " + + Math.round(delay) + + " ms ..." + ); + ajaxDfd = $.Deferred(function (ajaxDfd) { + setTimeout(function () { + $.ajax(ajax) + .done(function () { + ajaxDfd.resolveWith(this, arguments); + }) + .fail(function () { + ajaxDfd.rejectWith(this, arguments); + }); + }, delay); + }); + } else { + ajaxDfd = $.ajax(ajax); + } + } else if ($.isPlainObject(source) || _isArray(source)) { + // `source` is already a constant dict or list, but we convert + // to a thenable for unified processing. + // 2020-01-03: refactored. + // `ajaxDfd = $.when(source)` would do the trick, but the returned + // promise will resolve async, which broke some tests and + // would probably also break current implementations out there. + // So we mock-up a thenable that resolves synchronously: + ajaxDfd = { + then: function (resolve, reject) { + resolve(source, null, null); + }, + }; + isAsync = false; + } else { + $.error("Invalid source type: " + source); + } + + // Check for overlapping requests + if (node._requestId) { + node.warn( + "Recursive load request #" + + requestId + + " while #" + + node._requestId + + " is pending." + ); + node._requestId = requestId; + // node.debug("Send load request #" + requestId); + } + + if (isAsync) { + tree.debugTime(tag); + tree.nodeSetStatus(ctx, "loading"); + } + + // The async Ajax request has now started... + // Defer the deferred: + // we want to be able to reject invalid responses, even if + // the raw HTTP Ajax XHR resolved as Ok. + // We use the ajaxDfd.then() syntax here, which is compatible with + // jQuery and ECMA6. + // However resultDfd is a jQuery deferred, which is currently the + // expected result type of nodeLoadChildren() + resultDfd = new $.Deferred(); + ajaxDfd.then( + function (data, textStatus, jqXHR) { + // ajaxDfd was resolved, but we reject or resolve resultDfd + // depending on the response data + var errorObj, res; + + if ( + (source.dataType === "json" || + source.dataType === "jsonp") && + typeof data === "string" + ) { + $.error( + "Ajax request returned a string (did you get the JSON dataType wrong?)." + ); + } + if (node._requestId && node._requestId > requestId) { + // The expected request time stamp is later than `requestId` + // (which was kept as as closure variable to this handler function) + // node.warn("Ignored load response for obsolete request #" + requestId + " (expected #" + node._requestId + ")"); + resultDfd.rejectWith(this, [ + RECURSIVE_REQUEST_ERROR, + ]); + return; + // } else { + // node.debug("Response returned for load request #" + requestId); + } + if (node.parent === null && nodePrevParent !== null) { + resultDfd.rejectWith(this, [ + INVALID_REQUEST_TARGET_ERROR, + ]); + return; + } + // Allow to adjust the received response data in the `postProcess` event. + if (ctx.options.postProcess) { + // The handler may either + // - modify `ctx.response` in-place (and leave `ctx.result` undefined) + // => res = undefined + // - return a replacement in `ctx.result` + // => res = <new data> + // If res contains an `error` property, an error status is displayed + try { + res = tree._triggerNodeEvent( + "postProcess", + ctx, + ctx.originalEvent, + { + response: data, + error: null, + dataType: source.dataType, + } + ); + if (res.error) { + tree.warn( + "postProcess returned error:", + res + ); + } + } catch (e) { + res = { + error: e, + message: "" + e, + details: "postProcess failed", + }; + } + if (res.error) { + // Either postProcess failed with an exception, or the returned + // result object has an 'error' property attached: + errorObj = $.isPlainObject(res.error) + ? res.error + : { message: res.error }; + errorObj = tree._makeHookContext( + node, + null, + errorObj + ); + resultDfd.rejectWith(this, [errorObj]); + return; + } + if ( + _isArray(res) || + ($.isPlainObject(res) && _isArray(res.children)) + ) { + // Use `ctx.result` if valid + // (otherwise use existing data, which may have been modified in-place) + data = res; + } + } else if ( + data && + _hasProp(data, "d") && + ctx.options.enableAspx + ) { + // Process ASPX WebMethod JSON object inside "d" property + // (only if no postProcess event was defined) + if (ctx.options.enableAspx === 42) { + tree.warn( + "The default for enableAspx will change to `false` in the fututure. " + + "Pass `enableAspx: true` or implement postProcess to silence this warning." + ); + } + data = + typeof data.d === "string" + ? $.parseJSON(data.d) + : data.d; + } + resultDfd.resolveWith(this, [data]); + }, + function (jqXHR, textStatus, errorThrown) { + // ajaxDfd was rejected, so we reject resultDfd as well + var errorObj = tree._makeHookContext(node, null, { + error: jqXHR, + args: Array.prototype.slice.call(arguments), + message: errorThrown, + details: jqXHR.status + ": " + errorThrown, + }); + resultDfd.rejectWith(this, [errorObj]); + } + ); + + // The async Ajax request has now started. + // resultDfd will be resolved/rejected after the response arrived, + // was postProcessed, and checked. + // Now we implement the UI update and add the data to the tree. + // We also return this promise to the caller. + resultDfd + .done(function (data) { + tree.nodeSetStatus(ctx, "ok"); + var children, metaData, noDataRes; + + if ($.isPlainObject(data)) { + // We got {foo: 'abc', children: [...]} + // Copy extra properties to tree.data.foo + _assert( + node.isRootNode(), + "source may only be an object for root nodes (expecting an array of child objects otherwise)" + ); + _assert( + _isArray(data.children), + "if an object is passed as source, it must contain a 'children' array (all other properties are added to 'tree.data')" + ); + metaData = data; + children = data.children; + delete metaData.children; + // Copy some attributes to tree.data + $.each(TREE_ATTRS, function (i, attr) { + if (metaData[attr] !== undefined) { + tree[attr] = metaData[attr]; + delete metaData[attr]; + } + }); + // Copy all other attributes to tree.data.NAME + $.extend(tree.data, metaData); + } else { + children = data; + } + _assert( + _isArray(children), + "expected array of children" + ); + node._setChildren(children); + + if (tree.options.nodata && children.length === 0) { + if (_isFunction(tree.options.nodata)) { + noDataRes = tree.options.nodata.call( + tree, + { type: "nodata" }, + ctx + ); + } else if ( + tree.options.nodata === true && + node.isRootNode() + ) { + noDataRes = tree.options.strings.noData; + } else if ( + typeof tree.options.nodata === "string" && + node.isRootNode() + ) { + noDataRes = tree.options.nodata; + } + if (noDataRes) { + node.setStatus("nodata", noDataRes); + } + } + // trigger fancytreeloadchildren + tree._triggerNodeEvent("loadChildren", node); + }) + .fail(function (error) { + var ctxErr; + + if (error === RECURSIVE_REQUEST_ERROR) { + node.warn( + "Ignored response for obsolete load request #" + + requestId + + " (expected #" + + node._requestId + + ")" + ); + return; + } else if (error === INVALID_REQUEST_TARGET_ERROR) { + node.warn( + "Lazy parent node was removed while loading: discarding response." + ); + return; + } else if (error.node && error.error && error.message) { + // error is already a context object + ctxErr = error; + } else { + ctxErr = tree._makeHookContext(node, null, { + error: error, // it can be jqXHR or any custom error + args: Array.prototype.slice.call(arguments), + message: error + ? error.message || error.toString() + : "", + }); + if (ctxErr.message === "[object Object]") { + ctxErr.message = ""; + } + } + node.warn( + "Load children failed (" + ctxErr.message + ")", + ctxErr + ); + if ( + tree._triggerNodeEvent( + "loadError", + ctxErr, + null + ) !== false + ) { + tree.nodeSetStatus( + ctx, + "error", + ctxErr.message, + ctxErr.details + ); + } + }) + .always(function () { + node._requestId = null; + if (isAsync) { + tree.debugTimeEnd(tag); + } + }); + + return resultDfd.promise(); + }, + /** [Not Implemented] */ + nodeLoadKeyPath: function (ctx, keyPathList) { + // TODO: implement and improve + // http://code.google.com/p/dynatree/issues/detail?id=222 + }, + /** + * Remove a single direct child of ctx.node. + * @param {EventData} ctx + * @param {FancytreeNode} childNode dircect child of ctx.node + */ + nodeRemoveChild: function (ctx, childNode) { + var idx, + node = ctx.node, + // opts = ctx.options, + subCtx = $.extend({}, ctx, { node: childNode }), + children = node.children; + + // FT.debug("nodeRemoveChild()", node.toString(), childNode.toString()); + + if (children.length === 1) { + _assert(childNode === children[0], "invalid single child"); + return this.nodeRemoveChildren(ctx); + } + if ( + this.activeNode && + (childNode === this.activeNode || + this.activeNode.isDescendantOf(childNode)) + ) { + this.activeNode.setActive(false); // TODO: don't fire events + } + if ( + this.focusNode && + (childNode === this.focusNode || + this.focusNode.isDescendantOf(childNode)) + ) { + this.focusNode = null; + } + // TODO: persist must take care to clear select and expand cookies + this.nodeRemoveMarkup(subCtx); + this.nodeRemoveChildren(subCtx); + idx = $.inArray(childNode, children); + _assert(idx >= 0, "invalid child"); + // Notify listeners + node.triggerModifyChild("remove", childNode); + // Unlink to support GC + childNode.visit(function (n) { + n.parent = null; + }, true); + this._callHook("treeRegisterNode", this, false, childNode); + // remove from child list + children.splice(idx, 1); + }, + /**Remove HTML markup for all descendents of ctx.node. + * @param {EventData} ctx + */ + nodeRemoveChildMarkup: function (ctx) { + var node = ctx.node; + + // FT.debug("nodeRemoveChildMarkup()", node.toString()); + // TODO: Unlink attr.ftnode to support GC + if (node.ul) { + if (node.isRootNode()) { + $(node.ul).empty(); + } else { + $(node.ul).remove(); + node.ul = null; + } + node.visit(function (n) { + n.li = n.ul = null; + }); + } + }, + /**Remove all descendants of ctx.node. + * @param {EventData} ctx + */ + nodeRemoveChildren: function (ctx) { + var //subCtx, + tree = ctx.tree, + node = ctx.node, + children = node.children; + // opts = ctx.options; + + // FT.debug("nodeRemoveChildren()", node.toString()); + if (!children) { + return; + } + if (this.activeNode && this.activeNode.isDescendantOf(node)) { + this.activeNode.setActive(false); // TODO: don't fire events + } + if (this.focusNode && this.focusNode.isDescendantOf(node)) { + this.focusNode = null; + } + // TODO: persist must take care to clear select and expand cookies + this.nodeRemoveChildMarkup(ctx); + // Unlink children to support GC + // TODO: also delete this.children (not possible using visit()) + // subCtx = $.extend({}, ctx); + node.triggerModifyChild("remove", null); + node.visit(function (n) { + n.parent = null; + tree._callHook("treeRegisterNode", tree, false, n); + }); + if (node.lazy) { + // 'undefined' would be interpreted as 'not yet loaded' for lazy nodes + node.children = []; + } else { + node.children = null; + } + if (!node.isRootNode()) { + node.expanded = false; // #449, #459 + } + this.nodeRenderStatus(ctx); + }, + /**Remove HTML markup for ctx.node and all its descendents. + * @param {EventData} ctx + */ + nodeRemoveMarkup: function (ctx) { + var node = ctx.node; + // FT.debug("nodeRemoveMarkup()", node.toString()); + // TODO: Unlink attr.ftnode to support GC + if (node.li) { + $(node.li).remove(); + node.li = null; + } + this.nodeRemoveChildMarkup(ctx); + }, + /** + * Create `<li><span>..</span> .. </li>` tags for this node. + * + * This method takes care that all HTML markup is created that is required + * to display this node in its current state. + * + * Call this method to create new nodes, or after the strucuture + * was changed (e.g. after moving this node or adding/removing children) + * nodeRenderTitle() and nodeRenderStatus() are implied. + * + * ```html + * <li id='KEY' ftnode=NODE> + * <span class='fancytree-node fancytree-expanded fancytree-has-children fancytree-lastsib fancytree-exp-el fancytree-ico-e'> + * <span class="fancytree-expander"></span> + * <span class="fancytree-checkbox"></span> // only present in checkbox mode + * <span class="fancytree-icon"></span> + * <a href="#" class="fancytree-title"> Node 1 </a> + * </span> + * <ul> // only present if node has children + * <li id='KEY' ftnode=NODE> child1 ... </li> + * <li id='KEY' ftnode=NODE> child2 ... </li> + * </ul> + * </li> + * ``` + * + * @param {EventData} ctx + * @param {boolean} [force=false] re-render, even if html markup was already created + * @param {boolean} [deep=false] also render all descendants, even if parent is collapsed + * @param {boolean} [collapsed=false] force root node to be collapsed, so we can apply animated expand later + */ + nodeRender: function (ctx, force, deep, collapsed, _recursive) { + /* This method must take care of all cases where the current data mode + * (i.e. node hierarchy) does not match the current markup. + * + * - node was not yet rendered: + * create markup + * - node was rendered: exit fast + * - children have been added + * - children have been removed + */ + var childLI, + childNode1, + childNode2, + i, + l, + next, + subCtx, + node = ctx.node, + tree = ctx.tree, + opts = ctx.options, + aria = opts.aria, + firstTime = false, + parent = node.parent, + isRootNode = !parent, + children = node.children, + successorLi = null; + // FT.debug("nodeRender(" + !!force + ", " + !!deep + ")", node.toString()); + + if (tree._enableUpdate === false) { + // tree.debug("no render", tree._enableUpdate); + return; + } + if (!isRootNode && !parent.ul) { + // Calling node.collapse on a deep, unrendered node + return; + } + _assert(isRootNode || parent.ul, "parent UL must exist"); + + // Render the node + if (!isRootNode) { + // Discard markup on force-mode, or if it is not linked to parent <ul> + if ( + node.li && + (force || node.li.parentNode !== node.parent.ul) + ) { + if (node.li.parentNode === node.parent.ul) { + // #486: store following node, so we can insert the new markup there later + successorLi = node.li.nextSibling; + } else { + // May happen, when a top-level node was dropped over another + this.debug( + "Unlinking " + + node + + " (must be child of " + + node.parent + + ")" + ); + } + // this.debug("nodeRemoveMarkup..."); + this.nodeRemoveMarkup(ctx); + } + // Create <li><span /> </li> + // node.debug("render..."); + if (node.li) { + // this.nodeRenderTitle(ctx); + this.nodeRenderStatus(ctx); + } else { + // node.debug("render... really"); + firstTime = true; + node.li = document.createElement("li"); + node.li.ftnode = node; + + if (node.key && opts.generateIds) { + node.li.id = opts.idPrefix + node.key; + } + node.span = document.createElement("span"); + node.span.className = "fancytree-node"; + if (aria && !node.tr) { + $(node.li).attr("role", "treeitem"); + } + node.li.appendChild(node.span); + + // Create inner HTML for the <span> (expander, checkbox, icon, and title) + this.nodeRenderTitle(ctx); + + // Allow tweaking and binding, after node was created for the first time + if (opts.createNode) { + opts.createNode.call( + tree, + { type: "createNode" }, + ctx + ); + } + } + // Allow tweaking after node state was rendered + if (opts.renderNode) { + opts.renderNode.call(tree, { type: "renderNode" }, ctx); + } + } + + // Visit child nodes + if (children) { + if (isRootNode || node.expanded || deep === true) { + // Create a UL to hold the children + if (!node.ul) { + node.ul = document.createElement("ul"); + if ( + (collapsed === true && !_recursive) || + !node.expanded + ) { + // hide top UL, so we can use an animation to show it later + node.ul.style.display = "none"; + } + if (aria) { + $(node.ul).attr("role", "group"); + } + if (node.li) { + // issue #67 + node.li.appendChild(node.ul); + } else { + node.tree.$div.append(node.ul); + } + } + // Add child markup + for (i = 0, l = children.length; i < l; i++) { + subCtx = $.extend({}, ctx, { node: children[i] }); + this.nodeRender(subCtx, force, deep, false, true); + } + // Remove <li> if nodes have moved to another parent + childLI = node.ul.firstChild; + while (childLI) { + childNode2 = childLI.ftnode; + if (childNode2 && childNode2.parent !== node) { + node.debug( + "_fixParent: remove missing " + childNode2, + childLI + ); + next = childLI.nextSibling; + childLI.parentNode.removeChild(childLI); + childLI = next; + } else { + childLI = childLI.nextSibling; + } + } + // Make sure, that <li> order matches node.children order. + childLI = node.ul.firstChild; + for (i = 0, l = children.length - 1; i < l; i++) { + childNode1 = children[i]; + childNode2 = childLI.ftnode; + if (childNode1 === childNode2) { + childLI = childLI.nextSibling; + } else { + // node.debug("_fixOrder: mismatch at index " + i + ": " + childNode1 + " != " + childNode2); + node.ul.insertBefore( + childNode1.li, + childNode2.li + ); + } + } + } + } else { + // No children: remove markup if any + if (node.ul) { + // alert("remove child markup for " + node); + this.warn("remove child markup for " + node); + this.nodeRemoveChildMarkup(ctx); + } + } + if (!isRootNode) { + // Update element classes according to node state + // this.nodeRenderStatus(ctx); + // Finally add the whole structure to the DOM, so the browser can render + if (firstTime) { + // #486: successorLi is set, if we re-rendered (i.e. discarded) + // existing markup, which we want to insert at the same position. + // (null is equivalent to append) + // parent.ul.appendChild(node.li); + parent.ul.insertBefore(node.li, successorLi); + } + } + }, + /** Create HTML inside the node's outer `<span>` (i.e. expander, checkbox, + * icon, and title). + * + * nodeRenderStatus() is implied. + * @param {EventData} ctx + * @param {string} [title] optinal new title + */ + nodeRenderTitle: function (ctx, title) { + // set node connector images, links and text + var checkbox, + className, + icon, + nodeTitle, + role, + tabindex, + tooltip, + iconTooltip, + node = ctx.node, + tree = ctx.tree, + opts = ctx.options, + aria = opts.aria, + level = node.getLevel(), + ares = []; + + if (title !== undefined) { + node.title = title; + } + if (!node.span || tree._enableUpdate === false) { + // Silently bail out if node was not rendered yet, assuming + // node.render() will be called as the node becomes visible + return; + } + // Connector (expanded, expandable or simple) + role = + aria && node.hasChildren() !== false + ? " role='button'" + : ""; + if (level < opts.minExpandLevel) { + if (!node.lazy) { + node.expanded = true; + } + if (level > 1) { + ares.push( + "<span " + + role + + " class='fancytree-expander fancytree-expander-fixed'></span>" + ); + } + // .. else (i.e. for root level) skip expander/connector alltogether + } else { + ares.push( + "<span " + role + " class='fancytree-expander'></span>" + ); + } + // Checkbox mode + checkbox = FT.evalOption("checkbox", node, node, opts, false); + + if (checkbox && !node.isStatusNode()) { + role = aria ? " role='checkbox'" : ""; + className = "fancytree-checkbox"; + if ( + checkbox === "radio" || + (node.parent && node.parent.radiogroup) + ) { + className += " fancytree-radio"; + } + ares.push( + "<span " + role + " class='" + className + "'></span>" + ); + } + // Folder or doctype icon + if (node.data.iconClass !== undefined) { + // 2015-11-16 + // Handle / warn about backward compatibility + if (node.icon) { + $.error( + "'iconClass' node option is deprecated since v2.14.0: use 'icon' only instead" + ); + } else { + node.warn( + "'iconClass' node option is deprecated since v2.14.0: use 'icon' instead" + ); + node.icon = node.data.iconClass; + } + } + // If opts.icon is a callback and returns something other than undefined, use that + // else if node.icon is a boolean or string, use that + // else if opts.icon is a boolean or string, use that + // else show standard icon (which may be different for folders or documents) + icon = FT.evalOption("icon", node, node, opts, true); + // if( typeof icon !== "boolean" ) { + // // icon is defined, but not true/false: must be a string + // icon = "" + icon; + // } + if (icon !== false) { + role = aria ? " role='presentation'" : ""; + + iconTooltip = FT.evalOption( + "iconTooltip", + node, + node, + opts, + null + ); + iconTooltip = iconTooltip + ? " title='" + _escapeTooltip(iconTooltip) + "'" + : ""; + + if (typeof icon === "string") { + if (TEST_IMG.test(icon)) { + // node.icon is an image url. Prepend imagePath + icon = + icon.charAt(0) === "/" + ? icon + : (opts.imagePath || "") + icon; + ares.push( + "<img src='" + + icon + + "' class='fancytree-icon'" + + iconTooltip + + " alt='' />" + ); + } else { + ares.push( + "<span " + + role + + " class='fancytree-custom-icon " + + icon + + "'" + + iconTooltip + + "></span>" + ); + } + } else if (icon.text) { + ares.push( + "<span " + + role + + " class='fancytree-custom-icon " + + (icon.addClass || "") + + "'" + + iconTooltip + + ">" + + FT.escapeHtml(icon.text) + + "</span>" + ); + } else if (icon.html) { + ares.push( + "<span " + + role + + " class='fancytree-custom-icon " + + (icon.addClass || "") + + "'" + + iconTooltip + + ">" + + icon.html + + "</span>" + ); + } else { + // standard icon: theme css will take care of this + ares.push( + "<span " + + role + + " class='fancytree-icon'" + + iconTooltip + + "></span>" + ); + } + } + // Node title + nodeTitle = ""; + if (opts.renderTitle) { + nodeTitle = + opts.renderTitle.call( + tree, + { type: "renderTitle" }, + ctx + ) || ""; + } + if (!nodeTitle) { + tooltip = FT.evalOption("tooltip", node, node, opts, null); + if (tooltip === true) { + tooltip = node.title; + } + // if( node.tooltip ) { + // tooltip = node.tooltip; + // } else if ( opts.tooltip ) { + // tooltip = opts.tooltip === true ? node.title : opts.tooltip.call(tree, node); + // } + tooltip = tooltip + ? " title='" + _escapeTooltip(tooltip) + "'" + : ""; + tabindex = opts.titlesTabbable ? " tabindex='0'" : ""; + + nodeTitle = + "<span class='fancytree-title'" + + tooltip + + tabindex + + ">" + + (opts.escapeTitles + ? FT.escapeHtml(node.title) + : node.title) + + "</span>"; + } + ares.push(nodeTitle); + // Note: this will trigger focusout, if node had the focus + //$(node.span).html(ares.join("")); // it will cleanup the jQuery data currently associated with SPAN (if any), but it executes more slowly + node.span.innerHTML = ares.join(""); + // Update CSS classes + this.nodeRenderStatus(ctx); + if (opts.enhanceTitle) { + ctx.$title = $(">span.fancytree-title", node.span); + nodeTitle = + opts.enhanceTitle.call( + tree, + { type: "enhanceTitle" }, + ctx + ) || ""; + } + }, + /** Update element classes according to node state. + * @param {EventData} ctx + */ + nodeRenderStatus: function (ctx) { + // Set classes for current status + var $ariaElem, + node = ctx.node, + tree = ctx.tree, + opts = ctx.options, + // nodeContainer = node[tree.nodeContainerAttrName], + hasChildren = node.hasChildren(), + isLastSib = node.isLastSibling(), + aria = opts.aria, + cn = opts._classNames, + cnList = [], + statusElem = node[tree.statusClassPropName]; + + if (!statusElem || tree._enableUpdate === false) { + // if this function is called for an unrendered node, ignore it (will be updated on nect render anyway) + return; + } + if (aria) { + $ariaElem = $(node.tr || node.li); + } + // Build a list of class names that we will add to the node <span> + cnList.push(cn.node); + if (tree.activeNode === node) { + cnList.push(cn.active); + // $(">span.fancytree-title", statusElem).attr("tabindex", "0"); + // tree.$container.removeAttr("tabindex"); + // }else{ + // $(">span.fancytree-title", statusElem).removeAttr("tabindex"); + // tree.$container.attr("tabindex", "0"); + } + if (tree.focusNode === node) { + cnList.push(cn.focused); + } + if (node.expanded) { + cnList.push(cn.expanded); + } + if (aria) { + if (hasChildren === false) { + $ariaElem.removeAttr("aria-expanded"); + } else { + $ariaElem.attr("aria-expanded", Boolean(node.expanded)); + } + } + if (node.folder) { + cnList.push(cn.folder); + } + if (hasChildren !== false) { + cnList.push(cn.hasChildren); + } + // TODO: required? + if (isLastSib) { + cnList.push(cn.lastsib); + } + if (node.lazy && node.children == null) { + cnList.push(cn.lazy); + } + if (node.partload) { + cnList.push(cn.partload); + } + if (node.partsel) { + cnList.push(cn.partsel); + } + if (FT.evalOption("unselectable", node, node, opts, false)) { + cnList.push(cn.unselectable); + } + if (node._isLoading) { + cnList.push(cn.loading); + } + if (node._error) { + cnList.push(cn.error); + } + if (node.statusNodeType) { + cnList.push(cn.statusNodePrefix + node.statusNodeType); + } + if (node.selected) { + cnList.push(cn.selected); + if (aria) { + $ariaElem.attr("aria-selected", true); + } + } else if (aria) { + $ariaElem.attr("aria-selected", false); + } + if (node.extraClasses) { + cnList.push(node.extraClasses); + } + // IE6 doesn't correctly evaluate multiple class names, + // so we create combined class names that can be used in the CSS + if (hasChildren === false) { + cnList.push( + cn.combinedExpanderPrefix + "n" + (isLastSib ? "l" : "") + ); + } else { + cnList.push( + cn.combinedExpanderPrefix + + (node.expanded ? "e" : "c") + + (node.lazy && node.children == null ? "d" : "") + + (isLastSib ? "l" : "") + ); + } + cnList.push( + cn.combinedIconPrefix + + (node.expanded ? "e" : "c") + + (node.folder ? "f" : "") + ); + // node.span.className = cnList.join(" "); + statusElem.className = cnList.join(" "); + + // TODO: we should not set this in the <span> tag also, if we set it here: + // Maybe most (all) of the classes should be set in LI instead of SPAN? + if (node.li) { + // #719: we have to consider that there may be already other classes: + $(node.li).toggleClass(cn.lastsib, isLastSib); + } + }, + /** Activate node. + * flag defaults to true. + * If flag is true, the node is activated (must be a synchronous operation) + * If flag is false, the node is deactivated (must be a synchronous operation) + * @param {EventData} ctx + * @param {boolean} [flag=true] + * @param {object} [opts] additional options. Defaults to {noEvents: false, noFocus: false} + * @returns {$.Promise} + */ + nodeSetActive: function (ctx, flag, callOpts) { + // Handle user click / [space] / [enter], according to clickFolderMode. + callOpts = callOpts || {}; + var subCtx, + node = ctx.node, + tree = ctx.tree, + opts = ctx.options, + noEvents = callOpts.noEvents === true, + noFocus = callOpts.noFocus === true, + scroll = callOpts.scrollIntoView !== false, + isActive = node === tree.activeNode; + + // flag defaults to true + flag = flag !== false; + // node.debug("nodeSetActive", flag); + + if (isActive === flag) { + // Nothing to do + return _getResolvedPromise(node); + } + // #1042: don't scroll between mousedown/-up when clicking an embedded link + if ( + scroll && + ctx.originalEvent && + $(ctx.originalEvent.target).is("a,:checkbox") + ) { + node.info("Not scrolling while clicking an embedded link."); + scroll = false; + } + if ( + flag && + !noEvents && + this._triggerNodeEvent( + "beforeActivate", + node, + ctx.originalEvent + ) === false + ) { + // Callback returned false + return _getRejectedPromise(node, ["rejected"]); + } + if (flag) { + if (tree.activeNode) { + _assert( + tree.activeNode !== node, + "node was active (inconsistency)" + ); + subCtx = $.extend({}, ctx, { node: tree.activeNode }); + tree.nodeSetActive(subCtx, false); + _assert( + tree.activeNode === null, + "deactivate was out of sync?" + ); + } + + if (opts.activeVisible) { + // If no focus is set (noFocus: true) and there is no focused node, this node is made visible. + // scroll = noFocus && tree.focusNode == null; + // #863: scroll by default (unless `scrollIntoView: false` was passed) + node.makeVisible({ scrollIntoView: scroll }); + } + tree.activeNode = node; + tree.nodeRenderStatus(ctx); + if (!noFocus) { + tree.nodeSetFocus(ctx); + } + if (!noEvents) { + tree._triggerNodeEvent( + "activate", + node, + ctx.originalEvent + ); + } + } else { + _assert( + tree.activeNode === node, + "node was not active (inconsistency)" + ); + tree.activeNode = null; + this.nodeRenderStatus(ctx); + if (!noEvents) { + ctx.tree._triggerNodeEvent( + "deactivate", + node, + ctx.originalEvent + ); + } + } + return _getResolvedPromise(node); + }, + /** Expand or collapse node, return Deferred.promise. + * + * @param {EventData} ctx + * @param {boolean} [flag=true] + * @param {object} [opts] additional options. Defaults to `{noAnimation: false, noEvents: false}` + * @returns {$.Promise} The deferred will be resolved as soon as the (lazy) + * data was retrieved, rendered, and the expand animation finished. + */ + nodeSetExpanded: function (ctx, flag, callOpts) { + callOpts = callOpts || {}; + var _afterLoad, + dfd, + i, + l, + parents, + prevAC, + node = ctx.node, + tree = ctx.tree, + opts = ctx.options, + noAnimation = callOpts.noAnimation === true, + noEvents = callOpts.noEvents === true; + + // flag defaults to true + flag = flag !== false; + + // node.debug("nodeSetExpanded(" + flag + ")"); + + if ($(node.li).hasClass(opts._classNames.animating)) { + node.warn( + "setExpanded(" + flag + ") while animating: ignored." + ); + return _getRejectedPromise(node, ["recursion"]); + } + + if ((node.expanded && flag) || (!node.expanded && !flag)) { + // Nothing to do + // node.debug("nodeSetExpanded(" + flag + "): nothing to do"); + return _getResolvedPromise(node); + } else if (flag && !node.lazy && !node.hasChildren()) { + // Prevent expanding of empty nodes + // return _getRejectedPromise(node, ["empty"]); + return _getResolvedPromise(node); + } else if (!flag && node.getLevel() < opts.minExpandLevel) { + // Prevent collapsing locked levels + return _getRejectedPromise(node, ["locked"]); + } else if ( + !noEvents && + this._triggerNodeEvent( + "beforeExpand", + node, + ctx.originalEvent + ) === false + ) { + // Callback returned false + return _getRejectedPromise(node, ["rejected"]); + } + // If this node inside a collpased node, no animation and scrolling is needed + if (!noAnimation && !node.isVisible()) { + noAnimation = callOpts.noAnimation = true; + } + + dfd = new $.Deferred(); + + // Auto-collapse mode: collapse all siblings + if (flag && !node.expanded && opts.autoCollapse) { + parents = node.getParentList(false, true); + prevAC = opts.autoCollapse; + try { + opts.autoCollapse = false; + for (i = 0, l = parents.length; i < l; i++) { + // TODO: should return promise? + this._callHook( + "nodeCollapseSiblings", + parents[i], + callOpts + ); + } + } finally { + opts.autoCollapse = prevAC; + } + } + // Trigger expand/collapse after expanding + dfd.done(function () { + var lastChild = node.getLastChild(); + + if ( + flag && + opts.autoScroll && + !noAnimation && + lastChild && + tree._enableUpdate + ) { + // Scroll down to last child, but keep current node visible + lastChild + .scrollIntoView(true, { topNode: node }) + .always(function () { + if (!noEvents) { + ctx.tree._triggerNodeEvent( + flag ? "expand" : "collapse", + ctx + ); + } + }); + } else { + if (!noEvents) { + ctx.tree._triggerNodeEvent( + flag ? "expand" : "collapse", + ctx + ); + } + } + }); + // vvv Code below is executed after loading finished: + _afterLoad = function (callback) { + var cn = opts._classNames, + isVisible, + isExpanded, + effect = opts.toggleEffect; + + node.expanded = flag; + tree._callHook( + "treeStructureChanged", + ctx, + flag ? "expand" : "collapse" + ); + // Create required markup, but make sure the top UL is hidden, so we + // can animate later + tree._callHook("nodeRender", ctx, false, false, true); + + // Hide children, if node is collapsed + if (node.ul) { + isVisible = node.ul.style.display !== "none"; + isExpanded = !!node.expanded; + if (isVisible === isExpanded) { + node.warn( + "nodeSetExpanded: UL.style.display already set" + ); + } else if (!effect || noAnimation) { + node.ul.style.display = + node.expanded || !parent ? "" : "none"; + } else { + // The UI toggle() effect works with the ext-wide extension, + // while jQuery.animate() has problems when the title span + // has position: absolute. + // Since jQuery UI 1.12, the blind effect requires the parent + // element to have 'position: relative'. + // See #716, #717 + $(node.li).addClass(cn.animating); // #717 + + if (_isFunction($(node.ul)[effect.effect])) { + // tree.debug( "use jquery." + effect.effect + " method" ); + $(node.ul)[effect.effect]({ + duration: effect.duration, + always: function () { + // node.debug("fancytree-animating end: " + node.li.className); + $(this).removeClass(cn.animating); // #716 + $(node.li).removeClass(cn.animating); // #717 + callback(); + }, + }); + } else { + // The UI toggle() effect works with the ext-wide extension, + // while jQuery.animate() has problems when the title span + // has positon: absolute. + // Since jQuery UI 1.12, the blind effect requires the parent + // element to have 'position: relative'. + // See #716, #717 + // tree.debug("use specified effect (" + effect.effect + ") with the jqueryui.toggle method"); + + // try to stop an animation that might be already in progress + $(node.ul).stop(true, true); //< does not work after resetLazy has been called for a node whose animation wasn't complete and effect was "blind" + + // dirty fix to remove a defunct animation (effect: "blind") after resetLazy has been called + $(node.ul) + .parent() + .find(".ui-effects-placeholder") + .remove(); + + $(node.ul).toggle( + effect.effect, + effect.options, + effect.duration, + function () { + // node.debug("fancytree-animating end: " + node.li.className); + $(this).removeClass(cn.animating); // #716 + $(node.li).removeClass(cn.animating); // #717 + callback(); + } + ); + } + return; + } + } + callback(); + }; + // ^^^ Code above is executed after loading finshed. + + // Load lazy nodes, if any. Then continue with _afterLoad() + if (flag && node.lazy && node.hasChildren() === undefined) { + // node.debug("nodeSetExpanded: load start..."); + node.load() + .done(function () { + // node.debug("nodeSetExpanded: load done"); + if (dfd.notifyWith) { + // requires jQuery 1.6+ + dfd.notifyWith(node, ["loaded"]); + } + _afterLoad(function () { + dfd.resolveWith(node); + }); + }) + .fail(function (errMsg) { + _afterLoad(function () { + dfd.rejectWith(node, [ + "load failed (" + errMsg + ")", + ]); + }); + }); + /* + var source = tree._triggerNodeEvent("lazyLoad", node, ctx.originalEvent); + _assert(typeof source !== "boolean", "lazyLoad event must return source in data.result"); + node.debug("nodeSetExpanded: load start..."); + this._callHook("nodeLoadChildren", ctx, source).done(function(){ + node.debug("nodeSetExpanded: load done"); + if(dfd.notifyWith){ // requires jQuery 1.6+ + dfd.notifyWith(node, ["loaded"]); + } + _afterLoad.call(tree); + }).fail(function(errMsg){ + dfd.rejectWith(node, ["load failed (" + errMsg + ")"]); + }); + */ + } else { + _afterLoad(function () { + dfd.resolveWith(node); + }); + } + // node.debug("nodeSetExpanded: returns"); + return dfd.promise(); + }, + /** Focus or blur this node. + * @param {EventData} ctx + * @param {boolean} [flag=true] + */ + nodeSetFocus: function (ctx, flag) { + // ctx.node.debug("nodeSetFocus(" + flag + ")"); + var ctx2, + tree = ctx.tree, + node = ctx.node, + opts = tree.options, + // et = ctx.originalEvent && ctx.originalEvent.type, + isInput = ctx.originalEvent + ? $(ctx.originalEvent.target).is(":input") + : false; + + flag = flag !== false; + + // (node || tree).debug("nodeSetFocus(" + flag + "), event: " + et + ", isInput: "+ isInput); + // Blur previous node if any + if (tree.focusNode) { + if (tree.focusNode === node && flag) { + // node.debug("nodeSetFocus(" + flag + "): nothing to do"); + return; + } + ctx2 = $.extend({}, ctx, { node: tree.focusNode }); + tree.focusNode = null; + this._triggerNodeEvent("blur", ctx2); + this._callHook("nodeRenderStatus", ctx2); + } + // Set focus to container and node + if (flag) { + if (!this.hasFocus()) { + node.debug("nodeSetFocus: forcing container focus"); + this._callHook("treeSetFocus", ctx, true, { + calledByNode: true, + }); + } + node.makeVisible({ scrollIntoView: false }); + tree.focusNode = node; + if (opts.titlesTabbable) { + if (!isInput) { + // #621 + $(node.span).find(".fancytree-title").focus(); + } + } + if (opts.aria) { + // Set active descendant to node's span ID (create one, if needed) + $(tree.$container).attr( + "aria-activedescendant", + $(node.tr || node.li) + .uniqueId() + .attr("id") + ); + // "ftal_" + opts.idPrefix + node.key); + } + // $(node.span).find(".fancytree-title").focus(); + this._triggerNodeEvent("focus", ctx); + + // determine if we have focus on or inside tree container + var hasFancytreeFocus = + document.activeElement === tree.$container.get(0) || + $(document.activeElement, tree.$container).length >= 1; + + if (!hasFancytreeFocus) { + // We cannot set KB focus to a node, so use the tree container + // #563, #570: IE scrolls on every call to .focus(), if the container + // is partially outside the viewport. So do it only, when absolutely + // necessary. + $(tree.$container).focus(); + } + + // if( opts.autoActivate ){ + // tree.nodeSetActive(ctx, true); + // } + if (opts.autoScroll) { + node.scrollIntoView(); + } + this._callHook("nodeRenderStatus", ctx); + } + }, + /** (De)Select node, return new status (sync). + * + * @param {EventData} ctx + * @param {boolean} [flag=true] + * @param {object} [opts] additional options. Defaults to {noEvents: false, + * propagateDown: null, propagateUp: null, + * callback: null, + * } + * @returns {boolean} previous status + */ + nodeSetSelected: function (ctx, flag, callOpts) { + callOpts = callOpts || {}; + var node = ctx.node, + tree = ctx.tree, + opts = ctx.options, + noEvents = callOpts.noEvents === true, + parent = node.parent; + + // flag defaults to true + flag = flag !== false; + + // node.debug("nodeSetSelected(" + flag + ")", ctx); + + // Cannot (de)select unselectable nodes directly (only by propagation or + // by setting the `.selected` property) + if (FT.evalOption("unselectable", node, node, opts, false)) { + return; + } + + // Remember the user's intent, in case down -> up propagation prevents + // applying it to node.selected + node._lastSelectIntent = flag; // Confusing use of '!' + + // Nothing to do? + if (!!node.selected === flag) { + if (opts.selectMode === 3 && node.partsel && !flag) { + // If propagation prevented selecting this node last time, we still + // want to allow to apply setSelected(false) now + } else { + return flag; + } + } + + if ( + !noEvents && + this._triggerNodeEvent( + "beforeSelect", + node, + ctx.originalEvent + ) === false + ) { + return !!node.selected; + } + if (flag && opts.selectMode === 1) { + // single selection mode (we don't uncheck all tree nodes, for performance reasons) + if (tree.lastSelectedNode) { + tree.lastSelectedNode.setSelected(false); + } + node.selected = flag; + } else if ( + opts.selectMode === 3 && + parent && + !parent.radiogroup && + !node.radiogroup + ) { + // multi-hierarchical selection mode + node.selected = flag; + node.fixSelection3AfterClick(callOpts); + } else if (parent && parent.radiogroup) { + node.visitSiblings(function (n) { + n._changeSelectStatusAttrs(flag && n === node); + }, true); + } else { + // default: selectMode: 2, multi selection mode + node.selected = flag; + } + this.nodeRenderStatus(ctx); + tree.lastSelectedNode = flag ? node : null; + if (!noEvents) { + tree._triggerNodeEvent("select", ctx); + } + }, + /** Show node status (ok, loading, error, nodata) using styles and a dummy child node. + * + * @param {EventData} ctx + * @param status + * @param message + * @param details + * @since 2.3 + */ + nodeSetStatus: function (ctx, status, message, details) { + var node = ctx.node, + tree = ctx.tree; + + function _clearStatusNode() { + // Remove dedicated dummy node, if any + var firstChild = node.children ? node.children[0] : null; + if (firstChild && firstChild.isStatusNode()) { + try { + // I've seen exceptions here with loadKeyPath... + if (node.ul) { + node.ul.removeChild(firstChild.li); + firstChild.li = null; // avoid leaks (DT issue 215) + } + } catch (e) {} + if (node.children.length === 1) { + node.children = []; + } else { + node.children.shift(); + } + tree._callHook( + "treeStructureChanged", + ctx, + "clearStatusNode" + ); + } + } + function _setStatusNode(data, type) { + // Create/modify the dedicated dummy node for 'loading...' or + // 'error!' status. (only called for direct child of the invisible + // system root) + var firstChild = node.children ? node.children[0] : null; + if (firstChild && firstChild.isStatusNode()) { + $.extend(firstChild, data); + firstChild.statusNodeType = type; + tree._callHook("nodeRenderTitle", firstChild); + } else { + node._setChildren([data]); + tree._callHook( + "treeStructureChanged", + ctx, + "setStatusNode" + ); + node.children[0].statusNodeType = type; + tree.render(); + } + return node.children[0]; + } + + switch (status) { + case "ok": + _clearStatusNode(); + node._isLoading = false; + node._error = null; + node.renderStatus(); + break; + case "loading": + if (!node.parent) { + _setStatusNode( + { + title: + tree.options.strings.loading + + (message ? " (" + message + ")" : ""), + // icon: true, // needed for 'loding' icon + checkbox: false, + tooltip: details, + }, + status + ); + } + node._isLoading = true; + node._error = null; + node.renderStatus(); + break; + case "error": + _setStatusNode( + { + title: + tree.options.strings.loadError + + (message ? " (" + message + ")" : ""), + // icon: false, + checkbox: false, + tooltip: details, + }, + status + ); + node._isLoading = false; + node._error = { message: message, details: details }; + node.renderStatus(); + break; + case "nodata": + _setStatusNode( + { + title: message || tree.options.strings.noData, + // icon: false, + checkbox: false, + tooltip: details, + }, + status + ); + node._isLoading = false; + node._error = null; + node.renderStatus(); + break; + default: + $.error("invalid node status " + status); + } + }, + /** + * + * @param {EventData} ctx + */ + nodeToggleExpanded: function (ctx) { + return this.nodeSetExpanded(ctx, !ctx.node.expanded); + }, + /** + * @param {EventData} ctx + */ + nodeToggleSelected: function (ctx) { + var node = ctx.node, + flag = !node.selected; + + // In selectMode: 3 this node may be unselected+partsel, even if + // setSelected(true) was called before, due to `unselectable` children. + // In this case, we now toggle as `setSelected(false)` + if ( + node.partsel && + !node.selected && + node._lastSelectIntent === true + ) { + flag = false; + node.selected = true; // so it is not considered 'nothing to do' + } + node._lastSelectIntent = flag; + return this.nodeSetSelected(ctx, flag); + }, + /** Remove all nodes. + * @param {EventData} ctx + */ + treeClear: function (ctx) { + var tree = ctx.tree; + tree.activeNode = null; + tree.focusNode = null; + tree.$div.find(">ul.fancytree-container").empty(); + // TODO: call destructors and remove reference loops + tree.rootNode.children = null; + tree._callHook("treeStructureChanged", ctx, "clear"); + }, + /** Widget was created (called only once, even it re-initialized). + * @param {EventData} ctx + */ + treeCreate: function (ctx) {}, + /** Widget was destroyed. + * @param {EventData} ctx + */ + treeDestroy: function (ctx) { + this.$div.find(">ul.fancytree-container").remove(); + if (this.$source) { + this.$source.removeClass("fancytree-helper-hidden"); + } + }, + /** Widget was (re-)initialized. + * @param {EventData} ctx + */ + treeInit: function (ctx) { + var tree = ctx.tree, + opts = tree.options; + + //this.debug("Fancytree.treeInit()"); + // Add container to the TAB chain + // See http://www.w3.org/TR/wai-aria-practices/#focus_activedescendant + // #577: Allow to set tabindex to "0", "-1" and "" + tree.$container.attr("tabindex", opts.tabindex); + + // Copy some attributes to tree.data + $.each(TREE_ATTRS, function (i, attr) { + if (opts[attr] !== undefined) { + tree.info("Move option " + attr + " to tree"); + tree[attr] = opts[attr]; + delete opts[attr]; + } + }); + + if (opts.checkboxAutoHide) { + tree.$container.addClass("fancytree-checkbox-auto-hide"); + } + if (opts.rtl) { + tree.$container + .attr("DIR", "RTL") + .addClass("fancytree-rtl"); + } else { + tree.$container + .removeAttr("DIR") + .removeClass("fancytree-rtl"); + } + if (opts.aria) { + tree.$container.attr("role", "tree"); + if (opts.selectMode !== 1) { + tree.$container.attr("aria-multiselectable", true); + } + } + this.treeLoad(ctx); + }, + /** Parse Fancytree from source, as configured in the options. + * @param {EventData} ctx + * @param {object} [source] optional new source (use last data otherwise) + */ + treeLoad: function (ctx, source) { + var metaData, + type, + $ul, + tree = ctx.tree, + $container = ctx.widget.element, + dfd, + // calling context for root node + rootCtx = $.extend({}, ctx, { node: this.rootNode }); + + if (tree.rootNode.children) { + this.treeClear(ctx); + } + source = source || this.options.source; + + if (!source) { + type = $container.data("type") || "html"; + switch (type) { + case "html": + // There should be an embedded `<ul>` with initial nodes, + // but another `<ul class='fancytree-container'>` is appended + // to the tree's <div> on startup anyway. + $ul = $container + .find(">ul") + .not(".fancytree-container") + .first(); + + if ($ul.length) { + $ul.addClass( + "ui-fancytree-source fancytree-helper-hidden" + ); + source = $.ui.fancytree.parseHtml($ul); + // allow to init tree.data.foo from <ul data-foo=''> + this.data = $.extend( + this.data, + _getElementDataAsDict($ul) + ); + } else { + FT.warn( + "No `source` option was passed and container does not contain `<ul>`: assuming `source: []`." + ); + source = []; + } + break; + case "json": + source = $.parseJSON($container.text()); + // $container already contains the <ul>, but we remove the plain (json) text + // $container.empty(); + $container + .contents() + .filter(function () { + return this.nodeType === 3; + }) + .remove(); + if ($.isPlainObject(source)) { + // We got {foo: 'abc', children: [...]} + _assert( + _isArray(source.children), + "if an object is passed as source, it must contain a 'children' array (all other properties are added to 'tree.data')" + ); + metaData = source; + source = source.children; + delete metaData.children; + // Copy some attributes to tree.data + $.each(TREE_ATTRS, function (i, attr) { + if (metaData[attr] !== undefined) { + tree[attr] = metaData[attr]; + delete metaData[attr]; + } + }); + // Copy extra properties to tree.data.foo + $.extend(tree.data, metaData); + } + break; + default: + $.error("Invalid data-type: " + type); + } + } else if (typeof source === "string") { + // TODO: source is an element ID + $.error("Not implemented"); + } + + // preInit is fired when the widget markup is created, but nodes + // not yet loaded + tree._triggerTreeEvent("preInit", null); + + // Trigger fancytreeinit after nodes have been loaded + dfd = this.nodeLoadChildren(rootCtx, source) + .done(function () { + tree._callHook( + "treeStructureChanged", + ctx, + "loadChildren" + ); + tree.render(); + if (ctx.options.selectMode === 3) { + tree.rootNode.fixSelection3FromEndNodes(); + } + if (tree.activeNode && tree.options.activeVisible) { + tree.activeNode.makeVisible(); + } + tree._triggerTreeEvent("init", null, { status: true }); + }) + .fail(function () { + tree.render(); + tree._triggerTreeEvent("init", null, { status: false }); + }); + return dfd; + }, + /** Node was inserted into or removed from the tree. + * @param {EventData} ctx + * @param {boolean} add + * @param {FancytreeNode} node + */ + treeRegisterNode: function (ctx, add, node) { + ctx.tree._callHook( + "treeStructureChanged", + ctx, + add ? "addNode" : "removeNode" + ); + }, + /** Widget got focus. + * @param {EventData} ctx + * @param {boolean} [flag=true] + */ + treeSetFocus: function (ctx, flag, callOpts) { + var targetNode; + + flag = flag !== false; + + // this.debug("treeSetFocus(" + flag + "), callOpts: ", callOpts, this.hasFocus()); + // this.debug(" focusNode: " + this.focusNode); + // this.debug(" activeNode: " + this.activeNode); + if (flag !== this.hasFocus()) { + this._hasFocus = flag; + if (!flag && this.focusNode) { + // Node also looses focus if widget blurs + this.focusNode.setFocus(false); + } else if (flag && (!callOpts || !callOpts.calledByNode)) { + $(this.$container).focus(); + } + this.$container.toggleClass("fancytree-treefocus", flag); + this._triggerTreeEvent(flag ? "focusTree" : "blurTree"); + if (flag && !this.activeNode) { + // #712: Use last mousedowned node ('click' event fires after focusin) + targetNode = + this._lastMousedownNode || this.getFirstChild(); + if (targetNode) { + targetNode.setFocus(); + } + } + } + }, + /** Widget option was set using `$().fancytree("option", "KEY", VALUE)`. + * + * Note: `key` may reference a nested option, e.g. 'dnd5.scroll'. + * In this case `value`contains the complete, modified `dnd5` option hash. + * We can check for changed values like + * if( value.scroll !== tree.options.dnd5.scroll ) {...} + * + * @param {EventData} ctx + * @param {string} key option name + * @param {any} value option value + */ + treeSetOption: function (ctx, key, value) { + var tree = ctx.tree, + callDefault = true, + callCreate = false, + callRender = false; + + switch (key) { + case "aria": + case "checkbox": + case "icon": + case "minExpandLevel": + case "tabindex": + // tree._callHook("treeCreate", tree); + callCreate = true; + callRender = true; + break; + case "checkboxAutoHide": + tree.$container.toggleClass( + "fancytree-checkbox-auto-hide", + !!value + ); + break; + case "escapeTitles": + case "tooltip": + callRender = true; + break; + case "rtl": + if (value === false) { + tree.$container + .removeAttr("DIR") + .removeClass("fancytree-rtl"); + } else { + tree.$container + .attr("DIR", "RTL") + .addClass("fancytree-rtl"); + } + callRender = true; + break; + case "source": + callDefault = false; + tree._callHook("treeLoad", tree, value); + callRender = true; + break; + } + tree.debug( + "set option " + + key + + "=" + + value + + " <" + + typeof value + + ">" + ); + if (callDefault) { + if (this.widget._super) { + // jQuery UI 1.9+ + this.widget._super.call(this.widget, key, value); + } else { + // jQuery UI <= 1.8, we have to manually invoke the _setOption method from the base widget + $.Widget.prototype._setOption.call( + this.widget, + key, + value + ); + } + } + if (callCreate) { + tree._callHook("treeCreate", tree); + } + if (callRender) { + tree.render(true, false); // force, not-deep + } + }, + /** A Node was added, removed, moved, or it's visibility changed. + * @param {EventData} ctx + */ + treeStructureChanged: function (ctx, type) {}, + } + ); + + /******************************************************************************* + * jQuery UI widget boilerplate + */ + + /** + * The plugin (derrived from [jQuery.Widget](http://api.jqueryui.com/jQuery.widget/)). + * + * **Note:** + * These methods implement the standard jQuery UI widget API. + * It is recommended to use methods of the {Fancytree} instance instead + * + * @example + * // DEPRECATED: Access jQuery UI widget methods and members: + * var tree = $("#tree").fancytree("getTree"); + * var node = $("#tree").fancytree("getActiveNode"); + * + * // RECOMMENDED: Use the Fancytree object API + * var tree = $.ui.fancytree.getTree("#tree"); + * var node = tree.getActiveNode(); + * + * // or you may already have stored the tree instance upon creation: + * import {createTree, version} from 'jquery.fancytree' + * const tree = createTree('#tree', { ... }); + * var node = tree.getActiveNode(); + * + * @see {Fancytree_Static#getTree} + * @deprecated Use methods of the {Fancytree} instance instead + * @mixin Fancytree_Widget + */ + + $.widget( + "ui.fancytree", + /** @lends Fancytree_Widget# */ + { + /**These options will be used as defaults + * @type {FancytreeOptions} + */ + options: { + activeVisible: true, + ajax: { + type: "GET", + cache: false, // false: Append random '_' argument to the request url to prevent caching. + // timeout: 0, // >0: Make sure we get an ajax error if server is unreachable + dataType: "json", // Expect json format and pass json object to callbacks. + }, + aria: true, + autoActivate: true, + autoCollapse: false, + autoScroll: false, + checkbox: false, + clickFolderMode: 4, + copyFunctionsToData: false, + debugLevel: null, // 0..4 (null: use global setting $.ui.fancytree.debugLevel) + disabled: false, // TODO: required anymore? + enableAspx: 42, // TODO: this is truethy, but distinguishable from true: default will change to false in the future + escapeTitles: false, + extensions: [], + focusOnSelect: false, + generateIds: false, + icon: true, + idPrefix: "ft_", + keyboard: true, + keyPathSeparator: "/", + minExpandLevel: 1, + nodata: true, // (bool, string, or callback) display message, when no data available + quicksearch: false, + rtl: false, + scrollOfs: { top: 0, bottom: 0 }, + scrollParent: null, + selectMode: 2, + strings: { + loading: "Loading...", // … would be escaped when escapeTitles is true + loadError: "Load error!", + moreData: "More...", + noData: "No data.", + }, + tabindex: "0", + titlesTabbable: false, + toggleEffect: { effect: "slideToggle", duration: 200 }, //< "toggle" or "slideToggle" to use jQuery instead of jQueryUI for toggleEffect animation + tooltip: false, + treeId: null, + _classNames: { + active: "fancytree-active", + animating: "fancytree-animating", + combinedExpanderPrefix: "fancytree-exp-", + combinedIconPrefix: "fancytree-ico-", + error: "fancytree-error", + expanded: "fancytree-expanded", + focused: "fancytree-focused", + folder: "fancytree-folder", + hasChildren: "fancytree-has-children", + lastsib: "fancytree-lastsib", + lazy: "fancytree-lazy", + loading: "fancytree-loading", + node: "fancytree-node", + partload: "fancytree-partload", + partsel: "fancytree-partsel", + radio: "fancytree-radio", + selected: "fancytree-selected", + statusNodePrefix: "fancytree-statusnode-", + unselectable: "fancytree-unselectable", + }, + // events + lazyLoad: null, + postProcess: null, + }, + _deprecationWarning: function (name) { + var tree = this.tree; + + if (tree && tree.options.debugLevel >= 3) { + tree.warn( + "$().fancytree('" + + name + + "') is deprecated (see https://wwwendt.de/tech/fancytree/doc/jsdoc/Fancytree_Widget.html" + ); + } + }, + /* Set up the widget, Called on first $().fancytree() */ + _create: function () { + this.tree = new Fancytree(this); + + this.$source = + this.source || this.element.data("type") === "json" + ? this.element + : this.element.find(">ul").first(); + // Subclass Fancytree instance with all enabled extensions + var extension, + extName, + i, + opts = this.options, + extensions = opts.extensions, + base = this.tree; + + for (i = 0; i < extensions.length; i++) { + extName = extensions[i]; + extension = $.ui.fancytree._extensions[extName]; + if (!extension) { + $.error( + "Could not apply extension '" + + extName + + "' (it is not registered, did you forget to include it?)" + ); + } + // Add extension options as tree.options.EXTENSION + // _assert(!this.tree.options[extName], "Extension name must not exist as option name: " + extName); + + // console.info("extend " + extName, extension.options, this.tree.options[extName]) + // issue #876: we want to replace custom array-options, not merge them + this.tree.options[extName] = _simpleDeepMerge( + {}, + extension.options, + this.tree.options[extName] + ); + // this.tree.options[extName] = $.extend(true, {}, extension.options, this.tree.options[extName]); + + // console.info("extend " + extName + " =>", this.tree.options[extName]) + // console.info("extend " + extName + " org default =>", extension.options) + + // Add a namespace tree.ext.EXTENSION, to hold instance data + _assert( + this.tree.ext[extName] === undefined, + "Extension name must not exist as Fancytree.ext attribute: '" + + extName + + "'" + ); + // this.tree[extName] = extension; + this.tree.ext[extName] = {}; + // Subclass Fancytree methods using proxies. + _subclassObject(this.tree, base, extension, extName); + // current extension becomes base for the next extension + base = extension; + } + // + if (opts.icons !== undefined) { + // 2015-11-16 + if (opts.icon === true) { + this.tree.warn( + "'icons' tree option is deprecated since v2.14.0: use 'icon' instead" + ); + opts.icon = opts.icons; + } else { + $.error( + "'icons' tree option is deprecated since v2.14.0: use 'icon' only instead" + ); + } + } + if (opts.iconClass !== undefined) { + // 2015-11-16 + if (opts.icon) { + $.error( + "'iconClass' tree option is deprecated since v2.14.0: use 'icon' only instead" + ); + } else { + this.tree.warn( + "'iconClass' tree option is deprecated since v2.14.0: use 'icon' instead" + ); + opts.icon = opts.iconClass; + } + } + if (opts.tabbable !== undefined) { + // 2016-04-04 + opts.tabindex = opts.tabbable ? "0" : "-1"; + this.tree.warn( + "'tabbable' tree option is deprecated since v2.17.0: use 'tabindex='" + + opts.tabindex + + "' instead" + ); + } + // + this.tree._callHook("treeCreate", this.tree); + // Note: 'fancytreecreate' event is fired by widget base class + // this.tree._triggerTreeEvent("create"); + }, + + /* Called on every $().fancytree() */ + _init: function () { + this.tree._callHook("treeInit", this.tree); + // TODO: currently we call bind after treeInit, because treeInit + // might change tree.$container. + // It would be better, to move event binding into hooks altogether + this._bind(); + }, + + /* Use the _setOption method to respond to changes to options. */ + _setOption: function (key, value) { + return this.tree._callHook( + "treeSetOption", + this.tree, + key, + value + ); + }, + + /** Use the destroy method to clean up any modifications your widget has made to the DOM */ + _destroy: function () { + this._unbind(); + this.tree._callHook("treeDestroy", this.tree); + // In jQuery UI 1.8, you must invoke the destroy method from the base widget + // $.Widget.prototype.destroy.call(this); + // TODO: delete tree and nodes to make garbage collect easier? + // TODO: In jQuery UI 1.9 and above, you would define _destroy instead of destroy and not call the base method + }, + + // ------------------------------------------------------------------------- + + /* Remove all event handlers for our namespace */ + _unbind: function () { + var ns = this.tree._ns; + this.element.off(ns); + this.tree.$container.off(ns); + $(document).off(ns); + }, + /* Add mouse and kyboard handlers to the container */ + _bind: function () { + var self = this, + opts = this.options, + tree = this.tree, + ns = tree._ns; + // selstartEvent = ( $.support.selectstart ? "selectstart" : "mousedown" ) + + // Remove all previuous handlers for this tree + this._unbind(); + + //alert("keydown" + ns + "foc=" + tree.hasFocus() + tree.$container); + // tree.debug("bind events; container: ", tree.$container); + tree.$container + .on("focusin" + ns + " focusout" + ns, function (event) { + var node = FT.getNode(event), + flag = event.type === "focusin"; + + if (!flag && node && $(event.target).is("a")) { + // #764 + node.debug( + "Ignored focusout on embedded <a> element." + ); + return; + } + // tree.treeOnFocusInOut.call(tree, event); + // tree.debug("Tree container got event " + event.type, node, event, FT.getEventTarget(event)); + if (flag) { + if (tree._getExpiringValue("focusin")) { + // #789: IE 11 may send duplicate focusin events + tree.debug("Ignored double focusin."); + return; + } + tree._setExpiringValue("focusin", true, 50); + + if (!node) { + // #789: IE 11 may send focusin before mousdown(?) + node = tree._getExpiringValue("mouseDownNode"); + if (node) { + tree.debug( + "Reconstruct mouse target for focusin from recent event." + ); + } + } + } + if (node) { + // For example clicking into an <input> that is part of a node + tree._callHook( + "nodeSetFocus", + tree._makeHookContext(node, event), + flag + ); + } else { + if ( + tree.tbody && + $(event.target).parents( + "table.fancytree-container > thead" + ).length + ) { + // #767: ignore events in the table's header + tree.debug( + "Ignore focus event outside table body.", + event + ); + } else { + tree._callHook("treeSetFocus", tree, flag); + } + } + }) + .on( + "selectstart" + ns, + "span.fancytree-title", + function (event) { + // prevent mouse-drags to select text ranges + // tree.debug("<span title> got event " + event.type); + event.preventDefault(); + } + ) + .on("keydown" + ns, function (event) { + // TODO: also bind keyup and keypress + // tree.debug("got event " + event.type + ", hasFocus:" + tree.hasFocus()); + // if(opts.disabled || opts.keyboard === false || !tree.hasFocus() ){ + if (opts.disabled || opts.keyboard === false) { + return true; + } + var res, + node = tree.focusNode, // node may be null + ctx = tree._makeHookContext(node || tree, event), + prevPhase = tree.phase; + + try { + tree.phase = "userEvent"; + // If a 'fancytreekeydown' handler returns false, skip the default + // handling (implemented by tree.nodeKeydown()). + if (node) { + res = tree._triggerNodeEvent( + "keydown", + node, + event + ); + } else { + res = tree._triggerTreeEvent("keydown", event); + } + if (res === "preventNav") { + res = true; // prevent keyboard navigation, but don't prevent default handling of embedded input controls + } else if (res !== false) { + res = tree._callHook("nodeKeydown", ctx); + } + return res; + } finally { + tree.phase = prevPhase; + } + }) + .on("mousedown" + ns, function (event) { + var et = FT.getEventTarget(event); + // self.tree.debug("event(" + event.type + "): node: ", et.node); + // #712: Store the clicked node, so we can use it when we get a focusin event + // ('click' event fires after focusin) + // tree.debug("event(" + event.type + "): node: ", et.node); + tree._lastMousedownNode = et ? et.node : null; + // #789: Store the node also for a short period, so we can use it + // in a *resulting* focusin event + tree._setExpiringValue( + "mouseDownNode", + tree._lastMousedownNode + ); + }) + .on("click" + ns + " dblclick" + ns, function (event) { + if (opts.disabled) { + return true; + } + var ctx, + et = FT.getEventTarget(event), + node = et.node, + tree = self.tree, + prevPhase = tree.phase; + + // self.tree.debug("event(" + event.type + "): node: ", node); + if (!node) { + return true; // Allow bubbling of other events + } + ctx = tree._makeHookContext(node, event); + // self.tree.debug("event(" + event.type + "): node: ", node); + try { + tree.phase = "userEvent"; + switch (event.type) { + case "click": + ctx.targetType = et.type; + if (node.isPagingNode()) { + return ( + tree._triggerNodeEvent( + "clickPaging", + ctx, + event + ) === true + ); + } + return tree._triggerNodeEvent( + "click", + ctx, + event + ) === false + ? false + : tree._callHook("nodeClick", ctx); + case "dblclick": + ctx.targetType = et.type; + return tree._triggerNodeEvent( + "dblclick", + ctx, + event + ) === false + ? false + : tree._callHook("nodeDblclick", ctx); + } + } finally { + tree.phase = prevPhase; + } + }); + }, + /** Return the active node or null. + * @returns {FancytreeNode} + * @deprecated Use methods of the Fancytree instance instead (<a href="Fancytree_Widget.html">example above</a>). + */ + getActiveNode: function () { + this._deprecationWarning("getActiveNode"); + return this.tree.activeNode; + }, + /** Return the matching node or null. + * @param {string} key + * @returns {FancytreeNode} + * @deprecated Use methods of the Fancytree instance instead (<a href="Fancytree_Widget.html">example above</a>). + */ + getNodeByKey: function (key) { + this._deprecationWarning("getNodeByKey"); + return this.tree.getNodeByKey(key); + }, + /** Return the invisible system root node. + * @returns {FancytreeNode} + * @deprecated Use methods of the Fancytree instance instead (<a href="Fancytree_Widget.html">example above</a>). + */ + getRootNode: function () { + this._deprecationWarning("getRootNode"); + return this.tree.rootNode; + }, + /** Return the current tree instance. + * @returns {Fancytree} + * @deprecated Use `$.ui.fancytree.getTree()` instead (<a href="Fancytree_Widget.html">example above</a>). + */ + getTree: function () { + this._deprecationWarning("getTree"); + return this.tree; + }, + } + ); + + // $.ui.fancytree was created by the widget factory. Create a local shortcut: + FT = $.ui.fancytree; + + /** + * Static members in the `$.ui.fancytree` namespace. + * This properties and methods can be accessed without instantiating a concrete + * Fancytree instance. + * + * @example + * // Access static members: + * var node = $.ui.fancytree.getNode(element); + * alert($.ui.fancytree.version); + * + * @mixin Fancytree_Static + */ + $.extend( + $.ui.fancytree, + /** @lends Fancytree_Static# */ + { + /** Version number `"MAJOR.MINOR.PATCH"` + * @type {string} */ + version: "2.38.3", // Set to semver by 'grunt release' + /** @type {string} + * @description `"production" for release builds` */ + buildType: "production", // Set to 'production' by 'grunt build' + /** @type {int} + * @description 0: silent .. 5: verbose (default: 3 for release builds). */ + debugLevel: 3, // Set to 3 by 'grunt build' + // Used by $.ui.fancytree.debug() and as default for tree.options.debugLevel + + _nextId: 1, + _nextNodeKey: 1, + _extensions: {}, + // focusTree: null, + + /** Expose class object as `$.ui.fancytree._FancytreeClass`. + * Useful to extend `$.ui.fancytree._FancytreeClass.prototype`. + * @type {Fancytree} + */ + _FancytreeClass: Fancytree, + /** Expose class object as $.ui.fancytree._FancytreeNodeClass + * Useful to extend `$.ui.fancytree._FancytreeNodeClass.prototype`. + * @type {FancytreeNode} + */ + _FancytreeNodeClass: FancytreeNode, + /* Feature checks to provide backwards compatibility */ + jquerySupports: { + // http://jqueryui.com/upgrade-guide/1.9/#deprecated-offset-option-merged-into-my-and-at + positionMyOfs: isVersionAtLeast($.ui.version, 1, 9), + }, + /** Throw an error if condition fails (debug method). + * @param {boolean} cond + * @param {string} msg + */ + assert: function (cond, msg) { + return _assert(cond, msg); + }, + /** Create a new Fancytree instance on a target element. + * + * @param {Element | jQueryObject | string} el Target DOM element or selector + * @param {FancytreeOptions} [opts] Fancytree options + * @returns {Fancytree} new tree instance + * @example + * var tree = $.ui.fancytree.createTree("#tree", { + * source: {url: "my/webservice"} + * }); // Create tree for this matching element + * + * @since 2.25 + */ + createTree: function (el, opts) { + var $tree = $(el).fancytree(opts); + return FT.getTree($tree); + }, + /** Return a function that executes *fn* at most every *timeout* ms. + * @param {integer} timeout + * @param {function} fn + * @param {boolean} [invokeAsap=false] + * @param {any} [ctx] + */ + debounce: function (timeout, fn, invokeAsap, ctx) { + var timer; + if (arguments.length === 3 && typeof invokeAsap !== "boolean") { + ctx = invokeAsap; + invokeAsap = false; + } + return function () { + var args = arguments; + ctx = ctx || this; + // eslint-disable-next-line no-unused-expressions + invokeAsap && !timer && fn.apply(ctx, args); + clearTimeout(timer); + timer = setTimeout(function () { + // eslint-disable-next-line no-unused-expressions + invokeAsap || fn.apply(ctx, args); + timer = null; + }, timeout); + }; + }, + /** Write message to console if debugLevel >= 4 + * @param {string} msg + */ + debug: function (msg) { + if ($.ui.fancytree.debugLevel >= 4) { + consoleApply("log", arguments); + } + }, + /** Write error message to console if debugLevel >= 1. + * @param {string} msg + */ + error: function (msg) { + if ($.ui.fancytree.debugLevel >= 1) { + consoleApply("error", arguments); + } + }, + /** Convert `<`, `>`, `&`, `"`, `'`, and `/` to the equivalent entities. + * + * @param {string} s + * @returns {string} + */ + escapeHtml: function (s) { + return ("" + s).replace(REX_HTML, function (s) { + return ENTITY_MAP[s]; + }); + }, + /** Make jQuery.position() arguments backwards compatible, i.e. if + * jQuery UI version <= 1.8, convert + * { my: "left+3 center", at: "left bottom", of: $target } + * to + * { my: "left center", at: "left bottom", of: $target, offset: "3 0" } + * + * See http://jqueryui.com/upgrade-guide/1.9/#deprecated-offset-option-merged-into-my-and-at + * and http://jsfiddle.net/mar10/6xtu9a4e/ + * + * @param {object} opts + * @returns {object} the (potentially modified) original opts hash object + */ + fixPositionOptions: function (opts) { + if (opts.offset || ("" + opts.my + opts.at).indexOf("%") >= 0) { + $.error( + "expected new position syntax (but '%' is not supported)" + ); + } + if (!$.ui.fancytree.jquerySupports.positionMyOfs) { + var // parse 'left+3 center' into ['left+3 center', 'left', '+3', 'center', undefined] + myParts = /(\w+)([+-]?\d+)?\s+(\w+)([+-]?\d+)?/.exec( + opts.my + ), + atParts = /(\w+)([+-]?\d+)?\s+(\w+)([+-]?\d+)?/.exec( + opts.at + ), + // convert to numbers + dx = + (myParts[2] ? +myParts[2] : 0) + + (atParts[2] ? +atParts[2] : 0), + dy = + (myParts[4] ? +myParts[4] : 0) + + (atParts[4] ? +atParts[4] : 0); + + opts = $.extend({}, opts, { + // make a copy and overwrite + my: myParts[1] + " " + myParts[3], + at: atParts[1] + " " + atParts[3], + }); + if (dx || dy) { + opts.offset = "" + dx + " " + dy; + } + } + return opts; + }, + /** Return a {node: FancytreeNode, type: TYPE} object for a mouse event. + * + * @param {Event} event Mouse event, e.g. click, ... + * @returns {object} Return a {node: FancytreeNode, type: TYPE} object + * TYPE: 'title' | 'prefix' | 'expander' | 'checkbox' | 'icon' | undefined + */ + getEventTarget: function (event) { + var $target, + tree, + tcn = event && event.target ? event.target.className : "", + res = { node: this.getNode(event.target), type: undefined }; + // We use a fast version of $(res.node).hasClass() + // See http://jsperf.com/test-for-classname/2 + if (/\bfancytree-title\b/.test(tcn)) { + res.type = "title"; + } else if (/\bfancytree-expander\b/.test(tcn)) { + res.type = + res.node.hasChildren() === false + ? "prefix" + : "expander"; + // }else if( /\bfancytree-checkbox\b/.test(tcn) || /\bfancytree-radio\b/.test(tcn) ){ + } else if (/\bfancytree-checkbox\b/.test(tcn)) { + res.type = "checkbox"; + } else if (/\bfancytree(-custom)?-icon\b/.test(tcn)) { + res.type = "icon"; + } else if (/\bfancytree-node\b/.test(tcn)) { + // Somewhere near the title + res.type = "title"; + } else if (event && event.target) { + $target = $(event.target); + if ($target.is("ul[role=group]")) { + // #nnn: Clicking right to a node may hit the surrounding UL + tree = res.node && res.node.tree; + (tree || FT).debug("Ignoring click on outer UL."); + res.node = null; + } else if ($target.closest(".fancytree-title").length) { + // #228: clicking an embedded element inside a title + res.type = "title"; + } else if ($target.closest(".fancytree-checkbox").length) { + // E.g. <svg> inside checkbox span + res.type = "checkbox"; + } else if ($target.closest(".fancytree-expander").length) { + res.type = "expander"; + } + } + return res; + }, + /** Return a string describing the affected node region for a mouse event. + * + * @param {Event} event Mouse event, e.g. click, mousemove, ... + * @returns {string} 'title' | 'prefix' | 'expander' | 'checkbox' | 'icon' | undefined + */ + getEventTargetType: function (event) { + return this.getEventTarget(event).type; + }, + /** Return a FancytreeNode instance from element, event, or jQuery object. + * + * @param {Element | jQueryObject | Event} el + * @returns {FancytreeNode} matching node or null + */ + getNode: function (el) { + if (el instanceof FancytreeNode) { + return el; // el already was a FancytreeNode + } else if (el instanceof $) { + el = el[0]; // el was a jQuery object: use the DOM element + } else if (el.originalEvent !== undefined) { + el = el.target; // el was an Event + } + while (el) { + if (el.ftnode) { + return el.ftnode; + } + el = el.parentNode; + } + return null; + }, + /** Return a Fancytree instance, from element, index, event, or jQueryObject. + * + * @param {Element | jQueryObject | Event | integer | string} [el] + * @returns {Fancytree} matching tree or null + * @example + * $.ui.fancytree.getTree(); // Get first Fancytree instance on page + * $.ui.fancytree.getTree(1); // Get second Fancytree instance on page + * $.ui.fancytree.getTree(event); // Get tree for this mouse- or keyboard event + * $.ui.fancytree.getTree("foo"); // Get tree for this `opts.treeId` + * $.ui.fancytree.getTree("#tree"); // Get tree for this matching element + * + * @since 2.13 + */ + getTree: function (el) { + var widget, + orgEl = el; + + if (el instanceof Fancytree) { + return el; // el already was a Fancytree + } + if (el === undefined) { + el = 0; // get first tree + } + if (typeof el === "number") { + el = $(".fancytree-container").eq(el); // el was an integer: return nth instance + } else if (typeof el === "string") { + // `el` may be a treeId or a selector: + el = $("#ft-id-" + orgEl).eq(0); + if (!el.length) { + el = $(orgEl).eq(0); // el was a selector: use first match + } + } else if ( + el instanceof Element || + el instanceof HTMLDocument + ) { + el = $(el); + } else if (el instanceof $) { + el = el.eq(0); // el was a jQuery object: use the first + } else if (el.originalEvent !== undefined) { + el = $(el.target); // el was an Event + } + // el is a jQuery object wit one element here + el = el.closest(":ui-fancytree"); + widget = el.data("ui-fancytree") || el.data("fancytree"); // the latter is required by jQuery <= 1.8 + return widget ? widget.tree : null; + }, + /** Return an option value that has a default, but may be overridden by a + * callback or a node instance attribute. + * + * Evaluation sequence: + * + * If `tree.options.<optionName>` is a callback that returns something, use that. + * Else if `node.<optionName>` is defined, use that. + * Else if `tree.options.<optionName>` is a value, use that. + * Else use `defaultValue`. + * + * @param {string} optionName name of the option property (on node and tree) + * @param {FancytreeNode} node passed to the callback + * @param {object} nodeObject where to look for the local option property, e.g. `node` or `node.data` + * @param {object} treeOption where to look for the tree option, e.g. `tree.options` or `tree.options.dnd5` + * @param {any} [defaultValue] + * @returns {any} + * + * @example + * // Check for node.foo, tree,options.foo(), and tree.options.foo: + * $.ui.fancytree.evalOption("foo", node, node, tree.options); + * // Check for node.data.bar, tree,options.qux.bar(), and tree.options.qux.bar: + * $.ui.fancytree.evalOption("bar", node, node.data, tree.options.qux); + * + * @since 2.22 + */ + evalOption: function ( + optionName, + node, + nodeObject, + treeOptions, + defaultValue + ) { + var ctx, + res, + tree = node.tree, + treeOpt = treeOptions[optionName], + nodeOpt = nodeObject[optionName]; + + if (_isFunction(treeOpt)) { + ctx = { + node: node, + tree: tree, + widget: tree.widget, + options: tree.widget.options, + typeInfo: tree.types[node.type] || {}, + }; + res = treeOpt.call(tree, { type: optionName }, ctx); + if (res == null) { + res = nodeOpt; + } + } else { + res = nodeOpt == null ? treeOpt : nodeOpt; + } + if (res == null) { + res = defaultValue; // no option set at all: return default + } + return res; + }, + /** Set expander, checkbox, or node icon, supporting string and object format. + * + * @param {Element | jQueryObject} span + * @param {string} baseClass + * @param {string | object} icon + * @since 2.27 + */ + setSpanIcon: function (span, baseClass, icon) { + var $span = $(span); + + if (typeof icon === "string") { + $span.attr("class", baseClass + " " + icon); + } else { + // support object syntax: { text: ligature, addClasse: classname } + if (icon.text) { + $span.text("" + icon.text); + } else if (icon.html) { + span.innerHTML = icon.html; + } + $span.attr( + "class", + baseClass + " " + (icon.addClass || "") + ); + } + }, + /** Convert a keydown or mouse event to a canonical string like 'ctrl+a', + * 'ctrl+shift+f2', 'shift+leftdblclick'. + * + * This is especially handy for switch-statements in event handlers. + * + * @param {event} + * @returns {string} + * + * @example + + switch( $.ui.fancytree.eventToString(event) ) { + case "-": + tree.nodeSetExpanded(ctx, false); + break; + case "shift+return": + tree.nodeSetActive(ctx, true); + break; + case "down": + res = node.navigate(event.which, activate); + break; + default: + handled = false; + } + if( handled ){ + event.preventDefault(); + } + */ + eventToString: function (event) { + // Poor-man's hotkeys. See here for a complete implementation: + // https://github.com/jeresig/jquery.hotkeys + var which = event.which, + et = event.type, + s = []; + + if (event.altKey) { + s.push("alt"); + } + if (event.ctrlKey) { + s.push("ctrl"); + } + if (event.metaKey) { + s.push("meta"); + } + if (event.shiftKey) { + s.push("shift"); + } + + if (et === "click" || et === "dblclick") { + s.push(MOUSE_BUTTONS[event.button] + et); + } else if (et === "wheel") { + s.push(et); + } else if (!IGNORE_KEYCODES[which]) { + s.push( + SPECIAL_KEYCODES[which] || + String.fromCharCode(which).toLowerCase() + ); + } + return s.join("+"); + }, + /** Write message to console if debugLevel >= 3 + * @param {string} msg + */ + info: function (msg) { + if ($.ui.fancytree.debugLevel >= 3) { + consoleApply("info", arguments); + } + }, + /* @deprecated: use eventToString(event) instead. + */ + keyEventToString: function (event) { + this.warn( + "keyEventToString() is deprecated: use eventToString()" + ); + return this.eventToString(event); + }, + /** Return a wrapped handler method, that provides `this._super`. + * + * @example + // Implement `opts.createNode` event to add the 'draggable' attribute + $.ui.fancytree.overrideMethod(ctx.options, "createNode", function(event, data) { + // Default processing if any + this._super.apply(this, arguments); + // Add 'draggable' attribute + data.node.span.draggable = true; + }); + * + * @param {object} instance + * @param {string} methodName + * @param {function} handler + * @param {object} [context] optional context + */ + overrideMethod: function (instance, methodName, handler, context) { + var prevSuper, + _super = instance[methodName] || $.noop; + + instance[methodName] = function () { + var self = context || this; + + try { + prevSuper = self._super; + self._super = _super; + return handler.apply(self, arguments); + } finally { + self._super = prevSuper; + } + }; + }, + /** + * Parse tree data from HTML <ul> markup + * + * @param {jQueryObject} $ul + * @returns {NodeData[]} + */ + parseHtml: function ($ul) { + var classes, + className, + extraClasses, + i, + iPos, + l, + tmp, + tmp2, + $children = $ul.find(">li"), + children = []; + + $children.each(function () { + var allData, + lowerCaseAttr, + $li = $(this), + $liSpan = $li.find(">span", this).first(), + $liA = $liSpan.length ? null : $li.find(">a").first(), + d = { tooltip: null, data: {} }; + + if ($liSpan.length) { + d.title = $liSpan.html(); + } else if ($liA && $liA.length) { + // If a <li><a> tag is specified, use it literally and extract href/target. + d.title = $liA.html(); + d.data.href = $liA.attr("href"); + d.data.target = $liA.attr("target"); + d.tooltip = $liA.attr("title"); + } else { + // If only a <li> tag is specified, use the trimmed string up to + // the next child <ul> tag. + d.title = $li.html(); + iPos = d.title.search(/<ul/i); + if (iPos >= 0) { + d.title = d.title.substring(0, iPos); + } + } + d.title = _trim(d.title); + + // Make sure all fields exist + for (i = 0, l = CLASS_ATTRS.length; i < l; i++) { + d[CLASS_ATTRS[i]] = undefined; + } + // Initialize to `true`, if class is set and collect extraClasses + classes = this.className.split(" "); + extraClasses = []; + for (i = 0, l = classes.length; i < l; i++) { + className = classes[i]; + if (CLASS_ATTR_MAP[className]) { + d[className] = true; + } else { + extraClasses.push(className); + } + } + d.extraClasses = extraClasses.join(" "); + + // Parse node options from ID, title and class attributes + tmp = $li.attr("title"); + if (tmp) { + d.tooltip = tmp; // overrides <a title='...'> + } + tmp = $li.attr("id"); + if (tmp) { + d.key = tmp; + } + // Translate hideCheckbox -> checkbox:false + if ($li.attr("hideCheckbox")) { + d.checkbox = false; + } + // Add <li data-NAME='...'> as node.data.NAME + allData = _getElementDataAsDict($li); + if (allData && !$.isEmptyObject(allData)) { + // #507: convert data-hidecheckbox (lower case) to hideCheckbox + for (lowerCaseAttr in NODE_ATTR_LOWERCASE_MAP) { + if (_hasProp(allData, lowerCaseAttr)) { + allData[ + NODE_ATTR_LOWERCASE_MAP[lowerCaseAttr] + ] = allData[lowerCaseAttr]; + delete allData[lowerCaseAttr]; + } + } + // #56: Allow to set special node.attributes from data-... + for (i = 0, l = NODE_ATTRS.length; i < l; i++) { + tmp = NODE_ATTRS[i]; + tmp2 = allData[tmp]; + if (tmp2 != null) { + delete allData[tmp]; + d[tmp] = tmp2; + } + } + // All other data-... goes to node.data... + $.extend(d.data, allData); + } + // Recursive reading of child nodes, if LI tag contains an UL tag + $ul = $li.find(">ul").first(); + if ($ul.length) { + d.children = $.ui.fancytree.parseHtml($ul); + } else { + d.children = d.lazy ? undefined : null; + } + children.push(d); + // FT.debug("parse ", d, children); + }); + return children; + }, + /** Add Fancytree extension definition to the list of globally available extensions. + * + * @param {object} definition + */ + registerExtension: function (definition) { + _assert( + definition.name != null, + "extensions must have a `name` property." + ); + _assert( + definition.version != null, + "extensions must have a `version` property." + ); + $.ui.fancytree._extensions[definition.name] = definition; + }, + /** Replacement for the deprecated `jQuery.trim()`. + * + * @param {string} text + */ + trim: _trim, + /** Inverse of escapeHtml(). + * + * @param {string} s + * @returns {string} + */ + unescapeHtml: function (s) { + var e = document.createElement("div"); + e.innerHTML = s; + return e.childNodes.length === 0 + ? "" + : e.childNodes[0].nodeValue; + }, + /** Write warning message to console if debugLevel >= 2. + * @param {string} msg + */ + warn: function (msg) { + if ($.ui.fancytree.debugLevel >= 2) { + consoleApply("warn", arguments); + } + }, + } + ); + + // Value returned by `require('jquery.fancytree')` + return $.ui.fancytree; +}); // End of closure diff --git a/plugins/55/indexmenu/scripts/fancytree/modules/jquery.fancytree.logger.js b/plugins/55/indexmenu/scripts/fancytree/modules/jquery.fancytree.logger.js new file mode 100644 index 0000000..39a4264 --- /dev/null +++ b/plugins/55/indexmenu/scripts/fancytree/modules/jquery.fancytree.logger.js @@ -0,0 +1,309 @@ +/*! + * jquery.fancytree.logger.js + * + * Miscellaneous debug extensions. + * (Extension module for jquery.fancytree.js: https://github.com/mar10/fancytree/) + * + * Copyright (c) 2008-2023, Martin Wendt (https://wwWendt.de) + * + * Released under the MIT license + * https://github.com/mar10/fancytree/wiki/LicenseInfo + * + * @version 2.38.3 + * @date 2023-02-01T20:52:50Z + */ + +(function (factory) { + if (typeof define === "function" && define.amd) { + // AMD. Register as an anonymous module. + define(["jquery", "./jquery.fancytree"], factory); + } else if (typeof module === "object" && module.exports) { + // Node/CommonJS + require("./jquery.fancytree"); + module.exports = factory(require("jquery")); + } else { + // Browser globals + factory(jQuery); + } +})(function ($) { + "use strict"; + + /****************************************************************************** + * Private functions and variables + */ + var i, + FT = $.ui.fancytree, + PREFIX = "ft-logger: ", + logLine = window.console.log, + // HOOK_NAMES = "nodeClick nodeCollapseSiblings".split(" "), + TREE_EVENT_NAMES = + "beforeRestore beforeUpdateViewport blurTree create init focusTree preInit restore updateViewport".split( + " " + ), + NODE_EVENT_NAMES = + "activate activateCell beforeActivate beforeExpand beforeSelect blur click collapse createNode dblclick deactivate defaultGridAction expand enhanceTitle focus keydown keypress lazyLoad loadChildren loadError modifyChild postProcess renderNode renderTitle select".split( + " " + ), + EVENT_NAMES = TREE_EVENT_NAMES.concat(NODE_EVENT_NAMES), + // HOOK_NAME_MAP = {}, + EVENT_NAME_MAP = {}; + + /* + */ + // for (i = 0; i < HOOK_NAMES.length; i++) { + // HOOK_NAME_MAP[HOOK_NAMES[i]] = true; + // } + for (i = 0; i < EVENT_NAMES.length; i++) { + EVENT_NAME_MAP[EVENT_NAMES[i]] = true; + } + + function getBrowserInfo() { + var n = navigator.appName, + ua = navigator.userAgent, + tem, + m = ua.match( + /(opera|chrome|safari|firefox|msie)\/?\s*(\.?\d+(\.\d+)*)/i + ); + + if (m && (tem = ua.match(/version\/([.\d]+)/i)) !== null) { + m[2] = tem[1]; + } + m = m ? [m[1], m[2]] : [n, navigator.appVersion, "-?"]; + return m.join(", "); + } + + function logEvent(event, data) { + var res, + self = this, + // logName = PREFIX + "event." + event.type, + opts = data.options.logger, + tree = data.tree, + // widget = data.widget, + obj = data.node || tree, + logName = PREFIX + "event." + event.type + " (" + obj + ")"; + + if ( + !opts.traceEvents || + (opts.traceEvents !== true && $.inArray(name, opts.traceEvents) < 0) + ) { + return self._super.apply(self, arguments); + } + if ( + (self._super && opts.timings === true) || + (opts.timings && $.inArray(name, opts.timings) >= 0) + ) { + // if( name === "nodeRender" ) { logName += obj; } // allow timing for recursive calls + // logName += " (" + obj + ")"; + window.console.time(logName); + res = self._super.apply(self, arguments); + window.console.timeEnd(logName); + } else { + // obj.info(logName, data); + logLine(logName, event, data); + res = self._super.apply(self, arguments); + } + return res; + } + + function logHook(name, this_, args, extra) { + var res, + ctx = args[0], + opts = ctx.options.logger, + obj = ctx.node || ctx.tree, + logName = PREFIX + "hook." + name + " (" + obj + ")"; + + if ( + !opts.traceHooks || + (opts.traceHooks !== true && $.inArray(name, opts.traceHooks) < 0) + ) { + return this_._superApply.call(this_, args); + } + if ( + opts.timings === true || + (opts.timings && $.inArray(name, opts.timings) >= 0) + ) { + // if( name === "nodeRender" ) { logName += obj; } // allow timing for recursive calls + // logName += " (" + obj + ")"; + window.console.time(logName); + res = this_._superApply.call(this_, args); + window.console.timeEnd(logName); + } else { + if (extra) { + // obj.info(logName, extra, ctx); + logLine(logName, extra, ctx); + } else { + // obj.info(logName, ctx); + logLine(logName, ctx); + } + res = this_._superApply.call(this_, args); + } + return res; + } + + /****************************************************************************** + * Extension code + */ + $.ui.fancytree.registerExtension({ + name: "logger", + version: "2.38.3", + // Default options for this extension. + options: { + logTarget: null, // optional redirect logging to this <div> tag + traceEvents: true, // `true`or list of hook names + traceUnhandledEvents: false, + traceHooks: false, // `true`or list of event names + timings: false, // `true`or list of event names + }, + // Overide virtual methods for this extension. + // `this` : is this Fancytree object + // `this._super`: the virtual function that was overridden (member of prev. extension or Fancytree) + treeCreate: function (ctx) { + var tree = ctx.tree, + opts = ctx.options; + + if ( + this.options.extensions[this.options.extensions.length - 1] !== + "logger" + ) { + throw Error( + "Fancytree 'logger' extension must be listed as last entry." + ); + } + tree.warn( + "Fancytree logger extension is enabled (this may be slow).", + opts.logger + ); + + tree.debug( + "Fancytree v" + + $.ui.fancytree.version + + ", buildType='" + + $.ui.fancytree.buildType + + "'" + ); + tree.debug( + "jQuery UI " + + jQuery.ui.version + + " (uiBackCompat=" + + $.uiBackCompat + + ")" + ); + tree.debug("jQuery " + jQuery.fn.jquery); + tree.debug("Browser: " + getBrowserInfo()); + + function _log(event, data) { + logLine( + PREFIX + "event." + event.type + " (unhandled)", + event, + data + ); + } + $.each(EVENT_NAMES, function (i, name) { + if (typeof opts[name] === "function") { + // tree.info(PREFIX + "override '" + name + "' event"); + $.ui.fancytree.overrideMethod( + opts, + name, + logEvent, + ctx.widget + ); + } else if (opts.logger.traceUnhandledEvents) { + opts[name] = _log; + } + }); + + return logHook("treeCreate", this, arguments); + }, + nodeClick: function (ctx) { + return logHook( + "nodeClick", + this, + arguments, + FT.eventToString(ctx.originalEvent) + ); + }, + nodeCollapseSiblings: function (ctx) { + return logHook("nodeCollapseSiblings", this, arguments); + }, + nodeDblclick: function (ctx) { + return logHook("nodeDblclick", this, arguments); + }, + nodeKeydown: function (ctx) { + return logHook( + "nodeKeydown", + this, + arguments, + FT.eventToString(ctx.originalEvent) + ); + }, + nodeLoadChildren: function (ctx, source) { + return logHook("nodeLoadChildren", this, arguments); + }, + nodeRemoveChildMarkup: function (ctx) { + return logHook("nodeRemoveChildMarkup", this, arguments); + }, + nodeRemoveMarkup: function (ctx) { + return logHook("nodeRemoveMarkup", this, arguments); + }, + nodeRender: function (ctx, force, deep, collapsed, _recursive) { + return logHook("nodeRender", this, arguments); + }, + nodeRenderStatus: function (ctx) { + return logHook("nodeRenderStatus", this, arguments); + }, + nodeRenderTitle: function (ctx, title) { + return logHook("nodeRenderTitle", this, arguments); + }, + nodeSetActive: function (ctx, flag, callOpts) { + return logHook("nodeSetActive", this, arguments); + }, + nodeSetExpanded: function (ctx, flag, callOpts) { + return logHook("nodeSetExpanded", this, arguments); + }, + nodeSetFocus: function (ctx) { + return logHook("nodeSetFocus", this, arguments); + }, + nodeSetSelected: function (ctx, flag, callOpts) { + return logHook("nodeSetSelected", this, arguments); + }, + nodeSetStatus: function (ctx, status, message, details) { + return logHook("nodeSetStatus", this, arguments); + }, + nodeToggleExpanded: function (ctx) { + return logHook("nodeToggleExpanded", this, arguments); + }, + nodeToggleSelected: function (ctx) { + return logHook("nodeToggleSelected", this, arguments); + }, + treeClear: function (ctx) { + return logHook("treeClear", this, arguments); + }, + // treeCreate: function(ctx) { + // return logHook("treeCreate", this, arguments); + // }, + treeDestroy: function (ctx) { + return logHook("treeDestroy", this, arguments); + }, + treeInit: function (ctx) { + return logHook("treeInit", this, arguments); + }, + treeLoad: function (ctx, source) { + return logHook("treeLoad", this, arguments); + }, + treeRegisterNode: function (ctx, add, node) { + return logHook("treeRegisterNode", this, arguments); + }, + treeSetFocus: function (ctx, flag, callOpts) { + return logHook("treeSetFocus", this, arguments); + }, + treeSetOption: function (ctx, key, value) { + return logHook("treeSetOption", this, arguments); + }, + treeStructureChanged: function (ctx, type) { + return logHook("treeStructureChanged", this, arguments); + }, + }); + + // Value returned by `require('jquery.fancytree..')` + return $.ui.fancytree; +}); // End of closure diff --git a/plugins/55/indexmenu/scripts/fancytree/modules/jquery.fancytree.menu.js b/plugins/55/indexmenu/scripts/fancytree/modules/jquery.fancytree.menu.js new file mode 100644 index 0000000..71fee75 --- /dev/null +++ b/plugins/55/indexmenu/scripts/fancytree/modules/jquery.fancytree.menu.js @@ -0,0 +1,185 @@ +/*! + * jquery.fancytree.menu.js + * + * Enable jQuery UI Menu as context menu for tree nodes. + * (Extension module for jquery.fancytree.js: https://github.com/mar10/fancytree/) + * + * @see http://api.jqueryui.com/menu/ + * + * Copyright (c) 2008-2023, Martin Wendt (https://wwWendt.de) + * + * Released under the MIT license + * https://github.com/mar10/fancytree/wiki/LicenseInfo + * + * @version 2.38.3 + * @date 2023-02-01T20:52:50Z + */ + +(function (factory) { + if (typeof define === "function" && define.amd) { + // AMD. Register as an anonymous module. + define(["jquery", "./jquery.fancytree"], factory); + } else if (typeof module === "object" && module.exports) { + // Node/CommonJS + require("./jquery.fancytree"); + module.exports = factory(require("jquery")); + } else { + // Browser globals + factory(jQuery); + } +})(function ($) { + "use strict"; + + $.ui.fancytree.registerExtension({ + name: "menu", + version: "2.38.3", + // Default options for this extension. + options: { + enable: true, + selector: null, // + position: {}, // + // Events: + create: $.noop, // + beforeOpen: $.noop, // + open: $.noop, // + focus: $.noop, // + select: $.noop, // + close: $.noop, // + }, + // Override virtual methods for this extension. + // `this` : is this extension object + // `this._base` : the Fancytree instance + // `this._super`: the virtual function that was overridden (member of prev. extension or Fancytree) + treeInit: function (ctx) { + var opts = ctx.options, + tree = ctx.tree; + + this._superApply(arguments); + + // Prepare an object that will be passed with menu events + tree.ext.menu.data = { + tree: tree, + node: null, + $menu: null, + menuId: null, + }; + + // tree.$container[0].oncontextmenu = function() {return false;}; + // Replace the standard browser context menu with out own + tree.$container.on( + "contextmenu", + "span.fancytree-node", + function (event) { + var node = $.ui.fancytree.getNode(event), + ctx = { + node: node, + tree: node.tree, + originalEvent: event, + options: tree.options, + }; + tree.ext.menu._openMenu(ctx); + return false; + } + ); + + // Use jquery.ui.menu + $(opts.menu.selector) + .menu({ + create: function (event, ui) { + tree.ext.menu.data.$menu = $(this).menu("widget"); + var data = $.extend({}, tree.ext.menu.data); + opts.menu.create.call(tree, event, data); + }, + focus: function (event, ui) { + var data = $.extend({}, tree.ext.menu.data, { + menuItem: ui.item, + menuId: ui.item.find(">a").attr("href"), + }); + opts.menu.focus.call(tree, event, data); + }, + select: function (event, ui) { + var data = $.extend({}, tree.ext.menu.data, { + menuItem: ui.item, + menuId: ui.item.find(">a").attr("href"), + }); + if ( + opts.menu.select.call(tree, event, data) !== false + ) { + tree.ext.menu._closeMenu(ctx); + } + }, + }) + .hide(); + }, + treeDestroy: function (ctx) { + this._superApply(arguments); + }, + _openMenu: function (ctx) { + var data, + tree = ctx.tree, + opts = ctx.options, + $menu = $(opts.menu.selector); + + tree.ext.menu.data.node = ctx.node; + data = $.extend({}, tree.ext.menu.data); + + if ( + opts.menu.beforeOpen.call(tree, ctx.originalEvent, data) === + false + ) { + return; + } + + $(document) + .on("keydown.fancytree", function (event) { + if (event.which === $.ui.keyCode.ESCAPE) { + tree.ext.menu._closeMenu(ctx); + } + }) + .on("mousedown.fancytree", function (event) { + // Close menu when clicked outside menu + if ($(event.target).closest(".ui-menu-item").length === 0) { + tree.ext.menu._closeMenu(ctx); + } + }); + // $menu.position($.extend({my: "left top", at: "left bottom", of: event}, opts.menu.position)); + $menu + .css("position", "absolute") + .show() + .position({ + my: "left top", + at: "right top", + of: ctx.originalEvent, + collision: "fit", + }) + .focus(); + + opts.menu.open.call(tree, ctx.originalEvent, data); + }, + _closeMenu: function (ctx) { + var $menu, + tree = ctx.tree, + opts = ctx.options, + data = $.extend({}, tree.ext.menu.data); + if (opts.menu.close.call(tree, ctx.originalEvent, data) === false) { + return; + } + $menu = $(opts.menu.selector); + $(document).off("keydown.fancytree, mousedown.fancytree"); + $menu.hide(); + tree.ext.menu.data.node = null; + }, + // , + // nodeClick: function(ctx) { + // var event = ctx.originalEvent; + // if(event.which === 2 || (event.which === 1 && event.ctrlKey)){ + // event.preventDefault(); + // ctx.tree.ext.menu._openMenu(ctx); + // return false; + // } + // this._superApply(arguments); + // } + }); + // Value returned by `require('jquery.fancytree..')` + return $.ui.fancytree; +}); // End of closure diff --git a/plugins/55/indexmenu/scripts/fancytree/modules/jquery.fancytree.multi.js b/plugins/55/indexmenu/scripts/fancytree/modules/jquery.fancytree.multi.js new file mode 100644 index 0000000..ec61fed --- /dev/null +++ b/plugins/55/indexmenu/scripts/fancytree/modules/jquery.fancytree.multi.js @@ -0,0 +1,128 @@ +/*! + * jquery.fancytree.multi.js + * + * Allow multiple selection of nodes by mouse or keyboard. + * (Extension module for jquery.fancytree.js: https://github.com/mar10/fancytree/) + * + * Copyright (c) 2008-2023, Martin Wendt (https://wwWendt.de) + * + * Released under the MIT license + * https://github.com/mar10/fancytree/wiki/LicenseInfo + * + * @version 2.38.3 + * @date 2023-02-01T20:52:50Z + */ + +(function (factory) { + if (typeof define === "function" && define.amd) { + // AMD. Register as an anonymous module. + define(["jquery", "./jquery.fancytree"], factory); + } else if (typeof module === "object" && module.exports) { + // Node/CommonJS + require("./jquery.fancytree"); + module.exports = factory(require("jquery")); + } else { + // Browser globals + factory(jQuery); + } +})(function ($) { + "use strict"; + + /******************************************************************************* + * Private functions and variables + */ + + // var isMac = /Mac/.test(navigator.platform); + + /******************************************************************************* + * Extension code + */ + $.ui.fancytree.registerExtension({ + name: "multi", + version: "2.38.3", + // Default options for this extension. + options: { + allowNoSelect: false, // + mode: "sameParent", // + // Events: + // beforeSelect: $.noop // Return false to prevent cancel/save (data.input is available) + }, + + treeInit: function (ctx) { + this._superApply(arguments); + this.$container.addClass("fancytree-ext-multi"); + if (ctx.options.selectMode === 1) { + $.error( + "Fancytree ext-multi: selectMode: 1 (single) is not compatible." + ); + } + }, + nodeClick: function (ctx) { + var //pluginOpts = ctx.options.multi, + tree = ctx.tree, + node = ctx.node, + activeNode = tree.getActiveNode() || tree.getFirstChild(), + isCbClick = ctx.targetType === "checkbox", + isExpanderClick = ctx.targetType === "expander", + eventStr = $.ui.fancytree.eventToString(ctx.originalEvent); + + switch (eventStr) { + case "click": + if (isExpanderClick) { + break; + } // Default handler will expand/collapse + if (!isCbClick) { + tree.selectAll(false); + // Select clicked node (radio-button mode) + node.setSelected(); + } + // Default handler will toggle checkbox clicks and activate + break; + case "shift+click": + // node.debug("click") + tree.visitRows( + function (n) { + // n.debug("click2", n===node, node) + n.setSelected(); + if (n === node) { + return false; + } + }, + { + start: activeNode, + reverse: activeNode.isBelowOf(node), + } + ); + break; + case "ctrl+click": + case "meta+click": // Mac: [Command] + node.toggleSelected(); + return; + } + return this._superApply(arguments); + }, + nodeKeydown: function (ctx) { + var tree = ctx.tree, + node = ctx.node, + event = ctx.originalEvent, + eventStr = $.ui.fancytree.eventToString(event); + + switch (eventStr) { + case "up": + case "down": + tree.selectAll(false); + node.navigate(event.which, true); + tree.getActiveNode().setSelected(); + break; + case "shift+up": + case "shift+down": + node.navigate(event.which, true); + tree.getActiveNode().setSelected(); + break; + } + return this._superApply(arguments); + }, + }); + // Value returned by `require('jquery.fancytree..')` + return $.ui.fancytree; +}); // End of closure diff --git a/plugins/55/indexmenu/scripts/fancytree/modules/jquery.fancytree.persist.js b/plugins/55/indexmenu/scripts/fancytree/modules/jquery.fancytree.persist.js new file mode 100644 index 0000000..c389732 --- /dev/null +++ b/plugins/55/indexmenu/scripts/fancytree/modules/jquery.fancytree.persist.js @@ -0,0 +1,503 @@ +/*! + * jquery.fancytree.persist.js + * + * Persist tree status in cookiesRemove or highlight tree nodes, based on a filter. + * (Extension module for jquery.fancytree.js: https://github.com/mar10/fancytree/) + * + * @depends: js-cookie or jquery-cookie + * + * Copyright (c) 2008-2023, Martin Wendt (https://wwWendt.de) + * + * Released under the MIT license + * https://github.com/mar10/fancytree/wiki/LicenseInfo + * + * @version 2.38.3 + * @date 2023-02-01T20:52:50Z + */ + +(function (factory) { + if (typeof define === "function" && define.amd) { + // AMD. Register as an anonymous module. + define(["jquery", "./jquery.fancytree"], factory); + } else if (typeof module === "object" && module.exports) { + // Node/CommonJS + require("./jquery.fancytree"); + module.exports = factory(require("jquery")); + } else { + // Browser globals + factory(jQuery); + } +})(function ($) { + "use strict"; + /* global Cookies:false */ + + /******************************************************************************* + * Private functions and variables + */ + var cookieStore = null, + localStorageStore = null, + sessionStorageStore = null, + _assert = $.ui.fancytree.assert, + ACTIVE = "active", + EXPANDED = "expanded", + FOCUS = "focus", + SELECTED = "selected"; + + // Accessing window.xxxStorage may raise security exceptions (see #1022) + try { + _assert(window.localStorage && window.localStorage.getItem); + localStorageStore = { + get: function (key) { + return window.localStorage.getItem(key); + }, + set: function (key, value) { + window.localStorage.setItem(key, value); + }, + remove: function (key) { + window.localStorage.removeItem(key); + }, + }; + } catch (e) { + $.ui.fancytree.warn("Could not access window.localStorage", e); + } + + try { + _assert(window.sessionStorage && window.sessionStorage.getItem); + sessionStorageStore = { + get: function (key) { + return window.sessionStorage.getItem(key); + }, + set: function (key, value) { + window.sessionStorage.setItem(key, value); + }, + remove: function (key) { + window.sessionStorage.removeItem(key); + }, + }; + } catch (e) { + $.ui.fancytree.warn("Could not access window.sessionStorage", e); + } + + if (typeof Cookies === "function") { + // Assume https://github.com/js-cookie/js-cookie + cookieStore = { + get: Cookies.get, + set: function (key, value) { + Cookies.set(key, value, this.options.persist.cookie); + }, + remove: Cookies.remove, + }; + } else if ($ && typeof $.cookie === "function") { + // Fall back to https://github.com/carhartl/jquery-cookie + cookieStore = { + get: $.cookie, + set: function (key, value) { + $.cookie(key, value, this.options.persist.cookie); + }, + remove: $.removeCookie, + }; + } + + /* Recursively load lazy nodes + * @param {string} mode 'load', 'expand', false + */ + function _loadLazyNodes(tree, local, keyList, mode, dfd) { + var i, + key, + l, + node, + foundOne = false, + expandOpts = tree.options.persist.expandOpts, + deferredList = [], + missingKeyList = []; + + keyList = keyList || []; + dfd = dfd || $.Deferred(); + + for (i = 0, l = keyList.length; i < l; i++) { + key = keyList[i]; + node = tree.getNodeByKey(key); + if (node) { + if (mode && node.isUndefined()) { + foundOne = true; + tree.debug( + "_loadLazyNodes: " + node + " is lazy: loading..." + ); + if (mode === "expand") { + deferredList.push(node.setExpanded(true, expandOpts)); + } else { + deferredList.push(node.load()); + } + } else { + tree.debug("_loadLazyNodes: " + node + " already loaded."); + node.setExpanded(true, expandOpts); + } + } else { + missingKeyList.push(key); + tree.debug("_loadLazyNodes: " + node + " was not yet found."); + } + } + + $.when.apply($, deferredList).always(function () { + // All lazy-expands have finished + if (foundOne && missingKeyList.length > 0) { + // If we read new nodes from server, try to resolve yet-missing keys + _loadLazyNodes(tree, local, missingKeyList, mode, dfd); + } else { + if (missingKeyList.length) { + tree.warn( + "_loadLazyNodes: could not load those keys: ", + missingKeyList + ); + for (i = 0, l = missingKeyList.length; i < l; i++) { + key = keyList[i]; + local._appendKey(EXPANDED, keyList[i], false); + } + } + dfd.resolve(); + } + }); + return dfd; + } + + /** + * [ext-persist] Remove persistence data of the given type(s). + * Called like + * $.ui.fancytree.getTree("#tree").clearCookies("active expanded focus selected"); + * + * @alias Fancytree#clearPersistData + * @requires jquery.fancytree.persist.js + */ + $.ui.fancytree._FancytreeClass.prototype.clearPersistData = function ( + types + ) { + var local = this.ext.persist, + prefix = local.cookiePrefix; + + types = types || "active expanded focus selected"; + if (types.indexOf(ACTIVE) >= 0) { + local._data(prefix + ACTIVE, null); + } + if (types.indexOf(EXPANDED) >= 0) { + local._data(prefix + EXPANDED, null); + } + if (types.indexOf(FOCUS) >= 0) { + local._data(prefix + FOCUS, null); + } + if (types.indexOf(SELECTED) >= 0) { + local._data(prefix + SELECTED, null); + } + }; + + $.ui.fancytree._FancytreeClass.prototype.clearCookies = function (types) { + this.warn( + "'tree.clearCookies()' is deprecated since v2.27.0: use 'clearPersistData()' instead." + ); + return this.clearPersistData(types); + }; + + /** + * [ext-persist] Return persistence information from cookies + * + * Called like + * $.ui.fancytree.getTree("#tree").getPersistData(); + * + * @alias Fancytree#getPersistData + * @requires jquery.fancytree.persist.js + */ + $.ui.fancytree._FancytreeClass.prototype.getPersistData = function () { + var local = this.ext.persist, + prefix = local.cookiePrefix, + delim = local.cookieDelimiter, + res = {}; + + res[ACTIVE] = local._data(prefix + ACTIVE); + res[EXPANDED] = (local._data(prefix + EXPANDED) || "").split(delim); + res[SELECTED] = (local._data(prefix + SELECTED) || "").split(delim); + res[FOCUS] = local._data(prefix + FOCUS); + return res; + }; + + /****************************************************************************** + * Extension code + */ + $.ui.fancytree.registerExtension({ + name: "persist", + version: "2.38.3", + // Default options for this extension. + options: { + cookieDelimiter: "~", + cookiePrefix: undefined, // 'fancytree-<treeId>-' by default + cookie: { + raw: false, + expires: "", + path: "", + domain: "", + secure: false, + }, + expandLazy: false, // true: recursively expand and load lazy nodes + expandOpts: undefined, // optional `opts` argument passed to setExpanded() + fireActivate: true, // false: suppress `activate` event after active node was restored + overrideSource: true, // true: cookie takes precedence over `source` data attributes. + store: "auto", // 'cookie': force cookie, 'local': force localStore, 'session': force sessionStore + types: "active expanded focus selected", + }, + + /* Generic read/write string data to cookie, sessionStorage or localStorage. */ + _data: function (key, value) { + var store = this._local.store; + + if (value === undefined) { + return store.get.call(this, key); + } else if (value === null) { + store.remove.call(this, key); + } else { + store.set.call(this, key, value); + } + }, + + /* Append `key` to a cookie. */ + _appendKey: function (type, key, flag) { + key = "" + key; // #90 + var local = this._local, + instOpts = this.options.persist, + delim = instOpts.cookieDelimiter, + cookieName = local.cookiePrefix + type, + data = local._data(cookieName), + keyList = data ? data.split(delim) : [], + idx = $.inArray(key, keyList); + // Remove, even if we add a key, so the key is always the last entry + if (idx >= 0) { + keyList.splice(idx, 1); + } + // Append key to cookie + if (flag) { + keyList.push(key); + } + local._data(cookieName, keyList.join(delim)); + }, + + treeInit: function (ctx) { + var tree = ctx.tree, + opts = ctx.options, + local = this._local, + instOpts = this.options.persist; + + // // For 'auto' or 'cookie' mode, the cookie plugin must be available + // _assert((instOpts.store !== "auto" && instOpts.store !== "cookie") || cookieStore, + // "Missing required plugin for 'persist' extension: js.cookie.js or jquery.cookie.js"); + + local.cookiePrefix = + instOpts.cookiePrefix || "fancytree-" + tree._id + "-"; + local.storeActive = instOpts.types.indexOf(ACTIVE) >= 0; + local.storeExpanded = instOpts.types.indexOf(EXPANDED) >= 0; + local.storeSelected = instOpts.types.indexOf(SELECTED) >= 0; + local.storeFocus = instOpts.types.indexOf(FOCUS) >= 0; + local.store = null; + + if (instOpts.store === "auto") { + instOpts.store = localStorageStore ? "local" : "cookie"; + } + if ($.isPlainObject(instOpts.store)) { + local.store = instOpts.store; + } else if (instOpts.store === "cookie") { + local.store = cookieStore; + } else if (instOpts.store === "local") { + local.store = + instOpts.store === "local" + ? localStorageStore + : sessionStorageStore; + } else if (instOpts.store === "session") { + local.store = + instOpts.store === "local" + ? localStorageStore + : sessionStorageStore; + } + _assert(local.store, "Need a valid store."); + + // Bind init-handler to apply cookie state + tree.$div.on("fancytreeinit", function (event) { + if ( + tree._triggerTreeEvent("beforeRestore", null, {}) === false + ) { + return; + } + + var cookie, + dfd, + i, + keyList, + node, + prevFocus = local._data(local.cookiePrefix + FOCUS), // record this before node.setActive() overrides it; + noEvents = instOpts.fireActivate === false; + + // tree.debug("document.cookie:", document.cookie); + + cookie = local._data(local.cookiePrefix + EXPANDED); + keyList = cookie && cookie.split(instOpts.cookieDelimiter); + + if (local.storeExpanded) { + // Recursively load nested lazy nodes if expandLazy is 'expand' or 'load' + // Also remove expand-cookies for unmatched nodes + dfd = _loadLazyNodes( + tree, + local, + keyList, + instOpts.expandLazy ? "expand" : false, + null + ); + } else { + // nothing to do + dfd = new $.Deferred().resolve(); + } + + dfd.done(function () { + if (local.storeSelected) { + cookie = local._data(local.cookiePrefix + SELECTED); + if (cookie) { + keyList = cookie.split(instOpts.cookieDelimiter); + for (i = 0; i < keyList.length; i++) { + node = tree.getNodeByKey(keyList[i]); + if (node) { + if ( + node.selected === undefined || + (instOpts.overrideSource && + node.selected === false) + ) { + // node.setSelected(); + node.selected = true; + node.renderStatus(); + } + } else { + // node is no longer member of the tree: remove from cookie also + local._appendKey( + SELECTED, + keyList[i], + false + ); + } + } + } + // In selectMode 3 we have to fix the child nodes, since we + // only stored the selected *top* nodes + if (tree.options.selectMode === 3) { + tree.visit(function (n) { + if (n.selected) { + n.fixSelection3AfterClick(); + return "skip"; + } + }); + } + } + if (local.storeActive) { + cookie = local._data(local.cookiePrefix + ACTIVE); + if ( + cookie && + (opts.persist.overrideSource || !tree.activeNode) + ) { + node = tree.getNodeByKey(cookie); + if (node) { + node.debug("persist: set active", cookie); + // We only want to set the focus if the container + // had the keyboard focus before + node.setActive(true, { + noFocus: true, + noEvents: noEvents, + }); + } + } + } + if (local.storeFocus && prevFocus) { + node = tree.getNodeByKey(prevFocus); + if (node) { + // node.debug("persist: set focus", cookie); + if (tree.options.titlesTabbable) { + $(node.span).find(".fancytree-title").focus(); + } else { + $(tree.$container).focus(); + } + // node.setFocus(); + } + } + tree._triggerTreeEvent("restore", null, {}); + }); + }); + // Init the tree + return this._superApply(arguments); + }, + nodeSetActive: function (ctx, flag, callOpts) { + var res, + local = this._local; + + flag = flag !== false; + res = this._superApply(arguments); + + if (local.storeActive) { + local._data( + local.cookiePrefix + ACTIVE, + this.activeNode ? this.activeNode.key : null + ); + } + return res; + }, + nodeSetExpanded: function (ctx, flag, callOpts) { + var res, + node = ctx.node, + local = this._local; + + flag = flag !== false; + res = this._superApply(arguments); + + if (local.storeExpanded) { + local._appendKey(EXPANDED, node.key, flag); + } + return res; + }, + nodeSetFocus: function (ctx, flag) { + var res, + local = this._local; + + flag = flag !== false; + res = this._superApply(arguments); + + if (local.storeFocus) { + local._data( + local.cookiePrefix + FOCUS, + this.focusNode ? this.focusNode.key : null + ); + } + return res; + }, + nodeSetSelected: function (ctx, flag, callOpts) { + var res, + selNodes, + tree = ctx.tree, + node = ctx.node, + local = this._local; + + flag = flag !== false; + res = this._superApply(arguments); + + if (local.storeSelected) { + if (tree.options.selectMode === 3) { + // In selectMode 3 we only store the the selected *top* nodes. + // De-selecting a node may also de-select some parents, so we + // calculate the current status again + selNodes = $.map(tree.getSelectedNodes(true), function (n) { + return n.key; + }); + selNodes = selNodes.join( + ctx.options.persist.cookieDelimiter + ); + local._data(local.cookiePrefix + SELECTED, selNodes); + } else { + // beforeSelect can prevent the change - flag doesn't reflect the node.selected state + local._appendKey(SELECTED, node.key, node.selected); + } + } + return res; + }, + }); + // Value returned by `require('jquery.fancytree..')` + return $.ui.fancytree; +}); // End of closure diff --git a/plugins/55/indexmenu/scripts/fancytree/modules/jquery.fancytree.table.js b/plugins/55/indexmenu/scripts/fancytree/modules/jquery.fancytree.table.js new file mode 100644 index 0000000..ade8e11 --- /dev/null +++ b/plugins/55/indexmenu/scripts/fancytree/modules/jquery.fancytree.table.js @@ -0,0 +1,544 @@ +/*! + * jquery.fancytree.table.js + * + * Render tree as table (aka 'tree grid', 'table tree'). + * (Extension module for jquery.fancytree.js: https://github.com/mar10/fancytree/) + * + * Copyright (c) 2008-2023, Martin Wendt (https://wwWendt.de) + * + * Released under the MIT license + * https://github.com/mar10/fancytree/wiki/LicenseInfo + * + * @version 2.38.3 + * @date 2023-02-01T20:52:50Z + */ + +(function (factory) { + if (typeof define === "function" && define.amd) { + // AMD. Register as an anonymous module. + define(["jquery", "./jquery.fancytree"], factory); + } else if (typeof module === "object" && module.exports) { + // Node/CommonJS + require("./jquery.fancytree"); + module.exports = factory(require("jquery")); + } else { + // Browser globals + factory(jQuery); + } +})(function ($) { + "use strict"; + + /****************************************************************************** + * Private functions and variables + */ + var _assert = $.ui.fancytree.assert; + + function insertFirstChild(referenceNode, newNode) { + referenceNode.insertBefore(newNode, referenceNode.firstChild); + } + + function insertSiblingAfter(referenceNode, newNode) { + referenceNode.parentNode.insertBefore( + newNode, + referenceNode.nextSibling + ); + } + + /* Show/hide all rows that are structural descendants of `parent`. */ + function setChildRowVisibility(parent, flag) { + parent.visit(function (node) { + var tr = node.tr; + // currentFlag = node.hide ? false : flag; // fix for ext-filter + if (tr) { + tr.style.display = node.hide || !flag ? "none" : ""; + } + if (!node.expanded) { + return "skip"; + } + }); + } + + /* Find node that is rendered in previous row. */ + function findPrevRowNode(node) { + var i, + last, + prev, + parent = node.parent, + siblings = parent ? parent.children : null; + + if (siblings && siblings.length > 1 && siblings[0] !== node) { + // use the lowest descendant of the preceeding sibling + i = $.inArray(node, siblings); + prev = siblings[i - 1]; + _assert(prev.tr); + // descend to lowest child (with a <tr> tag) + while (prev.children && prev.children.length) { + last = prev.children[prev.children.length - 1]; + if (!last.tr) { + break; + } + prev = last; + } + } else { + // if there is no preceding sibling, use the direct parent + prev = parent; + } + return prev; + } + + $.ui.fancytree.registerExtension({ + name: "table", + version: "2.38.3", + // Default options for this extension. + options: { + checkboxColumnIdx: null, // render the checkboxes into the this column index (default: nodeColumnIdx) + indentation: 16, // indent every node level by 16px + mergeStatusColumns: true, // display 'nodata', 'loading', 'error' centered in a single, merged TR + nodeColumnIdx: 0, // render node expander, icon, and title to this column (default: #0) + }, + // Overide virtual methods for this extension. + // `this` : is this extension object + // `this._super`: the virtual function that was overriden (member of prev. extension or Fancytree) + treeInit: function (ctx) { + var i, + n, + $row, + $tbody, + tree = ctx.tree, + opts = ctx.options, + tableOpts = opts.table, + $table = tree.widget.element; + + if (tableOpts.customStatus != null) { + if (opts.renderStatusColumns == null) { + tree.warn( + "The 'customStatus' option is deprecated since v2.15.0. Use 'renderStatusColumns' instead." + ); + opts.renderStatusColumns = tableOpts.customStatus; + } else { + $.error( + "The 'customStatus' option is deprecated since v2.15.0. Use 'renderStatusColumns' only instead." + ); + } + } + if (opts.renderStatusColumns) { + if (opts.renderStatusColumns === true) { + opts.renderStatusColumns = opts.renderColumns; + // } else if( opts.renderStatusColumns === "wide" ) { + // opts.renderStatusColumns = _renderStatusNodeWide; + } + } + + $table.addClass("fancytree-container fancytree-ext-table"); + $tbody = $table.find(">tbody"); + if (!$tbody.length) { + // TODO: not sure if we can rely on browsers to insert missing <tbody> before <tr>s: + if ($table.find(">tr").length) { + $.error( + "Expected table > tbody > tr. If you see this please open an issue." + ); + } + $tbody = $("<tbody>").appendTo($table); + } + + tree.tbody = $tbody[0]; + + // Prepare row templates: + // Determine column count from table header if any + tree.columnCount = $("thead >tr", $table) + .last() + .find(">th", $table).length; + // Read TR templates from tbody if any + $row = $tbody.children("tr").first(); + if ($row.length) { + n = $row.children("td").length; + if (tree.columnCount && n !== tree.columnCount) { + tree.warn( + "Column count mismatch between thead (" + + tree.columnCount + + ") and tbody (" + + n + + "): using tbody." + ); + tree.columnCount = n; + } + $row = $row.clone(); + } else { + // Only thead is defined: create default row markup + _assert( + tree.columnCount >= 1, + "Need either <thead> or <tbody> with <td> elements to determine column count." + ); + $row = $("<tr />"); + for (i = 0; i < tree.columnCount; i++) { + $row.append("<td />"); + } + } + $row.find(">td") + .eq(tableOpts.nodeColumnIdx) + .html("<span class='fancytree-node' />"); + if (opts.aria) { + $row.attr("role", "row"); + $row.find("td").attr("role", "gridcell"); + } + tree.rowFragment = document.createDocumentFragment(); + tree.rowFragment.appendChild($row.get(0)); + + // // If tbody contains a second row, use this as status node template + // $row = $tbody.children("tr").eq(1); + // if( $row.length === 0 ) { + // tree.statusRowFragment = tree.rowFragment; + // } else { + // $row = $row.clone(); + // tree.statusRowFragment = document.createDocumentFragment(); + // tree.statusRowFragment.appendChild($row.get(0)); + // } + // + $tbody.empty(); + + // Make sure that status classes are set on the node's <tr> elements + tree.statusClassPropName = "tr"; + tree.ariaPropName = "tr"; + this.nodeContainerAttrName = "tr"; + + // #489: make sure $container is set to <table>, even if ext-dnd is listed before ext-table + tree.$container = $table; + + this._superApply(arguments); + + // standard Fancytree created a root UL + $(tree.rootNode.ul).remove(); + tree.rootNode.ul = null; + + // Add container to the TAB chain + // #577: Allow to set tabindex to "0", "-1" and "" + this.$container.attr("tabindex", opts.tabindex); + // this.$container.attr("tabindex", opts.tabbable ? "0" : "-1"); + if (opts.aria) { + tree.$container + .attr("role", "treegrid") + .attr("aria-readonly", true); + } + }, + nodeRemoveChildMarkup: function (ctx) { + var node = ctx.node; + // node.debug("nodeRemoveChildMarkup()"); + node.visit(function (n) { + if (n.tr) { + $(n.tr).remove(); + n.tr = null; + } + }); + }, + nodeRemoveMarkup: function (ctx) { + var node = ctx.node; + // node.debug("nodeRemoveMarkup()"); + if (node.tr) { + $(node.tr).remove(); + node.tr = null; + } + this.nodeRemoveChildMarkup(ctx); + }, + /* Override standard render. */ + nodeRender: function (ctx, force, deep, collapsed, _recursive) { + var children, + firstTr, + i, + l, + newRow, + prevNode, + prevTr, + subCtx, + tree = ctx.tree, + node = ctx.node, + opts = ctx.options, + isRootNode = !node.parent; + + if (tree._enableUpdate === false) { + // $.ui.fancytree.debug("*** nodeRender _enableUpdate: false"); + return; + } + if (!_recursive) { + ctx.hasCollapsedParents = node.parent && !node.parent.expanded; + } + // $.ui.fancytree.debug("*** nodeRender " + node + ", isRoot=" + isRootNode, "tr=" + node.tr, "hcp=" + ctx.hasCollapsedParents, "parent.tr=" + (node.parent && node.parent.tr)); + if (!isRootNode) { + if (node.tr && force) { + this.nodeRemoveMarkup(ctx); + } + if (node.tr) { + if (force) { + // Set icon, link, and title (normally this is only required on initial render) + this.nodeRenderTitle(ctx); // triggers renderColumns() + } else { + // Update element classes according to node state + this.nodeRenderStatus(ctx); + } + } else { + if (ctx.hasCollapsedParents && !deep) { + // #166: we assume that the parent will be (recursively) rendered + // later anyway. + // node.debug("nodeRender ignored due to unrendered parent"); + return; + } + // Create new <tr> after previous row + // if( node.isStatusNode() ) { + // newRow = tree.statusRowFragment.firstChild.cloneNode(true); + // } else { + newRow = tree.rowFragment.firstChild.cloneNode(true); + // } + prevNode = findPrevRowNode(node); + // $.ui.fancytree.debug("*** nodeRender " + node + ": prev: " + prevNode.key); + _assert(prevNode); + if (collapsed === true && _recursive) { + // hide all child rows, so we can use an animation to show it later + newRow.style.display = "none"; + } else if (deep && ctx.hasCollapsedParents) { + // also hide this row if deep === true but any parent is collapsed + newRow.style.display = "none"; + // newRow.style.color = "red"; + } + if (prevNode.tr) { + insertSiblingAfter(prevNode.tr, newRow); + } else { + _assert( + !prevNode.parent, + "prev. row must have a tr, or be system root" + ); + // tree.tbody.appendChild(newRow); + insertFirstChild(tree.tbody, newRow); // #675 + } + node.tr = newRow; + if (node.key && opts.generateIds) { + node.tr.id = opts.idPrefix + node.key; + } + node.tr.ftnode = node; + // if(opts.aria){ + // $(node.tr).attr("aria-labelledby", "ftal_" + opts.idPrefix + node.key); + // } + node.span = $("span.fancytree-node", node.tr).get(0); + // Set icon, link, and title (normally this is only required on initial render) + this.nodeRenderTitle(ctx); + // Allow tweaking, binding, after node was created for the first time + // tree._triggerNodeEvent("createNode", ctx); + if (opts.createNode) { + opts.createNode.call(tree, { type: "createNode" }, ctx); + } + } + } + // Allow tweaking after node state was rendered + // tree._triggerNodeEvent("renderNode", ctx); + if (opts.renderNode) { + opts.renderNode.call(tree, { type: "renderNode" }, ctx); + } + // Visit child nodes + // Add child markup + children = node.children; + if (children && (isRootNode || deep || node.expanded)) { + for (i = 0, l = children.length; i < l; i++) { + subCtx = $.extend({}, ctx, { node: children[i] }); + subCtx.hasCollapsedParents = + subCtx.hasCollapsedParents || !node.expanded; + this.nodeRender(subCtx, force, deep, collapsed, true); + } + } + // Make sure, that <tr> order matches node.children order. + if (children && !_recursive) { + // we only have to do it once, for the root branch + prevTr = node.tr || null; + firstTr = tree.tbody.firstChild; + // Iterate over all descendants + node.visit(function (n) { + if (n.tr) { + if ( + !n.parent.expanded && + n.tr.style.display !== "none" + ) { + // fix after a node was dropped over a collapsed + n.tr.style.display = "none"; + setChildRowVisibility(n, false); + } + if (n.tr.previousSibling !== prevTr) { + node.debug("_fixOrder: mismatch at node: " + n); + var nextTr = prevTr ? prevTr.nextSibling : firstTr; + tree.tbody.insertBefore(n.tr, nextTr); + } + prevTr = n.tr; + } + }); + } + // Update element classes according to node state + // if(!isRootNode){ + // this.nodeRenderStatus(ctx); + // } + }, + nodeRenderTitle: function (ctx, title) { + var $cb, + res, + tree = ctx.tree, + node = ctx.node, + opts = ctx.options, + isStatusNode = node.isStatusNode(); + + res = this._super(ctx, title); + + if (node.isRootNode()) { + return res; + } + // Move checkbox to custom column + if ( + opts.checkbox && + !isStatusNode && + opts.table.checkboxColumnIdx != null + ) { + $cb = $("span.fancytree-checkbox", node.span); //.detach(); + $(node.tr) + .find("td") + .eq(+opts.table.checkboxColumnIdx) + .html($cb); + } + // Update element classes according to node state + this.nodeRenderStatus(ctx); + + if (isStatusNode) { + if (opts.renderStatusColumns) { + // Let user code write column content + opts.renderStatusColumns.call( + tree, + { type: "renderStatusColumns" }, + ctx + ); + } else if (opts.table.mergeStatusColumns && node.isTopLevel()) { + $(node.tr) + .find(">td") + .eq(0) + .prop("colspan", tree.columnCount) + .text(node.title) + .addClass("fancytree-status-merged") + .nextAll() + .remove(); + } // else: default rendering for status node: leave other cells empty + } else if (opts.renderColumns) { + opts.renderColumns.call(tree, { type: "renderColumns" }, ctx); + } + return res; + }, + nodeRenderStatus: function (ctx) { + var indent, + node = ctx.node, + opts = ctx.options; + + this._super(ctx); + + $(node.tr).removeClass("fancytree-node"); + // indent + indent = (node.getLevel() - 1) * opts.table.indentation; + if (opts.rtl) { + $(node.span).css({ paddingRight: indent + "px" }); + } else { + $(node.span).css({ paddingLeft: indent + "px" }); + } + }, + /* Expand node, return Deferred.promise. */ + nodeSetExpanded: function (ctx, flag, callOpts) { + // flag defaults to true + flag = flag !== false; + + if ((ctx.node.expanded && flag) || (!ctx.node.expanded && !flag)) { + // Expanded state isn't changed - just call base implementation + return this._superApply(arguments); + } + + var dfd = new $.Deferred(), + subOpts = $.extend({}, callOpts, { + noEvents: true, + noAnimation: true, + }); + + callOpts = callOpts || {}; + + function _afterExpand(ok, args) { + // ctx.tree.info("ok:" + ok, args); + if (ok) { + // #1108 minExpandLevel: 2 together with table extension does not work + // don't call when 'ok' is false: + setChildRowVisibility(ctx.node, flag); + if ( + flag && + ctx.options.autoScroll && + !callOpts.noAnimation && + ctx.node.hasChildren() + ) { + // Scroll down to last child, but keep current node visible + ctx.node + .getLastChild() + .scrollIntoView(true, { topNode: ctx.node }) + .always(function () { + if (!callOpts.noEvents) { + ctx.tree._triggerNodeEvent( + flag ? "expand" : "collapse", + ctx + ); + } + dfd.resolveWith(ctx.node); + }); + } else { + if (!callOpts.noEvents) { + ctx.tree._triggerNodeEvent( + flag ? "expand" : "collapse", + ctx + ); + } + dfd.resolveWith(ctx.node); + } + } else { + if (!callOpts.noEvents) { + ctx.tree._triggerNodeEvent( + flag ? "expand" : "collapse", + ctx + ); + } + dfd.rejectWith(ctx.node); + } + } + // Call base-expand with disabled events and animation + this._super(ctx, flag, subOpts) + .done(function () { + _afterExpand(true, arguments); + }) + .fail(function () { + _afterExpand(false, arguments); + }); + return dfd.promise(); + }, + nodeSetStatus: function (ctx, status, message, details) { + if (status === "ok") { + var node = ctx.node, + firstChild = node.children ? node.children[0] : null; + if (firstChild && firstChild.isStatusNode()) { + $(firstChild.tr).remove(); + } + } + return this._superApply(arguments); + }, + treeClear: function (ctx) { + this.nodeRemoveChildMarkup(this._makeHookContext(this.rootNode)); + return this._superApply(arguments); + }, + treeDestroy: function (ctx) { + this.$container.find("tbody").empty(); + if (this.$source) { + this.$source.removeClass("fancytree-helper-hidden"); + } + return this._superApply(arguments); + }, + /*, + treeSetFocus: function(ctx, flag) { +// alert("treeSetFocus" + ctx.tree.$container); + ctx.tree.$container.focus(); + $.ui.fancytree.focusTree = ctx.tree; + }*/ + }); + // Value returned by `require('jquery.fancytree..')` + return $.ui.fancytree; +}); // End of closure diff --git a/plugins/55/indexmenu/scripts/fancytree/modules/jquery.fancytree.themeroller.js b/plugins/55/indexmenu/scripts/fancytree/modules/jquery.fancytree.themeroller.js new file mode 100644 index 0000000..bb2a443 --- /dev/null +++ b/plugins/55/indexmenu/scripts/fancytree/modules/jquery.fancytree.themeroller.js @@ -0,0 +1,125 @@ +/*! + * jquery.fancytree.themeroller.js + * + * Enable jQuery UI ThemeRoller styles. + * (Extension module for jquery.fancytree.js: https://github.com/mar10/fancytree/) + * + * @see http://jqueryui.com/themeroller/ + * + * Copyright (c) 2008-2023, Martin Wendt (https://wwWendt.de) + * + * Released under the MIT license + * https://github.com/mar10/fancytree/wiki/LicenseInfo + * + * @version 2.38.3 + * @date 2023-02-01T20:52:50Z + */ + +(function (factory) { + if (typeof define === "function" && define.amd) { + // AMD. Register as an anonymous module. + define(["jquery", "./jquery.fancytree"], factory); + } else if (typeof module === "object" && module.exports) { + // Node/CommonJS + require("./jquery.fancytree"); + module.exports = factory(require("jquery")); + } else { + // Browser globals + factory(jQuery); + } +})(function ($) { + "use strict"; + + /******************************************************************************* + * Extension code + */ + $.ui.fancytree.registerExtension({ + name: "themeroller", + version: "2.38.3", + // Default options for this extension. + options: { + activeClass: "ui-state-active", // Class added to active node + // activeClass: "ui-state-highlight", + addClass: "ui-corner-all", // Class added to all nodes + focusClass: "ui-state-focus", // Class added to focused node + hoverClass: "ui-state-hover", // Class added to hovered node + selectedClass: "ui-state-highlight", // Class added to selected nodes + // selectedClass: "ui-state-active" + }, + + treeInit: function (ctx) { + var $el = ctx.widget.element, + opts = ctx.options.themeroller; + + this._superApply(arguments); + + if ($el[0].nodeName === "TABLE") { + $el.addClass("ui-widget ui-corner-all"); + $el.find(">thead tr").addClass("ui-widget-header"); + $el.find(">tbody").addClass("ui-widget-conent"); + } else { + $el.addClass("ui-widget ui-widget-content ui-corner-all"); + } + + $el.on( + "mouseenter mouseleave", + ".fancytree-node", + function (event) { + var node = $.ui.fancytree.getNode(event.target), + flag = event.type === "mouseenter"; + + $(node.tr ? node.tr : node.span).toggleClass( + opts.hoverClass + " " + opts.addClass, + flag + ); + } + ); + }, + treeDestroy: function (ctx) { + this._superApply(arguments); + ctx.widget.element.removeClass( + "ui-widget ui-widget-content ui-corner-all" + ); + }, + nodeRenderStatus: function (ctx) { + var classes = {}, + node = ctx.node, + $el = $(node.tr ? node.tr : node.span), + opts = ctx.options.themeroller; + + this._super(ctx); + /* + .ui-state-highlight: Class to be applied to highlighted or selected elements. Applies "highlight" container styles to an element and its child text, links, and icons. + .ui-state-error: Class to be applied to error messaging container elements. Applies "error" container styles to an element and its child text, links, and icons. + .ui-state-error-text: An additional class that applies just the error text color without background. Can be used on form labels for instance. Also applies error icon color to child icons. + + .ui-state-default: Class to be applied to clickable button-like elements. Applies "clickable default" container styles to an element and its child text, links, and icons. + .ui-state-hover: Class to be applied on mouseover to clickable button-like elements. Applies "clickable hover" container styles to an element and its child text, links, and icons. + .ui-state-focus: Class to be applied on keyboard focus to clickable button-like elements. Applies "clickable hover" container styles to an element and its child text, links, and icons. + .ui-state-active: Class to be applied on mousedown to clickable button-like elements. Applies "clickable active" container styles to an element and its child text, links, and icons. +*/ + // Set ui-state-* class (handle the case that the same class is assigned + // to different states) + classes[opts.activeClass] = false; + classes[opts.focusClass] = false; + classes[opts.selectedClass] = false; + if (node.isActive()) { + classes[opts.activeClass] = true; + } + if (node.hasFocus()) { + classes[opts.focusClass] = true; + } + // activeClass takes precedence before selectedClass: + if (node.isSelected() && !node.isActive()) { + classes[opts.selectedClass] = true; + } + $el.toggleClass(opts.activeClass, classes[opts.activeClass]); + $el.toggleClass(opts.focusClass, classes[opts.focusClass]); + $el.toggleClass(opts.selectedClass, classes[opts.selectedClass]); + // Additional classes (e.g. 'ui-corner-all') + $el.addClass(opts.addClass); + }, + }); + // Value returned by `require('jquery.fancytree..')` + return $.ui.fancytree; +}); // End of closure diff --git a/plugins/55/indexmenu/scripts/fancytree/modules/jquery.fancytree.ui-deps.js b/plugins/55/indexmenu/scripts/fancytree/modules/jquery.fancytree.ui-deps.js new file mode 100644 index 0000000..ca0a1b9 --- /dev/null +++ b/plugins/55/indexmenu/scripts/fancytree/modules/jquery.fancytree.ui-deps.js @@ -0,0 +1,1449 @@ +/*! jQuery UI - v1.13.2 - 2022-08-16 +* http://jqueryui.com +* Includes: widget.js, position.js, jquery-patch.js, keycode.js, scroll-parent.js, unique-id.js +* Copyright jQuery Foundation and other contributors; Licensed MIT */ + +( function( factory ) { + "use strict"; + + if ( typeof define === "function" && define.amd ) { + + // AMD. Register as an anonymous module. + define( [ "jquery" ], factory ); + } else { + + // Browser globals + factory( jQuery ); + } +} )( function( $ ) { +"use strict"; + +$.ui = $.ui || {}; + +var version = $.ui.version = "1.13.2"; + + +/*! + * jQuery UI Widget 1.13.2 + * http://jqueryui.com + * + * Copyright jQuery Foundation and other contributors + * Released under the MIT license. + * http://jquery.org/license + */ + +//>>label: Widget +//>>group: Core +//>>description: Provides a factory for creating stateful widgets with a common API. +//>>docs: http://api.jqueryui.com/jQuery.widget/ +//>>demos: http://jqueryui.com/widget/ + + +var widgetUuid = 0; +var widgetHasOwnProperty = Array.prototype.hasOwnProperty; +var widgetSlice = Array.prototype.slice; + +$.cleanData = $.cleanData || ( function( orig ) { + return function( elems ) { + var events, elem, i; + for ( i = 0; ( elem = elems[ i ] ) != null; i++ ) { + + // Only trigger remove when necessary to save time + events = $._data( elem, "events" ); + if ( events && events.remove ) { + $( elem ).triggerHandler( "remove" ); + } + } + orig( elems ); + }; +} )( $.cleanData ); + +$.widget = $.widget || function( name, base, prototype ) { + var existingConstructor, constructor, basePrototype; + + // ProxiedPrototype allows the provided prototype to remain unmodified + // so that it can be used as a mixin for multiple widgets (#8876) + var proxiedPrototype = {}; + + var namespace = name.split( "." )[ 0 ]; + name = name.split( "." )[ 1 ]; + var fullName = namespace + "-" + name; + + if ( !prototype ) { + prototype = base; + base = $.Widget; + } + + if ( Array.isArray( prototype ) ) { + prototype = $.extend.apply( null, [ {} ].concat( prototype ) ); + } + + // Create selector for plugin + $.expr.pseudos[ fullName.toLowerCase() ] = function( elem ) { + return !!$.data( elem, fullName ); + }; + + $[ namespace ] = $[ namespace ] || {}; + existingConstructor = $[ namespace ][ name ]; + constructor = $[ namespace ][ name ] = function( options, element ) { + + // Allow instantiation without "new" keyword + if ( !this || !this._createWidget ) { + return new constructor( options, element ); + } + + // Allow instantiation without initializing for simple inheritance + // must use "new" keyword (the code above always passes args) + if ( arguments.length ) { + this._createWidget( options, element ); + } + }; + + // Extend with the existing constructor to carry over any static properties + $.extend( constructor, existingConstructor, { + version: prototype.version, + + // Copy the object used to create the prototype in case we need to + // redefine the widget later + _proto: $.extend( {}, prototype ), + + // Track widgets that inherit from this widget in case this widget is + // redefined after a widget inherits from it + _childConstructors: [] + } ); + + basePrototype = new base(); + + // We need to make the options hash a property directly on the new instance + // otherwise we'll modify the options hash on the prototype that we're + // inheriting from + basePrototype.options = $.widget.extend( {}, basePrototype.options ); + $.each( prototype, function( prop, value ) { + if ( typeof value !== "function" ) { + proxiedPrototype[ prop ] = value; + return; + } + proxiedPrototype[ prop ] = ( function() { + function _super() { + return base.prototype[ prop ].apply( this, arguments ); + } + + function _superApply( args ) { + return base.prototype[ prop ].apply( this, args ); + } + + return function() { + var __super = this._super; + var __superApply = this._superApply; + var returnValue; + + this._super = _super; + this._superApply = _superApply; + + returnValue = value.apply( this, arguments ); + + this._super = __super; + this._superApply = __superApply; + + return returnValue; + }; + } )(); + } ); + constructor.prototype = $.widget.extend( basePrototype, { + + // TODO: remove support for widgetEventPrefix + // always use the name + a colon as the prefix, e.g., draggable:start + // don't prefix for widgets that aren't DOM-based + widgetEventPrefix: existingConstructor ? ( basePrototype.widgetEventPrefix || name ) : name + }, proxiedPrototype, { + constructor: constructor, + namespace: namespace, + widgetName: name, + widgetFullName: fullName + } ); + + // If this widget is being redefined then we need to find all widgets that + // are inheriting from it and redefine all of them so that they inherit from + // the new version of this widget. We're essentially trying to replace one + // level in the prototype chain. + if ( existingConstructor ) { + $.each( existingConstructor._childConstructors, function( i, child ) { + var childPrototype = child.prototype; + + // Redefine the child widget using the same prototype that was + // originally used, but inherit from the new version of the base + $.widget( childPrototype.namespace + "." + childPrototype.widgetName, constructor, + child._proto ); + } ); + + // Remove the list of existing child constructors from the old constructor + // so the old child constructors can be garbage collected + delete existingConstructor._childConstructors; + } else { + base._childConstructors.push( constructor ); + } + + $.widget.bridge( name, constructor ); + + return constructor; +}; + +$.widget.extend = function( target ) { + var input = widgetSlice.call( arguments, 1 ); + var inputIndex = 0; + var inputLength = input.length; + var key; + var value; + + for ( ; inputIndex < inputLength; inputIndex++ ) { + for ( key in input[ inputIndex ] ) { + value = input[ inputIndex ][ key ]; + if ( widgetHasOwnProperty.call( input[ inputIndex ], key ) && value !== undefined ) { + + // Clone objects + if ( $.isPlainObject( value ) ) { + target[ key ] = $.isPlainObject( target[ key ] ) ? + $.widget.extend( {}, target[ key ], value ) : + + // Don't extend strings, arrays, etc. with objects + $.widget.extend( {}, value ); + + // Copy everything else by reference + } else { + target[ key ] = value; + } + } + } + } + return target; +}; + +$.widget.bridge = function( name, object ) { + var fullName = object.prototype.widgetFullName || name; + $.fn[ name ] = function( options ) { + var isMethodCall = typeof options === "string"; + var args = widgetSlice.call( arguments, 1 ); + var returnValue = this; + + if ( isMethodCall ) { + + // If this is an empty collection, we need to have the instance method + // return undefined instead of the jQuery instance + if ( !this.length && options === "instance" ) { + returnValue = undefined; + } else { + this.each( function() { + var methodValue; + var instance = $.data( this, fullName ); + + if ( options === "instance" ) { + returnValue = instance; + return false; + } + + if ( !instance ) { + return $.error( "cannot call methods on " + name + + " prior to initialization; " + + "attempted to call method '" + options + "'" ); + } + + if ( typeof instance[ options ] !== "function" || + options.charAt( 0 ) === "_" ) { + return $.error( "no such method '" + options + "' for " + name + + " widget instance" ); + } + + methodValue = instance[ options ].apply( instance, args ); + + if ( methodValue !== instance && methodValue !== undefined ) { + returnValue = methodValue && methodValue.jquery ? + returnValue.pushStack( methodValue.get() ) : + methodValue; + return false; + } + } ); + } + } else { + + // Allow multiple hashes to be passed on init + if ( args.length ) { + options = $.widget.extend.apply( null, [ options ].concat( args ) ); + } + + this.each( function() { + var instance = $.data( this, fullName ); + if ( instance ) { + instance.option( options || {} ); + if ( instance._init ) { + instance._init(); + } + } else { + $.data( this, fullName, new object( options, this ) ); + } + } ); + } + + return returnValue; + }; +}; + +$.Widget = $.Widget || function( /* options, element */ ) {}; +$.Widget._childConstructors = []; + +$.Widget.prototype = { + widgetName: "widget", + widgetEventPrefix: "", + defaultElement: "<div>", + + options: { + classes: {}, + disabled: false, + + // Callbacks + create: null + }, + + _createWidget: function( options, element ) { + element = $( element || this.defaultElement || this )[ 0 ]; + this.element = $( element ); + this.uuid = widgetUuid++; + this.eventNamespace = "." + this.widgetName + this.uuid; + + this.bindings = $(); + this.hoverable = $(); + this.focusable = $(); + this.classesElementLookup = {}; + + if ( element !== this ) { + $.data( element, this.widgetFullName, this ); + this._on( true, this.element, { + remove: function( event ) { + if ( event.target === element ) { + this.destroy(); + } + } + } ); + this.document = $( element.style ? + + // Element within the document + element.ownerDocument : + + // Element is window or document + element.document || element ); + this.window = $( this.document[ 0 ].defaultView || this.document[ 0 ].parentWindow ); + } + + this.options = $.widget.extend( {}, + this.options, + this._getCreateOptions(), + options ); + + this._create(); + + if ( this.options.disabled ) { + this._setOptionDisabled( this.options.disabled ); + } + + this._trigger( "create", null, this._getCreateEventData() ); + this._init(); + }, + + _getCreateOptions: function() { + return {}; + }, + + _getCreateEventData: $.noop, + + _create: $.noop, + + _init: $.noop, + + destroy: function() { + var that = this; + + this._destroy(); + $.each( this.classesElementLookup, function( key, value ) { + that._removeClass( value, key ); + } ); + + // We can probably remove the unbind calls in 2.0 + // all event bindings should go through this._on() + this.element + .off( this.eventNamespace ) + .removeData( this.widgetFullName ); + this.widget() + .off( this.eventNamespace ) + .removeAttr( "aria-disabled" ); + + // Clean up events and states + this.bindings.off( this.eventNamespace ); + }, + + _destroy: $.noop, + + widget: function() { + return this.element; + }, + + option: function( key, value ) { + var options = key; + var parts; + var curOption; + var i; + + if ( arguments.length === 0 ) { + + // Don't return a reference to the internal hash + return $.widget.extend( {}, this.options ); + } + + if ( typeof key === "string" ) { + + // Handle nested keys, e.g., "foo.bar" => { foo: { bar: ___ } } + options = {}; + parts = key.split( "." ); + key = parts.shift(); + if ( parts.length ) { + curOption = options[ key ] = $.widget.extend( {}, this.options[ key ] ); + for ( i = 0; i < parts.length - 1; i++ ) { + curOption[ parts[ i ] ] = curOption[ parts[ i ] ] || {}; + curOption = curOption[ parts[ i ] ]; + } + key = parts.pop(); + if ( arguments.length === 1 ) { + return curOption[ key ] === undefined ? null : curOption[ key ]; + } + curOption[ key ] = value; + } else { + if ( arguments.length === 1 ) { + return this.options[ key ] === undefined ? null : this.options[ key ]; + } + options[ key ] = value; + } + } + + this._setOptions( options ); + + return this; + }, + + _setOptions: function( options ) { + var key; + + for ( key in options ) { + this._setOption( key, options[ key ] ); + } + + return this; + }, + + _setOption: function( key, value ) { + if ( key === "classes" ) { + this._setOptionClasses( value ); + } + + this.options[ key ] = value; + + if ( key === "disabled" ) { + this._setOptionDisabled( value ); + } + + return this; + }, + + _setOptionClasses: function( value ) { + var classKey, elements, currentElements; + + for ( classKey in value ) { + currentElements = this.classesElementLookup[ classKey ]; + if ( value[ classKey ] === this.options.classes[ classKey ] || + !currentElements || + !currentElements.length ) { + continue; + } + + // We are doing this to create a new jQuery object because the _removeClass() call + // on the next line is going to destroy the reference to the current elements being + // tracked. We need to save a copy of this collection so that we can add the new classes + // below. + elements = $( currentElements.get() ); + this._removeClass( currentElements, classKey ); + + // We don't use _addClass() here, because that uses this.options.classes + // for generating the string of classes. We want to use the value passed in from + // _setOption(), this is the new value of the classes option which was passed to + // _setOption(). We pass this value directly to _classes(). + elements.addClass( this._classes( { + element: elements, + keys: classKey, + classes: value, + add: true + } ) ); + } + }, + + _setOptionDisabled: function( value ) { + this._toggleClass( this.widget(), this.widgetFullName + "-disabled", null, !!value ); + + // If the widget is becoming disabled, then nothing is interactive + if ( value ) { + this._removeClass( this.hoverable, null, "ui-state-hover" ); + this._removeClass( this.focusable, null, "ui-state-focus" ); + } + }, + + enable: function() { + return this._setOptions( { disabled: false } ); + }, + + disable: function() { + return this._setOptions( { disabled: true } ); + }, + + _classes: function( options ) { + var full = []; + var that = this; + + options = $.extend( { + element: this.element, + classes: this.options.classes || {} + }, options ); + + function bindRemoveEvent() { + var nodesToBind = []; + + options.element.each( function( _, element ) { + var isTracked = $.map( that.classesElementLookup, function( elements ) { + return elements; + } ) + .some( function( elements ) { + return elements.is( element ); + } ); + + if ( !isTracked ) { + nodesToBind.push( element ); + } + } ); + + that._on( $( nodesToBind ), { + remove: "_untrackClassesElement" + } ); + } + + function processClassString( classes, checkOption ) { + var current, i; + for ( i = 0; i < classes.length; i++ ) { + current = that.classesElementLookup[ classes[ i ] ] || $(); + if ( options.add ) { + bindRemoveEvent(); + current = $( $.uniqueSort( current.get().concat( options.element.get() ) ) ); + } else { + current = $( current.not( options.element ).get() ); + } + that.classesElementLookup[ classes[ i ] ] = current; + full.push( classes[ i ] ); + if ( checkOption && options.classes[ classes[ i ] ] ) { + full.push( options.classes[ classes[ i ] ] ); + } + } + } + + if ( options.keys ) { + processClassString( options.keys.match( /\S+/g ) || [], true ); + } + if ( options.extra ) { + processClassString( options.extra.match( /\S+/g ) || [] ); + } + + return full.join( " " ); + }, + + _untrackClassesElement: function( event ) { + var that = this; + $.each( that.classesElementLookup, function( key, value ) { + if ( $.inArray( event.target, value ) !== -1 ) { + that.classesElementLookup[ key ] = $( value.not( event.target ).get() ); + } + } ); + + this._off( $( event.target ) ); + }, + + _removeClass: function( element, keys, extra ) { + return this._toggleClass( element, keys, extra, false ); + }, + + _addClass: function( element, keys, extra ) { + return this._toggleClass( element, keys, extra, true ); + }, + + _toggleClass: function( element, keys, extra, add ) { + add = ( typeof add === "boolean" ) ? add : extra; + var shift = ( typeof element === "string" || element === null ), + options = { + extra: shift ? keys : extra, + keys: shift ? element : keys, + element: shift ? this.element : element, + add: add + }; + options.element.toggleClass( this._classes( options ), add ); + return this; + }, + + _on: function( suppressDisabledCheck, element, handlers ) { + var delegateElement; + var instance = this; + + // No suppressDisabledCheck flag, shuffle arguments + if ( typeof suppressDisabledCheck !== "boolean" ) { + handlers = element; + element = suppressDisabledCheck; + suppressDisabledCheck = false; + } + + // No element argument, shuffle and use this.element + if ( !handlers ) { + handlers = element; + element = this.element; + delegateElement = this.widget(); + } else { + element = delegateElement = $( element ); + this.bindings = this.bindings.add( element ); + } + + $.each( handlers, function( event, handler ) { + function handlerProxy() { + + // Allow widgets to customize the disabled handling + // - disabled as an array instead of boolean + // - disabled class as method for disabling individual parts + if ( !suppressDisabledCheck && + ( instance.options.disabled === true || + $( this ).hasClass( "ui-state-disabled" ) ) ) { + return; + } + return ( typeof handler === "string" ? instance[ handler ] : handler ) + .apply( instance, arguments ); + } + + // Copy the guid so direct unbinding works + if ( typeof handler !== "string" ) { + handlerProxy.guid = handler.guid = + handler.guid || handlerProxy.guid || $.guid++; + } + + var match = event.match( /^([\w:-]*)\s*(.*)$/ ); + var eventName = match[ 1 ] + instance.eventNamespace; + var selector = match[ 2 ]; + + if ( selector ) { + delegateElement.on( eventName, selector, handlerProxy ); + } else { + element.on( eventName, handlerProxy ); + } + } ); + }, + + _off: function( element, eventName ) { + eventName = ( eventName || "" ).split( " " ).join( this.eventNamespace + " " ) + + this.eventNamespace; + element.off( eventName ); + + // Clear the stack to avoid memory leaks (#10056) + this.bindings = $( this.bindings.not( element ).get() ); + this.focusable = $( this.focusable.not( element ).get() ); + this.hoverable = $( this.hoverable.not( element ).get() ); + }, + + _delay: function( handler, delay ) { + function handlerProxy() { + return ( typeof handler === "string" ? instance[ handler ] : handler ) + .apply( instance, arguments ); + } + var instance = this; + return setTimeout( handlerProxy, delay || 0 ); + }, + + _hoverable: function( element ) { + this.hoverable = this.hoverable.add( element ); + this._on( element, { + mouseenter: function( event ) { + this._addClass( $( event.currentTarget ), null, "ui-state-hover" ); + }, + mouseleave: function( event ) { + this._removeClass( $( event.currentTarget ), null, "ui-state-hover" ); + } + } ); + }, + + _focusable: function( element ) { + this.focusable = this.focusable.add( element ); + this._on( element, { + focusin: function( event ) { + this._addClass( $( event.currentTarget ), null, "ui-state-focus" ); + }, + focusout: function( event ) { + this._removeClass( $( event.currentTarget ), null, "ui-state-focus" ); + } + } ); + }, + + _trigger: function( type, event, data ) { + var prop, orig; + var callback = this.options[ type ]; + + data = data || {}; + event = $.Event( event ); + event.type = ( type === this.widgetEventPrefix ? + type : + this.widgetEventPrefix + type ).toLowerCase(); + + // The original event may come from any element + // so we need to reset the target on the new event + event.target = this.element[ 0 ]; + + // Copy original event properties over to the new event + orig = event.originalEvent; + if ( orig ) { + for ( prop in orig ) { + if ( !( prop in event ) ) { + event[ prop ] = orig[ prop ]; + } + } + } + + this.element.trigger( event, data ); + return !( typeof callback === "function" && + callback.apply( this.element[ 0 ], [ event ].concat( data ) ) === false || + event.isDefaultPrevented() ); + } +}; + +$.each( { show: "fadeIn", hide: "fadeOut" }, function( method, defaultEffect ) { + $.Widget.prototype[ "_" + method ] = function( element, options, callback ) { + if ( typeof options === "string" ) { + options = { effect: options }; + } + + var hasOptions; + var effectName = !options ? + method : + options === true || typeof options === "number" ? + defaultEffect : + options.effect || defaultEffect; + + options = options || {}; + if ( typeof options === "number" ) { + options = { duration: options }; + } else if ( options === true ) { + options = {}; + } + + hasOptions = !$.isEmptyObject( options ); + options.complete = callback; + + if ( options.delay ) { + element.delay( options.delay ); + } + + if ( hasOptions && $.effects && $.effects.effect[ effectName ] ) { + element[ method ]( options ); + } else if ( effectName !== method && element[ effectName ] ) { + element[ effectName ]( options.duration, options.easing, callback ); + } else { + element.queue( function( next ) { + $( this )[ method ](); + if ( callback ) { + callback.call( element[ 0 ] ); + } + next(); + } ); + } + }; +} ); + +var widget = $.widget; + + +/*! + * jQuery UI Position 1.13.2 + * http://jqueryui.com + * + * Copyright jQuery Foundation and other contributors + * Released under the MIT license. + * http://jquery.org/license + * + * http://api.jqueryui.com/position/ + */ + +//>>label: Position +//>>group: Core +//>>description: Positions elements relative to other elements. +//>>docs: http://api.jqueryui.com/position/ +//>>demos: http://jqueryui.com/position/ + + +( function() { +var cachedScrollbarWidth, + max = Math.max, + abs = Math.abs, + rhorizontal = /left|center|right/, + rvertical = /top|center|bottom/, + roffset = /[\+\-]\d+(\.[\d]+)?%?/, + rposition = /^\w+/, + rpercent = /%$/, + _position = $.fn.position; + +function getOffsets( offsets, width, height ) { + return [ + parseFloat( offsets[ 0 ] ) * ( rpercent.test( offsets[ 0 ] ) ? width / 100 : 1 ), + parseFloat( offsets[ 1 ] ) * ( rpercent.test( offsets[ 1 ] ) ? height / 100 : 1 ) + ]; +} + +function parseCss( element, property ) { + return parseInt( $.css( element, property ), 10 ) || 0; +} + +function isWindow( obj ) { + return obj != null && obj === obj.window; +} + +function getDimensions( elem ) { + var raw = elem[ 0 ]; + if ( raw.nodeType === 9 ) { + return { + width: elem.width(), + height: elem.height(), + offset: { top: 0, left: 0 } + }; + } + if ( isWindow( raw ) ) { + return { + width: elem.width(), + height: elem.height(), + offset: { top: elem.scrollTop(), left: elem.scrollLeft() } + }; + } + if ( raw.preventDefault ) { + return { + width: 0, + height: 0, + offset: { top: raw.pageY, left: raw.pageX } + }; + } + return { + width: elem.outerWidth(), + height: elem.outerHeight(), + offset: elem.offset() + }; +} + +$.position = $.position || { + scrollbarWidth: function() { + if ( cachedScrollbarWidth !== undefined ) { + return cachedScrollbarWidth; + } + var w1, w2, + div = $( "<div style=" + + "'display:block;position:absolute;width:200px;height:200px;overflow:hidden;'>" + + "<div style='height:300px;width:auto;'></div></div>" ), + innerDiv = div.children()[ 0 ]; + + $( "body" ).append( div ); + w1 = innerDiv.offsetWidth; + div.css( "overflow", "scroll" ); + + w2 = innerDiv.offsetWidth; + + if ( w1 === w2 ) { + w2 = div[ 0 ].clientWidth; + } + + div.remove(); + + return ( cachedScrollbarWidth = w1 - w2 ); + }, + getScrollInfo: function( within ) { + var overflowX = within.isWindow || within.isDocument ? "" : + within.element.css( "overflow-x" ), + overflowY = within.isWindow || within.isDocument ? "" : + within.element.css( "overflow-y" ), + hasOverflowX = overflowX === "scroll" || + ( overflowX === "auto" && within.width < within.element[ 0 ].scrollWidth ), + hasOverflowY = overflowY === "scroll" || + ( overflowY === "auto" && within.height < within.element[ 0 ].scrollHeight ); + return { + width: hasOverflowY ? $.position.scrollbarWidth() : 0, + height: hasOverflowX ? $.position.scrollbarWidth() : 0 + }; + }, + getWithinInfo: function( element ) { + var withinElement = $( element || window ), + isElemWindow = isWindow( withinElement[ 0 ] ), + isDocument = !!withinElement[ 0 ] && withinElement[ 0 ].nodeType === 9, + hasOffset = !isElemWindow && !isDocument; + return { + element: withinElement, + isWindow: isElemWindow, + isDocument: isDocument, + offset: hasOffset ? $( element ).offset() : { left: 0, top: 0 }, + scrollLeft: withinElement.scrollLeft(), + scrollTop: withinElement.scrollTop(), + width: withinElement.outerWidth(), + height: withinElement.outerHeight() + }; + } +}; + +$.fn.position = function( options ) { + if ( !options || !options.of ) { + return _position.apply( this, arguments ); + } + + // Make a copy, we don't want to modify arguments + options = $.extend( {}, options ); + + var atOffset, targetWidth, targetHeight, targetOffset, basePosition, dimensions, + + // Make sure string options are treated as CSS selectors + target = typeof options.of === "string" ? + $( document ).find( options.of ) : + $( options.of ), + + within = $.position.getWithinInfo( options.within ), + scrollInfo = $.position.getScrollInfo( within ), + collision = ( options.collision || "flip" ).split( " " ), + offsets = {}; + + dimensions = getDimensions( target ); + if ( target[ 0 ].preventDefault ) { + + // Force left top to allow flipping + options.at = "left top"; + } + targetWidth = dimensions.width; + targetHeight = dimensions.height; + targetOffset = dimensions.offset; + + // Clone to reuse original targetOffset later + basePosition = $.extend( {}, targetOffset ); + + // Force my and at to have valid horizontal and vertical positions + // if a value is missing or invalid, it will be converted to center + $.each( [ "my", "at" ], function() { + var pos = ( options[ this ] || "" ).split( " " ), + horizontalOffset, + verticalOffset; + + if ( pos.length === 1 ) { + pos = rhorizontal.test( pos[ 0 ] ) ? + pos.concat( [ "center" ] ) : + rvertical.test( pos[ 0 ] ) ? + [ "center" ].concat( pos ) : + [ "center", "center" ]; + } + pos[ 0 ] = rhorizontal.test( pos[ 0 ] ) ? pos[ 0 ] : "center"; + pos[ 1 ] = rvertical.test( pos[ 1 ] ) ? pos[ 1 ] : "center"; + + // Calculate offsets + horizontalOffset = roffset.exec( pos[ 0 ] ); + verticalOffset = roffset.exec( pos[ 1 ] ); + offsets[ this ] = [ + horizontalOffset ? horizontalOffset[ 0 ] : 0, + verticalOffset ? verticalOffset[ 0 ] : 0 + ]; + + // Reduce to just the positions without the offsets + options[ this ] = [ + rposition.exec( pos[ 0 ] )[ 0 ], + rposition.exec( pos[ 1 ] )[ 0 ] + ]; + } ); + + // Normalize collision option + if ( collision.length === 1 ) { + collision[ 1 ] = collision[ 0 ]; + } + + if ( options.at[ 0 ] === "right" ) { + basePosition.left += targetWidth; + } else if ( options.at[ 0 ] === "center" ) { + basePosition.left += targetWidth / 2; + } + + if ( options.at[ 1 ] === "bottom" ) { + basePosition.top += targetHeight; + } else if ( options.at[ 1 ] === "center" ) { + basePosition.top += targetHeight / 2; + } + + atOffset = getOffsets( offsets.at, targetWidth, targetHeight ); + basePosition.left += atOffset[ 0 ]; + basePosition.top += atOffset[ 1 ]; + + return this.each( function() { + var collisionPosition, using, + elem = $( this ), + elemWidth = elem.outerWidth(), + elemHeight = elem.outerHeight(), + marginLeft = parseCss( this, "marginLeft" ), + marginTop = parseCss( this, "marginTop" ), + collisionWidth = elemWidth + marginLeft + parseCss( this, "marginRight" ) + + scrollInfo.width, + collisionHeight = elemHeight + marginTop + parseCss( this, "marginBottom" ) + + scrollInfo.height, + position = $.extend( {}, basePosition ), + myOffset = getOffsets( offsets.my, elem.outerWidth(), elem.outerHeight() ); + + if ( options.my[ 0 ] === "right" ) { + position.left -= elemWidth; + } else if ( options.my[ 0 ] === "center" ) { + position.left -= elemWidth / 2; + } + + if ( options.my[ 1 ] === "bottom" ) { + position.top -= elemHeight; + } else if ( options.my[ 1 ] === "center" ) { + position.top -= elemHeight / 2; + } + + position.left += myOffset[ 0 ]; + position.top += myOffset[ 1 ]; + + collisionPosition = { + marginLeft: marginLeft, + marginTop: marginTop + }; + + $.each( [ "left", "top" ], function( i, dir ) { + if ( $.ui.position[ collision[ i ] ] ) { + $.ui.position[ collision[ i ] ][ dir ]( position, { + targetWidth: targetWidth, + targetHeight: targetHeight, + elemWidth: elemWidth, + elemHeight: elemHeight, + collisionPosition: collisionPosition, + collisionWidth: collisionWidth, + collisionHeight: collisionHeight, + offset: [ atOffset[ 0 ] + myOffset[ 0 ], atOffset [ 1 ] + myOffset[ 1 ] ], + my: options.my, + at: options.at, + within: within, + elem: elem + } ); + } + } ); + + if ( options.using ) { + + // Adds feedback as second argument to using callback, if present + using = function( props ) { + var left = targetOffset.left - position.left, + right = left + targetWidth - elemWidth, + top = targetOffset.top - position.top, + bottom = top + targetHeight - elemHeight, + feedback = { + target: { + element: target, + left: targetOffset.left, + top: targetOffset.top, + width: targetWidth, + height: targetHeight + }, + element: { + element: elem, + left: position.left, + top: position.top, + width: elemWidth, + height: elemHeight + }, + horizontal: right < 0 ? "left" : left > 0 ? "right" : "center", + vertical: bottom < 0 ? "top" : top > 0 ? "bottom" : "middle" + }; + if ( targetWidth < elemWidth && abs( left + right ) < targetWidth ) { + feedback.horizontal = "center"; + } + if ( targetHeight < elemHeight && abs( top + bottom ) < targetHeight ) { + feedback.vertical = "middle"; + } + if ( max( abs( left ), abs( right ) ) > max( abs( top ), abs( bottom ) ) ) { + feedback.important = "horizontal"; + } else { + feedback.important = "vertical"; + } + options.using.call( this, props, feedback ); + }; + } + + elem.offset( $.extend( position, { using: using } ) ); + } ); +}; + +$.ui.position = { + fit: { + left: function( position, data ) { + var within = data.within, + withinOffset = within.isWindow ? within.scrollLeft : within.offset.left, + outerWidth = within.width, + collisionPosLeft = position.left - data.collisionPosition.marginLeft, + overLeft = withinOffset - collisionPosLeft, + overRight = collisionPosLeft + data.collisionWidth - outerWidth - withinOffset, + newOverRight; + + // Element is wider than within + if ( data.collisionWidth > outerWidth ) { + + // Element is initially over the left side of within + if ( overLeft > 0 && overRight <= 0 ) { + newOverRight = position.left + overLeft + data.collisionWidth - outerWidth - + withinOffset; + position.left += overLeft - newOverRight; + + // Element is initially over right side of within + } else if ( overRight > 0 && overLeft <= 0 ) { + position.left = withinOffset; + + // Element is initially over both left and right sides of within + } else { + if ( overLeft > overRight ) { + position.left = withinOffset + outerWidth - data.collisionWidth; + } else { + position.left = withinOffset; + } + } + + // Too far left -> align with left edge + } else if ( overLeft > 0 ) { + position.left += overLeft; + + // Too far right -> align with right edge + } else if ( overRight > 0 ) { + position.left -= overRight; + + // Adjust based on position and margin + } else { + position.left = max( position.left - collisionPosLeft, position.left ); + } + }, + top: function( position, data ) { + var within = data.within, + withinOffset = within.isWindow ? within.scrollTop : within.offset.top, + outerHeight = data.within.height, + collisionPosTop = position.top - data.collisionPosition.marginTop, + overTop = withinOffset - collisionPosTop, + overBottom = collisionPosTop + data.collisionHeight - outerHeight - withinOffset, + newOverBottom; + + // Element is taller than within + if ( data.collisionHeight > outerHeight ) { + + // Element is initially over the top of within + if ( overTop > 0 && overBottom <= 0 ) { + newOverBottom = position.top + overTop + data.collisionHeight - outerHeight - + withinOffset; + position.top += overTop - newOverBottom; + + // Element is initially over bottom of within + } else if ( overBottom > 0 && overTop <= 0 ) { + position.top = withinOffset; + + // Element is initially over both top and bottom of within + } else { + if ( overTop > overBottom ) { + position.top = withinOffset + outerHeight - data.collisionHeight; + } else { + position.top = withinOffset; + } + } + + // Too far up -> align with top + } else if ( overTop > 0 ) { + position.top += overTop; + + // Too far down -> align with bottom edge + } else if ( overBottom > 0 ) { + position.top -= overBottom; + + // Adjust based on position and margin + } else { + position.top = max( position.top - collisionPosTop, position.top ); + } + } + }, + flip: { + left: function( position, data ) { + var within = data.within, + withinOffset = within.offset.left + within.scrollLeft, + outerWidth = within.width, + offsetLeft = within.isWindow ? within.scrollLeft : within.offset.left, + collisionPosLeft = position.left - data.collisionPosition.marginLeft, + overLeft = collisionPosLeft - offsetLeft, + overRight = collisionPosLeft + data.collisionWidth - outerWidth - offsetLeft, + myOffset = data.my[ 0 ] === "left" ? + -data.elemWidth : + data.my[ 0 ] === "right" ? + data.elemWidth : + 0, + atOffset = data.at[ 0 ] === "left" ? + data.targetWidth : + data.at[ 0 ] === "right" ? + -data.targetWidth : + 0, + offset = -2 * data.offset[ 0 ], + newOverRight, + newOverLeft; + + if ( overLeft < 0 ) { + newOverRight = position.left + myOffset + atOffset + offset + data.collisionWidth - + outerWidth - withinOffset; + if ( newOverRight < 0 || newOverRight < abs( overLeft ) ) { + position.left += myOffset + atOffset + offset; + } + } else if ( overRight > 0 ) { + newOverLeft = position.left - data.collisionPosition.marginLeft + myOffset + + atOffset + offset - offsetLeft; + if ( newOverLeft > 0 || abs( newOverLeft ) < overRight ) { + position.left += myOffset + atOffset + offset; + } + } + }, + top: function( position, data ) { + var within = data.within, + withinOffset = within.offset.top + within.scrollTop, + outerHeight = within.height, + offsetTop = within.isWindow ? within.scrollTop : within.offset.top, + collisionPosTop = position.top - data.collisionPosition.marginTop, + overTop = collisionPosTop - offsetTop, + overBottom = collisionPosTop + data.collisionHeight - outerHeight - offsetTop, + top = data.my[ 1 ] === "top", + myOffset = top ? + -data.elemHeight : + data.my[ 1 ] === "bottom" ? + data.elemHeight : + 0, + atOffset = data.at[ 1 ] === "top" ? + data.targetHeight : + data.at[ 1 ] === "bottom" ? + -data.targetHeight : + 0, + offset = -2 * data.offset[ 1 ], + newOverTop, + newOverBottom; + if ( overTop < 0 ) { + newOverBottom = position.top + myOffset + atOffset + offset + data.collisionHeight - + outerHeight - withinOffset; + if ( newOverBottom < 0 || newOverBottom < abs( overTop ) ) { + position.top += myOffset + atOffset + offset; + } + } else if ( overBottom > 0 ) { + newOverTop = position.top - data.collisionPosition.marginTop + myOffset + atOffset + + offset - offsetTop; + if ( newOverTop > 0 || abs( newOverTop ) < overBottom ) { + position.top += myOffset + atOffset + offset; + } + } + } + }, + flipfit: { + left: function() { + $.ui.position.flip.left.apply( this, arguments ); + $.ui.position.fit.left.apply( this, arguments ); + }, + top: function() { + $.ui.position.flip.top.apply( this, arguments ); + $.ui.position.fit.top.apply( this, arguments ); + } + } +}; + +} )(); + +var position = $.ui.position; + + +/*! + * jQuery UI Support for jQuery core 1.8.x and newer 1.13.2 + * http://jqueryui.com + * + * Copyright jQuery Foundation and other contributors + * Released under the MIT license. + * http://jquery.org/license + * + */ + +//>>label: jQuery 1.8+ Support +//>>group: Core +//>>description: Support version 1.8.x and newer of jQuery core + + +// Support: jQuery 1.9.x or older +// $.expr[ ":" ] is deprecated. +if ( !$.expr.pseudos ) { + $.expr.pseudos = $.expr[ ":" ]; +} + +// Support: jQuery 1.11.x or older +// $.unique has been renamed to $.uniqueSort +if ( !$.uniqueSort ) { + $.uniqueSort = $.unique; +} + +// Support: jQuery 2.2.x or older. +// This method has been defined in jQuery 3.0.0. +// Code from https://github.com/jquery/jquery/blob/e539bac79e666bba95bba86d690b4e609dca2286/src/selector/escapeSelector.js +if ( !$.escapeSelector ) { + + // CSS string/identifier serialization + // https://drafts.csswg.org/cssom/#common-serializing-idioms + var rcssescape = /([\0-\x1f\x7f]|^-?\d)|^-$|[^\x80-\uFFFF\w-]/g; + + var fcssescape = function( ch, asCodePoint ) { + if ( asCodePoint ) { + + // U+0000 NULL becomes U+FFFD REPLACEMENT CHARACTER + if ( ch === "\0" ) { + return "\uFFFD"; + } + + // Control characters and (dependent upon position) numbers get escaped as code points + return ch.slice( 0, -1 ) + "\\" + ch.charCodeAt( ch.length - 1 ).toString( 16 ) + " "; + } + + // Other potentially-special ASCII characters get backslash-escaped + return "\\" + ch; + }; + + $.escapeSelector = function( sel ) { + return ( sel + "" ).replace( rcssescape, fcssescape ); + }; +} + +// Support: jQuery 3.4.x or older +// These methods have been defined in jQuery 3.5.0. +if ( !$.fn.even || !$.fn.odd ) { + $.fn.extend( { + even: function() { + return this.filter( function( i ) { + return i % 2 === 0; + } ); + }, + odd: function() { + return this.filter( function( i ) { + return i % 2 === 1; + } ); + } + } ); +} + +; +/*! + * jQuery UI Keycode 1.13.2 + * http://jqueryui.com + * + * Copyright jQuery Foundation and other contributors + * Released under the MIT license. + * http://jquery.org/license + */ + +//>>label: Keycode +//>>group: Core +//>>description: Provide keycodes as keynames +//>>docs: http://api.jqueryui.com/jQuery.ui.keyCode/ + + +var keycode = $.ui.keyCode = { + BACKSPACE: 8, + COMMA: 188, + DELETE: 46, + DOWN: 40, + END: 35, + ENTER: 13, + ESCAPE: 27, + HOME: 36, + LEFT: 37, + PAGE_DOWN: 34, + PAGE_UP: 33, + PERIOD: 190, + RIGHT: 39, + SPACE: 32, + TAB: 9, + UP: 38 +}; + + +/*! + * jQuery UI Scroll Parent 1.13.2 + * http://jqueryui.com + * + * Copyright jQuery Foundation and other contributors + * Released under the MIT license. + * http://jquery.org/license + */ + +//>>label: scrollParent +//>>group: Core +//>>description: Get the closest ancestor element that is scrollable. +//>>docs: http://api.jqueryui.com/scrollParent/ + + +var scrollParent = $.fn.scrollParent = function( includeHidden ) { + var position = this.css( "position" ), + excludeStaticParent = position === "absolute", + overflowRegex = includeHidden ? /(auto|scroll|hidden)/ : /(auto|scroll)/, + scrollParent = this.parents().filter( function() { + var parent = $( this ); + if ( excludeStaticParent && parent.css( "position" ) === "static" ) { + return false; + } + return overflowRegex.test( parent.css( "overflow" ) + parent.css( "overflow-y" ) + + parent.css( "overflow-x" ) ); + } ).eq( 0 ); + + return position === "fixed" || !scrollParent.length ? + $( this[ 0 ].ownerDocument || document ) : + scrollParent; +}; + + +/*! + * jQuery UI Unique ID 1.13.2 + * http://jqueryui.com + * + * Copyright jQuery Foundation and other contributors + * Released under the MIT license. + * http://jquery.org/license + */ + +//>>label: uniqueId +//>>group: Core +//>>description: Functions to generate and remove uniqueId's +//>>docs: http://api.jqueryui.com/uniqueId/ + + +var uniqueId = $.fn.extend( { + uniqueId: ( function() { + var uuid = 0; + + return function() { + return this.each( function() { + if ( !this.id ) { + this.id = "ui-id-" + ( ++uuid ); + } + } ); + }; + } )(), + + removeUniqueId: function() { + return this.each( function() { + if ( /^ui-id-\d+$/.test( this.id ) ) { + $( this ).removeAttr( "id" ); + } + } ); + } +} ); + + + + +} );
\ No newline at end of file diff --git a/plugins/55/indexmenu/scripts/fancytree/modules/jquery.fancytree.wide.js b/plugins/55/indexmenu/scripts/fancytree/modules/jquery.fancytree.wide.js new file mode 100644 index 0000000..742d29c --- /dev/null +++ b/plugins/55/indexmenu/scripts/fancytree/modules/jquery.fancytree.wide.js @@ -0,0 +1,257 @@ +/*! + * jquery.fancytree.wide.js + * Support for 100% wide selection bars. + * (Extension module for jquery.fancytree.js: https://github.com/mar10/fancytree/) + * + * Copyright (c) 2008-2023, Martin Wendt (https://wwWendt.de) + * + * Released under the MIT license + * https://github.com/mar10/fancytree/wiki/LicenseInfo + * + * @version 2.38.3 + * @date 2023-02-01T20:52:50Z + */ + +(function (factory) { + if (typeof define === "function" && define.amd) { + // AMD. Register as an anonymous module. + define(["jquery", "./jquery.fancytree"], factory); + } else if (typeof module === "object" && module.exports) { + // Node/CommonJS + require("./jquery.fancytree"); + module.exports = factory(require("jquery")); + } else { + // Browser globals + factory(jQuery); + } +})(function ($) { + "use strict"; + + var reNumUnit = /^([+-]?(?:\d+|\d*\.\d+))([a-z]*|%)$/; // split "1.5em" to ["1.5", "em"] + + /******************************************************************************* + * Private functions and variables + */ + // var _assert = $.ui.fancytree.assert; + + /* Calculate inner width without scrollbar */ + // function realInnerWidth($el) { + // // http://blog.jquery.com/2012/08/16/jquery-1-8-box-sizing-width-csswidth-and-outerwidth/ + // // inst.contWidth = parseFloat(this.$container.css("width"), 10); + // // 'Client width without scrollbar' - 'padding' + // return $el[0].clientWidth - ($el.innerWidth() - parseFloat($el.css("width"), 10)); + // } + + /* Create a global embedded CSS style for the tree. */ + function defineHeadStyleElement(id, cssText) { + id = "fancytree-style-" + id; + var $headStyle = $("#" + id); + + if (!cssText) { + $headStyle.remove(); + return null; + } + if (!$headStyle.length) { + $headStyle = $("<style />") + .attr("id", id) + .addClass("fancytree-style") + .prop("type", "text/css") + .appendTo("head"); + } + try { + $headStyle.html(cssText); + } catch (e) { + // fix for IE 6-8 + $headStyle[0].styleSheet.cssText = cssText; + } + return $headStyle; + } + + /* Calculate the CSS rules that indent title spans. */ + function renderLevelCss( + containerId, + depth, + levelOfs, + lineOfs, + labelOfs, + measureUnit + ) { + var i, + prefix = "#" + containerId + " span.fancytree-level-", + rules = []; + + for (i = 0; i < depth; i++) { + rules.push( + prefix + + (i + 1) + + " span.fancytree-title { padding-left: " + + (i * levelOfs + lineOfs) + + measureUnit + + "; }" + ); + } + // Some UI animations wrap the UL inside a DIV and set position:relative on both. + // This breaks the left:0 and padding-left:nn settings of the title + rules.push( + "#" + + containerId + + " div.ui-effects-wrapper ul li span.fancytree-title, " + + "#" + + containerId + + " li.fancytree-animating span.fancytree-title " + // #716 + "{ padding-left: " + + labelOfs + + measureUnit + + "; position: static; width: auto; }" + ); + return rules.join("\n"); + } + + // /** + // * [ext-wide] Recalculate the width of the selection bar after the tree container + // * was resized.<br> + // * May be called explicitly on container resize, since there is no resize event + // * for DIV tags. + // * + // * @alias Fancytree#wideUpdate + // * @requires jquery.fancytree.wide.js + // */ + // $.ui.fancytree._FancytreeClass.prototype.wideUpdate = function(){ + // var inst = this.ext.wide, + // prevCw = inst.contWidth, + // prevLo = inst.lineOfs; + + // inst.contWidth = realInnerWidth(this.$container); + // // Each title is precceeded by 2 or 3 icons (16px + 3 margin) + // // + 1px title border and 3px title padding + // // TODO: use code from treeInit() below + // inst.lineOfs = (this.options.checkbox ? 3 : 2) * 19; + // if( prevCw !== inst.contWidth || prevLo !== inst.lineOfs ) { + // this.debug("wideUpdate: " + inst.contWidth); + // this.visit(function(node){ + // node.tree._callHook("nodeRenderTitle", node); + // }); + // } + // }; + + /******************************************************************************* + * Extension code + */ + $.ui.fancytree.registerExtension({ + name: "wide", + version: "2.38.3", + // Default options for this extension. + options: { + iconWidth: null, // Adjust this if @fancy-icon-width != "16px" + iconSpacing: null, // Adjust this if @fancy-icon-spacing != "3px" + labelSpacing: null, // Adjust this if padding between icon and label != "3px" + levelOfs: null, // Adjust this if ul padding != "16px" + }, + + treeCreate: function (ctx) { + this._superApply(arguments); + this.$container.addClass("fancytree-ext-wide"); + + var containerId, + cssText, + iconSpacingUnit, + labelSpacingUnit, + iconWidthUnit, + levelOfsUnit, + instOpts = ctx.options.wide, + // css sniffing + $dummyLI = $( + "<li id='fancytreeTemp'><span class='fancytree-node'><span class='fancytree-icon' /><span class='fancytree-title' /></span><ul />" + ).appendTo(ctx.tree.$container), + $dummyIcon = $dummyLI.find(".fancytree-icon"), + $dummyUL = $dummyLI.find("ul"), + // $dummyTitle = $dummyLI.find(".fancytree-title"), + iconSpacing = + instOpts.iconSpacing || $dummyIcon.css("margin-left"), + iconWidth = instOpts.iconWidth || $dummyIcon.css("width"), + labelSpacing = instOpts.labelSpacing || "3px", + levelOfs = instOpts.levelOfs || $dummyUL.css("padding-left"); + + $dummyLI.remove(); + + iconSpacingUnit = iconSpacing.match(reNumUnit)[2]; + iconSpacing = parseFloat(iconSpacing, 10); + labelSpacingUnit = labelSpacing.match(reNumUnit)[2]; + labelSpacing = parseFloat(labelSpacing, 10); + iconWidthUnit = iconWidth.match(reNumUnit)[2]; + iconWidth = parseFloat(iconWidth, 10); + levelOfsUnit = levelOfs.match(reNumUnit)[2]; + if ( + iconSpacingUnit !== iconWidthUnit || + levelOfsUnit !== iconWidthUnit || + labelSpacingUnit !== iconWidthUnit + ) { + $.error( + "iconWidth, iconSpacing, and levelOfs must have the same css measure unit" + ); + } + this._local.measureUnit = iconWidthUnit; + this._local.levelOfs = parseFloat(levelOfs); + this._local.lineOfs = + (1 + + (ctx.options.checkbox ? 1 : 0) + + (ctx.options.icon === false ? 0 : 1)) * + (iconWidth + iconSpacing) + + iconSpacing; + this._local.labelOfs = labelSpacing; + this._local.maxDepth = 10; + + // Get/Set a unique Id on the container (if not already exists) + containerId = this.$container.uniqueId().attr("id"); + // Generated css rules for some levels (extended on demand) + cssText = renderLevelCss( + containerId, + this._local.maxDepth, + this._local.levelOfs, + this._local.lineOfs, + this._local.labelOfs, + this._local.measureUnit + ); + defineHeadStyleElement(containerId, cssText); + }, + treeDestroy: function (ctx) { + // Remove generated css rules + defineHeadStyleElement(this.$container.attr("id"), null); + return this._superApply(arguments); + }, + nodeRenderStatus: function (ctx) { + var containerId, + cssText, + res, + node = ctx.node, + level = node.getLevel(); + + res = this._super(ctx); + // Generate some more level-n rules if required + if (level > this._local.maxDepth) { + containerId = this.$container.attr("id"); + this._local.maxDepth *= 2; + node.debug( + "Define global ext-wide css up to level " + + this._local.maxDepth + ); + cssText = renderLevelCss( + containerId, + this._local.maxDepth, + this._local.levelOfs, + this._local.lineOfs, + this._local.labelSpacing, + this._local.measureUnit + ); + defineHeadStyleElement(containerId, cssText); + } + // Add level-n class to apply indentation padding. + // (Setting element style would not work, since it cannot easily be + // overriden while animations run) + $(node.span).addClass("fancytree-level-" + level); + return res; + }, + }); + // Value returned by `require('jquery.fancytree..')` + return $.ui.fancytree; +}); // End of closure diff --git a/plugins/55/indexmenu/scripts/fancytree/readme/icons_layout__from ods.png b/plugins/55/indexmenu/scripts/fancytree/readme/icons_layout__from ods.png Binary files differnew file mode 100644 index 0000000..1ab4b72 --- /dev/null +++ b/plugins/55/indexmenu/scripts/fancytree/readme/icons_layout__from ods.png diff --git a/plugins/55/indexmenu/scripts/fancytree/skin-awesome/skin-common.less b/plugins/55/indexmenu/scripts/fancytree/skin-awesome/skin-common.less new file mode 100644 index 0000000..fc0da50 --- /dev/null +++ b/plugins/55/indexmenu/scripts/fancytree/skin-awesome/skin-common.less @@ -0,0 +1,972 @@ +/******************************************************************************* + * Common Styles for Fancytree Skins. + * + * This section is automatically generated from the `skin-common.less` template. + * + * Copyright (c) 2008-2023, Martin Wendt (https://wwWendt.de) + * Released under the MIT license + * https://github.com/mar10/fancytree/wiki/LicenseInfo + * + * @version 2.38.3 + * @date 2023-02-01T20:52:50Z +******************************************************************************/ + +// Variables (defaults, may be overwritten by the including .less files) +@fancy-use-sprites: true; // false: suppress all background images (i.e. icons) +// @fancy-hide-connectors: true; // false: show vertical connector lines + +@fancy-level-indent: 16px; +@fancy-line-height: 16px; // height of a nodes selection bar including borders +@fancy-node-v-spacing: 1px; // gap between two node borders +@fancy-icon-width: 16px; +@fancy-icon-height: 16px; +@fancy-icon-spacing: 3px; // margin between icon/icon or icon/title +@fancy-icon-ofs-top: 0px; // extra vertical offset for expander, checkbox and icon +@fancy-title-ofs-top: 0px; // extra vertical offset for title +@fancy-node-border-width: 1px; +@fancy-node-border-radius: 0px; +@fancy-node-outline-width: 1px; + +// @fancy-line-ofs-top: (@fancy-line-height - @fancy-icon-height) / 2; + +// webpack uses /dist/skin-common.less as root path +// grunt-less uses /dist/skin-Xxx/ui.fancyree.less as root path +// So we define our theme LESS files for webpack compatibility, i.e. +// define the image path n every main LESS file instead of here. +// Prefix may be set to "", "/", "./", or any other value +// Note: this variable must be defined by the main LESS files: +// @fancy-image-prefix: ""; + +// Use 'url(...)' to link to the throbber image, or +// use data-uri(...)' to inline the data in css instead: +/* CHANGE use url, as less does not handel data-uri() correct. DokuWiki can eventually inline it */ + @fancy-loading-url: url("@{fancy-image-prefix}loading.gif"); +//@fancy-loading-url: data-uri("@{fancy-image-prefix}loading.gif"); + +// Set to `true` to use `data-uri(...)` instead of a `url(...)` link: +@fancy-inline-sprites: false; // data-uri() is not handle correct by phpless + +@fancy-font-size: 10pt; +@fancy-font-family: tahoma, arial, helvetica; +@fancy-font-color: black; +@fancy-font-color-dimm: #c0c0c0; +@fancy-font-error-color: red; + +//------------------------------------------------------------------------------ +// Mixins +//------------------------------------------------------------------------------ +.setBgPos(@x, @y, @cond:true) when (@cond) { + background-position: (@x * -@fancy-icon-width) (@y * -@fancy-icon-height); +} +.clearBgImage(@cond:true) when (@cond) { + background-image: none; +} +.setBgImageUrl(@url) when (@fancy-use-sprites) and not (@fancy-inline-sprites) { + background-image: url("@{fancy-image-prefix}@{url}"); +} +.setBgImageUrl(@url) when (@fancy-use-sprites) and (@fancy-inline-sprites) { + background-image: data-uri("@{fancy-image-prefix}@{url}"); +} +.useSprite(@x, @y) when (@fancy-use-sprites) { + .setBgPos(@x, @y); +} +.rounded-corners(@radius) { + -webkit-border-radius: @radius; + -moz-border-radius: @radius; + -ms-border-radius: @radius; + -o-border-radius: @radius; + border-radius: @radius; +} +.spanStyleMixin(@color, @bgcolor, @bordercolor) { + border-color: @bordercolor; + background: @bgcolor; + color: @color; +} +.spanStyleMixin(@color, @bgcolor, @bordercolor, @startColor, @stopColor) { + .spanStyleMixin(@color, @bgcolor, @bordercolor); + // @c-start: argb(@startColor); + // @c-end: argb(@stopColor); + background: -moz-linear-gradient( + top, + @startColor 0%, + @stopColor 100% + ); // FF3.6+ + background: -webkit-gradient( + linear, + left top, + left bottom, + color-stop(0%, @startColor), + color-stop(100%, @stopColor) + ); // Chrome,Safari4+ + background: -webkit-linear-gradient( + top, + @startColor 0%, + @stopColor 100% + ); // Chrome10+,Safari5.1+ + background: -o-linear-gradient( + top, + @startColor 0%, + @stopColor 100% + ); // Opera 11.10+ + background: -ms-linear-gradient( + top, + @startColor 0%, + @stopColor 100% + ); // IE10+ + background: linear-gradient( + to bottom, + @startColor 0%, + @stopColor 100% + ); // W3C + filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='@{startColor}', endColorstr='@{stopColor}',GradientType=0 ); // IE6-9 +} + +/*------------------------------------------------------------------------------ + * Helpers + *----------------------------------------------------------------------------*/ +// Redefine, in case jQuery-UI is not included +// .ui-helper-hidden, +.fancytree-helper-hidden { + display: none; +} +.fancytree-helper-indeterminate-cb { + // tri-state checkbox + color: #777; +} +.fancytree-helper-disabled { + color: @fancy-font-color-dimm; +} + +/* Helper to allow spinning loader icon with glyph-, ligature-, and SVG-icons. */ +/* CHANGE: renamed spin to spin-fancytree */ +.fancytree-helper-spin { + -webkit-animation: spin-fancytree 1000ms infinite linear; + animation: spin-fancytree 1000ms infinite linear; +} +/* CHANGE: commented because it is wrong prefixed by phpless +@-webkit-keyframes spin { + 0% { + -webkit-transform: rotate(0deg); + transform: rotate(0deg); + } + 100% { + -webkit-transform: rotate(359deg); + transform: rotate(359deg); + } +} +@keyframes spin { + 0% { + -webkit-transform: rotate(0deg); + transform: rotate(0deg); + } + 100% { + -webkit-transform: rotate(359deg); + transform: rotate(359deg); + } +} +*/ +/*------------------------------------------------------------------------------ + * Container and UL / LI + *----------------------------------------------------------------------------*/ + +ul.fancytree-container { + font-family: @fancy-font-family; + font-size: @fancy-font-size; + white-space: nowrap; + padding: 3px; + margin: 0; // DT issue 201 + //background-color: white; CHANGE + //border: 1px dotted gray; CHANGE + // overflow: auto; // ext-dnd5: otherwise this is always the scroll parent + // height: 100%; // DT issue 263, 470 + min-height: 0%; // #192 + position: relative; // #235 + ul { + padding: 0 0 0 @fancy-level-indent; + margin: 0; + } + ul > li:before { + // #538 + content: none; + } + li { + list-style-image: none; + list-style-position: outside; + list-style-type: none; + -moz-background-clip: border; + -moz-background-inline-policy: continuous; + -moz-background-origin: padding; + background-attachment: scroll; + background-color: transparent; + .setBgPos(0, 0); + background-repeat: repeat-y; + background-image: none; // no v-lines + + margin: 0; + // padding: 1px 0 0 0; // issue #246 + } + // Suppress lines for last child node + li.fancytree-lastsib { + background-image: none; + } +} + +// Style, when control is disabled +.ui-fancytree-disabled ul.fancytree-container { + opacity: 0.5; + // filter: alpha(opacity=50); // Yields a css warning + background-color: silver; +} + +ul.fancytree-connectors.fancytree-container { + li { + // Use 'data-uri(...)' to embed the image into CSS instead of linking to 'loading.gif': + /* CHANGE: phpless does not handle data-uri() correct */ + //background-image: data-uri("@{fancy-image-prefix}vline.gif"); + background-image: url("@{fancy-image-prefix}vline.gif"); + background-position: 0 0; + } +} + +// Suppress lines for last child node +ul.fancytree-container li.fancytree-lastsib, +// Suppress lines if level is fixed expanded (option minExpandLevel) +ul.fancytree-no-connector > li { + background-image: none; +} + +// Fix jQuery UI 'blind' animation for jQuery UI (#717) +li.fancytree-animating { + position: relative; +} + +/*------------------------------------------------------------------------------ + * Common icon definitions + *----------------------------------------------------------------------------*/ + +span.fancytree-empty, +span.fancytree-vline, +span.fancytree-expander, +span.fancytree-icon, +span.fancytree-checkbox, +// span.fancytree-radio, +span.fancytree-drag-helper-img, +#fancytree-drop-marker { + width: @fancy-icon-width; + height: @fancy-icon-height; + // display: -moz-inline-box; // @ FF 1+2 removed for issue 221 + // -moz-box-align: start; /* issue 221 */ + display: inline-block; // Required to make a span sizeable + vertical-align: top; + background-repeat: no-repeat; + // background-position: left; + .setBgImageUrl("icons.gif"); + .setBgPos(0, 0); +} +span.fancytree-icon, +span.fancytree-checkbox, +span.fancytree-expander, +// span.fancytree-radio, +span.fancytree-custom-icon { + margin-top: @fancy-icon-ofs-top; +} +/* Used by icon option: */ +span.fancytree-custom-icon { + width: @fancy-icon-width; + height: @fancy-icon-height; + display: inline-block; + margin-left: @fancy-icon-spacing; + .setBgPos(0, 0); +} +/* Used by 'icon' node option: */ +img.fancytree-icon { + width: @fancy-icon-width; + height: @fancy-icon-height; + margin-left: @fancy-icon-spacing; + margin-top: @fancy-icon-ofs-top; + vertical-align: top; + border-style: none; +} + +/*------------------------------------------------------------------------------ + * Expander icon + * + * Note: IE6 doesn't correctly evaluate multiples class names, + * so we create combined class names that can be used in the CSS. + * + * Prefix: fancytree-exp- + * 1st character: 'e': expanded, 'c': collapsed, 'n': no children + * 2nd character (optional): 'd': lazy (Delayed) + * 3rd character (optional): 'l': Last sibling + *----------------------------------------------------------------------------*/ + +span.fancytree-expander { + // .useSprite(0, 5); + cursor: pointer; +} +// span.fancytree-expander:hover { +// // .useSprite(1, 5); +// } + +// --- End nodes (use connectors instead of expanders) + +.fancytree-exp-n span.fancytree-expander, +.fancytree-exp-nl span.fancytree-expander { + // .clearBgImage( @fancy-hide-connectors ); + background-image: none; + cursor: default; +} +.fancytree-connectors { + .fancytree-exp-n span.fancytree-expander, + .fancytree-exp-nl span.fancytree-expander { + .setBgImageUrl("icons.gif"); + margin-top: 0; + } + .fancytree-exp-n span.fancytree-expander, // End-node, not last sibling + .fancytree-exp-n span.fancytree-expander:hover { + .useSprite(0, 4); + } + .fancytree-exp-nl span.fancytree-expander, // End-node, last sibling + .fancytree-exp-nl span.fancytree-expander:hover { + .useSprite(1, 4); + } +} + +// --- Collapsed + +.fancytree-exp-c span.fancytree-expander { + // Collapsed, not delayed, not last sibling + .useSprite(0, 5); +} +.fancytree-exp-c span.fancytree-expander:hover { + .useSprite(1, 5); +} +.fancytree-exp-cl span.fancytree-expander { + // Collapsed, not delayed, last sibling + .useSprite(0, 6); +} +.fancytree-exp-cl span.fancytree-expander:hover { + .useSprite(1, 6); +} +.fancytree-exp-cd span.fancytree-expander { + // Collapsed, delayed, not last sibling + .useSprite(4, 5); +} +.fancytree-exp-cd span.fancytree-expander:hover { + .useSprite(5, 5); +} +.fancytree-exp-cdl span.fancytree-expander { + // Collapsed, delayed, last sibling + .useSprite(4, 6); +} +.fancytree-exp-cdl span.fancytree-expander:hover { + .useSprite(5, 6); +} + +// --- Expanded + +.fancytree-exp-e span.fancytree-expander, // Expanded, not delayed, not last sibling +.fancytree-exp-ed span.fancytree-expander { + // Expanded, delayed, not last sibling + .useSprite(2, 5); +} +.fancytree-exp-e span.fancytree-expander:hover, +.fancytree-exp-ed span.fancytree-expander:hover { + .useSprite(3, 5); +} +.fancytree-exp-el span.fancytree-expander, // Expanded, not delayed, last sibling +.fancytree-exp-edl span.fancytree-expander { + // Expanded, delayed, last sibling + .useSprite(2, 6); +} +.fancytree-exp-el span.fancytree-expander:hover, +.fancytree-exp-edl span.fancytree-expander:hover { + .useSprite(3, 6); +} + +/* Fade out expanders, when container is not hovered or active */ +.fancytree-fade-expander { + span.fancytree-expander { + transition: opacity 1.5s; + opacity: 0; + } + &:hover span.fancytree-expander, + &.fancytree-treefocus span.fancytree-expander, + .fancytree-treefocus span.fancytree-expander, + [class*="fancytree-statusnode-"] span.fancytree-expander { + transition: opacity 0.6s; + opacity: 1; + } +} + +//// CHANGE: not used. +///*------------------------------------------------------------------------------ +// * Checkbox icon +// *----------------------------------------------------------------------------*/ +// +//span.fancytree-checkbox { +// margin-left: @fancy-icon-spacing; +// .useSprite(0, 2); +// &:hover { +// .useSprite(1, 2); +// } +// &.fancytree-radio { +// .useSprite(0, 3); +// } +// &.fancytree-radio:hover { +// .useSprite(1, 3); +// } +//} +//.fancytree-partsel span.fancytree-checkbox { +// .useSprite(4, 2); +// &:hover { +// .useSprite(5, 2); +// } +// &.fancytree-radio { +// .useSprite(4, 3); +// } +// &.fancytree-radio:hover { +// .useSprite(5, 3); +// } +//} +//// selected after partsel, so it takes precedence: +//.fancytree-selected span.fancytree-checkbox { +// .useSprite(2, 2); +// &:hover { +// .useSprite(3, 2); +// } +// &.fancytree-radio { +// .useSprite(2, 3); +// } +// &.fancytree-radio:hover { +// .useSprite(3, 3); +// } +//} +//// Unselectable is dimmed, without hover effects +//.fancytree-unselectable { +// span.fancytree-checkbox { +// opacity: 0.4; +// filter: alpha(opacity=40); +// } +// span.fancytree-checkbox:hover { +// .useSprite(0, 2); +// } +// span.fancytree-checkbox.fancytree-radio:hover { +// .useSprite(0, 3); +// } +// &.fancytree-partsel span.fancytree-checkbox:hover { +// .useSprite(4, 2); +// } +// &.fancytree-selected span.fancytree-checkbox:hover { +// .useSprite(2, 2); +// } +// &.fancytree-selected span.fancytree-checkbox.fancytree-radio:hover { +// .useSprite(2, 3); +// } +//} +// +//// Auto-hide checkboxes unless selected or hovered +//.fancytree-container.fancytree-checkbox-auto-hide { +// span.fancytree-checkbox { +// visibility: hidden; +// } +// .fancytree-node:hover span.fancytree-checkbox, +// tr:hover td span.fancytree-checkbox, +// .fancytree-node.fancytree-selected span.fancytree-checkbox, +// tr.fancytree-selected td span.fancytree-checkbox { +// visibility: unset; +// } +// &.fancytree-treefocus { +// .fancytree-node.fancytree-active span.fancytree-checkbox, +// tr.fancytree-active td span.fancytree-checkbox { +// visibility: unset; +// } +// } +//} + +/*------------------------------------------------------------------------------ + * Node type icon + * Note: IE6 doesn't correctly evaluate multiples class names, + * so we create combined class names that can be used in the CSS. + * + * Prefix: fancytree-ico- + * 1st character: 'e': expanded, 'c': collapsed + * 2nd character (optional): 'f': folder + *----------------------------------------------------------------------------*/ + +span.fancytree-icon { + // Default icon + margin-left: @fancy-icon-spacing; + .useSprite(0, 0); +} + +/* Documents */ +.fancytree-ico-c span.fancytree-icon { + // Collapsed folder (empty) + // .useSprite(0, 0); +} +.fancytree-ico-c span.fancytree-icon:hover { + .useSprite(1, 0); +} +.fancytree-has-children.fancytree-ico-c span.fancytree-icon { + // Collapsed folder (not empty) + .useSprite(2, 0); +} +.fancytree-has-children.fancytree-ico-c span.fancytree-icon:hover { + .useSprite(3, 0); +} +.fancytree-ico-e span.fancytree-icon { + // Expanded folder + .useSprite(4, 0); +} +.fancytree-ico-e span.fancytree-icon:hover { + .useSprite(5, 0); +} + +/* Folders */ +.fancytree-ico-cf span.fancytree-icon { + // Collapsed folder (empty) + .useSprite(0, 1); +} +.fancytree-ico-cf span.fancytree-icon:hover { + .useSprite(1, 1); +} +.fancytree-has-children.fancytree-ico-cf span.fancytree-icon { + // Collapsed folder (not empty) + .useSprite(2, 1); +} +.fancytree-has-children.fancytree-ico-cf span.fancytree-icon:hover { + .useSprite(3, 1); +} +.fancytree-ico-ef span.fancytree-icon { + // Expanded folder + .useSprite(4, 1); +} +.fancytree-ico-ef span.fancytree-icon:hover { + .useSprite(5, 1); +} + +// 'Loading' status overrides all others +.fancytree-loading span.fancytree-expander, +.fancytree-loading span.fancytree-expander:hover, +.fancytree-statusnode-loading span.fancytree-icon, +.fancytree-statusnode-loading span.fancytree-icon:hover, +span.fancytree-icon.fancytree-icon-loading { + background-image: @fancy-loading-url; + .useSprite(0, 0); +} + +/* Status node icons */ + +.fancytree-statusnode-error span.fancytree-icon, +.fancytree-statusnode-error span.fancytree-icon:hover { + .useSprite(0, 7); +} + +/*------------------------------------------------------------------------------ + * Node titles and highlighting + *----------------------------------------------------------------------------*/ + +span.fancytree-node { + /* See #117 */ + display: inherit; // #117, resolves to 'display: list-item;' for standard trees + width: 100%; + margin-top: @fancy-node-v-spacing; + min-height: @fancy-line-height; +} +span.fancytree-title { + color: @fancy-font-color; // inherit doesn't work on IE + cursor: pointer; + display: inline-block; // Better alignment, when title contains <br> + vertical-align: top; + min-height: @fancy-line-height; + padding: 0 3px 0 3px; // Otherwise italic font will be outside right bounds + margin: @fancy-title-ofs-top 0 0 @fancy-icon-spacing; + // margin: 0px; + // margin-top: @fancy-line-ofs-top; + // margin-left: @fancy-icon-spacing; + border: @fancy-node-border-width solid transparent; // avoid jumping, when a border is added on hover + .rounded-corners(@fancy-node-border-radius); + // outline: 0; // @ Firefox, prevent dotted border after click + // Set transparent border to prevent jumping when active node gets a border + // (we can do this, because this theme doesn't use vertical lines) + // border: 1px solid white; // Note: 'transparent' would not work in IE6 +} +span.fancytree-node.fancytree-error span.fancytree-title { + color: @fancy-font-error-color; +} + +//// CHANGE: not used. +///*------------------------------------------------------------------------------ +// * Drag'n'drop support +// *----------------------------------------------------------------------------*/ +///* ext-dnd5: */ +//span.fancytree-childcounter { +// color: #fff; +// background: #337ab7; // bootstrap blue +// border: 1px solid gray; +// border-radius: 10px; +// padding: 2px; +// text-align: center; +//} +// +///* ext-dnd: */ +//div.fancytree-drag-helper { +// span.fancytree-childcounter, +// span.fancytree-dnd-modifier { +// display: inline-block; +// color: #fff; +// background: #337ab7; // bootstrap blue +// border: 1px solid gray; +// min-width: 10px; +// // min-height: 16px; +// height: 10px; +// line-height: 1; +// vertical-align: baseline; +// border-radius: 10px; +// padding: 2px; +// text-align: center; +// font-size: 9px; +// } +// span.fancytree-childcounter { +// position: absolute; +// // left: 16px; +// top: -6px; +// right: -6px; +// } +// span.fancytree-dnd-modifier { +// background: #5cb85c; // bootstrap green +// border: none; +// // min-height: 16px; +// // font-size: 12px; +// font-weight: bolder; +// } +// &.fancytree-drop-accept { +// span.fancytree-drag-helper-img { +// .useSprite(2, 7); +// } +// } +// &.fancytree-drop-reject { +// span.fancytree-drag-helper-img { +// .useSprite(1, 7); +// } +// } +//} +// +///*** Drop marker icon *********************************************************/ +//#fancytree-drop-marker { +// width: 2 * @fancy-icon-width; // was 24px, but 32 should be correct +// position: absolute; +// .useSprite(0, 8); +// margin: 0; +// &.fancytree-drop-after, +// &.fancytree-drop-before { +// width: 4 * @fancy-icon-width; // 64px; +// .useSprite(0, 9); +// } +// &.fancytree-drop-copy { +// .useSprite(4, 8); +// } +// &.fancytree-drop-move { +// .useSprite(2, 8); +// } +//} +// +///*** Source node while dragging ***********************************************/ +// +//span.fancytree-drag-source { +// &.fancytree-drag-remove { +// // text-decoration: line-through; +// opacity: 0.15; +// } +//} +// +///*** Target node while dragging cursor is over it *****************************/ +// +//span.fancytree-drop-target { +// &.fancytree-drop-accept { +// // outline: 1px dotted #5cb85c; // bootstrap sucess +// } +//} +//span.fancytree-drop-reject { +// // outline: 1px dotted #d9534f; // boostrap warning +//} + +/*------------------------------------------------------------------------------ + * 'rtl' option + *----------------------------------------------------------------------------*/ + +.fancytree-container.fancytree-rtl { + .fancytree-title { + /*unicode-bidi: bidi-override;*/ /* optional: reverse title letters */ + } + span.fancytree-connector, + span.fancytree-expander, + span.fancytree-icon, + span.fancytree-drag-helper-img { + .setBgImageUrl("icons-rtl.gif"); + } + .fancytree-exp-n span.fancytree-expander, + .fancytree-exp-nl span.fancytree-expander { + background-image: none; + } + &.fancytree-connectors .fancytree-exp-n span.fancytree-expander, + &.fancytree-connectors .fancytree-exp-nl span.fancytree-expander { + .setBgImageUrl("icons-rtl.gif"); + } +} +ul.fancytree-container.fancytree-rtl { + ul { + padding: 0 16px 0 0; + } + &.fancytree-connectors li { + background-position: right 0; + background-image: url("@{fancy-image-prefix}vline-rtl.gif"); + } + // Suppress lines for last child node + li.fancytree-lastsib, + // Suppress lines if level is fixed expanded (option minExpandLevel) + &.fancytree-no-connector > li { + background-image: none; + } +} +#fancytree-drop-marker.fancytree-rtl { + .setBgImageUrl("icons-rtl.gif"); +} + +//// CHANGE: not used. +///*------------------------------------------------------------------------------ +// * 'table' extension +// *----------------------------------------------------------------------------*/ +// +//table.fancytree-ext-table { +// font-family: @fancy-font-family; +// font-size: @fancy-font-size; +// border-collapse: collapse; +// span.fancytree-node { +// display: inline-block; // #117 +// box-sizing: border-box; // #562 +// } +// td.fancytree-status-merged { +// text-align: center; +// // font-weight: bold; +// font-style: italic; +// // line-height: 100px; +// color: @fancy-font-color-dimm; +// } +// tr.fancytree-statusnode-error td.fancytree-status-merged { +// color: @fancy-font-error-color; +// } +// /* ext-ariagrid */ +// &.fancytree-ext-ariagrid.fancytree-cell-mode { +// > tbody > tr.fancytree-active > td { +// background-color: #eee; +// } +// > tbody > tr > td.fancytree-active-cell { +// background-color: #cbe8f6; +// } +// &.fancytree-cell-nav-mode > tbody > tr > td.fancytree-active-cell { +// background-color: #3875d7; +// } +// } +//} +// +///*------------------------------------------------------------------------------ +// * 'columnview' extension +// *----------------------------------------------------------------------------*/ +// +//table.fancytree-ext-columnview { +// // border-collapse: collapse; +// // width: 100%; +// tbody tr td { +// position: relative; +// border: 1px solid gray; +// vertical-align: top; +// overflow: auto; +// > ul { +// padding: 0; +// li { +// list-style-image: none; +// list-style-position: outside; +// list-style-type: none; +// -moz-background-clip: border; +// -moz-background-inline-policy: continuous; +// -moz-background-origin: padding; +// background-attachment: scroll; +// background-color: transparent; +// .setBgPos(0, 0); +// background-repeat: repeat-y; +// background-image: none; /* no v-lines */ +// +// margin: 0; +// // padding: 1px 0 0 0; // issue #246 +// } +// } +// } +// span.fancytree-node { +// position: relative; /* allow positioning of embedded spans */ +// display: inline-block; // #117 +// } +// span.fancytree-node.fancytree-expanded { +// background-color: #e0e0e0; +// } +// span.fancytree-node.fancytree-active { +// background-color: #cbe8f6; +// // background-color: royalblue; +// } +// .fancytree-has-children span.fancytree-cv-right { +// position: absolute; +// right: 3px; +// .useSprite(0, 5); +// &:hover { +// .useSprite(1, 5); +// } +// } +//} +// +///*------------------------------------------------------------------------------ +// * 'filter' extension +// *----------------------------------------------------------------------------*/ +// +//.fancytree-ext-filter-dimm { +// span.fancytree-node span.fancytree-title { +// color: @fancy-font-color-dimm; +// font-weight: lighter; +// } +// tr.fancytree-submatch span.fancytree-title, +// span.fancytree-node.fancytree-submatch span.fancytree-title { +// color: black; +// font-weight: normal; +// } +// tr.fancytree-match span.fancytree-title, +// span.fancytree-node.fancytree-match span.fancytree-title { +// color: black; +// font-weight: bold; +// } +//} +//.fancytree-ext-filter-hide { +// tr.fancytree-hide, +// span.fancytree-node.fancytree-hide { +// display: none; +// } +// tr.fancytree-submatch span.fancytree-title, +// span.fancytree-node.fancytree-submatch span.fancytree-title { +// color: @fancy-font-color-dimm; +// font-weight: lighter; +// } +// tr.fancytree-match span.fancytree-title, +// span.fancytree-node.fancytree-match span.fancytree-title { +// color: black; +// font-weight: normal; +// } +//} +///* Hide expanders if all child nodes are hidden by filter */ +//.fancytree-ext-filter-hide-expanders { +// tr.fancytree-match span.fancytree-expander, +// span.fancytree-node.fancytree-match span.fancytree-expander { +// visibility: hidden; +// } +// tr.fancytree-submatch span.fancytree-expander, +// span.fancytree-node.fancytree-submatch span.fancytree-expander { +// visibility: visible; +// } +//} +// +//.fancytree-ext-childcounter, +//.fancytree-ext-filter { +// // span.fancytree-title mark { +// // font-style: normal; +// // background-color: #ead61c; // yellow +// // border-radius: 3px; +// // } +// span.fancytree-icon, +// span.fancytree-custom-icon { +// position: relative; +// } +// span.fancytree-childcounter { +// color: #fff; +// background: #777; // #337ab7; // bootstrap blue +// border: 1px solid gray; +// position: absolute; +// top: -6px; +// right: -6px; +// min-width: 10px; +// height: 10px; +// line-height: 1; +// vertical-align: baseline; +// border-radius: 10px; +// padding: 2px; +// text-align: center; +// font-size: 9px; +// } +//} +///*------------------------------------------------------------------------------ +// * 'wide' extension +// *----------------------------------------------------------------------------*/ +// +//ul.fancytree-ext-wide { +// position: relative; +// min-width: 100%; +// z-index: 2; +// +// -webkit-box-sizing: border-box; +// -moz-box-sizing: border-box; +// box-sizing: border-box; +// +// span.fancytree-node > span { +// position: relative; +// z-index: 2; +// } +// span.fancytree-node span.fancytree-title { +// position: absolute; // Allow left: 0. Note: prevents smooth dropdown animation +// z-index: 1; // Behind expander and checkbox +// left: 0px; +// min-width: 100%; +// margin-left: 0; +// margin-right: 0; +// +// -webkit-box-sizing: border-box; +// -moz-box-sizing: border-box; +// box-sizing: border-box; +// } +//} +// +///*------------------------------------------------------------------------------ +// * 'fixed' extension +// *----------------------------------------------------------------------------*/ +// +//.fancytree-ext-fixed-wrapper { +// .fancytree-ext-fixed-hidden { +// display: none; +// } +// div.fancytree-ext-fixed-scroll-border-bottom { +// border-bottom: 3px solid rgba(0, 0, 0, 0.75); +// } +// div.fancytree-ext-fixed-scroll-border-right { +// border-right: 3px solid rgba(0, 0, 0, 0.75); +// } +// div.fancytree-ext-fixed-wrapper-tl { +// position: absolute; +// overflow: hidden; +// z-index: 3; +// top: 0px; +// left: 0px; +// } +// div.fancytree-ext-fixed-wrapper-tr { +// position: absolute; +// overflow: hidden; +// z-index: 2; +// top: 0px; +// } +// div.fancytree-ext-fixed-wrapper-bl { +// position: absolute; +// overflow: hidden; +// z-index: 2; +// left: 0px; +// } +// div.fancytree-ext-fixed-wrapper-br { +// position: absolute; +// overflow: scroll; +// z-index: 1; +// } +//} diff --git a/plugins/55/indexmenu/scripts/fancytree/skin-awesome/ui.fancytree.css b/plugins/55/indexmenu/scripts/fancytree/skin-awesome/ui.fancytree.css new file mode 100644 index 0000000..b5ab63f --- /dev/null +++ b/plugins/55/indexmenu/scripts/fancytree/skin-awesome/ui.fancytree.css @@ -0,0 +1,588 @@ +/*! + * Fancytree "awesome" skin. + * + * DON'T EDIT THE CSS FILE DIRECTLY, since it is automatically generated from + * the LESS templates. + */ +/******************************************************************************* + * Common Styles for Fancytree Skins. + * + * This section is automatically generated from the `skin-common.less` template. + * + * Copyright (c) 2008-2023, Martin Wendt (https://wwWendt.de) + * Released under the MIT license + * https://github.com/mar10/fancytree/wiki/LicenseInfo + * + * @version 2.38.3 + * @date 2023-02-01T20:52:50Z +******************************************************************************/ +/*------------------------------------------------------------------------------ + * Helpers + *----------------------------------------------------------------------------*/ +.fancytree-helper-hidden { + display: none; +} +.fancytree-helper-indeterminate-cb { + color: #777; +} +.fancytree-helper-disabled { + color: silver; +} +/* Helper to allow spinning loader icon with glyph-, ligature-, and SVG-icons. */ +.fancytree-helper-spin { + -webkit-animation: spin 1000ms infinite linear; + animation: spin 1000ms infinite linear; +} +@-webkit-keyframes spin { + 0% { + -webkit-transform: rotate(0deg); + transform: rotate(0deg); + } + 100% { + -webkit-transform: rotate(359deg); + transform: rotate(359deg); + } +} +@keyframes spin { + 0% { + -webkit-transform: rotate(0deg); + transform: rotate(0deg); + } + 100% { + -webkit-transform: rotate(359deg); + transform: rotate(359deg); + } +} +/*------------------------------------------------------------------------------ + * Container and UL / LI + *----------------------------------------------------------------------------*/ +ul.fancytree-container { + font-family: tahoma, arial, helvetica; + font-size: 10pt; + white-space: nowrap; + padding: 3px; + margin: 0; + background-color: white; + border: 1px dotted gray; + min-height: 0%; + position: relative; +} +ul.fancytree-container ul { + padding: 0 0 0 10pt; + margin: 0; +} +ul.fancytree-container ul > li:before { + content: none; +} +ul.fancytree-container li { + list-style-image: none; + list-style-position: outside; + list-style-type: none; + -moz-background-clip: border; + -moz-background-inline-policy: continuous; + -moz-background-origin: padding; + background-attachment: scroll; + background-color: transparent; + background-position: 0pt 0pt; + background-repeat: repeat-y; + background-image: none; + margin: 0; +} +ul.fancytree-container li.fancytree-lastsib { + background-image: none; +} +.ui-fancytree-disabled ul.fancytree-container { + opacity: 0.5; + background-color: silver; +} +ul.fancytree-connectors.fancytree-container li { + background-image: url("../skin-awesome/vline.gif"); + background-position: 0 0; +} +ul.fancytree-container li.fancytree-lastsib, +ul.fancytree-no-connector > li { + background-image: none; +} +li.fancytree-animating { + position: relative; +} +/*------------------------------------------------------------------------------ + * Common icon definitions + *----------------------------------------------------------------------------*/ +span.fancytree-empty, +span.fancytree-vline, +span.fancytree-expander, +span.fancytree-icon, +span.fancytree-checkbox, +span.fancytree-drag-helper-img, +#fancytree-drop-marker { + width: 10pt; + height: 10pt; + display: inline-block; + vertical-align: top; + background-repeat: no-repeat; + background-position: 0pt 0pt; +} +span.fancytree-icon, +span.fancytree-checkbox, +span.fancytree-expander, +span.fancytree-custom-icon { + margin-top: 0px; +} +/* Used by icon option: */ +span.fancytree-custom-icon { + width: 10pt; + height: 10pt; + display: inline-block; + margin-left: 3px; + background-position: 0pt 0pt; +} +/* Used by 'icon' node option: */ +img.fancytree-icon { + width: 10pt; + height: 10pt; + margin-left: 3px; + margin-top: 0px; + vertical-align: top; + border-style: none; +} +/*------------------------------------------------------------------------------ + * Expander icon + * + * Note: IE6 doesn't correctly evaluate multiples class names, + * so we create combined class names that can be used in the CSS. + * + * Prefix: fancytree-exp- + * 1st character: 'e': expanded, 'c': collapsed, 'n': no children + * 2nd character (optional): 'd': lazy (Delayed) + * 3rd character (optional): 'l': Last sibling + *----------------------------------------------------------------------------*/ +span.fancytree-expander { + cursor: pointer; +} +.fancytree-exp-n span.fancytree-expander, +.fancytree-exp-nl span.fancytree-expander { + background-image: none; + cursor: default; +} +.fancytree-connectors .fancytree-exp-n span.fancytree-expander, +.fancytree-connectors .fancytree-exp-nl span.fancytree-expander { + margin-top: 0; +} +/* Fade out expanders, when container is not hovered or active */ +.fancytree-fade-expander span.fancytree-expander { + transition: opacity 1.5s; + opacity: 0; +} +.fancytree-fade-expander:hover span.fancytree-expander, +.fancytree-fade-expander.fancytree-treefocus span.fancytree-expander, +.fancytree-fade-expander .fancytree-treefocus span.fancytree-expander, +.fancytree-fade-expander [class*="fancytree-statusnode-"] span.fancytree-expander { + transition: opacity 0.6s; + opacity: 1; +} +/*------------------------------------------------------------------------------ + * Checkbox icon + *----------------------------------------------------------------------------*/ +span.fancytree-checkbox { + margin-left: 3px; +} +.fancytree-unselectable span.fancytree-checkbox { + opacity: 0.4; + filter: alpha(opacity=40); +} +.fancytree-container.fancytree-checkbox-auto-hide span.fancytree-checkbox { + visibility: hidden; +} +.fancytree-container.fancytree-checkbox-auto-hide .fancytree-node:hover span.fancytree-checkbox, +.fancytree-container.fancytree-checkbox-auto-hide tr:hover td span.fancytree-checkbox, +.fancytree-container.fancytree-checkbox-auto-hide .fancytree-node.fancytree-selected span.fancytree-checkbox, +.fancytree-container.fancytree-checkbox-auto-hide tr.fancytree-selected td span.fancytree-checkbox { + visibility: unset; +} +.fancytree-container.fancytree-checkbox-auto-hide.fancytree-treefocus .fancytree-node.fancytree-active span.fancytree-checkbox, +.fancytree-container.fancytree-checkbox-auto-hide.fancytree-treefocus tr.fancytree-active td span.fancytree-checkbox { + visibility: unset; +} +/*------------------------------------------------------------------------------ + * Node type icon + * Note: IE6 doesn't correctly evaluate multiples class names, + * so we create combined class names that can be used in the CSS. + * + * Prefix: fancytree-ico- + * 1st character: 'e': expanded, 'c': collapsed + * 2nd character (optional): 'f': folder + *----------------------------------------------------------------------------*/ +span.fancytree-icon { + margin-left: 3px; +} +/* Documents */ +/* Folders */ +.fancytree-loading span.fancytree-expander, +.fancytree-loading span.fancytree-expander:hover, +.fancytree-statusnode-loading span.fancytree-icon, +.fancytree-statusnode-loading span.fancytree-icon:hover, +span.fancytree-icon.fancytree-icon-loading { + background-image: none; +} +/* Status node icons */ +/*------------------------------------------------------------------------------ + * Node titles and highlighting + *----------------------------------------------------------------------------*/ +span.fancytree-node { + /* See #117 */ + display: inherit; + width: 100%; + margin-top: 1px; + min-height: 10pt; +} +span.fancytree-title { + color: #000; + cursor: pointer; + display: inline-block; + vertical-align: top; + min-height: 10pt; + padding: 0 3px 0 3px; + margin: 0px 0 0 3px; + border: 1px solid transparent; + -webkit-border-radius: 0px; + -moz-border-radius: 0px; + -ms-border-radius: 0px; + -o-border-radius: 0px; + border-radius: 0px; +} +span.fancytree-node.fancytree-error span.fancytree-title { + color: red; +} +/*------------------------------------------------------------------------------ + * Drag'n'drop support + *----------------------------------------------------------------------------*/ +/* ext-dnd5: */ +span.fancytree-childcounter { + color: #fff; + background: #337ab7; + border: 1px solid gray; + border-radius: 10px; + padding: 2px; + text-align: center; +} +/* ext-dnd: */ +div.fancytree-drag-helper span.fancytree-childcounter, +div.fancytree-drag-helper span.fancytree-dnd-modifier { + display: inline-block; + color: #fff; + background: #337ab7; + border: 1px solid gray; + min-width: 10px; + height: 10px; + line-height: 1; + vertical-align: baseline; + border-radius: 10px; + padding: 2px; + text-align: center; + font-size: 9px; +} +div.fancytree-drag-helper span.fancytree-childcounter { + position: absolute; + top: -6px; + right: -6px; +} +div.fancytree-drag-helper span.fancytree-dnd-modifier { + background: #5cb85c; + border: none; + font-weight: bolder; +} +/*** Drop marker icon *********************************************************/ +#fancytree-drop-marker { + width: 20pt; + position: absolute; + margin: 0; +} +#fancytree-drop-marker.fancytree-drop-after, +#fancytree-drop-marker.fancytree-drop-before { + width: 40pt; +} +/*** Source node while dragging ***********************************************/ +span.fancytree-drag-source.fancytree-drag-remove { + opacity: 0.15; +} +/*** Target node while dragging cursor is over it *****************************/ +/*------------------------------------------------------------------------------ + * 'rtl' option + *----------------------------------------------------------------------------*/ +.fancytree-container.fancytree-rtl .fancytree-title { + /*unicode-bidi: bidi-override;*/ + /* optional: reverse title letters */ +} +.fancytree-container.fancytree-rtl .fancytree-exp-n span.fancytree-expander, +.fancytree-container.fancytree-rtl .fancytree-exp-nl span.fancytree-expander { + background-image: none; +} +ul.fancytree-container.fancytree-rtl ul { + padding: 0 16px 0 0; +} +ul.fancytree-container.fancytree-rtl.fancytree-connectors li { + background-position: right 0; + background-image: url("../skin-awesome/vline-rtl.gif"); +} +ul.fancytree-container.fancytree-rtl li.fancytree-lastsib, +ul.fancytree-container.fancytree-rtl.fancytree-no-connector > li { + background-image: none; +} +/*------------------------------------------------------------------------------ + * 'table' extension + *----------------------------------------------------------------------------*/ +table.fancytree-ext-table { + font-family: tahoma, arial, helvetica; + font-size: 10pt; + border-collapse: collapse; + /* ext-ariagrid */ +} +table.fancytree-ext-table span.fancytree-node { + display: inline-block; + box-sizing: border-box; +} +table.fancytree-ext-table td.fancytree-status-merged { + text-align: center; + font-style: italic; + color: silver; +} +table.fancytree-ext-table tr.fancytree-statusnode-error td.fancytree-status-merged { + color: red; +} +table.fancytree-ext-table.fancytree-ext-ariagrid.fancytree-cell-mode > tbody > tr.fancytree-active > td { + background-color: #eee; +} +table.fancytree-ext-table.fancytree-ext-ariagrid.fancytree-cell-mode > tbody > tr > td.fancytree-active-cell { + background-color: #cbe8f6; +} +table.fancytree-ext-table.fancytree-ext-ariagrid.fancytree-cell-mode.fancytree-cell-nav-mode > tbody > tr > td.fancytree-active-cell { + background-color: #3875d7; +} +/*------------------------------------------------------------------------------ + * 'columnview' extension + *----------------------------------------------------------------------------*/ +table.fancytree-ext-columnview tbody tr td { + position: relative; + border: 1px solid gray; + vertical-align: top; + overflow: auto; +} +table.fancytree-ext-columnview tbody tr td > ul { + padding: 0; +} +table.fancytree-ext-columnview tbody tr td > ul li { + list-style-image: none; + list-style-position: outside; + list-style-type: none; + -moz-background-clip: border; + -moz-background-inline-policy: continuous; + -moz-background-origin: padding; + background-attachment: scroll; + background-color: transparent; + background-position: 0pt 0pt; + background-repeat: repeat-y; + background-image: none; + /* no v-lines */ + margin: 0; +} +table.fancytree-ext-columnview span.fancytree-node { + position: relative; + /* allow positioning of embedded spans */ + display: inline-block; +} +table.fancytree-ext-columnview span.fancytree-node.fancytree-expanded { + background-color: #e0e0e0; +} +table.fancytree-ext-columnview span.fancytree-node.fancytree-active { + background-color: #cbe8f6; +} +table.fancytree-ext-columnview .fancytree-has-children span.fancytree-cv-right { + position: absolute; + right: 3px; +} +/*------------------------------------------------------------------------------ + * 'filter' extension + *----------------------------------------------------------------------------*/ +.fancytree-ext-filter-dimm span.fancytree-node span.fancytree-title { + color: silver; + font-weight: lighter; +} +.fancytree-ext-filter-dimm tr.fancytree-submatch span.fancytree-title, +.fancytree-ext-filter-dimm span.fancytree-node.fancytree-submatch span.fancytree-title { + color: black; + font-weight: normal; +} +.fancytree-ext-filter-dimm tr.fancytree-match span.fancytree-title, +.fancytree-ext-filter-dimm span.fancytree-node.fancytree-match span.fancytree-title { + color: black; + font-weight: bold; +} +.fancytree-ext-filter-hide tr.fancytree-hide, +.fancytree-ext-filter-hide span.fancytree-node.fancytree-hide { + display: none; +} +.fancytree-ext-filter-hide tr.fancytree-submatch span.fancytree-title, +.fancytree-ext-filter-hide span.fancytree-node.fancytree-submatch span.fancytree-title { + color: silver; + font-weight: lighter; +} +.fancytree-ext-filter-hide tr.fancytree-match span.fancytree-title, +.fancytree-ext-filter-hide span.fancytree-node.fancytree-match span.fancytree-title { + color: black; + font-weight: normal; +} +/* Hide expanders if all child nodes are hidden by filter */ +.fancytree-ext-filter-hide-expanders tr.fancytree-match span.fancytree-expander, +.fancytree-ext-filter-hide-expanders span.fancytree-node.fancytree-match span.fancytree-expander { + visibility: hidden; +} +.fancytree-ext-filter-hide-expanders tr.fancytree-submatch span.fancytree-expander, +.fancytree-ext-filter-hide-expanders span.fancytree-node.fancytree-submatch span.fancytree-expander { + visibility: visible; +} +.fancytree-ext-childcounter span.fancytree-icon, +.fancytree-ext-filter span.fancytree-icon, +.fancytree-ext-childcounter span.fancytree-custom-icon, +.fancytree-ext-filter span.fancytree-custom-icon { + position: relative; +} +.fancytree-ext-childcounter span.fancytree-childcounter, +.fancytree-ext-filter span.fancytree-childcounter { + color: #fff; + background: #777; + border: 1px solid gray; + position: absolute; + top: -6px; + right: -6px; + min-width: 10px; + height: 10px; + line-height: 1; + vertical-align: baseline; + border-radius: 10px; + padding: 2px; + text-align: center; + font-size: 9px; +} +/*------------------------------------------------------------------------------ + * 'wide' extension + *----------------------------------------------------------------------------*/ +ul.fancytree-ext-wide { + position: relative; + min-width: 100%; + z-index: 2; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; +} +ul.fancytree-ext-wide span.fancytree-node > span { + position: relative; + z-index: 2; +} +ul.fancytree-ext-wide span.fancytree-node span.fancytree-title { + position: absolute; + z-index: 1; + left: 0px; + min-width: 100%; + margin-left: 0; + margin-right: 0; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; +} +/*------------------------------------------------------------------------------ + * 'fixed' extension + *----------------------------------------------------------------------------*/ +.fancytree-ext-fixed-wrapper .fancytree-ext-fixed-hidden { + display: none; +} +.fancytree-ext-fixed-wrapper div.fancytree-ext-fixed-scroll-border-bottom { + border-bottom: 3px solid rgba(0, 0, 0, 0.75); +} +.fancytree-ext-fixed-wrapper div.fancytree-ext-fixed-scroll-border-right { + border-right: 3px solid rgba(0, 0, 0, 0.75); +} +.fancytree-ext-fixed-wrapper div.fancytree-ext-fixed-wrapper-tl { + position: absolute; + overflow: hidden; + z-index: 3; + top: 0px; + left: 0px; +} +.fancytree-ext-fixed-wrapper div.fancytree-ext-fixed-wrapper-tr { + position: absolute; + overflow: hidden; + z-index: 2; + top: 0px; +} +.fancytree-ext-fixed-wrapper div.fancytree-ext-fixed-wrapper-bl { + position: absolute; + overflow: hidden; + z-index: 2; + left: 0px; +} +.fancytree-ext-fixed-wrapper div.fancytree-ext-fixed-wrapper-br { + position: absolute; + overflow: scroll; + z-index: 1; +} +/******************************************************************************* + * Styles specific to this skin. + * + * This section is automatically generated from the `ui-fancytree.less` template. + ******************************************************************************/ +ul.fancytree-container ul { + padding: 0.3em 0 0 1em; + margin: 0; +} +.fancytree-expander, +.fancytree-checkbox, +.fancytree-icon { + min-width: 10pt; + text-align: center; +} +svg.fancytree-checkbox, +svg.fancytree-icon { + padding-left: 3px; +} +/******************************************************************************* + * Node titles + */ +span.fancytree-title { + border: 1px solid transparent; + border-radius: 0; +} +span.fancytree-focused span.fancytree-title { + outline: 1px dotted black; +} +span.fancytree-active span.fancytree-title { + background-color: #D4D4D4; +} +.fancytree-treefocus span.fancytree-active span.fancytree-title { + color: white; + background-color: #3875D7; +} +/******************************************************************************* + * 'table' extension + */ +table.fancytree-ext-table { + border-collapse: collapse; +} +table.fancytree-ext-table tbody tr.fancytree-focused { + background-color: #99DEFD; +} +table.fancytree-ext-table tbody tr.fancytree-active { + background-color: royalblue; +} +/******************************************************************************* + * 'columnview' extension + */ +table.fancytree-ext-columnview tbody tr td { + border: 1px solid gray; +} +table.fancytree-ext-columnview span.fancytree-node.fancytree-expanded { + background-color: #ccc; +} +table.fancytree-ext-columnview span.fancytree-node.fancytree-active { + background-color: royalblue; +} diff --git a/plugins/55/indexmenu/scripts/fancytree/skin-awesome/ui.fancytree.less b/plugins/55/indexmenu/scripts/fancytree/skin-awesome/ui.fancytree.less new file mode 100644 index 0000000..51189b1 --- /dev/null +++ b/plugins/55/indexmenu/scripts/fancytree/skin-awesome/ui.fancytree.less @@ -0,0 +1,134 @@ +/*! + * Fancytree "awesome" skin. + * + * DON'T EDIT THE CSS FILE DIRECTLY, since it is automatically generated from + * the LESS templates. + */ + +// Import common styles +@import "skin-common.less"; + +// We need to define this variable here (not in skin-common.less) to make it +// work with grunt and webpack: +@fancy-image-prefix: "./skin-awesome/"; + + +/******************************************************************************* + * Styles specific to this skin. + * + * This section is automatically generated from the `ui-fancytree.less` template. + ******************************************************************************/ + +@fancy-use-sprites: false; // false: suppress all background images (i.e. icons) +@fancy-loading-url: none; + +@fancy-cst-size: 16px; + +@fancy-level-indent: @fancy-cst-size; //@fancy-cst-size; +@fancy-line-height: @fancy-cst-size; // height of a nodes selection bar including borders +@fancy-node-v-spacing: 1px; // gap between two node borders +@fancy-icon-width: @fancy-cst-size; +@fancy-icon-height: @fancy-cst-size; +@fancy-icon-spacing: 3px; // margin between icon/icon or icon/title +@fancy-icon-ofs-top: 0px; // extra vertical offset for expander, checkbox and icon +@fancy-title-ofs-top: 0px; // extra vertical offset for title +@fancy-node-border-width: 1px; +@fancy-node-border-radius: 0px; +@fancy-node-outline-width: 1px; + +// @fancy-loading-url: data-uri("@{fancy-image-prefix}loading.gif"); + +// Set to `true` to use `data-uri(...)` instead of a `url(...)` link: +@fancy-inline-sprites: false; + +//default 10pt, which is used in a relative manner resulting in 13.3 in dokuwiki-template. +@fancy-font-size: 93%; //@fancy-cst-size; +@fancy-font-family: tahoma, arial, helvetica; +@fancy-font-color: #000; +@fancy-font-color-dimm: silver; +@fancy-font-error-color: red; + +// set icon color to font color as well +span.fancytree-node { + color: @fancy-font-color; +} + +ul.fancytree-container ul +{ + padding: 0 0 0 1em; // 0.3em 0 0 1em; + margin: 0; +} + + +// The standard CSS assumes span.icon, but Fontawesome may use SVG or SPAN +.fancytree-expander, +.fancytree-checkbox, +.fancytree-icon { + min-width: @fancy-icon-width; + text-align: center; + font-size: @fancy-cst-size; +} +svg.fancytree-checkbox, // span... is already defined in skin-common-less +svg.fancytree-icon { + padding-left: @fancy-icon-spacing; +} + +/******************************************************************************* + * Node titles + */ +span.fancytree-title { + border: 1px solid transparent; // reserve some space for status borders + border-radius: 0; +} +span.fancytree-focused span.fancytree-title { + outline: 1px dotted black; +} +// span.fancytree-selected span.fancytree-title, +span.fancytree-active span.fancytree-title { + background-color: #D4D4D4; // gray +} +// span.fancytree-selected span.fancytree-title { +// font-style: italic; +// } +// .fancytree-treefocus span.fancytree-selected span.fancytree-title, +.fancytree-treefocus span.fancytree-active span.fancytree-title { + color: white; + background-color: #3875D7; // blue +} + +// .fancytree-treefocus span.fancytree-selected span.fancytree-title{ +// color: white; +// background-color: #99DEFD; // blue +// } + +///******************************************************************************* +// * 'table' extension +// */ +//table.fancytree-ext-table { +// border-collapse: collapse; +// tbody { +// tr.fancytree-focused { +// background-color: #99DEFD; +// } +// tr.fancytree-active { +// background-color: royalblue; +// } +// // tr.fancytree-selected { +// // background-color: #99DEFD; +// // } +// } +//} +// +///******************************************************************************* +// * 'columnview' extension +// */ +// +//table.fancytree-ext-columnview tbody tr td { +// border: 1px solid gray; +//} +//table.fancytree-ext-columnview span.fancytree-node.fancytree-expanded { +// background-color: #ccc; +//} +//table.fancytree-ext-columnview span.fancytree-node.fancytree-active { +// background-color: royalblue; +//} diff --git a/plugins/55/indexmenu/scripts/fancytree/skin-awesome/ui.fancytree.min.css b/plugins/55/indexmenu/scripts/fancytree/skin-awesome/ui.fancytree.min.css new file mode 100644 index 0000000..7fa2856 --- /dev/null +++ b/plugins/55/indexmenu/scripts/fancytree/skin-awesome/ui.fancytree.min.css @@ -0,0 +1,6 @@ +/*! + * Fancytree "awesome" skin. + * + * DON'T EDIT THE CSS FILE DIRECTLY, since it is automatically generated from + * the LESS templates. + */.fancytree-helper-hidden{display:none}.fancytree-helper-indeterminate-cb{color:#777}.fancytree-helper-disabled{color:silver}.fancytree-helper-spin{-webkit-animation:spin 1s infinite linear;animation:spin 1s infinite linear}@-webkit-keyframes spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}ul.fancytree-container{font-family:tahoma,arial,helvetica;font-size:10pt;white-space:nowrap;padding:3px;margin:0;background-color:#fff;border:1px dotted gray;min-height:0;position:relative}ul.fancytree-container ul{padding:0 0 0 10pt;margin:0}ul.fancytree-container ul>li:before{content:none}ul.fancytree-container li{list-style-image:none;list-style-position:outside;list-style-type:none;-moz-background-clip:border;-moz-background-inline-policy:continuous;-moz-background-origin:padding;background-attachment:scroll;background-color:transparent;background-position:0 0;background-repeat:repeat-y;background-image:none;margin:0}ul.fancytree-container li.fancytree-lastsib{background-image:none}.ui-fancytree-disabled ul.fancytree-container{opacity:.5;background-color:silver}ul.fancytree-connectors.fancytree-container li{background-image:url("../skin-awesome/vline.gif");background-position:0 0}ul.fancytree-container li.fancytree-lastsib,ul.fancytree-no-connector>li{background-image:none}li.fancytree-animating{position:relative}#fancytree-drop-marker,span.fancytree-checkbox,span.fancytree-drag-helper-img,span.fancytree-empty,span.fancytree-expander,span.fancytree-icon,span.fancytree-vline{width:10pt;height:10pt;display:inline-block;vertical-align:top;background-repeat:no-repeat;background-position:0 0}span.fancytree-checkbox,span.fancytree-custom-icon,span.fancytree-expander,span.fancytree-icon{margin-top:0}span.fancytree-custom-icon{width:10pt;height:10pt;display:inline-block;margin-left:3px;background-position:0 0}img.fancytree-icon{width:10pt;height:10pt;margin-left:3px;margin-top:0;vertical-align:top;border-style:none}span.fancytree-expander{cursor:pointer}.fancytree-exp-n span.fancytree-expander,.fancytree-exp-nl span.fancytree-expander{background-image:none;cursor:default}.fancytree-connectors .fancytree-exp-n span.fancytree-expander,.fancytree-connectors .fancytree-exp-nl span.fancytree-expander{margin-top:0}.fancytree-fade-expander span.fancytree-expander{transition:opacity 1.5s;opacity:0}.fancytree-fade-expander .fancytree-treefocus span.fancytree-expander,.fancytree-fade-expander [class*=fancytree-statusnode-] span.fancytree-expander,.fancytree-fade-expander.fancytree-treefocus span.fancytree-expander,.fancytree-fade-expander:hover span.fancytree-expander{transition:opacity .6s;opacity:1}span.fancytree-checkbox{margin-left:3px}.fancytree-unselectable span.fancytree-checkbox{opacity:.4}.fancytree-container.fancytree-checkbox-auto-hide span.fancytree-checkbox{visibility:hidden}.fancytree-container.fancytree-checkbox-auto-hide .fancytree-node.fancytree-selected span.fancytree-checkbox,.fancytree-container.fancytree-checkbox-auto-hide .fancytree-node:hover span.fancytree-checkbox,.fancytree-container.fancytree-checkbox-auto-hide tr.fancytree-selected td span.fancytree-checkbox,.fancytree-container.fancytree-checkbox-auto-hide tr:hover td span.fancytree-checkbox{visibility:unset}.fancytree-container.fancytree-checkbox-auto-hide.fancytree-treefocus .fancytree-node.fancytree-active span.fancytree-checkbox,.fancytree-container.fancytree-checkbox-auto-hide.fancytree-treefocus tr.fancytree-active td span.fancytree-checkbox{visibility:unset}span.fancytree-icon{margin-left:3px}.fancytree-loading span.fancytree-expander,.fancytree-loading span.fancytree-expander:hover,.fancytree-statusnode-loading span.fancytree-icon,.fancytree-statusnode-loading span.fancytree-icon:hover,span.fancytree-icon.fancytree-icon-loading{background-image:none}span.fancytree-node{display:inherit;width:100%;margin-top:1px;min-height:10pt}span.fancytree-title{color:#000;cursor:pointer;display:inline-block;vertical-align:top;min-height:10pt;padding:0 3px 0 3px;margin:0 0 0 3px;border:1px solid transparent;-webkit-border-radius:0px;-moz-border-radius:0;-ms-border-radius:0px;-o-border-radius:0;border-radius:0}span.fancytree-node.fancytree-error span.fancytree-title{color:red}span.fancytree-childcounter{color:#fff;background:#337ab7;border:1px solid gray;border-radius:10px;padding:2px;text-align:center}div.fancytree-drag-helper span.fancytree-childcounter,div.fancytree-drag-helper span.fancytree-dnd-modifier{display:inline-block;color:#fff;background:#337ab7;border:1px solid gray;min-width:10px;height:10px;line-height:1;vertical-align:baseline;border-radius:10px;padding:2px;text-align:center;font-size:9px}div.fancytree-drag-helper span.fancytree-childcounter{position:absolute;top:-6px;right:-6px}div.fancytree-drag-helper span.fancytree-dnd-modifier{background:#5cb85c;border:none;font-weight:bolder}#fancytree-drop-marker{width:20pt;position:absolute;margin:0}#fancytree-drop-marker.fancytree-drop-after,#fancytree-drop-marker.fancytree-drop-before{width:40pt}span.fancytree-drag-source.fancytree-drag-remove{opacity:.15}.fancytree-container.fancytree-rtl .fancytree-exp-n span.fancytree-expander,.fancytree-container.fancytree-rtl .fancytree-exp-nl span.fancytree-expander{background-image:none}ul.fancytree-container.fancytree-rtl ul{padding:0 16px 0 0}ul.fancytree-container.fancytree-rtl.fancytree-connectors li{background-position:right 0;background-image:url("../skin-awesome/vline-rtl.gif")}ul.fancytree-container.fancytree-rtl li.fancytree-lastsib,ul.fancytree-container.fancytree-rtl.fancytree-no-connector>li{background-image:none}table.fancytree-ext-table{font-family:tahoma,arial,helvetica;font-size:10pt;border-collapse:collapse}table.fancytree-ext-table span.fancytree-node{display:inline-block;box-sizing:border-box}table.fancytree-ext-table td.fancytree-status-merged{text-align:center;font-style:italic;color:silver}table.fancytree-ext-table tr.fancytree-statusnode-error td.fancytree-status-merged{color:red}table.fancytree-ext-table.fancytree-ext-ariagrid.fancytree-cell-mode>tbody>tr.fancytree-active>td{background-color:#eee}table.fancytree-ext-table.fancytree-ext-ariagrid.fancytree-cell-mode>tbody>tr>td.fancytree-active-cell{background-color:#cbe8f6}table.fancytree-ext-table.fancytree-ext-ariagrid.fancytree-cell-mode.fancytree-cell-nav-mode>tbody>tr>td.fancytree-active-cell{background-color:#3875d7}table.fancytree-ext-columnview tbody tr td{position:relative;border:1px solid gray;vertical-align:top;overflow:auto}table.fancytree-ext-columnview tbody tr td>ul{padding:0}table.fancytree-ext-columnview tbody tr td>ul li{list-style-image:none;list-style-position:outside;list-style-type:none;-moz-background-clip:border;-moz-background-inline-policy:continuous;-moz-background-origin:padding;background-attachment:scroll;background-color:transparent;background-position:0 0;background-repeat:repeat-y;background-image:none;margin:0}table.fancytree-ext-columnview span.fancytree-node{position:relative;display:inline-block}table.fancytree-ext-columnview span.fancytree-node.fancytree-expanded{background-color:#e0e0e0}table.fancytree-ext-columnview span.fancytree-node.fancytree-active{background-color:#cbe8f6}table.fancytree-ext-columnview .fancytree-has-children span.fancytree-cv-right{position:absolute;right:3px}.fancytree-ext-filter-dimm span.fancytree-node span.fancytree-title{color:silver;font-weight:lighter}.fancytree-ext-filter-dimm span.fancytree-node.fancytree-submatch span.fancytree-title,.fancytree-ext-filter-dimm tr.fancytree-submatch span.fancytree-title{color:#000;font-weight:400}.fancytree-ext-filter-dimm span.fancytree-node.fancytree-match span.fancytree-title,.fancytree-ext-filter-dimm tr.fancytree-match span.fancytree-title{color:#000;font-weight:700}.fancytree-ext-filter-hide span.fancytree-node.fancytree-hide,.fancytree-ext-filter-hide tr.fancytree-hide{display:none}.fancytree-ext-filter-hide span.fancytree-node.fancytree-submatch span.fancytree-title,.fancytree-ext-filter-hide tr.fancytree-submatch span.fancytree-title{color:silver;font-weight:lighter}.fancytree-ext-filter-hide span.fancytree-node.fancytree-match span.fancytree-title,.fancytree-ext-filter-hide tr.fancytree-match span.fancytree-title{color:#000;font-weight:400}.fancytree-ext-filter-hide-expanders span.fancytree-node.fancytree-match span.fancytree-expander,.fancytree-ext-filter-hide-expanders tr.fancytree-match span.fancytree-expander{visibility:hidden}.fancytree-ext-filter-hide-expanders span.fancytree-node.fancytree-submatch span.fancytree-expander,.fancytree-ext-filter-hide-expanders tr.fancytree-submatch span.fancytree-expander{visibility:visible}.fancytree-ext-childcounter span.fancytree-custom-icon,.fancytree-ext-childcounter span.fancytree-icon,.fancytree-ext-filter span.fancytree-custom-icon,.fancytree-ext-filter span.fancytree-icon{position:relative}.fancytree-ext-childcounter span.fancytree-childcounter,.fancytree-ext-filter span.fancytree-childcounter{color:#fff;background:#777;border:1px solid gray;position:absolute;top:-6px;right:-6px;min-width:10px;height:10px;line-height:1;vertical-align:baseline;border-radius:10px;padding:2px;text-align:center;font-size:9px}ul.fancytree-ext-wide{position:relative;min-width:100%;z-index:2;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}ul.fancytree-ext-wide span.fancytree-node>span{position:relative;z-index:2}ul.fancytree-ext-wide span.fancytree-node span.fancytree-title{position:absolute;z-index:1;left:0;min-width:100%;margin-left:0;margin-right:0;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.fancytree-ext-fixed-wrapper .fancytree-ext-fixed-hidden{display:none}.fancytree-ext-fixed-wrapper div.fancytree-ext-fixed-scroll-border-bottom{border-bottom:3px solid rgba(0,0,0,.75)}.fancytree-ext-fixed-wrapper div.fancytree-ext-fixed-scroll-border-right{border-right:3px solid rgba(0,0,0,.75)}.fancytree-ext-fixed-wrapper div.fancytree-ext-fixed-wrapper-tl{position:absolute;overflow:hidden;z-index:3;top:0;left:0}.fancytree-ext-fixed-wrapper div.fancytree-ext-fixed-wrapper-tr{position:absolute;overflow:hidden;z-index:2;top:0}.fancytree-ext-fixed-wrapper div.fancytree-ext-fixed-wrapper-bl{position:absolute;overflow:hidden;z-index:2;left:0}.fancytree-ext-fixed-wrapper div.fancytree-ext-fixed-wrapper-br{position:absolute;overflow:scroll;z-index:1}ul.fancytree-container ul{padding:.3em 0 0 1em;margin:0}.fancytree-checkbox,.fancytree-expander,.fancytree-icon{min-width:10pt;text-align:center}svg.fancytree-checkbox,svg.fancytree-icon{padding-left:3px}span.fancytree-title{border:1px solid transparent;border-radius:0}span.fancytree-focused span.fancytree-title{outline:1px dotted black}span.fancytree-active span.fancytree-title{background-color:#d4d4d4}.fancytree-treefocus span.fancytree-active span.fancytree-title{color:#fff;background-color:#3875d7}table.fancytree-ext-table{border-collapse:collapse}table.fancytree-ext-table tbody tr.fancytree-focused{background-color:#99defd}table.fancytree-ext-table tbody tr.fancytree-active{background-color:#4169e1}table.fancytree-ext-columnview tbody tr td{border:1px solid gray}table.fancytree-ext-columnview span.fancytree-node.fancytree-expanded{background-color:#ccc}table.fancytree-ext-columnview span.fancytree-node.fancytree-active{background-color:#4169e1}
\ No newline at end of file diff --git a/plugins/55/indexmenu/scripts/fancytree/skin-awesome/vline-rtl.gif b/plugins/55/indexmenu/scripts/fancytree/skin-awesome/vline-rtl.gif Binary files differnew file mode 100644 index 0000000..0400cb3 --- /dev/null +++ b/plugins/55/indexmenu/scripts/fancytree/skin-awesome/vline-rtl.gif diff --git a/plugins/55/indexmenu/scripts/fancytree/skin-awesome/vline.gif b/plugins/55/indexmenu/scripts/fancytree/skin-awesome/vline.gif Binary files differnew file mode 100644 index 0000000..1b00ae5 --- /dev/null +++ b/plugins/55/indexmenu/scripts/fancytree/skin-awesome/vline.gif diff --git a/plugins/55/indexmenu/scripts/fancytree/skin-bootstrap-n/skin-common.less b/plugins/55/indexmenu/scripts/fancytree/skin-bootstrap-n/skin-common.less new file mode 100644 index 0000000..fc0da50 --- /dev/null +++ b/plugins/55/indexmenu/scripts/fancytree/skin-bootstrap-n/skin-common.less @@ -0,0 +1,972 @@ +/******************************************************************************* + * Common Styles for Fancytree Skins. + * + * This section is automatically generated from the `skin-common.less` template. + * + * Copyright (c) 2008-2023, Martin Wendt (https://wwWendt.de) + * Released under the MIT license + * https://github.com/mar10/fancytree/wiki/LicenseInfo + * + * @version 2.38.3 + * @date 2023-02-01T20:52:50Z +******************************************************************************/ + +// Variables (defaults, may be overwritten by the including .less files) +@fancy-use-sprites: true; // false: suppress all background images (i.e. icons) +// @fancy-hide-connectors: true; // false: show vertical connector lines + +@fancy-level-indent: 16px; +@fancy-line-height: 16px; // height of a nodes selection bar including borders +@fancy-node-v-spacing: 1px; // gap between two node borders +@fancy-icon-width: 16px; +@fancy-icon-height: 16px; +@fancy-icon-spacing: 3px; // margin between icon/icon or icon/title +@fancy-icon-ofs-top: 0px; // extra vertical offset for expander, checkbox and icon +@fancy-title-ofs-top: 0px; // extra vertical offset for title +@fancy-node-border-width: 1px; +@fancy-node-border-radius: 0px; +@fancy-node-outline-width: 1px; + +// @fancy-line-ofs-top: (@fancy-line-height - @fancy-icon-height) / 2; + +// webpack uses /dist/skin-common.less as root path +// grunt-less uses /dist/skin-Xxx/ui.fancyree.less as root path +// So we define our theme LESS files for webpack compatibility, i.e. +// define the image path n every main LESS file instead of here. +// Prefix may be set to "", "/", "./", or any other value +// Note: this variable must be defined by the main LESS files: +// @fancy-image-prefix: ""; + +// Use 'url(...)' to link to the throbber image, or +// use data-uri(...)' to inline the data in css instead: +/* CHANGE use url, as less does not handel data-uri() correct. DokuWiki can eventually inline it */ + @fancy-loading-url: url("@{fancy-image-prefix}loading.gif"); +//@fancy-loading-url: data-uri("@{fancy-image-prefix}loading.gif"); + +// Set to `true` to use `data-uri(...)` instead of a `url(...)` link: +@fancy-inline-sprites: false; // data-uri() is not handle correct by phpless + +@fancy-font-size: 10pt; +@fancy-font-family: tahoma, arial, helvetica; +@fancy-font-color: black; +@fancy-font-color-dimm: #c0c0c0; +@fancy-font-error-color: red; + +//------------------------------------------------------------------------------ +// Mixins +//------------------------------------------------------------------------------ +.setBgPos(@x, @y, @cond:true) when (@cond) { + background-position: (@x * -@fancy-icon-width) (@y * -@fancy-icon-height); +} +.clearBgImage(@cond:true) when (@cond) { + background-image: none; +} +.setBgImageUrl(@url) when (@fancy-use-sprites) and not (@fancy-inline-sprites) { + background-image: url("@{fancy-image-prefix}@{url}"); +} +.setBgImageUrl(@url) when (@fancy-use-sprites) and (@fancy-inline-sprites) { + background-image: data-uri("@{fancy-image-prefix}@{url}"); +} +.useSprite(@x, @y) when (@fancy-use-sprites) { + .setBgPos(@x, @y); +} +.rounded-corners(@radius) { + -webkit-border-radius: @radius; + -moz-border-radius: @radius; + -ms-border-radius: @radius; + -o-border-radius: @radius; + border-radius: @radius; +} +.spanStyleMixin(@color, @bgcolor, @bordercolor) { + border-color: @bordercolor; + background: @bgcolor; + color: @color; +} +.spanStyleMixin(@color, @bgcolor, @bordercolor, @startColor, @stopColor) { + .spanStyleMixin(@color, @bgcolor, @bordercolor); + // @c-start: argb(@startColor); + // @c-end: argb(@stopColor); + background: -moz-linear-gradient( + top, + @startColor 0%, + @stopColor 100% + ); // FF3.6+ + background: -webkit-gradient( + linear, + left top, + left bottom, + color-stop(0%, @startColor), + color-stop(100%, @stopColor) + ); // Chrome,Safari4+ + background: -webkit-linear-gradient( + top, + @startColor 0%, + @stopColor 100% + ); // Chrome10+,Safari5.1+ + background: -o-linear-gradient( + top, + @startColor 0%, + @stopColor 100% + ); // Opera 11.10+ + background: -ms-linear-gradient( + top, + @startColor 0%, + @stopColor 100% + ); // IE10+ + background: linear-gradient( + to bottom, + @startColor 0%, + @stopColor 100% + ); // W3C + filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='@{startColor}', endColorstr='@{stopColor}',GradientType=0 ); // IE6-9 +} + +/*------------------------------------------------------------------------------ + * Helpers + *----------------------------------------------------------------------------*/ +// Redefine, in case jQuery-UI is not included +// .ui-helper-hidden, +.fancytree-helper-hidden { + display: none; +} +.fancytree-helper-indeterminate-cb { + // tri-state checkbox + color: #777; +} +.fancytree-helper-disabled { + color: @fancy-font-color-dimm; +} + +/* Helper to allow spinning loader icon with glyph-, ligature-, and SVG-icons. */ +/* CHANGE: renamed spin to spin-fancytree */ +.fancytree-helper-spin { + -webkit-animation: spin-fancytree 1000ms infinite linear; + animation: spin-fancytree 1000ms infinite linear; +} +/* CHANGE: commented because it is wrong prefixed by phpless +@-webkit-keyframes spin { + 0% { + -webkit-transform: rotate(0deg); + transform: rotate(0deg); + } + 100% { + -webkit-transform: rotate(359deg); + transform: rotate(359deg); + } +} +@keyframes spin { + 0% { + -webkit-transform: rotate(0deg); + transform: rotate(0deg); + } + 100% { + -webkit-transform: rotate(359deg); + transform: rotate(359deg); + } +} +*/ +/*------------------------------------------------------------------------------ + * Container and UL / LI + *----------------------------------------------------------------------------*/ + +ul.fancytree-container { + font-family: @fancy-font-family; + font-size: @fancy-font-size; + white-space: nowrap; + padding: 3px; + margin: 0; // DT issue 201 + //background-color: white; CHANGE + //border: 1px dotted gray; CHANGE + // overflow: auto; // ext-dnd5: otherwise this is always the scroll parent + // height: 100%; // DT issue 263, 470 + min-height: 0%; // #192 + position: relative; // #235 + ul { + padding: 0 0 0 @fancy-level-indent; + margin: 0; + } + ul > li:before { + // #538 + content: none; + } + li { + list-style-image: none; + list-style-position: outside; + list-style-type: none; + -moz-background-clip: border; + -moz-background-inline-policy: continuous; + -moz-background-origin: padding; + background-attachment: scroll; + background-color: transparent; + .setBgPos(0, 0); + background-repeat: repeat-y; + background-image: none; // no v-lines + + margin: 0; + // padding: 1px 0 0 0; // issue #246 + } + // Suppress lines for last child node + li.fancytree-lastsib { + background-image: none; + } +} + +// Style, when control is disabled +.ui-fancytree-disabled ul.fancytree-container { + opacity: 0.5; + // filter: alpha(opacity=50); // Yields a css warning + background-color: silver; +} + +ul.fancytree-connectors.fancytree-container { + li { + // Use 'data-uri(...)' to embed the image into CSS instead of linking to 'loading.gif': + /* CHANGE: phpless does not handle data-uri() correct */ + //background-image: data-uri("@{fancy-image-prefix}vline.gif"); + background-image: url("@{fancy-image-prefix}vline.gif"); + background-position: 0 0; + } +} + +// Suppress lines for last child node +ul.fancytree-container li.fancytree-lastsib, +// Suppress lines if level is fixed expanded (option minExpandLevel) +ul.fancytree-no-connector > li { + background-image: none; +} + +// Fix jQuery UI 'blind' animation for jQuery UI (#717) +li.fancytree-animating { + position: relative; +} + +/*------------------------------------------------------------------------------ + * Common icon definitions + *----------------------------------------------------------------------------*/ + +span.fancytree-empty, +span.fancytree-vline, +span.fancytree-expander, +span.fancytree-icon, +span.fancytree-checkbox, +// span.fancytree-radio, +span.fancytree-drag-helper-img, +#fancytree-drop-marker { + width: @fancy-icon-width; + height: @fancy-icon-height; + // display: -moz-inline-box; // @ FF 1+2 removed for issue 221 + // -moz-box-align: start; /* issue 221 */ + display: inline-block; // Required to make a span sizeable + vertical-align: top; + background-repeat: no-repeat; + // background-position: left; + .setBgImageUrl("icons.gif"); + .setBgPos(0, 0); +} +span.fancytree-icon, +span.fancytree-checkbox, +span.fancytree-expander, +// span.fancytree-radio, +span.fancytree-custom-icon { + margin-top: @fancy-icon-ofs-top; +} +/* Used by icon option: */ +span.fancytree-custom-icon { + width: @fancy-icon-width; + height: @fancy-icon-height; + display: inline-block; + margin-left: @fancy-icon-spacing; + .setBgPos(0, 0); +} +/* Used by 'icon' node option: */ +img.fancytree-icon { + width: @fancy-icon-width; + height: @fancy-icon-height; + margin-left: @fancy-icon-spacing; + margin-top: @fancy-icon-ofs-top; + vertical-align: top; + border-style: none; +} + +/*------------------------------------------------------------------------------ + * Expander icon + * + * Note: IE6 doesn't correctly evaluate multiples class names, + * so we create combined class names that can be used in the CSS. + * + * Prefix: fancytree-exp- + * 1st character: 'e': expanded, 'c': collapsed, 'n': no children + * 2nd character (optional): 'd': lazy (Delayed) + * 3rd character (optional): 'l': Last sibling + *----------------------------------------------------------------------------*/ + +span.fancytree-expander { + // .useSprite(0, 5); + cursor: pointer; +} +// span.fancytree-expander:hover { +// // .useSprite(1, 5); +// } + +// --- End nodes (use connectors instead of expanders) + +.fancytree-exp-n span.fancytree-expander, +.fancytree-exp-nl span.fancytree-expander { + // .clearBgImage( @fancy-hide-connectors ); + background-image: none; + cursor: default; +} +.fancytree-connectors { + .fancytree-exp-n span.fancytree-expander, + .fancytree-exp-nl span.fancytree-expander { + .setBgImageUrl("icons.gif"); + margin-top: 0; + } + .fancytree-exp-n span.fancytree-expander, // End-node, not last sibling + .fancytree-exp-n span.fancytree-expander:hover { + .useSprite(0, 4); + } + .fancytree-exp-nl span.fancytree-expander, // End-node, last sibling + .fancytree-exp-nl span.fancytree-expander:hover { + .useSprite(1, 4); + } +} + +// --- Collapsed + +.fancytree-exp-c span.fancytree-expander { + // Collapsed, not delayed, not last sibling + .useSprite(0, 5); +} +.fancytree-exp-c span.fancytree-expander:hover { + .useSprite(1, 5); +} +.fancytree-exp-cl span.fancytree-expander { + // Collapsed, not delayed, last sibling + .useSprite(0, 6); +} +.fancytree-exp-cl span.fancytree-expander:hover { + .useSprite(1, 6); +} +.fancytree-exp-cd span.fancytree-expander { + // Collapsed, delayed, not last sibling + .useSprite(4, 5); +} +.fancytree-exp-cd span.fancytree-expander:hover { + .useSprite(5, 5); +} +.fancytree-exp-cdl span.fancytree-expander { + // Collapsed, delayed, last sibling + .useSprite(4, 6); +} +.fancytree-exp-cdl span.fancytree-expander:hover { + .useSprite(5, 6); +} + +// --- Expanded + +.fancytree-exp-e span.fancytree-expander, // Expanded, not delayed, not last sibling +.fancytree-exp-ed span.fancytree-expander { + // Expanded, delayed, not last sibling + .useSprite(2, 5); +} +.fancytree-exp-e span.fancytree-expander:hover, +.fancytree-exp-ed span.fancytree-expander:hover { + .useSprite(3, 5); +} +.fancytree-exp-el span.fancytree-expander, // Expanded, not delayed, last sibling +.fancytree-exp-edl span.fancytree-expander { + // Expanded, delayed, last sibling + .useSprite(2, 6); +} +.fancytree-exp-el span.fancytree-expander:hover, +.fancytree-exp-edl span.fancytree-expander:hover { + .useSprite(3, 6); +} + +/* Fade out expanders, when container is not hovered or active */ +.fancytree-fade-expander { + span.fancytree-expander { + transition: opacity 1.5s; + opacity: 0; + } + &:hover span.fancytree-expander, + &.fancytree-treefocus span.fancytree-expander, + .fancytree-treefocus span.fancytree-expander, + [class*="fancytree-statusnode-"] span.fancytree-expander { + transition: opacity 0.6s; + opacity: 1; + } +} + +//// CHANGE: not used. +///*------------------------------------------------------------------------------ +// * Checkbox icon +// *----------------------------------------------------------------------------*/ +// +//span.fancytree-checkbox { +// margin-left: @fancy-icon-spacing; +// .useSprite(0, 2); +// &:hover { +// .useSprite(1, 2); +// } +// &.fancytree-radio { +// .useSprite(0, 3); +// } +// &.fancytree-radio:hover { +// .useSprite(1, 3); +// } +//} +//.fancytree-partsel span.fancytree-checkbox { +// .useSprite(4, 2); +// &:hover { +// .useSprite(5, 2); +// } +// &.fancytree-radio { +// .useSprite(4, 3); +// } +// &.fancytree-radio:hover { +// .useSprite(5, 3); +// } +//} +//// selected after partsel, so it takes precedence: +//.fancytree-selected span.fancytree-checkbox { +// .useSprite(2, 2); +// &:hover { +// .useSprite(3, 2); +// } +// &.fancytree-radio { +// .useSprite(2, 3); +// } +// &.fancytree-radio:hover { +// .useSprite(3, 3); +// } +//} +//// Unselectable is dimmed, without hover effects +//.fancytree-unselectable { +// span.fancytree-checkbox { +// opacity: 0.4; +// filter: alpha(opacity=40); +// } +// span.fancytree-checkbox:hover { +// .useSprite(0, 2); +// } +// span.fancytree-checkbox.fancytree-radio:hover { +// .useSprite(0, 3); +// } +// &.fancytree-partsel span.fancytree-checkbox:hover { +// .useSprite(4, 2); +// } +// &.fancytree-selected span.fancytree-checkbox:hover { +// .useSprite(2, 2); +// } +// &.fancytree-selected span.fancytree-checkbox.fancytree-radio:hover { +// .useSprite(2, 3); +// } +//} +// +//// Auto-hide checkboxes unless selected or hovered +//.fancytree-container.fancytree-checkbox-auto-hide { +// span.fancytree-checkbox { +// visibility: hidden; +// } +// .fancytree-node:hover span.fancytree-checkbox, +// tr:hover td span.fancytree-checkbox, +// .fancytree-node.fancytree-selected span.fancytree-checkbox, +// tr.fancytree-selected td span.fancytree-checkbox { +// visibility: unset; +// } +// &.fancytree-treefocus { +// .fancytree-node.fancytree-active span.fancytree-checkbox, +// tr.fancytree-active td span.fancytree-checkbox { +// visibility: unset; +// } +// } +//} + +/*------------------------------------------------------------------------------ + * Node type icon + * Note: IE6 doesn't correctly evaluate multiples class names, + * so we create combined class names that can be used in the CSS. + * + * Prefix: fancytree-ico- + * 1st character: 'e': expanded, 'c': collapsed + * 2nd character (optional): 'f': folder + *----------------------------------------------------------------------------*/ + +span.fancytree-icon { + // Default icon + margin-left: @fancy-icon-spacing; + .useSprite(0, 0); +} + +/* Documents */ +.fancytree-ico-c span.fancytree-icon { + // Collapsed folder (empty) + // .useSprite(0, 0); +} +.fancytree-ico-c span.fancytree-icon:hover { + .useSprite(1, 0); +} +.fancytree-has-children.fancytree-ico-c span.fancytree-icon { + // Collapsed folder (not empty) + .useSprite(2, 0); +} +.fancytree-has-children.fancytree-ico-c span.fancytree-icon:hover { + .useSprite(3, 0); +} +.fancytree-ico-e span.fancytree-icon { + // Expanded folder + .useSprite(4, 0); +} +.fancytree-ico-e span.fancytree-icon:hover { + .useSprite(5, 0); +} + +/* Folders */ +.fancytree-ico-cf span.fancytree-icon { + // Collapsed folder (empty) + .useSprite(0, 1); +} +.fancytree-ico-cf span.fancytree-icon:hover { + .useSprite(1, 1); +} +.fancytree-has-children.fancytree-ico-cf span.fancytree-icon { + // Collapsed folder (not empty) + .useSprite(2, 1); +} +.fancytree-has-children.fancytree-ico-cf span.fancytree-icon:hover { + .useSprite(3, 1); +} +.fancytree-ico-ef span.fancytree-icon { + // Expanded folder + .useSprite(4, 1); +} +.fancytree-ico-ef span.fancytree-icon:hover { + .useSprite(5, 1); +} + +// 'Loading' status overrides all others +.fancytree-loading span.fancytree-expander, +.fancytree-loading span.fancytree-expander:hover, +.fancytree-statusnode-loading span.fancytree-icon, +.fancytree-statusnode-loading span.fancytree-icon:hover, +span.fancytree-icon.fancytree-icon-loading { + background-image: @fancy-loading-url; + .useSprite(0, 0); +} + +/* Status node icons */ + +.fancytree-statusnode-error span.fancytree-icon, +.fancytree-statusnode-error span.fancytree-icon:hover { + .useSprite(0, 7); +} + +/*------------------------------------------------------------------------------ + * Node titles and highlighting + *----------------------------------------------------------------------------*/ + +span.fancytree-node { + /* See #117 */ + display: inherit; // #117, resolves to 'display: list-item;' for standard trees + width: 100%; + margin-top: @fancy-node-v-spacing; + min-height: @fancy-line-height; +} +span.fancytree-title { + color: @fancy-font-color; // inherit doesn't work on IE + cursor: pointer; + display: inline-block; // Better alignment, when title contains <br> + vertical-align: top; + min-height: @fancy-line-height; + padding: 0 3px 0 3px; // Otherwise italic font will be outside right bounds + margin: @fancy-title-ofs-top 0 0 @fancy-icon-spacing; + // margin: 0px; + // margin-top: @fancy-line-ofs-top; + // margin-left: @fancy-icon-spacing; + border: @fancy-node-border-width solid transparent; // avoid jumping, when a border is added on hover + .rounded-corners(@fancy-node-border-radius); + // outline: 0; // @ Firefox, prevent dotted border after click + // Set transparent border to prevent jumping when active node gets a border + // (we can do this, because this theme doesn't use vertical lines) + // border: 1px solid white; // Note: 'transparent' would not work in IE6 +} +span.fancytree-node.fancytree-error span.fancytree-title { + color: @fancy-font-error-color; +} + +//// CHANGE: not used. +///*------------------------------------------------------------------------------ +// * Drag'n'drop support +// *----------------------------------------------------------------------------*/ +///* ext-dnd5: */ +//span.fancytree-childcounter { +// color: #fff; +// background: #337ab7; // bootstrap blue +// border: 1px solid gray; +// border-radius: 10px; +// padding: 2px; +// text-align: center; +//} +// +///* ext-dnd: */ +//div.fancytree-drag-helper { +// span.fancytree-childcounter, +// span.fancytree-dnd-modifier { +// display: inline-block; +// color: #fff; +// background: #337ab7; // bootstrap blue +// border: 1px solid gray; +// min-width: 10px; +// // min-height: 16px; +// height: 10px; +// line-height: 1; +// vertical-align: baseline; +// border-radius: 10px; +// padding: 2px; +// text-align: center; +// font-size: 9px; +// } +// span.fancytree-childcounter { +// position: absolute; +// // left: 16px; +// top: -6px; +// right: -6px; +// } +// span.fancytree-dnd-modifier { +// background: #5cb85c; // bootstrap green +// border: none; +// // min-height: 16px; +// // font-size: 12px; +// font-weight: bolder; +// } +// &.fancytree-drop-accept { +// span.fancytree-drag-helper-img { +// .useSprite(2, 7); +// } +// } +// &.fancytree-drop-reject { +// span.fancytree-drag-helper-img { +// .useSprite(1, 7); +// } +// } +//} +// +///*** Drop marker icon *********************************************************/ +//#fancytree-drop-marker { +// width: 2 * @fancy-icon-width; // was 24px, but 32 should be correct +// position: absolute; +// .useSprite(0, 8); +// margin: 0; +// &.fancytree-drop-after, +// &.fancytree-drop-before { +// width: 4 * @fancy-icon-width; // 64px; +// .useSprite(0, 9); +// } +// &.fancytree-drop-copy { +// .useSprite(4, 8); +// } +// &.fancytree-drop-move { +// .useSprite(2, 8); +// } +//} +// +///*** Source node while dragging ***********************************************/ +// +//span.fancytree-drag-source { +// &.fancytree-drag-remove { +// // text-decoration: line-through; +// opacity: 0.15; +// } +//} +// +///*** Target node while dragging cursor is over it *****************************/ +// +//span.fancytree-drop-target { +// &.fancytree-drop-accept { +// // outline: 1px dotted #5cb85c; // bootstrap sucess +// } +//} +//span.fancytree-drop-reject { +// // outline: 1px dotted #d9534f; // boostrap warning +//} + +/*------------------------------------------------------------------------------ + * 'rtl' option + *----------------------------------------------------------------------------*/ + +.fancytree-container.fancytree-rtl { + .fancytree-title { + /*unicode-bidi: bidi-override;*/ /* optional: reverse title letters */ + } + span.fancytree-connector, + span.fancytree-expander, + span.fancytree-icon, + span.fancytree-drag-helper-img { + .setBgImageUrl("icons-rtl.gif"); + } + .fancytree-exp-n span.fancytree-expander, + .fancytree-exp-nl span.fancytree-expander { + background-image: none; + } + &.fancytree-connectors .fancytree-exp-n span.fancytree-expander, + &.fancytree-connectors .fancytree-exp-nl span.fancytree-expander { + .setBgImageUrl("icons-rtl.gif"); + } +} +ul.fancytree-container.fancytree-rtl { + ul { + padding: 0 16px 0 0; + } + &.fancytree-connectors li { + background-position: right 0; + background-image: url("@{fancy-image-prefix}vline-rtl.gif"); + } + // Suppress lines for last child node + li.fancytree-lastsib, + // Suppress lines if level is fixed expanded (option minExpandLevel) + &.fancytree-no-connector > li { + background-image: none; + } +} +#fancytree-drop-marker.fancytree-rtl { + .setBgImageUrl("icons-rtl.gif"); +} + +//// CHANGE: not used. +///*------------------------------------------------------------------------------ +// * 'table' extension +// *----------------------------------------------------------------------------*/ +// +//table.fancytree-ext-table { +// font-family: @fancy-font-family; +// font-size: @fancy-font-size; +// border-collapse: collapse; +// span.fancytree-node { +// display: inline-block; // #117 +// box-sizing: border-box; // #562 +// } +// td.fancytree-status-merged { +// text-align: center; +// // font-weight: bold; +// font-style: italic; +// // line-height: 100px; +// color: @fancy-font-color-dimm; +// } +// tr.fancytree-statusnode-error td.fancytree-status-merged { +// color: @fancy-font-error-color; +// } +// /* ext-ariagrid */ +// &.fancytree-ext-ariagrid.fancytree-cell-mode { +// > tbody > tr.fancytree-active > td { +// background-color: #eee; +// } +// > tbody > tr > td.fancytree-active-cell { +// background-color: #cbe8f6; +// } +// &.fancytree-cell-nav-mode > tbody > tr > td.fancytree-active-cell { +// background-color: #3875d7; +// } +// } +//} +// +///*------------------------------------------------------------------------------ +// * 'columnview' extension +// *----------------------------------------------------------------------------*/ +// +//table.fancytree-ext-columnview { +// // border-collapse: collapse; +// // width: 100%; +// tbody tr td { +// position: relative; +// border: 1px solid gray; +// vertical-align: top; +// overflow: auto; +// > ul { +// padding: 0; +// li { +// list-style-image: none; +// list-style-position: outside; +// list-style-type: none; +// -moz-background-clip: border; +// -moz-background-inline-policy: continuous; +// -moz-background-origin: padding; +// background-attachment: scroll; +// background-color: transparent; +// .setBgPos(0, 0); +// background-repeat: repeat-y; +// background-image: none; /* no v-lines */ +// +// margin: 0; +// // padding: 1px 0 0 0; // issue #246 +// } +// } +// } +// span.fancytree-node { +// position: relative; /* allow positioning of embedded spans */ +// display: inline-block; // #117 +// } +// span.fancytree-node.fancytree-expanded { +// background-color: #e0e0e0; +// } +// span.fancytree-node.fancytree-active { +// background-color: #cbe8f6; +// // background-color: royalblue; +// } +// .fancytree-has-children span.fancytree-cv-right { +// position: absolute; +// right: 3px; +// .useSprite(0, 5); +// &:hover { +// .useSprite(1, 5); +// } +// } +//} +// +///*------------------------------------------------------------------------------ +// * 'filter' extension +// *----------------------------------------------------------------------------*/ +// +//.fancytree-ext-filter-dimm { +// span.fancytree-node span.fancytree-title { +// color: @fancy-font-color-dimm; +// font-weight: lighter; +// } +// tr.fancytree-submatch span.fancytree-title, +// span.fancytree-node.fancytree-submatch span.fancytree-title { +// color: black; +// font-weight: normal; +// } +// tr.fancytree-match span.fancytree-title, +// span.fancytree-node.fancytree-match span.fancytree-title { +// color: black; +// font-weight: bold; +// } +//} +//.fancytree-ext-filter-hide { +// tr.fancytree-hide, +// span.fancytree-node.fancytree-hide { +// display: none; +// } +// tr.fancytree-submatch span.fancytree-title, +// span.fancytree-node.fancytree-submatch span.fancytree-title { +// color: @fancy-font-color-dimm; +// font-weight: lighter; +// } +// tr.fancytree-match span.fancytree-title, +// span.fancytree-node.fancytree-match span.fancytree-title { +// color: black; +// font-weight: normal; +// } +//} +///* Hide expanders if all child nodes are hidden by filter */ +//.fancytree-ext-filter-hide-expanders { +// tr.fancytree-match span.fancytree-expander, +// span.fancytree-node.fancytree-match span.fancytree-expander { +// visibility: hidden; +// } +// tr.fancytree-submatch span.fancytree-expander, +// span.fancytree-node.fancytree-submatch span.fancytree-expander { +// visibility: visible; +// } +//} +// +//.fancytree-ext-childcounter, +//.fancytree-ext-filter { +// // span.fancytree-title mark { +// // font-style: normal; +// // background-color: #ead61c; // yellow +// // border-radius: 3px; +// // } +// span.fancytree-icon, +// span.fancytree-custom-icon { +// position: relative; +// } +// span.fancytree-childcounter { +// color: #fff; +// background: #777; // #337ab7; // bootstrap blue +// border: 1px solid gray; +// position: absolute; +// top: -6px; +// right: -6px; +// min-width: 10px; +// height: 10px; +// line-height: 1; +// vertical-align: baseline; +// border-radius: 10px; +// padding: 2px; +// text-align: center; +// font-size: 9px; +// } +//} +///*------------------------------------------------------------------------------ +// * 'wide' extension +// *----------------------------------------------------------------------------*/ +// +//ul.fancytree-ext-wide { +// position: relative; +// min-width: 100%; +// z-index: 2; +// +// -webkit-box-sizing: border-box; +// -moz-box-sizing: border-box; +// box-sizing: border-box; +// +// span.fancytree-node > span { +// position: relative; +// z-index: 2; +// } +// span.fancytree-node span.fancytree-title { +// position: absolute; // Allow left: 0. Note: prevents smooth dropdown animation +// z-index: 1; // Behind expander and checkbox +// left: 0px; +// min-width: 100%; +// margin-left: 0; +// margin-right: 0; +// +// -webkit-box-sizing: border-box; +// -moz-box-sizing: border-box; +// box-sizing: border-box; +// } +//} +// +///*------------------------------------------------------------------------------ +// * 'fixed' extension +// *----------------------------------------------------------------------------*/ +// +//.fancytree-ext-fixed-wrapper { +// .fancytree-ext-fixed-hidden { +// display: none; +// } +// div.fancytree-ext-fixed-scroll-border-bottom { +// border-bottom: 3px solid rgba(0, 0, 0, 0.75); +// } +// div.fancytree-ext-fixed-scroll-border-right { +// border-right: 3px solid rgba(0, 0, 0, 0.75); +// } +// div.fancytree-ext-fixed-wrapper-tl { +// position: absolute; +// overflow: hidden; +// z-index: 3; +// top: 0px; +// left: 0px; +// } +// div.fancytree-ext-fixed-wrapper-tr { +// position: absolute; +// overflow: hidden; +// z-index: 2; +// top: 0px; +// } +// div.fancytree-ext-fixed-wrapper-bl { +// position: absolute; +// overflow: hidden; +// z-index: 2; +// left: 0px; +// } +// div.fancytree-ext-fixed-wrapper-br { +// position: absolute; +// overflow: scroll; +// z-index: 1; +// } +//} diff --git a/plugins/55/indexmenu/scripts/fancytree/skin-bootstrap-n/ui.fancytree.css b/plugins/55/indexmenu/scripts/fancytree/skin-bootstrap-n/ui.fancytree.css new file mode 100644 index 0000000..f407a96 --- /dev/null +++ b/plugins/55/indexmenu/scripts/fancytree/skin-bootstrap-n/ui.fancytree.css @@ -0,0 +1,620 @@ +/*! + * Fancytree "bootstrap" skin (highlighting the node span instead of title-only). + * + * DON'T EDIT THE CSS FILE DIRECTLY, since it is automatically generated from + * the LESS templates. + */ +/******************************************************************************* + * Common Styles for Fancytree Skins. + * + * This section is automatically generated from the `skin-common.less` template. + * + * Copyright (c) 2008-2023, Martin Wendt (https://wwWendt.de) + * Released under the MIT license + * https://github.com/mar10/fancytree/wiki/LicenseInfo + * + * @version 2.38.3 + * @date 2023-02-01T20:52:50Z +******************************************************************************/ +/*------------------------------------------------------------------------------ + * Helpers + *----------------------------------------------------------------------------*/ +.fancytree-helper-hidden { + display: none; +} +.fancytree-helper-indeterminate-cb { + color: #777; +} +.fancytree-helper-disabled { + color: #c0c0c0; +} +/* Helper to allow spinning loader icon with glyph-, ligature-, and SVG-icons. */ +.fancytree-helper-spin { + -webkit-animation: spin 1000ms infinite linear; + animation: spin 1000ms infinite linear; +} +@-webkit-keyframes spin { + 0% { + -webkit-transform: rotate(0deg); + transform: rotate(0deg); + } + 100% { + -webkit-transform: rotate(359deg); + transform: rotate(359deg); + } +} +@keyframes spin { + 0% { + -webkit-transform: rotate(0deg); + transform: rotate(0deg); + } + 100% { + -webkit-transform: rotate(359deg); + transform: rotate(359deg); + } +} +/*------------------------------------------------------------------------------ + * Container and UL / LI + *----------------------------------------------------------------------------*/ +ul.fancytree-container { + font-family: tahoma, arial, helvetica; + font-size: 10pt; + white-space: nowrap; + padding: 3px; + margin: 0; + background-color: white; + border: 1px dotted gray; + min-height: 0%; + position: relative; +} +ul.fancytree-container ul { + padding: 0 0 0 16px; + margin: 0; +} +ul.fancytree-container ul > li:before { + content: none; +} +ul.fancytree-container li { + list-style-image: none; + list-style-position: outside; + list-style-type: none; + -moz-background-clip: border; + -moz-background-inline-policy: continuous; + -moz-background-origin: padding; + background-attachment: scroll; + background-color: transparent; + background-position: 0em 0em; + background-repeat: repeat-y; + background-image: none; + margin: 0; +} +ul.fancytree-container li.fancytree-lastsib { + background-image: none; +} +.ui-fancytree-disabled ul.fancytree-container { + opacity: 0.5; + background-color: silver; +} +ul.fancytree-connectors.fancytree-container li { + background-image: url("../skin-bootstrap-n/vline.gif"); + background-position: 0 0; +} +ul.fancytree-container li.fancytree-lastsib, +ul.fancytree-no-connector > li { + background-image: none; +} +li.fancytree-animating { + position: relative; +} +/*------------------------------------------------------------------------------ + * Common icon definitions + *----------------------------------------------------------------------------*/ +span.fancytree-empty, +span.fancytree-vline, +span.fancytree-expander, +span.fancytree-icon, +span.fancytree-checkbox, +span.fancytree-drag-helper-img, +#fancytree-drop-marker { + width: 1em; + height: 1em; + display: inline-block; + vertical-align: top; + background-repeat: no-repeat; + background-position: 0em 0em; +} +span.fancytree-icon, +span.fancytree-checkbox, +span.fancytree-expander, +span.fancytree-custom-icon { + margin-top: 0px; +} +/* Used by icon option: */ +span.fancytree-custom-icon { + width: 1em; + height: 1em; + display: inline-block; + margin-left: 0.5em; + background-position: 0em 0em; +} +/* Used by 'icon' node option: */ +img.fancytree-icon { + width: 1em; + height: 1em; + margin-left: 0.5em; + margin-top: 0px; + vertical-align: top; + border-style: none; +} +/*------------------------------------------------------------------------------ + * Expander icon + * + * Note: IE6 doesn't correctly evaluate multiples class names, + * so we create combined class names that can be used in the CSS. + * + * Prefix: fancytree-exp- + * 1st character: 'e': expanded, 'c': collapsed, 'n': no children + * 2nd character (optional): 'd': lazy (Delayed) + * 3rd character (optional): 'l': Last sibling + *----------------------------------------------------------------------------*/ +span.fancytree-expander { + cursor: pointer; +} +.fancytree-exp-n span.fancytree-expander, +.fancytree-exp-nl span.fancytree-expander { + background-image: none; + cursor: default; +} +.fancytree-connectors .fancytree-exp-n span.fancytree-expander, +.fancytree-connectors .fancytree-exp-nl span.fancytree-expander { + margin-top: 0; +} +/* Fade out expanders, when container is not hovered or active */ +.fancytree-fade-expander span.fancytree-expander { + transition: opacity 1.5s; + opacity: 0; +} +.fancytree-fade-expander:hover span.fancytree-expander, +.fancytree-fade-expander.fancytree-treefocus span.fancytree-expander, +.fancytree-fade-expander .fancytree-treefocus span.fancytree-expander, +.fancytree-fade-expander [class*="fancytree-statusnode-"] span.fancytree-expander { + transition: opacity 0.6s; + opacity: 1; +} +/*------------------------------------------------------------------------------ + * Checkbox icon + *----------------------------------------------------------------------------*/ +span.fancytree-checkbox { + margin-left: 0.5em; +} +.fancytree-unselectable span.fancytree-checkbox { + opacity: 0.4; + filter: alpha(opacity=40); +} +.fancytree-container.fancytree-checkbox-auto-hide span.fancytree-checkbox { + visibility: hidden; +} +.fancytree-container.fancytree-checkbox-auto-hide .fancytree-node:hover span.fancytree-checkbox, +.fancytree-container.fancytree-checkbox-auto-hide tr:hover td span.fancytree-checkbox, +.fancytree-container.fancytree-checkbox-auto-hide .fancytree-node.fancytree-selected span.fancytree-checkbox, +.fancytree-container.fancytree-checkbox-auto-hide tr.fancytree-selected td span.fancytree-checkbox { + visibility: unset; +} +.fancytree-container.fancytree-checkbox-auto-hide.fancytree-treefocus .fancytree-node.fancytree-active span.fancytree-checkbox, +.fancytree-container.fancytree-checkbox-auto-hide.fancytree-treefocus tr.fancytree-active td span.fancytree-checkbox { + visibility: unset; +} +/*------------------------------------------------------------------------------ + * Node type icon + * Note: IE6 doesn't correctly evaluate multiples class names, + * so we create combined class names that can be used in the CSS. + * + * Prefix: fancytree-ico- + * 1st character: 'e': expanded, 'c': collapsed + * 2nd character (optional): 'f': folder + *----------------------------------------------------------------------------*/ +span.fancytree-icon { + margin-left: 0.5em; +} +/* Documents */ +/* Folders */ +.fancytree-loading span.fancytree-expander, +.fancytree-loading span.fancytree-expander:hover, +.fancytree-statusnode-loading span.fancytree-icon, +.fancytree-statusnode-loading span.fancytree-icon:hover, +span.fancytree-icon.fancytree-icon-loading { + background-image: none; +} +/* Status node icons */ +/*------------------------------------------------------------------------------ + * Node titles and highlighting + *----------------------------------------------------------------------------*/ +span.fancytree-node { + /* See #117 */ + display: inherit; + width: 100%; + margin-top: 1px; + min-height: 1em; +} +span.fancytree-title { + color: black; + cursor: pointer; + display: inline-block; + vertical-align: top; + min-height: 1em; + padding: 0 3px 0 3px; + margin: 0px 0 0 0.5em; + border: 1px solid transparent; + -webkit-border-radius: 0px; + -moz-border-radius: 0px; + -ms-border-radius: 0px; + -o-border-radius: 0px; + border-radius: 0px; +} +span.fancytree-node.fancytree-error span.fancytree-title { + color: red; +} +/*------------------------------------------------------------------------------ + * Drag'n'drop support + *----------------------------------------------------------------------------*/ +/* ext-dnd5: */ +span.fancytree-childcounter { + color: #fff; + background: #337ab7; + border: 1px solid gray; + border-radius: 10px; + padding: 2px; + text-align: center; +} +/* ext-dnd: */ +div.fancytree-drag-helper span.fancytree-childcounter, +div.fancytree-drag-helper span.fancytree-dnd-modifier { + display: inline-block; + color: #fff; + background: #337ab7; + border: 1px solid gray; + min-width: 10px; + height: 10px; + line-height: 1; + vertical-align: baseline; + border-radius: 10px; + padding: 2px; + text-align: center; + font-size: 9px; +} +div.fancytree-drag-helper span.fancytree-childcounter { + position: absolute; + top: -6px; + right: -6px; +} +div.fancytree-drag-helper span.fancytree-dnd-modifier { + background: #5cb85c; + border: none; + font-weight: bolder; +} +/*** Drop marker icon *********************************************************/ +#fancytree-drop-marker { + width: 2em; + position: absolute; + margin: 0; +} +#fancytree-drop-marker.fancytree-drop-after, +#fancytree-drop-marker.fancytree-drop-before { + width: 4em; +} +/*** Source node while dragging ***********************************************/ +span.fancytree-drag-source.fancytree-drag-remove { + opacity: 0.15; +} +/*** Target node while dragging cursor is over it *****************************/ +/*------------------------------------------------------------------------------ + * 'rtl' option + *----------------------------------------------------------------------------*/ +.fancytree-container.fancytree-rtl .fancytree-title { + /*unicode-bidi: bidi-override;*/ + /* optional: reverse title letters */ +} +.fancytree-container.fancytree-rtl .fancytree-exp-n span.fancytree-expander, +.fancytree-container.fancytree-rtl .fancytree-exp-nl span.fancytree-expander { + background-image: none; +} +ul.fancytree-container.fancytree-rtl ul { + padding: 0 16px 0 0; +} +ul.fancytree-container.fancytree-rtl.fancytree-connectors li { + background-position: right 0; + background-image: url("../skin-bootstrap-n/vline-rtl.gif"); +} +ul.fancytree-container.fancytree-rtl li.fancytree-lastsib, +ul.fancytree-container.fancytree-rtl.fancytree-no-connector > li { + background-image: none; +} +/*------------------------------------------------------------------------------ + * 'table' extension + *----------------------------------------------------------------------------*/ +table.fancytree-ext-table { + font-family: tahoma, arial, helvetica; + font-size: 10pt; + border-collapse: collapse; + /* ext-ariagrid */ +} +table.fancytree-ext-table span.fancytree-node { + display: inline-block; + box-sizing: border-box; +} +table.fancytree-ext-table td.fancytree-status-merged { + text-align: center; + font-style: italic; + color: #c0c0c0; +} +table.fancytree-ext-table tr.fancytree-statusnode-error td.fancytree-status-merged { + color: red; +} +table.fancytree-ext-table.fancytree-ext-ariagrid.fancytree-cell-mode > tbody > tr.fancytree-active > td { + background-color: #eee; +} +table.fancytree-ext-table.fancytree-ext-ariagrid.fancytree-cell-mode > tbody > tr > td.fancytree-active-cell { + background-color: #cbe8f6; +} +table.fancytree-ext-table.fancytree-ext-ariagrid.fancytree-cell-mode.fancytree-cell-nav-mode > tbody > tr > td.fancytree-active-cell { + background-color: #3875d7; +} +/*------------------------------------------------------------------------------ + * 'columnview' extension + *----------------------------------------------------------------------------*/ +table.fancytree-ext-columnview tbody tr td { + position: relative; + border: 1px solid gray; + vertical-align: top; + overflow: auto; +} +table.fancytree-ext-columnview tbody tr td > ul { + padding: 0; +} +table.fancytree-ext-columnview tbody tr td > ul li { + list-style-image: none; + list-style-position: outside; + list-style-type: none; + -moz-background-clip: border; + -moz-background-inline-policy: continuous; + -moz-background-origin: padding; + background-attachment: scroll; + background-color: transparent; + background-position: 0em 0em; + background-repeat: repeat-y; + background-image: none; + /* no v-lines */ + margin: 0; +} +table.fancytree-ext-columnview span.fancytree-node { + position: relative; + /* allow positioning of embedded spans */ + display: inline-block; +} +table.fancytree-ext-columnview span.fancytree-node.fancytree-expanded { + background-color: #e0e0e0; +} +table.fancytree-ext-columnview span.fancytree-node.fancytree-active { + background-color: #cbe8f6; +} +table.fancytree-ext-columnview .fancytree-has-children span.fancytree-cv-right { + position: absolute; + right: 3px; +} +/*------------------------------------------------------------------------------ + * 'filter' extension + *----------------------------------------------------------------------------*/ +.fancytree-ext-filter-dimm span.fancytree-node span.fancytree-title { + color: #c0c0c0; + font-weight: lighter; +} +.fancytree-ext-filter-dimm tr.fancytree-submatch span.fancytree-title, +.fancytree-ext-filter-dimm span.fancytree-node.fancytree-submatch span.fancytree-title { + color: black; + font-weight: normal; +} +.fancytree-ext-filter-dimm tr.fancytree-match span.fancytree-title, +.fancytree-ext-filter-dimm span.fancytree-node.fancytree-match span.fancytree-title { + color: black; + font-weight: bold; +} +.fancytree-ext-filter-hide tr.fancytree-hide, +.fancytree-ext-filter-hide span.fancytree-node.fancytree-hide { + display: none; +} +.fancytree-ext-filter-hide tr.fancytree-submatch span.fancytree-title, +.fancytree-ext-filter-hide span.fancytree-node.fancytree-submatch span.fancytree-title { + color: #c0c0c0; + font-weight: lighter; +} +.fancytree-ext-filter-hide tr.fancytree-match span.fancytree-title, +.fancytree-ext-filter-hide span.fancytree-node.fancytree-match span.fancytree-title { + color: black; + font-weight: normal; +} +/* Hide expanders if all child nodes are hidden by filter */ +.fancytree-ext-filter-hide-expanders tr.fancytree-match span.fancytree-expander, +.fancytree-ext-filter-hide-expanders span.fancytree-node.fancytree-match span.fancytree-expander { + visibility: hidden; +} +.fancytree-ext-filter-hide-expanders tr.fancytree-submatch span.fancytree-expander, +.fancytree-ext-filter-hide-expanders span.fancytree-node.fancytree-submatch span.fancytree-expander { + visibility: visible; +} +.fancytree-ext-childcounter span.fancytree-icon, +.fancytree-ext-filter span.fancytree-icon, +.fancytree-ext-childcounter span.fancytree-custom-icon, +.fancytree-ext-filter span.fancytree-custom-icon { + position: relative; +} +.fancytree-ext-childcounter span.fancytree-childcounter, +.fancytree-ext-filter span.fancytree-childcounter { + color: #fff; + background: #777; + border: 1px solid gray; + position: absolute; + top: -6px; + right: -6px; + min-width: 10px; + height: 10px; + line-height: 1; + vertical-align: baseline; + border-radius: 10px; + padding: 2px; + text-align: center; + font-size: 9px; +} +/*------------------------------------------------------------------------------ + * 'wide' extension + *----------------------------------------------------------------------------*/ +ul.fancytree-ext-wide { + position: relative; + min-width: 100%; + z-index: 2; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; +} +ul.fancytree-ext-wide span.fancytree-node > span { + position: relative; + z-index: 2; +} +ul.fancytree-ext-wide span.fancytree-node span.fancytree-title { + position: absolute; + z-index: 1; + left: 0px; + min-width: 100%; + margin-left: 0; + margin-right: 0; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; +} +/*------------------------------------------------------------------------------ + * 'fixed' extension + *----------------------------------------------------------------------------*/ +.fancytree-ext-fixed-wrapper .fancytree-ext-fixed-hidden { + display: none; +} +.fancytree-ext-fixed-wrapper div.fancytree-ext-fixed-scroll-border-bottom { + border-bottom: 3px solid rgba(0, 0, 0, 0.75); +} +.fancytree-ext-fixed-wrapper div.fancytree-ext-fixed-scroll-border-right { + border-right: 3px solid rgba(0, 0, 0, 0.75); +} +.fancytree-ext-fixed-wrapper div.fancytree-ext-fixed-wrapper-tl { + position: absolute; + overflow: hidden; + z-index: 3; + top: 0px; + left: 0px; +} +.fancytree-ext-fixed-wrapper div.fancytree-ext-fixed-wrapper-tr { + position: absolute; + overflow: hidden; + z-index: 2; + top: 0px; +} +.fancytree-ext-fixed-wrapper div.fancytree-ext-fixed-wrapper-bl { + position: absolute; + overflow: hidden; + z-index: 2; + left: 0px; +} +.fancytree-ext-fixed-wrapper div.fancytree-ext-fixed-wrapper-br { + position: absolute; + overflow: scroll; + z-index: 1; +} +/******************************************************************************* + * Styles specific to this skin. + * + * This section is automatically generated from the `ui-fancytree.less` template. + ******************************************************************************/ +ul.fancytree-container ul { + padding: 0 0 0 1.5em; + margin: 0; +} +/* Prevent focus frame */ +.fancytree-container:focus { + outline: none; +} +.fancytree-container span.fancytree-statusnode-error span.fancytree-expander { + color: red; +} +span.fancytree-node { + border: 1px solid transparent; + border-radius: 3px; + padding-left: 8px; +} +span.fancytree-title { + border-radius: 3px; +} +span.fancytree-node.fancytree-selected { + background-color: #80c780; + border-color: #80c780; +} +span.fancytree-node.fancytree-selected span.fancytree-title { + background-color: #80c780; +} +span.fancytree-node.fancytree-active { + background-color: #6aa3d5; +} +.fancytree-container.fancytree-treefocus span.fancytree-node:hover { + background-color: #e9f2f9; +} +.fancytree-container.fancytree-treefocus span.fancytree-node.fancytree-focused { + border-color: #428bca; +} +.fancytree-container.fancytree-treefocus span.fancytree-node.fancytree-selected { + background-color: #5cb85c; +} +.fancytree-container.fancytree-treefocus span.fancytree-node.fancytree-selected span.fancytree-title { + background-color: #5cb85c; +} +.fancytree-container.fancytree-treefocus span.fancytree-node.fancytree-active { + background-color: #428bca; + border-color: #428bca; +} +/******************************************************************************* + * 'table' extension + */ +table.fancytree-ext-table tbody tr td { + border: 1px solid #eeeeee; +} +table.fancytree-ext-table tbody tr.fancytree-selected { + background-color: #80c780; +} +table.fancytree-ext-table tbody tr.fancytree-selected span.fancytree-node { + background-color: #80c780; +} +table.fancytree-ext-table tbody tr.fancytree-selected span.fancytree-title { + background-color: #80c780; +} +table.fancytree-ext-table tbody tr.fancytree-active { + background-color: #6aa3d5; +} +table.fancytree-ext-table tbody tr.fancytree-active span.fancytree-node { + background-color: #6aa3d5; +} +table.fancytree-ext-table.fancytree-treefocus tbody tr:hover { + background-color: #e9f2f9; +} +table.fancytree-ext-table.fancytree-treefocus tbody tr.fancytree-focused span.fancytree-title { + outline: 1px dotted #428bca; +} +table.fancytree-ext-table.fancytree-treefocus tbody tr.fancytree-selected { + background-color: #5cb85c; +} +table.fancytree-ext-table.fancytree-treefocus tbody tr.fancytree-selected span.fancytree-node { + background-color: #5cb85c; +} +table.fancytree-ext-table.fancytree-treefocus tbody tr.fancytree-selected span.fancytree-title { + background-color: #5cb85c; +} +table.fancytree-ext-table.fancytree-treefocus tbody tr.fancytree-active { + background-color: #428bca; +} +table.fancytree-ext-table.fancytree-treefocus tbody tr.fancytree-active span.fancytree-node { + background-color: #428bca; +} diff --git a/plugins/55/indexmenu/scripts/fancytree/skin-bootstrap-n/ui.fancytree.less b/plugins/55/indexmenu/scripts/fancytree/skin-bootstrap-n/ui.fancytree.less new file mode 100644 index 0000000..20fcbb4 --- /dev/null +++ b/plugins/55/indexmenu/scripts/fancytree/skin-bootstrap-n/ui.fancytree.less @@ -0,0 +1,185 @@ +/*! + * Fancytree "bootstrap" skin (highlighting the node span instead of title-only). + * + * DON'T EDIT THE CSS FILE DIRECTLY, since it is automatically generated from + * the LESS templates. + */ + +// Import common styles +@import "skin-common.less"; + + +/******************************************************************************* + * Styles specific to this skin. + * + * This section is automatically generated from the `ui-fancytree.less` template. + ******************************************************************************/ + + +// local vars +// @fancy-my-icon-size: 16px; + +// Override the variable after the import. +// NOTE: Variables are always resolved as the last definition, even if it is +// after where it is used. +@fancy-use-sprites: false; // false: suppress all background images (i.e. icons) +@fancy-loading-url: none; + +@fancy-icon-width: 1em; +@fancy-icon-height: 1em; +@fancy-line-height: 1em; +@fancy-icon-spacing: 0.5em; + +// Use 'data-uri(...)' to embed the image into CSS instead of linking to 'loading.gif': +// @fancy-loading-url: data-uri("@{fancy-image-prefix}loading.gif"); +// Set to `true` to use `data-uri(...)` which will embed icons.gif into CSS +// instead of linking to that file: +// @fancy-inline-sprites: true; + +// We need to define this variable here (not in skin-common.less) to make it +// work with grunt and webpack: +@fancy-image-prefix: "./skin-bootstrap-n/"; + +//default 10pt, which is used in a relative manner resulting in 13.3 in dokuwiki-template. +@fancy-font-size: 93%; //@fancy-cst-size; + +ul.fancytree-container ul { + padding: 0 0 0 1.5em; + margin: 0; +} +/* Prevent focus frame */ +.fancytree-container:focus { + outline: none; +} + +// Error status node +.fancytree-container span.fancytree-statusnode-error span.fancytree-expander { + color: @fancy-font-error-color; +} + +///// +// Original bootstrap colors (http://getbootstrap.com/css/#responsive-utilities) +@gray-darker: lighten(#000, 13.5%); // #222 +@gray-dark: lighten(#000, 20%); // #333 +@gray: lighten(#000, 33.5%); // #555 +@gray-light: lighten(#000, 60%); // #999 +@gray-lighter: lighten(#000, 93.5%); // #eee + +@brand-primary: #428bca; // blue +@brand-success: #5cb85c; // green +@brand-info: #5bc0de; // light blue +@brand-warning: #f0ad4e; // orange +@brand-danger: #d9534f; // red + +@border-radius-base: 4px; +@border-radius-large: 6px; +@border-radius-small: 3px; +///////////// + +span.fancytree-node { + border: @fancy-node-border-width solid transparent; // avoid jumping, when a border is added on hover + border-radius: @border-radius-small; + padding-left: 8px; + color: @fancy-font-color; //set icon color to font color as well +} +span.fancytree-title { + border-radius: @border-radius-small; +} +// Inactive tree: +span.fancytree-node.fancytree-selected { // selected nodes inside inactive tree + background-color: lighten(@brand-success, 10%); + border-color: lighten(@brand-success, 10%); + span.fancytree-title { + background-color: lighten(@brand-success, 10%); // green title, even when active + } +} +span.fancytree-node.fancytree-active { // active nodes inside inactive tree + background-color: lighten(@brand-primary, 10%); +} +// Active tree: +.fancytree-container.fancytree-treefocus { + span.fancytree-node:hover { + background-color: lighten(@brand-primary, 42%); + } + span.fancytree-node.fancytree-focused { + border-color: @brand-primary; + } + span.fancytree-node.fancytree-selected { + background-color: @brand-success; + span.fancytree-title { + background-color: @brand-success; // green title, even when active + } + } + span.fancytree-node.fancytree-active { + background-color: @brand-primary; + border-color: @brand-primary; + } +} + +///******************************************************************************* +// * 'table' extension +// */ +//table.fancytree-ext-table tbody { +// tr td { +// border: 1px solid @gray-lighter; +// } +// // span.fancytree-node, +// // span.fancytree-node:hover { // undo standard tree css +// // border: none; +// // background: none; +// // } +// // // Title get's a white background, when hovered. Undo standard node formatting +// // span.fancytree-title:hover { +// // border: none; +// // background: inherit; +// // background: transparent; +// // background: none; +// // filter: none; +// // } +// // dimmed, if inside inactive tree +// tr.fancytree-selected { +// background-color: lighten(@brand-success, 10%); +// span.fancytree-node { +// background-color: lighten(@brand-success, 10%); +// } +// span.fancytree-title { +// background-color: lighten(@brand-success, 10%); // green title, even when active +// } +// } +// tr.fancytree-active { // dimmed, if inside inactive tree +// background-color: lighten(@brand-primary, 10%); +// span.fancytree-node { +// background-color: lighten(@brand-primary, 10%); +// } +// } +//} +// +//table.fancytree-ext-table.fancytree-treefocus tbody { +// tr:hover { +// background-color: lighten(@brand-primary, 42%); +// // outline: 1px solid @brand-primary; +// } +// tr.fancytree-focused span.fancytree-title { +// outline: 1px dotted @brand-primary; +// } +// tr.fancytree-active:hover, +// tr.fancytree-selected:hover { +// // background-color: #CBE8F6; +// // outline: 1px solid #26A0DA; +// } +// tr.fancytree-selected { +// background-color: @brand-success; +// span.fancytree-node { +// background-color: @brand-success; +// } +// span.fancytree-title { +// background-color: @brand-success; // green title, even when active +// } +// } +// tr.fancytree-active { +// background-color: @brand-primary; +// span.fancytree-node { +// background-color: @brand-primary; +// } +// } +//} diff --git a/plugins/55/indexmenu/scripts/fancytree/skin-bootstrap-n/ui.fancytree.min.css b/plugins/55/indexmenu/scripts/fancytree/skin-bootstrap-n/ui.fancytree.min.css new file mode 100644 index 0000000..ebfd3b1 --- /dev/null +++ b/plugins/55/indexmenu/scripts/fancytree/skin-bootstrap-n/ui.fancytree.min.css @@ -0,0 +1,6 @@ +/*! + * Fancytree "bootstrap" skin (highlighting the node span instead of title-only). + * + * DON'T EDIT THE CSS FILE DIRECTLY, since it is automatically generated from + * the LESS templates. + */.fancytree-helper-hidden{display:none}.fancytree-helper-indeterminate-cb{color:#777}.fancytree-helper-disabled{color:silver}.fancytree-helper-spin{-webkit-animation:spin 1s infinite linear;animation:spin 1s infinite linear}@-webkit-keyframes spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}ul.fancytree-container{font-family:tahoma,arial,helvetica;font-size:10pt;white-space:nowrap;padding:3px;margin:0;background-color:#fff;border:1px dotted gray;min-height:0;position:relative}ul.fancytree-container ul{padding:0 0 0 16px;margin:0}ul.fancytree-container ul>li:before{content:none}ul.fancytree-container li{list-style-image:none;list-style-position:outside;list-style-type:none;-moz-background-clip:border;-moz-background-inline-policy:continuous;-moz-background-origin:padding;background-attachment:scroll;background-color:transparent;background-position:0 0;background-repeat:repeat-y;background-image:none;margin:0}ul.fancytree-container li.fancytree-lastsib{background-image:none}.ui-fancytree-disabled ul.fancytree-container{opacity:.5;background-color:silver}ul.fancytree-connectors.fancytree-container li{background-image:url("../skin-bootstrap-n/vline.gif");background-position:0 0}ul.fancytree-container li.fancytree-lastsib,ul.fancytree-no-connector>li{background-image:none}li.fancytree-animating{position:relative}#fancytree-drop-marker,span.fancytree-checkbox,span.fancytree-drag-helper-img,span.fancytree-empty,span.fancytree-expander,span.fancytree-icon,span.fancytree-vline{width:1em;height:1em;display:inline-block;vertical-align:top;background-repeat:no-repeat;background-position:0 0}span.fancytree-checkbox,span.fancytree-custom-icon,span.fancytree-expander,span.fancytree-icon{margin-top:0}span.fancytree-custom-icon{width:1em;height:1em;display:inline-block;margin-left:.5em;background-position:0 0}img.fancytree-icon{width:1em;height:1em;margin-left:.5em;margin-top:0;vertical-align:top;border-style:none}span.fancytree-expander{cursor:pointer}.fancytree-exp-n span.fancytree-expander,.fancytree-exp-nl span.fancytree-expander{background-image:none;cursor:default}.fancytree-connectors .fancytree-exp-n span.fancytree-expander,.fancytree-connectors .fancytree-exp-nl span.fancytree-expander{margin-top:0}.fancytree-fade-expander span.fancytree-expander{transition:opacity 1.5s;opacity:0}.fancytree-fade-expander .fancytree-treefocus span.fancytree-expander,.fancytree-fade-expander [class*=fancytree-statusnode-] span.fancytree-expander,.fancytree-fade-expander.fancytree-treefocus span.fancytree-expander,.fancytree-fade-expander:hover span.fancytree-expander{transition:opacity .6s;opacity:1}span.fancytree-checkbox{margin-left:.5em}.fancytree-unselectable span.fancytree-checkbox{opacity:.4}.fancytree-container.fancytree-checkbox-auto-hide span.fancytree-checkbox{visibility:hidden}.fancytree-container.fancytree-checkbox-auto-hide .fancytree-node.fancytree-selected span.fancytree-checkbox,.fancytree-container.fancytree-checkbox-auto-hide .fancytree-node:hover span.fancytree-checkbox,.fancytree-container.fancytree-checkbox-auto-hide tr.fancytree-selected td span.fancytree-checkbox,.fancytree-container.fancytree-checkbox-auto-hide tr:hover td span.fancytree-checkbox{visibility:unset}.fancytree-container.fancytree-checkbox-auto-hide.fancytree-treefocus .fancytree-node.fancytree-active span.fancytree-checkbox,.fancytree-container.fancytree-checkbox-auto-hide.fancytree-treefocus tr.fancytree-active td span.fancytree-checkbox{visibility:unset}span.fancytree-icon{margin-left:.5em}.fancytree-loading span.fancytree-expander,.fancytree-loading span.fancytree-expander:hover,.fancytree-statusnode-loading span.fancytree-icon,.fancytree-statusnode-loading span.fancytree-icon:hover,span.fancytree-icon.fancytree-icon-loading{background-image:none}span.fancytree-node{display:inherit;width:100%;margin-top:1px;min-height:1em}span.fancytree-title{color:#000;cursor:pointer;display:inline-block;vertical-align:top;min-height:1em;padding:0 3px 0 3px;margin:0 0 0 .5em;border:1px solid transparent;-webkit-border-radius:0px;-moz-border-radius:0;-ms-border-radius:0px;-o-border-radius:0;border-radius:0}span.fancytree-node.fancytree-error span.fancytree-title{color:red}span.fancytree-childcounter{color:#fff;background:#337ab7;border:1px solid gray;border-radius:10px;padding:2px;text-align:center}div.fancytree-drag-helper span.fancytree-childcounter,div.fancytree-drag-helper span.fancytree-dnd-modifier{display:inline-block;color:#fff;background:#337ab7;border:1px solid gray;min-width:10px;height:10px;line-height:1;vertical-align:baseline;border-radius:10px;padding:2px;text-align:center;font-size:9px}div.fancytree-drag-helper span.fancytree-childcounter{position:absolute;top:-6px;right:-6px}div.fancytree-drag-helper span.fancytree-dnd-modifier{background:#5cb85c;border:none;font-weight:bolder}#fancytree-drop-marker{width:2em;position:absolute;margin:0}#fancytree-drop-marker.fancytree-drop-after,#fancytree-drop-marker.fancytree-drop-before{width:4em}span.fancytree-drag-source.fancytree-drag-remove{opacity:.15}.fancytree-container.fancytree-rtl .fancytree-exp-n span.fancytree-expander,.fancytree-container.fancytree-rtl .fancytree-exp-nl span.fancytree-expander{background-image:none}ul.fancytree-container.fancytree-rtl ul{padding:0 16px 0 0}ul.fancytree-container.fancytree-rtl.fancytree-connectors li{background-position:right 0;background-image:url("../skin-bootstrap-n/vline-rtl.gif")}ul.fancytree-container.fancytree-rtl li.fancytree-lastsib,ul.fancytree-container.fancytree-rtl.fancytree-no-connector>li{background-image:none}table.fancytree-ext-table{font-family:tahoma,arial,helvetica;font-size:10pt;border-collapse:collapse}table.fancytree-ext-table span.fancytree-node{display:inline-block;box-sizing:border-box}table.fancytree-ext-table td.fancytree-status-merged{text-align:center;font-style:italic;color:silver}table.fancytree-ext-table tr.fancytree-statusnode-error td.fancytree-status-merged{color:red}table.fancytree-ext-table.fancytree-ext-ariagrid.fancytree-cell-mode>tbody>tr.fancytree-active>td{background-color:#eee}table.fancytree-ext-table.fancytree-ext-ariagrid.fancytree-cell-mode>tbody>tr>td.fancytree-active-cell{background-color:#cbe8f6}table.fancytree-ext-table.fancytree-ext-ariagrid.fancytree-cell-mode.fancytree-cell-nav-mode>tbody>tr>td.fancytree-active-cell{background-color:#3875d7}table.fancytree-ext-columnview tbody tr td{position:relative;border:1px solid gray;vertical-align:top;overflow:auto}table.fancytree-ext-columnview tbody tr td>ul{padding:0}table.fancytree-ext-columnview tbody tr td>ul li{list-style-image:none;list-style-position:outside;list-style-type:none;-moz-background-clip:border;-moz-background-inline-policy:continuous;-moz-background-origin:padding;background-attachment:scroll;background-color:transparent;background-position:0 0;background-repeat:repeat-y;background-image:none;margin:0}table.fancytree-ext-columnview span.fancytree-node{position:relative;display:inline-block}table.fancytree-ext-columnview span.fancytree-node.fancytree-expanded{background-color:#e0e0e0}table.fancytree-ext-columnview span.fancytree-node.fancytree-active{background-color:#cbe8f6}table.fancytree-ext-columnview .fancytree-has-children span.fancytree-cv-right{position:absolute;right:3px}.fancytree-ext-filter-dimm span.fancytree-node span.fancytree-title{color:silver;font-weight:lighter}.fancytree-ext-filter-dimm span.fancytree-node.fancytree-submatch span.fancytree-title,.fancytree-ext-filter-dimm tr.fancytree-submatch span.fancytree-title{color:#000;font-weight:400}.fancytree-ext-filter-dimm span.fancytree-node.fancytree-match span.fancytree-title,.fancytree-ext-filter-dimm tr.fancytree-match span.fancytree-title{color:#000;font-weight:700}.fancytree-ext-filter-hide span.fancytree-node.fancytree-hide,.fancytree-ext-filter-hide tr.fancytree-hide{display:none}.fancytree-ext-filter-hide span.fancytree-node.fancytree-submatch span.fancytree-title,.fancytree-ext-filter-hide tr.fancytree-submatch span.fancytree-title{color:silver;font-weight:lighter}.fancytree-ext-filter-hide span.fancytree-node.fancytree-match span.fancytree-title,.fancytree-ext-filter-hide tr.fancytree-match span.fancytree-title{color:#000;font-weight:400}.fancytree-ext-filter-hide-expanders span.fancytree-node.fancytree-match span.fancytree-expander,.fancytree-ext-filter-hide-expanders tr.fancytree-match span.fancytree-expander{visibility:hidden}.fancytree-ext-filter-hide-expanders span.fancytree-node.fancytree-submatch span.fancytree-expander,.fancytree-ext-filter-hide-expanders tr.fancytree-submatch span.fancytree-expander{visibility:visible}.fancytree-ext-childcounter span.fancytree-custom-icon,.fancytree-ext-childcounter span.fancytree-icon,.fancytree-ext-filter span.fancytree-custom-icon,.fancytree-ext-filter span.fancytree-icon{position:relative}.fancytree-ext-childcounter span.fancytree-childcounter,.fancytree-ext-filter span.fancytree-childcounter{color:#fff;background:#777;border:1px solid gray;position:absolute;top:-6px;right:-6px;min-width:10px;height:10px;line-height:1;vertical-align:baseline;border-radius:10px;padding:2px;text-align:center;font-size:9px}ul.fancytree-ext-wide{position:relative;min-width:100%;z-index:2;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}ul.fancytree-ext-wide span.fancytree-node>span{position:relative;z-index:2}ul.fancytree-ext-wide span.fancytree-node span.fancytree-title{position:absolute;z-index:1;left:0;min-width:100%;margin-left:0;margin-right:0;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.fancytree-ext-fixed-wrapper .fancytree-ext-fixed-hidden{display:none}.fancytree-ext-fixed-wrapper div.fancytree-ext-fixed-scroll-border-bottom{border-bottom:3px solid rgba(0,0,0,.75)}.fancytree-ext-fixed-wrapper div.fancytree-ext-fixed-scroll-border-right{border-right:3px solid rgba(0,0,0,.75)}.fancytree-ext-fixed-wrapper div.fancytree-ext-fixed-wrapper-tl{position:absolute;overflow:hidden;z-index:3;top:0;left:0}.fancytree-ext-fixed-wrapper div.fancytree-ext-fixed-wrapper-tr{position:absolute;overflow:hidden;z-index:2;top:0}.fancytree-ext-fixed-wrapper div.fancytree-ext-fixed-wrapper-bl{position:absolute;overflow:hidden;z-index:2;left:0}.fancytree-ext-fixed-wrapper div.fancytree-ext-fixed-wrapper-br{position:absolute;overflow:scroll;z-index:1}ul.fancytree-container ul{padding:0 0 0 1.5em;margin:0}.fancytree-container:focus{outline:0}.fancytree-container span.fancytree-statusnode-error span.fancytree-expander{color:red}span.fancytree-node{border:1px solid transparent;border-radius:3px;padding-left:8px}span.fancytree-title{border-radius:3px}span.fancytree-node.fancytree-selected{background-color:#80c780;border-color:#80c780}span.fancytree-node.fancytree-selected span.fancytree-title{background-color:#80c780}span.fancytree-node.fancytree-active{background-color:#6aa3d5}.fancytree-container.fancytree-treefocus span.fancytree-node:hover{background-color:#e9f2f9}.fancytree-container.fancytree-treefocus span.fancytree-node.fancytree-focused{border-color:#428bca}.fancytree-container.fancytree-treefocus span.fancytree-node.fancytree-selected{background-color:#5cb85c}.fancytree-container.fancytree-treefocus span.fancytree-node.fancytree-selected span.fancytree-title{background-color:#5cb85c}.fancytree-container.fancytree-treefocus span.fancytree-node.fancytree-active{background-color:#428bca;border-color:#428bca}table.fancytree-ext-table tbody tr td{border:1px solid #eee}table.fancytree-ext-table tbody tr.fancytree-selected{background-color:#80c780}table.fancytree-ext-table tbody tr.fancytree-selected span.fancytree-node{background-color:#80c780}table.fancytree-ext-table tbody tr.fancytree-selected span.fancytree-title{background-color:#80c780}table.fancytree-ext-table tbody tr.fancytree-active{background-color:#6aa3d5}table.fancytree-ext-table tbody tr.fancytree-active span.fancytree-node{background-color:#6aa3d5}table.fancytree-ext-table.fancytree-treefocus tbody tr:hover{background-color:#e9f2f9}table.fancytree-ext-table.fancytree-treefocus tbody tr.fancytree-focused span.fancytree-title{outline:1px dotted #428bca}table.fancytree-ext-table.fancytree-treefocus tbody tr.fancytree-selected{background-color:#5cb85c}table.fancytree-ext-table.fancytree-treefocus tbody tr.fancytree-selected span.fancytree-node{background-color:#5cb85c}table.fancytree-ext-table.fancytree-treefocus tbody tr.fancytree-selected span.fancytree-title{background-color:#5cb85c}table.fancytree-ext-table.fancytree-treefocus tbody tr.fancytree-active{background-color:#428bca}table.fancytree-ext-table.fancytree-treefocus tbody tr.fancytree-active span.fancytree-node{background-color:#428bca}
\ No newline at end of file diff --git a/plugins/55/indexmenu/scripts/fancytree/skin-bootstrap-n/vline-rtl.gif b/plugins/55/indexmenu/scripts/fancytree/skin-bootstrap-n/vline-rtl.gif Binary files differnew file mode 100644 index 0000000..0400cb3 --- /dev/null +++ b/plugins/55/indexmenu/scripts/fancytree/skin-bootstrap-n/vline-rtl.gif diff --git a/plugins/55/indexmenu/scripts/fancytree/skin-bootstrap-n/vline.gif b/plugins/55/indexmenu/scripts/fancytree/skin-bootstrap-n/vline.gif Binary files differnew file mode 100644 index 0000000..1b00ae5 --- /dev/null +++ b/plugins/55/indexmenu/scripts/fancytree/skin-bootstrap-n/vline.gif diff --git a/plugins/55/indexmenu/scripts/fancytree/skin-bootstrap/boot.css b/plugins/55/indexmenu/scripts/fancytree/skin-bootstrap/boot.css new file mode 100644 index 0000000..0e0d2d2 --- /dev/null +++ b/plugins/55/indexmenu/scripts/fancytree/skin-bootstrap/boot.css @@ -0,0 +1,1065 @@ +@font-face { + font-family: "Glyphicons Halflings"; + src: url(../fonts/glyphicons-halflings-regular.eot); + src: url(../fonts/glyphicons-halflings-regular.eot?#iefix) format("embedded-opentype"), url(../fonts/glyphicons-halflings-regular.woff2) format("woff2"), url(../fonts/glyphicons-halflings-regular.woff) format("woff"), url(../fonts/glyphicons-halflings-regular.ttf) format("truetype"), url(../fonts/glyphicons-halflings-regular.svg#glyphicons_halflingsregular) format("svg") +} + +.glyphicon { + position: relative; + top: 1px; + display: inline-block; + font-family: "Glyphicons Halflings"; + font-style: normal; + font-weight: 400; + line-height: 1; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale +} + +/*.glyphicon-asterisk:before {*/ +/* content: "\002a"*/ +/*}*/ + +/*.glyphicon-plus:before {*/ +/* content: "\002b"*/ +/*}*/ + +/*.glyphicon-eur:before, .glyphicon-euro:before {*/ +/* content: "\20ac"*/ +/*}*/ + +/*.glyphicon-minus:before {*/ +/* content: "\2212"*/ +/*}*/ + +/*.glyphicon-cloud:before {*/ +/* content: "\2601"*/ +/*}*/ + +/*.glyphicon-envelope:before {*/ +/* content: "\2709"*/ +/*}*/ + +/*.glyphicon-pencil:before {*/ +/* content: "\270f"*/ +/*}*/ + +/*.glyphicon-glass:before {*/ +/* content: "\e001"*/ +/*}*/ + +/*.glyphicon-music:before {*/ +/* content: "\e002"*/ +/*}*/ + +/*.glyphicon-search:before {*/ +/* content: "\e003"*/ +/*}*/ + +/*.glyphicon-heart:before {*/ +/* content: "\e005"*/ +/*}*/ + +/*.glyphicon-star:before {*/ +/* content: "\e006"*/ +/*}*/ + +/*.glyphicon-star-empty:before {*/ +/* content: "\e007"*/ +/*}*/ + +/*.glyphicon-user:before {*/ +/* content: "\e008"*/ +/*}*/ + +/*.glyphicon-film:before {*/ +/* content: "\e009"*/ +/*}*/ + +/*.glyphicon-th-large:before {*/ +/* content: "\e010"*/ +/*}*/ + +/*.glyphicon-th:before {*/ +/* content: "\e011"*/ +/*}*/ + +/*.glyphicon-th-list:before {*/ +/* content: "\e012"*/ +/*}*/ + +/*.glyphicon-ok:before {*/ +/* content: "\e013"*/ +/*}*/ + +/*.glyphicon-remove:before {*/ +/* content: "\e014"*/ +/*}*/ + +/*.glyphicon-zoom-in:before {*/ +/* content: "\e015"*/ +/*}*/ + +/*.glyphicon-zoom-out:before {*/ +/* content: "\e016"*/ +/*}*/ + +/*.glyphicon-off:before {*/ +/* content: "\e017"*/ +/*}*/ + +/*.glyphicon-signal:before {*/ +/* content: "\e018"*/ +/*}*/ + +/*.glyphicon-cog:before {*/ +/* content: "\e019"*/ +/*}*/ + +/*.glyphicon-trash:before {*/ +/* content: "\e020"*/ +/*}*/ + +/*.glyphicon-home:before {*/ +/* content: "\e021"*/ +/*}*/ + +.glyphicon-file:before { + content: "\e022" +} + +/*.glyphicon-time:before {*/ +/* content: "\e023"*/ +/*}*/ + +/*.glyphicon-road:before {*/ +/* content: "\e024"*/ +/*}*/ + +/*.glyphicon-download-alt:before {*/ +/* content: "\e025"*/ +/*}*/ + +/*.glyphicon-download:before {*/ +/* content: "\e026"*/ +/*}*/ + +/*.glyphicon-upload:before {*/ +/* content: "\e027"*/ +/*}*/ + +/*.glyphicon-inbox:before {*/ +/* content: "\e028"*/ +/*}*/ + +/*.glyphicon-play-circle:before {*/ +/* content: "\e029"*/ +/*}*/ + +/*.glyphicon-repeat:before {*/ +/* content: "\e030"*/ +/*}*/ + +.glyphicon-refresh:before { + content: "\e031" +} + +/*.glyphicon-list-alt:before {*/ +/* content: "\e032"*/ +/*}*/ + +/*.glyphicon-lock:before {*/ +/* content: "\e033"*/ +/*}*/ + +/*.glyphicon-flag:before {*/ +/* content: "\e034"*/ +/*}*/ + +/*.glyphicon-headphones:before {*/ +/* content: "\e035"*/ +/*}*/ + +/*.glyphicon-volume-off:before {*/ +/* content: "\e036"*/ +/*}*/ + +/*.glyphicon-volume-down:before {*/ +/* content: "\e037"*/ +/*}*/ + +/*.glyphicon-volume-up:before {*/ +/* content: "\e038"*/ +/*}*/ + +/*.glyphicon-qrcode:before {*/ +/* content: "\e039"*/ +/*}*/ + +/*.glyphicon-barcode:before {*/ +/* content: "\e040"*/ +/*}*/ + +/*.glyphicon-tag:before {*/ +/* content: "\e041"*/ +/*}*/ + +/*.glyphicon-tags:before {*/ +/* content: "\e042"*/ +/*}*/ + +/*.glyphicon-book:before {*/ +/* content: "\e043"*/ +/*}*/ + +/*.glyphicon-bookmark:before {*/ +/* content: "\e044"*/ +/*}*/ + +/*.glyphicon-print:before {*/ +/* content: "\e045"*/ +/*}*/ + +/*.glyphicon-camera:before {*/ +/* content: "\e046"*/ +/*}*/ + +/*.glyphicon-font:before {*/ +/* content: "\e047"*/ +/*}*/ + +/*.glyphicon-bold:before {*/ +/* content: "\e048"*/ +/*}*/ + +/*.glyphicon-italic:before {*/ +/* content: "\e049"*/ +/*}*/ + +/*.glyphicon-text-height:before {*/ +/* content: "\e050"*/ +/*}*/ + +/*.glyphicon-text-width:before {*/ +/* content: "\e051"*/ +/*}*/ + +/*.glyphicon-align-left:before {*/ +/* content: "\e052"*/ +/*}*/ + +/*.glyphicon-align-center:before {*/ +/* content: "\e053"*/ +/*}*/ + +/*.glyphicon-align-right:before {*/ +/* content: "\e054"*/ +/*}*/ + +/*.glyphicon-align-justify:before {*/ +/* content: "\e055"*/ +/*}*/ + +/*.glyphicon-list:before {*/ +/* content: "\e056"*/ +/*}*/ + +/*.glyphicon-indent-left:before {*/ +/* content: "\e057"*/ +/*}*/ + +/*.glyphicon-indent-right:before {*/ +/* content: "\e058"*/ +/*}*/ + +/*.glyphicon-facetime-video:before {*/ +/* content: "\e059"*/ +/*}*/ + +/*.glyphicon-picture:before {*/ +/* content: "\e060"*/ +/*}*/ + +/*.glyphicon-map-marker:before {*/ +/* content: "\e062"*/ +/*}*/ + +/*.glyphicon-adjust:before {*/ +/* content: "\e063"*/ +/*}*/ + +/*.glyphicon-tint:before {*/ +/* content: "\e064"*/ +/*}*/ + +/*.glyphicon-edit:before {*/ +/* content: "\e065"*/ +/*}*/ + +/*.glyphicon-share:before {*/ +/* content: "\e066"*/ +/*}*/ + +.glyphicon-check:before { + content: "\e067" +} + +/*.glyphicon-move:before {*/ +/* content: "\e068"*/ +/*}*/ + +/*.glyphicon-step-backward:before {*/ +/* content: "\e069"*/ +/*}*/ + +/*.glyphicon-fast-backward:before {*/ +/* content: "\e070"*/ +/*}*/ + +/*.glyphicon-backward:before {*/ +/* content: "\e071"*/ +/*}*/ + +.glyphicon-play:before { + content: "\e072" +} + +/*.glyphicon-pause:before {*/ +/* content: "\e073"*/ +/*}*/ + +/*.glyphicon-stop:before {*/ +/* content: "\e074"*/ +/*}*/ + +/*.glyphicon-forward:before {*/ +/* content: "\e075"*/ +/*}*/ + +/*.glyphicon-fast-forward:before {*/ +/* content: "\e076"*/ +/*}*/ + +/*.glyphicon-step-forward:before {*/ +/* content: "\e077"*/ +/*}*/ + +/*.glyphicon-eject:before {*/ +/* content: "\e078"*/ +/*}*/ + +/*.glyphicon-chevron-left:before {*/ +/* content: "\e079"*/ +/*}*/ + +/*.glyphicon-chevron-right:before {*/ +/* content: "\e080"*/ +/*}*/ + +/*.glyphicon-plus-sign:before {*/ +/* content: "\e081"*/ +/*}*/ + +/*.glyphicon-minus-sign:before {*/ +/* content: "\e082"*/ +/*}*/ + +/*.glyphicon-remove-sign:before {*/ +/* content: "\e083"*/ +/*}*/ + +/*.glyphicon-ok-sign:before {*/ +/* content: "\e084"*/ +/*}*/ + +/*.glyphicon-question-sign:before {*/ +/* content: "\e085"*/ +/*}*/ + +.glyphicon-info-sign:before { + content: "\e086" +} + +/*.glyphicon-screenshot:before {*/ +/* content: "\e087"*/ +/*}*/ + +.glyphicon-remove-circle:before { + content: "\e088" +} + +/*.glyphicon-ok-circle:before {*/ +/* content: "\e089"*/ +/*}*/ + +/*.glyphicon-ban-circle:before {*/ +/* content: "\e090"*/ +/*}*/ + +/*.glyphicon-arrow-left:before {*/ +/* content: "\e091"*/ +/*}*/ + +.glyphicon-arrow-right:before { + content: "\e092" +} + +/*.glyphicon-arrow-up:before {*/ +/* content: "\e093"*/ +/*}*/ + +/*.glyphicon-arrow-down:before {*/ +/* content: "\e094"*/ +/*}*/ + +/*.glyphicon-share-alt:before {*/ +/* content: "\e095"*/ +/*}*/ + +/*.glyphicon-resize-full:before {*/ +/* content: "\e096"*/ +/*}*/ + +/*.glyphicon-resize-small:before {*/ +/* content: "\e097"*/ +/*}*/ + +/*.glyphicon-exclamation-sign:before {*/ +/* content: "\e101"*/ +/*}*/ + +/*.glyphicon-gift:before {*/ +/* content: "\e102"*/ +/*}*/ + +/*.glyphicon-leaf:before {*/ +/* content: "\e103"*/ +/*}*/ + +/*.glyphicon-fire:before {*/ +/* content: "\e104"*/ +/*}*/ + +/*.glyphicon-eye-open:before {*/ +/* content: "\e105"*/ +/*}*/ + +/*.glyphicon-eye-close:before {*/ +/* content: "\e106"*/ +/*}*/ + +.glyphicon-warning-sign:before { + content: "\e107" +} + +/*.glyphicon-plane:before {*/ +/* content: "\e108"*/ +/*}*/ + +/*.glyphicon-calendar:before {*/ +/* content: "\e109"*/ +/*}*/ + +/*.glyphicon-random:before {*/ +/* content: "\e110"*/ +/*}*/ + +/*.glyphicon-comment:before {*/ +/* content: "\e111"*/ +/*}*/ + +/*.glyphicon-magnet:before {*/ +/* content: "\e112"*/ +/*}*/ + +/*.glyphicon-chevron-up:before {*/ +/* content: "\e113"*/ +/*}*/ + +/*.glyphicon-chevron-down:before {*/ +/* content: "\e114"*/ +/*}*/ + +/*.glyphicon-retweet:before {*/ +/* content: "\e115"*/ +/*}*/ + +/*.glyphicon-shopping-cart:before {*/ +/* content: "\e116"*/ +/*}*/ + +.glyphicon-folder-close:before { + content: "\e117" +} + +.glyphicon-folder-open:before { + content: "\e118" +} + +/*.glyphicon-resize-vertical:before {*/ +/* content: "\e119"*/ +/*}*/ + +/*.glyphicon-resize-horizontal:before {*/ +/* content: "\e120"*/ +/*}*/ + +/*.glyphicon-hdd:before {*/ +/* content: "\e121"*/ +/*}*/ + +/*.glyphicon-bullhorn:before {*/ +/* content: "\e122"*/ +/*}*/ + +/*.glyphicon-bell:before {*/ +/* content: "\e123"*/ +/*}*/ + +/*.glyphicon-certificate:before {*/ +/* content: "\e124"*/ +/*}*/ + +/*.glyphicon-thumbs-up:before {*/ +/* content: "\e125"*/ +/*}*/ + +/*.glyphicon-thumbs-down:before {*/ +/* content: "\e126"*/ +/*}*/ + +/*.glyphicon-hand-right:before {*/ +/* content: "\e127"*/ +/*}*/ + +/*.glyphicon-hand-left:before {*/ +/* content: "\e128"*/ +/*}*/ + +/*.glyphicon-hand-up:before {*/ +/* content: "\e129"*/ +/*}*/ + +/*.glyphicon-hand-down:before {*/ +/* content: "\e130"*/ +/*}*/ + +/*.glyphicon-circle-arrow-right:before {*/ +/* content: "\e131"*/ +/*}*/ + +/*.glyphicon-circle-arrow-left:before {*/ +/* content: "\e132"*/ +/*}*/ + +/*.glyphicon-circle-arrow-up:before {*/ +/* content: "\e133"*/ +/*}*/ + +/*.glyphicon-circle-arrow-down:before {*/ +/* content: "\e134"*/ +/*}*/ + +/*.glyphicon-globe:before {*/ +/* content: "\e135"*/ +/*}*/ + +/*.glyphicon-wrench:before {*/ +/* content: "\e136"*/ +/*}*/ + +/*.glyphicon-tasks:before {*/ +/* content: "\e137"*/ +/*}*/ + +/*.glyphicon-filter:before {*/ +/* content: "\e138"*/ +/*}*/ + +/*.glyphicon-briefcase:before {*/ +/* content: "\e139"*/ +/*}*/ + +/*.glyphicon-fullscreen:before {*/ +/* content: "\e140"*/ +/*}*/ + +/*.glyphicon-dashboard:before {*/ +/* content: "\e141"*/ +/*}*/ + +/*.glyphicon-paperclip:before {*/ +/* content: "\e142"*/ +/*}*/ + +/*.glyphicon-heart-empty:before {*/ +/* content: "\e143"*/ +/*}*/ + +/*.glyphicon-link:before {*/ +/* content: "\e144"*/ +/*}*/ + +/*.glyphicon-phone:before {*/ +/* content: "\e145"*/ +/*}*/ + +/*.glyphicon-pushpin:before {*/ +/* content: "\e146"*/ +/*}*/ + +/*.glyphicon-usd:before {*/ +/* content: "\e148"*/ +/*}*/ + +/*.glyphicon-gbp:before {*/ +/* content: "\e149"*/ +/*}*/ + +/*.glyphicon-sort:before {*/ +/* content: "\e150"*/ +/*}*/ + +/*.glyphicon-sort-by-alphabet:before {*/ +/* content: "\e151"*/ +/*}*/ + +/*.glyphicon-sort-by-alphabet-alt:before {*/ +/* content: "\e152"*/ +/*}*/ + +/*.glyphicon-sort-by-order:before {*/ +/* content: "\e153"*/ +/*}*/ + +/*.glyphicon-sort-by-order-alt:before {*/ +/* content: "\e154"*/ +/*}*/ + +/*.glyphicon-sort-by-attributes:before {*/ +/* content: "\e155"*/ +/*}*/ + +/*.glyphicon-sort-by-attributes-alt:before {*/ +/* content: "\e156"*/ +/*}*/ + +.glyphicon-unchecked:before { + content: "\e157" +} + +.glyphicon-expand:before { + content: "\e158" +} + +/*.glyphicon-collapse-down:before {*/ +/* content: "\e159"*/ +/*}*/ + +/*.glyphicon-collapse-up:before {*/ +/* content: "\e160"*/ +/*}*/ + +/*.glyphicon-log-in:before {*/ +/* content: "\e161"*/ +/*}*/ + +/*.glyphicon-flash:before {*/ +/* content: "\e162"*/ +/*}*/ + +/*.glyphicon-log-out:before {*/ +/* content: "\e163"*/ +/*}*/ + +/*.glyphicon-new-window:before {*/ +/* content: "\e164"*/ +/*}*/ + +/*.glyphicon-record:before {*/ +/* content: "\e165"*/ +/*}*/ + +/*.glyphicon-save:before {*/ +/* content: "\e166"*/ +/*}*/ + +/*.glyphicon-open:before {*/ +/* content: "\e167"*/ +/*}*/ + +/*.glyphicon-saved:before {*/ +/* content: "\e168"*/ +/*}*/ + +/*.glyphicon-import:before {*/ +/* content: "\e169"*/ +/*}*/ + +/*.glyphicon-export:before {*/ +/* content: "\e170"*/ +/*}*/ + +/*.glyphicon-send:before {*/ +/* content: "\e171"*/ +/*}*/ + +/*.glyphicon-floppy-disk:before {*/ +/* content: "\e172"*/ +/*}*/ + +/*.glyphicon-floppy-saved:before {*/ +/* content: "\e173"*/ +/*}*/ + +/*.glyphicon-floppy-remove:before {*/ +/* content: "\e174"*/ +/*}*/ + +/*.glyphicon-floppy-save:before {*/ +/* content: "\e175"*/ +/*}*/ + +/*.glyphicon-floppy-open:before {*/ +/* content: "\e176"*/ +/*}*/ + +/*.glyphicon-credit-card:before {*/ +/* content: "\e177"*/ +/*}*/ + +/*.glyphicon-transfer:before {*/ +/* content: "\e178"*/ +/*}*/ + +/*.glyphicon-cutlery:before {*/ +/* content: "\e179"*/ +/*}*/ + +/*.glyphicon-header:before {*/ +/* content: "\e180"*/ +/*}*/ + +/*.glyphicon-compressed:before {*/ +/* content: "\e181"*/ +/*}*/ + +/*.glyphicon-earphone:before {*/ +/* content: "\e182"*/ +/*}*/ + +/*.glyphicon-phone-alt:before {*/ +/* content: "\e183"*/ +/*}*/ + +/*.glyphicon-tower:before {*/ +/* content: "\e184"*/ +/*}*/ + +/*.glyphicon-stats:before {*/ +/* content: "\e185"*/ +/*}*/ + +/*.glyphicon-sd-video:before {*/ +/* content: "\e186"*/ +/*}*/ + +/*.glyphicon-hd-video:before {*/ +/* content: "\e187"*/ +/*}*/ + +/*.glyphicon-subtitles:before {*/ +/* content: "\e188"*/ +/*}*/ + +/*.glyphicon-sound-stereo:before {*/ +/* content: "\e189"*/ +/*}*/ + +/*.glyphicon-sound-dolby:before {*/ +/* content: "\e190"*/ +/*}*/ + +/*.glyphicon-sound-5-1:before {*/ +/* content: "\e191"*/ +/*}*/ + +/*.glyphicon-sound-6-1:before {*/ +/* content: "\e192"*/ +/*}*/ + +/*.glyphicon-sound-7-1:before {*/ +/* content: "\e193"*/ +/*}*/ + +/*.glyphicon-copyright-mark:before {*/ +/* content: "\e194"*/ +/*}*/ + +/*.glyphicon-registration-mark:before {*/ +/* content: "\e195"*/ +/*}*/ + +/*.glyphicon-cloud-download:before {*/ +/* content: "\e197"*/ +/*}*/ + +/*.glyphicon-cloud-upload:before {*/ +/* content: "\e198"*/ +/*}*/ + +/*.glyphicon-tree-conifer:before {*/ +/* content: "\e199"*/ +/*}*/ + +/*.glyphicon-tree-deciduous:before {*/ +/* content: "\e200"*/ +/*}*/ + +/*.glyphicon-cd:before {*/ +/* content: "\e201"*/ +/*}*/ + +/*.glyphicon-save-file:before {*/ +/* content: "\e202"*/ +/*}*/ + +/*.glyphicon-open-file:before {*/ +/* content: "\e203"*/ +/*}*/ + +/*.glyphicon-level-up:before {*/ +/* content: "\e204"*/ +/*}*/ + +/*.glyphicon-copy:before {*/ +/* content: "\e205"*/ +/*}*/ + +/*.glyphicon-paste:before {*/ +/* content: "\e206"*/ +/*}*/ + +/*.glyphicon-alert:before {*/ +/* content: "\e209"*/ +/*}*/ + +/*.glyphicon-equalizer:before {*/ +/* content: "\e210"*/ +/*}*/ + +/*.glyphicon-king:before {*/ +/* content: "\e211"*/ +/*}*/ + +/*.glyphicon-queen:before {*/ +/* content: "\e212"*/ +/*}*/ + +/*.glyphicon-pawn:before {*/ +/* content: "\e213"*/ +/*}*/ + +/*.glyphicon-bishop:before {*/ +/* content: "\e214"*/ +/*}*/ + +/*.glyphicon-knight:before {*/ +/* content: "\e215"*/ +/*}*/ + +/*.glyphicon-baby-formula:before {*/ +/* content: "\e216"*/ +/*}*/ + +/*.glyphicon-tent:before {*/ +/* content: "\26fa"*/ +/*}*/ + +/*.glyphicon-blackboard:before {*/ +/* content: "\e218"*/ +/*}*/ + +/*.glyphicon-bed:before {*/ +/* content: "\e219"*/ +/*}*/ + +/*.glyphicon-apple:before {*/ +/* content: "\f8ff"*/ +/*}*/ + +/*.glyphicon-erase:before {*/ +/* content: "\e221"*/ +/*}*/ + +/*.glyphicon-hourglass:before {*/ +/* content: "\231b"*/ +/*}*/ + +/*.glyphicon-lamp:before {*/ +/* content: "\e223"*/ +/*}*/ + +/*.glyphicon-duplicate:before {*/ +/* content: "\e224"*/ +/*}*/ + +/*.glyphicon-piggy-bank:before {*/ +/* content: "\e225"*/ +/*}*/ + +/*.glyphicon-scissors:before {*/ +/* content: "\e226"*/ +/*}*/ + +/*.glyphicon-bitcoin:before {*/ +/* content: "\e227"*/ +/*}*/ + +/*.glyphicon-btc:before {*/ +/* content: "\e227"*/ +/*}*/ + +/*.glyphicon-xbt:before {*/ +/* content: "\e227"*/ +/*}*/ + +/*.glyphicon-yen:before {*/ +/* content: "\00a5"*/ +/*}*/ + +/*.glyphicon-jpy:before {*/ +/* content: "\00a5"*/ +/*}*/ + +/*.glyphicon-ruble:before {*/ +/* content: "\20bd"*/ +/*}*/ + +/*.glyphicon-rub:before {*/ +/* content: "\20bd"*/ +/*}*/ + +/*.glyphicon-scale:before {*/ +/* content: "\e230"*/ +/*}*/ + +/*.glyphicon-ice-lolly:before {*/ +/* content: "\e231"*/ +/*}*/ + +/*.glyphicon-ice-lolly-tasted:before {*/ +/* content: "\e232"*/ +/*}*/ + +/*.glyphicon-education:before {*/ +/* content: "\e233"*/ +/*}*/ + +/*.glyphicon-option-horizontal:before {*/ +/* content: "\e234"*/ +/*}*/ + +/*.glyphicon-option-vertical:before {*/ +/* content: "\e235"*/ +/*}*/ + +/*.glyphicon-menu-hamburger:before {*/ +/* content: "\e236"*/ +/*}*/ + +/*.glyphicon-modal-window:before {*/ +/* content: "\e237"*/ +/*}*/ + +/*.glyphicon-oil:before {*/ +/* content: "\e238"*/ +/*}*/ + +/*.glyphicon-grain:before {*/ +/* content: "\e239"*/ +/*}*/ + +/*.glyphicon-sunglasses:before {*/ +/* content: "\e240"*/ +/*}*/ + +/*.glyphicon-text-size:before {*/ +/* content: "\e241"*/ +/*}*/ + +/*.glyphicon-text-color:before {*/ +/* content: "\e242"*/ +/*}*/ + +/*.glyphicon-text-background:before {*/ +/* content: "\e243"*/ +/*}*/ + +/*.glyphicon-object-align-top:before {*/ +/* content: "\e244"*/ +/*}*/ + +/*.glyphicon-object-align-bottom:before {*/ +/* content: "\e245"*/ +/*}*/ + +/*.glyphicon-object-align-horizontal:before {*/ +/* content: "\e246"*/ +/*}*/ + +/*.glyphicon-object-align-left:before {*/ +/* content: "\e247"*/ +/*}*/ + +/*.glyphicon-object-align-vertical:before {*/ +/* content: "\e248"*/ +/*}*/ + +/*.glyphicon-object-align-right:before {*/ +/* content: "\e249"*/ +/*}*/ + +/*.glyphicon-triangle-right:before {*/ +/* content: "\e250"*/ +/*}*/ + +/*.glyphicon-triangle-left:before {*/ +/* content: "\e251"*/ +/*}*/ + +/*.glyphicon-triangle-bottom:before {*/ +/* content: "\e252"*/ +/*}*/ + +/*.glyphicon-triangle-top:before {*/ +/* content: "\e253"*/ +/*}*/ + +/*.glyphicon-console:before {*/ +/* content: "\e254"*/ +/*}*/ + +/*.glyphicon-superscript:before {*/ +/* content: "\e255"*/ +/*}*/ + +/*.glyphicon-subscript:before {*/ +/* content: "\e256"*/ +/*}*/ + +/*.glyphicon-menu-left:before {*/ +/* content: "\e257"*/ +/*}*/ + +.glyphicon-menu-right:before { + content: "\e258" +} + +.glyphicon-menu-down:before { + content: "\e259" +} + +/*.glyphicon-menu-up:before {*/ +/* content: "\e260"*/ +/*}*/ diff --git a/plugins/55/indexmenu/scripts/fancytree/skin-bootstrap/skin-common.less b/plugins/55/indexmenu/scripts/fancytree/skin-bootstrap/skin-common.less new file mode 100644 index 0000000..fc0da50 --- /dev/null +++ b/plugins/55/indexmenu/scripts/fancytree/skin-bootstrap/skin-common.less @@ -0,0 +1,972 @@ +/******************************************************************************* + * Common Styles for Fancytree Skins. + * + * This section is automatically generated from the `skin-common.less` template. + * + * Copyright (c) 2008-2023, Martin Wendt (https://wwWendt.de) + * Released under the MIT license + * https://github.com/mar10/fancytree/wiki/LicenseInfo + * + * @version 2.38.3 + * @date 2023-02-01T20:52:50Z +******************************************************************************/ + +// Variables (defaults, may be overwritten by the including .less files) +@fancy-use-sprites: true; // false: suppress all background images (i.e. icons) +// @fancy-hide-connectors: true; // false: show vertical connector lines + +@fancy-level-indent: 16px; +@fancy-line-height: 16px; // height of a nodes selection bar including borders +@fancy-node-v-spacing: 1px; // gap between two node borders +@fancy-icon-width: 16px; +@fancy-icon-height: 16px; +@fancy-icon-spacing: 3px; // margin between icon/icon or icon/title +@fancy-icon-ofs-top: 0px; // extra vertical offset for expander, checkbox and icon +@fancy-title-ofs-top: 0px; // extra vertical offset for title +@fancy-node-border-width: 1px; +@fancy-node-border-radius: 0px; +@fancy-node-outline-width: 1px; + +// @fancy-line-ofs-top: (@fancy-line-height - @fancy-icon-height) / 2; + +// webpack uses /dist/skin-common.less as root path +// grunt-less uses /dist/skin-Xxx/ui.fancyree.less as root path +// So we define our theme LESS files for webpack compatibility, i.e. +// define the image path n every main LESS file instead of here. +// Prefix may be set to "", "/", "./", or any other value +// Note: this variable must be defined by the main LESS files: +// @fancy-image-prefix: ""; + +// Use 'url(...)' to link to the throbber image, or +// use data-uri(...)' to inline the data in css instead: +/* CHANGE use url, as less does not handel data-uri() correct. DokuWiki can eventually inline it */ + @fancy-loading-url: url("@{fancy-image-prefix}loading.gif"); +//@fancy-loading-url: data-uri("@{fancy-image-prefix}loading.gif"); + +// Set to `true` to use `data-uri(...)` instead of a `url(...)` link: +@fancy-inline-sprites: false; // data-uri() is not handle correct by phpless + +@fancy-font-size: 10pt; +@fancy-font-family: tahoma, arial, helvetica; +@fancy-font-color: black; +@fancy-font-color-dimm: #c0c0c0; +@fancy-font-error-color: red; + +//------------------------------------------------------------------------------ +// Mixins +//------------------------------------------------------------------------------ +.setBgPos(@x, @y, @cond:true) when (@cond) { + background-position: (@x * -@fancy-icon-width) (@y * -@fancy-icon-height); +} +.clearBgImage(@cond:true) when (@cond) { + background-image: none; +} +.setBgImageUrl(@url) when (@fancy-use-sprites) and not (@fancy-inline-sprites) { + background-image: url("@{fancy-image-prefix}@{url}"); +} +.setBgImageUrl(@url) when (@fancy-use-sprites) and (@fancy-inline-sprites) { + background-image: data-uri("@{fancy-image-prefix}@{url}"); +} +.useSprite(@x, @y) when (@fancy-use-sprites) { + .setBgPos(@x, @y); +} +.rounded-corners(@radius) { + -webkit-border-radius: @radius; + -moz-border-radius: @radius; + -ms-border-radius: @radius; + -o-border-radius: @radius; + border-radius: @radius; +} +.spanStyleMixin(@color, @bgcolor, @bordercolor) { + border-color: @bordercolor; + background: @bgcolor; + color: @color; +} +.spanStyleMixin(@color, @bgcolor, @bordercolor, @startColor, @stopColor) { + .spanStyleMixin(@color, @bgcolor, @bordercolor); + // @c-start: argb(@startColor); + // @c-end: argb(@stopColor); + background: -moz-linear-gradient( + top, + @startColor 0%, + @stopColor 100% + ); // FF3.6+ + background: -webkit-gradient( + linear, + left top, + left bottom, + color-stop(0%, @startColor), + color-stop(100%, @stopColor) + ); // Chrome,Safari4+ + background: -webkit-linear-gradient( + top, + @startColor 0%, + @stopColor 100% + ); // Chrome10+,Safari5.1+ + background: -o-linear-gradient( + top, + @startColor 0%, + @stopColor 100% + ); // Opera 11.10+ + background: -ms-linear-gradient( + top, + @startColor 0%, + @stopColor 100% + ); // IE10+ + background: linear-gradient( + to bottom, + @startColor 0%, + @stopColor 100% + ); // W3C + filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='@{startColor}', endColorstr='@{stopColor}',GradientType=0 ); // IE6-9 +} + +/*------------------------------------------------------------------------------ + * Helpers + *----------------------------------------------------------------------------*/ +// Redefine, in case jQuery-UI is not included +// .ui-helper-hidden, +.fancytree-helper-hidden { + display: none; +} +.fancytree-helper-indeterminate-cb { + // tri-state checkbox + color: #777; +} +.fancytree-helper-disabled { + color: @fancy-font-color-dimm; +} + +/* Helper to allow spinning loader icon with glyph-, ligature-, and SVG-icons. */ +/* CHANGE: renamed spin to spin-fancytree */ +.fancytree-helper-spin { + -webkit-animation: spin-fancytree 1000ms infinite linear; + animation: spin-fancytree 1000ms infinite linear; +} +/* CHANGE: commented because it is wrong prefixed by phpless +@-webkit-keyframes spin { + 0% { + -webkit-transform: rotate(0deg); + transform: rotate(0deg); + } + 100% { + -webkit-transform: rotate(359deg); + transform: rotate(359deg); + } +} +@keyframes spin { + 0% { + -webkit-transform: rotate(0deg); + transform: rotate(0deg); + } + 100% { + -webkit-transform: rotate(359deg); + transform: rotate(359deg); + } +} +*/ +/*------------------------------------------------------------------------------ + * Container and UL / LI + *----------------------------------------------------------------------------*/ + +ul.fancytree-container { + font-family: @fancy-font-family; + font-size: @fancy-font-size; + white-space: nowrap; + padding: 3px; + margin: 0; // DT issue 201 + //background-color: white; CHANGE + //border: 1px dotted gray; CHANGE + // overflow: auto; // ext-dnd5: otherwise this is always the scroll parent + // height: 100%; // DT issue 263, 470 + min-height: 0%; // #192 + position: relative; // #235 + ul { + padding: 0 0 0 @fancy-level-indent; + margin: 0; + } + ul > li:before { + // #538 + content: none; + } + li { + list-style-image: none; + list-style-position: outside; + list-style-type: none; + -moz-background-clip: border; + -moz-background-inline-policy: continuous; + -moz-background-origin: padding; + background-attachment: scroll; + background-color: transparent; + .setBgPos(0, 0); + background-repeat: repeat-y; + background-image: none; // no v-lines + + margin: 0; + // padding: 1px 0 0 0; // issue #246 + } + // Suppress lines for last child node + li.fancytree-lastsib { + background-image: none; + } +} + +// Style, when control is disabled +.ui-fancytree-disabled ul.fancytree-container { + opacity: 0.5; + // filter: alpha(opacity=50); // Yields a css warning + background-color: silver; +} + +ul.fancytree-connectors.fancytree-container { + li { + // Use 'data-uri(...)' to embed the image into CSS instead of linking to 'loading.gif': + /* CHANGE: phpless does not handle data-uri() correct */ + //background-image: data-uri("@{fancy-image-prefix}vline.gif"); + background-image: url("@{fancy-image-prefix}vline.gif"); + background-position: 0 0; + } +} + +// Suppress lines for last child node +ul.fancytree-container li.fancytree-lastsib, +// Suppress lines if level is fixed expanded (option minExpandLevel) +ul.fancytree-no-connector > li { + background-image: none; +} + +// Fix jQuery UI 'blind' animation for jQuery UI (#717) +li.fancytree-animating { + position: relative; +} + +/*------------------------------------------------------------------------------ + * Common icon definitions + *----------------------------------------------------------------------------*/ + +span.fancytree-empty, +span.fancytree-vline, +span.fancytree-expander, +span.fancytree-icon, +span.fancytree-checkbox, +// span.fancytree-radio, +span.fancytree-drag-helper-img, +#fancytree-drop-marker { + width: @fancy-icon-width; + height: @fancy-icon-height; + // display: -moz-inline-box; // @ FF 1+2 removed for issue 221 + // -moz-box-align: start; /* issue 221 */ + display: inline-block; // Required to make a span sizeable + vertical-align: top; + background-repeat: no-repeat; + // background-position: left; + .setBgImageUrl("icons.gif"); + .setBgPos(0, 0); +} +span.fancytree-icon, +span.fancytree-checkbox, +span.fancytree-expander, +// span.fancytree-radio, +span.fancytree-custom-icon { + margin-top: @fancy-icon-ofs-top; +} +/* Used by icon option: */ +span.fancytree-custom-icon { + width: @fancy-icon-width; + height: @fancy-icon-height; + display: inline-block; + margin-left: @fancy-icon-spacing; + .setBgPos(0, 0); +} +/* Used by 'icon' node option: */ +img.fancytree-icon { + width: @fancy-icon-width; + height: @fancy-icon-height; + margin-left: @fancy-icon-spacing; + margin-top: @fancy-icon-ofs-top; + vertical-align: top; + border-style: none; +} + +/*------------------------------------------------------------------------------ + * Expander icon + * + * Note: IE6 doesn't correctly evaluate multiples class names, + * so we create combined class names that can be used in the CSS. + * + * Prefix: fancytree-exp- + * 1st character: 'e': expanded, 'c': collapsed, 'n': no children + * 2nd character (optional): 'd': lazy (Delayed) + * 3rd character (optional): 'l': Last sibling + *----------------------------------------------------------------------------*/ + +span.fancytree-expander { + // .useSprite(0, 5); + cursor: pointer; +} +// span.fancytree-expander:hover { +// // .useSprite(1, 5); +// } + +// --- End nodes (use connectors instead of expanders) + +.fancytree-exp-n span.fancytree-expander, +.fancytree-exp-nl span.fancytree-expander { + // .clearBgImage( @fancy-hide-connectors ); + background-image: none; + cursor: default; +} +.fancytree-connectors { + .fancytree-exp-n span.fancytree-expander, + .fancytree-exp-nl span.fancytree-expander { + .setBgImageUrl("icons.gif"); + margin-top: 0; + } + .fancytree-exp-n span.fancytree-expander, // End-node, not last sibling + .fancytree-exp-n span.fancytree-expander:hover { + .useSprite(0, 4); + } + .fancytree-exp-nl span.fancytree-expander, // End-node, last sibling + .fancytree-exp-nl span.fancytree-expander:hover { + .useSprite(1, 4); + } +} + +// --- Collapsed + +.fancytree-exp-c span.fancytree-expander { + // Collapsed, not delayed, not last sibling + .useSprite(0, 5); +} +.fancytree-exp-c span.fancytree-expander:hover { + .useSprite(1, 5); +} +.fancytree-exp-cl span.fancytree-expander { + // Collapsed, not delayed, last sibling + .useSprite(0, 6); +} +.fancytree-exp-cl span.fancytree-expander:hover { + .useSprite(1, 6); +} +.fancytree-exp-cd span.fancytree-expander { + // Collapsed, delayed, not last sibling + .useSprite(4, 5); +} +.fancytree-exp-cd span.fancytree-expander:hover { + .useSprite(5, 5); +} +.fancytree-exp-cdl span.fancytree-expander { + // Collapsed, delayed, last sibling + .useSprite(4, 6); +} +.fancytree-exp-cdl span.fancytree-expander:hover { + .useSprite(5, 6); +} + +// --- Expanded + +.fancytree-exp-e span.fancytree-expander, // Expanded, not delayed, not last sibling +.fancytree-exp-ed span.fancytree-expander { + // Expanded, delayed, not last sibling + .useSprite(2, 5); +} +.fancytree-exp-e span.fancytree-expander:hover, +.fancytree-exp-ed span.fancytree-expander:hover { + .useSprite(3, 5); +} +.fancytree-exp-el span.fancytree-expander, // Expanded, not delayed, last sibling +.fancytree-exp-edl span.fancytree-expander { + // Expanded, delayed, last sibling + .useSprite(2, 6); +} +.fancytree-exp-el span.fancytree-expander:hover, +.fancytree-exp-edl span.fancytree-expander:hover { + .useSprite(3, 6); +} + +/* Fade out expanders, when container is not hovered or active */ +.fancytree-fade-expander { + span.fancytree-expander { + transition: opacity 1.5s; + opacity: 0; + } + &:hover span.fancytree-expander, + &.fancytree-treefocus span.fancytree-expander, + .fancytree-treefocus span.fancytree-expander, + [class*="fancytree-statusnode-"] span.fancytree-expander { + transition: opacity 0.6s; + opacity: 1; + } +} + +//// CHANGE: not used. +///*------------------------------------------------------------------------------ +// * Checkbox icon +// *----------------------------------------------------------------------------*/ +// +//span.fancytree-checkbox { +// margin-left: @fancy-icon-spacing; +// .useSprite(0, 2); +// &:hover { +// .useSprite(1, 2); +// } +// &.fancytree-radio { +// .useSprite(0, 3); +// } +// &.fancytree-radio:hover { +// .useSprite(1, 3); +// } +//} +//.fancytree-partsel span.fancytree-checkbox { +// .useSprite(4, 2); +// &:hover { +// .useSprite(5, 2); +// } +// &.fancytree-radio { +// .useSprite(4, 3); +// } +// &.fancytree-radio:hover { +// .useSprite(5, 3); +// } +//} +//// selected after partsel, so it takes precedence: +//.fancytree-selected span.fancytree-checkbox { +// .useSprite(2, 2); +// &:hover { +// .useSprite(3, 2); +// } +// &.fancytree-radio { +// .useSprite(2, 3); +// } +// &.fancytree-radio:hover { +// .useSprite(3, 3); +// } +//} +//// Unselectable is dimmed, without hover effects +//.fancytree-unselectable { +// span.fancytree-checkbox { +// opacity: 0.4; +// filter: alpha(opacity=40); +// } +// span.fancytree-checkbox:hover { +// .useSprite(0, 2); +// } +// span.fancytree-checkbox.fancytree-radio:hover { +// .useSprite(0, 3); +// } +// &.fancytree-partsel span.fancytree-checkbox:hover { +// .useSprite(4, 2); +// } +// &.fancytree-selected span.fancytree-checkbox:hover { +// .useSprite(2, 2); +// } +// &.fancytree-selected span.fancytree-checkbox.fancytree-radio:hover { +// .useSprite(2, 3); +// } +//} +// +//// Auto-hide checkboxes unless selected or hovered +//.fancytree-container.fancytree-checkbox-auto-hide { +// span.fancytree-checkbox { +// visibility: hidden; +// } +// .fancytree-node:hover span.fancytree-checkbox, +// tr:hover td span.fancytree-checkbox, +// .fancytree-node.fancytree-selected span.fancytree-checkbox, +// tr.fancytree-selected td span.fancytree-checkbox { +// visibility: unset; +// } +// &.fancytree-treefocus { +// .fancytree-node.fancytree-active span.fancytree-checkbox, +// tr.fancytree-active td span.fancytree-checkbox { +// visibility: unset; +// } +// } +//} + +/*------------------------------------------------------------------------------ + * Node type icon + * Note: IE6 doesn't correctly evaluate multiples class names, + * so we create combined class names that can be used in the CSS. + * + * Prefix: fancytree-ico- + * 1st character: 'e': expanded, 'c': collapsed + * 2nd character (optional): 'f': folder + *----------------------------------------------------------------------------*/ + +span.fancytree-icon { + // Default icon + margin-left: @fancy-icon-spacing; + .useSprite(0, 0); +} + +/* Documents */ +.fancytree-ico-c span.fancytree-icon { + // Collapsed folder (empty) + // .useSprite(0, 0); +} +.fancytree-ico-c span.fancytree-icon:hover { + .useSprite(1, 0); +} +.fancytree-has-children.fancytree-ico-c span.fancytree-icon { + // Collapsed folder (not empty) + .useSprite(2, 0); +} +.fancytree-has-children.fancytree-ico-c span.fancytree-icon:hover { + .useSprite(3, 0); +} +.fancytree-ico-e span.fancytree-icon { + // Expanded folder + .useSprite(4, 0); +} +.fancytree-ico-e span.fancytree-icon:hover { + .useSprite(5, 0); +} + +/* Folders */ +.fancytree-ico-cf span.fancytree-icon { + // Collapsed folder (empty) + .useSprite(0, 1); +} +.fancytree-ico-cf span.fancytree-icon:hover { + .useSprite(1, 1); +} +.fancytree-has-children.fancytree-ico-cf span.fancytree-icon { + // Collapsed folder (not empty) + .useSprite(2, 1); +} +.fancytree-has-children.fancytree-ico-cf span.fancytree-icon:hover { + .useSprite(3, 1); +} +.fancytree-ico-ef span.fancytree-icon { + // Expanded folder + .useSprite(4, 1); +} +.fancytree-ico-ef span.fancytree-icon:hover { + .useSprite(5, 1); +} + +// 'Loading' status overrides all others +.fancytree-loading span.fancytree-expander, +.fancytree-loading span.fancytree-expander:hover, +.fancytree-statusnode-loading span.fancytree-icon, +.fancytree-statusnode-loading span.fancytree-icon:hover, +span.fancytree-icon.fancytree-icon-loading { + background-image: @fancy-loading-url; + .useSprite(0, 0); +} + +/* Status node icons */ + +.fancytree-statusnode-error span.fancytree-icon, +.fancytree-statusnode-error span.fancytree-icon:hover { + .useSprite(0, 7); +} + +/*------------------------------------------------------------------------------ + * Node titles and highlighting + *----------------------------------------------------------------------------*/ + +span.fancytree-node { + /* See #117 */ + display: inherit; // #117, resolves to 'display: list-item;' for standard trees + width: 100%; + margin-top: @fancy-node-v-spacing; + min-height: @fancy-line-height; +} +span.fancytree-title { + color: @fancy-font-color; // inherit doesn't work on IE + cursor: pointer; + display: inline-block; // Better alignment, when title contains <br> + vertical-align: top; + min-height: @fancy-line-height; + padding: 0 3px 0 3px; // Otherwise italic font will be outside right bounds + margin: @fancy-title-ofs-top 0 0 @fancy-icon-spacing; + // margin: 0px; + // margin-top: @fancy-line-ofs-top; + // margin-left: @fancy-icon-spacing; + border: @fancy-node-border-width solid transparent; // avoid jumping, when a border is added on hover + .rounded-corners(@fancy-node-border-radius); + // outline: 0; // @ Firefox, prevent dotted border after click + // Set transparent border to prevent jumping when active node gets a border + // (we can do this, because this theme doesn't use vertical lines) + // border: 1px solid white; // Note: 'transparent' would not work in IE6 +} +span.fancytree-node.fancytree-error span.fancytree-title { + color: @fancy-font-error-color; +} + +//// CHANGE: not used. +///*------------------------------------------------------------------------------ +// * Drag'n'drop support +// *----------------------------------------------------------------------------*/ +///* ext-dnd5: */ +//span.fancytree-childcounter { +// color: #fff; +// background: #337ab7; // bootstrap blue +// border: 1px solid gray; +// border-radius: 10px; +// padding: 2px; +// text-align: center; +//} +// +///* ext-dnd: */ +//div.fancytree-drag-helper { +// span.fancytree-childcounter, +// span.fancytree-dnd-modifier { +// display: inline-block; +// color: #fff; +// background: #337ab7; // bootstrap blue +// border: 1px solid gray; +// min-width: 10px; +// // min-height: 16px; +// height: 10px; +// line-height: 1; +// vertical-align: baseline; +// border-radius: 10px; +// padding: 2px; +// text-align: center; +// font-size: 9px; +// } +// span.fancytree-childcounter { +// position: absolute; +// // left: 16px; +// top: -6px; +// right: -6px; +// } +// span.fancytree-dnd-modifier { +// background: #5cb85c; // bootstrap green +// border: none; +// // min-height: 16px; +// // font-size: 12px; +// font-weight: bolder; +// } +// &.fancytree-drop-accept { +// span.fancytree-drag-helper-img { +// .useSprite(2, 7); +// } +// } +// &.fancytree-drop-reject { +// span.fancytree-drag-helper-img { +// .useSprite(1, 7); +// } +// } +//} +// +///*** Drop marker icon *********************************************************/ +//#fancytree-drop-marker { +// width: 2 * @fancy-icon-width; // was 24px, but 32 should be correct +// position: absolute; +// .useSprite(0, 8); +// margin: 0; +// &.fancytree-drop-after, +// &.fancytree-drop-before { +// width: 4 * @fancy-icon-width; // 64px; +// .useSprite(0, 9); +// } +// &.fancytree-drop-copy { +// .useSprite(4, 8); +// } +// &.fancytree-drop-move { +// .useSprite(2, 8); +// } +//} +// +///*** Source node while dragging ***********************************************/ +// +//span.fancytree-drag-source { +// &.fancytree-drag-remove { +// // text-decoration: line-through; +// opacity: 0.15; +// } +//} +// +///*** Target node while dragging cursor is over it *****************************/ +// +//span.fancytree-drop-target { +// &.fancytree-drop-accept { +// // outline: 1px dotted #5cb85c; // bootstrap sucess +// } +//} +//span.fancytree-drop-reject { +// // outline: 1px dotted #d9534f; // boostrap warning +//} + +/*------------------------------------------------------------------------------ + * 'rtl' option + *----------------------------------------------------------------------------*/ + +.fancytree-container.fancytree-rtl { + .fancytree-title { + /*unicode-bidi: bidi-override;*/ /* optional: reverse title letters */ + } + span.fancytree-connector, + span.fancytree-expander, + span.fancytree-icon, + span.fancytree-drag-helper-img { + .setBgImageUrl("icons-rtl.gif"); + } + .fancytree-exp-n span.fancytree-expander, + .fancytree-exp-nl span.fancytree-expander { + background-image: none; + } + &.fancytree-connectors .fancytree-exp-n span.fancytree-expander, + &.fancytree-connectors .fancytree-exp-nl span.fancytree-expander { + .setBgImageUrl("icons-rtl.gif"); + } +} +ul.fancytree-container.fancytree-rtl { + ul { + padding: 0 16px 0 0; + } + &.fancytree-connectors li { + background-position: right 0; + background-image: url("@{fancy-image-prefix}vline-rtl.gif"); + } + // Suppress lines for last child node + li.fancytree-lastsib, + // Suppress lines if level is fixed expanded (option minExpandLevel) + &.fancytree-no-connector > li { + background-image: none; + } +} +#fancytree-drop-marker.fancytree-rtl { + .setBgImageUrl("icons-rtl.gif"); +} + +//// CHANGE: not used. +///*------------------------------------------------------------------------------ +// * 'table' extension +// *----------------------------------------------------------------------------*/ +// +//table.fancytree-ext-table { +// font-family: @fancy-font-family; +// font-size: @fancy-font-size; +// border-collapse: collapse; +// span.fancytree-node { +// display: inline-block; // #117 +// box-sizing: border-box; // #562 +// } +// td.fancytree-status-merged { +// text-align: center; +// // font-weight: bold; +// font-style: italic; +// // line-height: 100px; +// color: @fancy-font-color-dimm; +// } +// tr.fancytree-statusnode-error td.fancytree-status-merged { +// color: @fancy-font-error-color; +// } +// /* ext-ariagrid */ +// &.fancytree-ext-ariagrid.fancytree-cell-mode { +// > tbody > tr.fancytree-active > td { +// background-color: #eee; +// } +// > tbody > tr > td.fancytree-active-cell { +// background-color: #cbe8f6; +// } +// &.fancytree-cell-nav-mode > tbody > tr > td.fancytree-active-cell { +// background-color: #3875d7; +// } +// } +//} +// +///*------------------------------------------------------------------------------ +// * 'columnview' extension +// *----------------------------------------------------------------------------*/ +// +//table.fancytree-ext-columnview { +// // border-collapse: collapse; +// // width: 100%; +// tbody tr td { +// position: relative; +// border: 1px solid gray; +// vertical-align: top; +// overflow: auto; +// > ul { +// padding: 0; +// li { +// list-style-image: none; +// list-style-position: outside; +// list-style-type: none; +// -moz-background-clip: border; +// -moz-background-inline-policy: continuous; +// -moz-background-origin: padding; +// background-attachment: scroll; +// background-color: transparent; +// .setBgPos(0, 0); +// background-repeat: repeat-y; +// background-image: none; /* no v-lines */ +// +// margin: 0; +// // padding: 1px 0 0 0; // issue #246 +// } +// } +// } +// span.fancytree-node { +// position: relative; /* allow positioning of embedded spans */ +// display: inline-block; // #117 +// } +// span.fancytree-node.fancytree-expanded { +// background-color: #e0e0e0; +// } +// span.fancytree-node.fancytree-active { +// background-color: #cbe8f6; +// // background-color: royalblue; +// } +// .fancytree-has-children span.fancytree-cv-right { +// position: absolute; +// right: 3px; +// .useSprite(0, 5); +// &:hover { +// .useSprite(1, 5); +// } +// } +//} +// +///*------------------------------------------------------------------------------ +// * 'filter' extension +// *----------------------------------------------------------------------------*/ +// +//.fancytree-ext-filter-dimm { +// span.fancytree-node span.fancytree-title { +// color: @fancy-font-color-dimm; +// font-weight: lighter; +// } +// tr.fancytree-submatch span.fancytree-title, +// span.fancytree-node.fancytree-submatch span.fancytree-title { +// color: black; +// font-weight: normal; +// } +// tr.fancytree-match span.fancytree-title, +// span.fancytree-node.fancytree-match span.fancytree-title { +// color: black; +// font-weight: bold; +// } +//} +//.fancytree-ext-filter-hide { +// tr.fancytree-hide, +// span.fancytree-node.fancytree-hide { +// display: none; +// } +// tr.fancytree-submatch span.fancytree-title, +// span.fancytree-node.fancytree-submatch span.fancytree-title { +// color: @fancy-font-color-dimm; +// font-weight: lighter; +// } +// tr.fancytree-match span.fancytree-title, +// span.fancytree-node.fancytree-match span.fancytree-title { +// color: black; +// font-weight: normal; +// } +//} +///* Hide expanders if all child nodes are hidden by filter */ +//.fancytree-ext-filter-hide-expanders { +// tr.fancytree-match span.fancytree-expander, +// span.fancytree-node.fancytree-match span.fancytree-expander { +// visibility: hidden; +// } +// tr.fancytree-submatch span.fancytree-expander, +// span.fancytree-node.fancytree-submatch span.fancytree-expander { +// visibility: visible; +// } +//} +// +//.fancytree-ext-childcounter, +//.fancytree-ext-filter { +// // span.fancytree-title mark { +// // font-style: normal; +// // background-color: #ead61c; // yellow +// // border-radius: 3px; +// // } +// span.fancytree-icon, +// span.fancytree-custom-icon { +// position: relative; +// } +// span.fancytree-childcounter { +// color: #fff; +// background: #777; // #337ab7; // bootstrap blue +// border: 1px solid gray; +// position: absolute; +// top: -6px; +// right: -6px; +// min-width: 10px; +// height: 10px; +// line-height: 1; +// vertical-align: baseline; +// border-radius: 10px; +// padding: 2px; +// text-align: center; +// font-size: 9px; +// } +//} +///*------------------------------------------------------------------------------ +// * 'wide' extension +// *----------------------------------------------------------------------------*/ +// +//ul.fancytree-ext-wide { +// position: relative; +// min-width: 100%; +// z-index: 2; +// +// -webkit-box-sizing: border-box; +// -moz-box-sizing: border-box; +// box-sizing: border-box; +// +// span.fancytree-node > span { +// position: relative; +// z-index: 2; +// } +// span.fancytree-node span.fancytree-title { +// position: absolute; // Allow left: 0. Note: prevents smooth dropdown animation +// z-index: 1; // Behind expander and checkbox +// left: 0px; +// min-width: 100%; +// margin-left: 0; +// margin-right: 0; +// +// -webkit-box-sizing: border-box; +// -moz-box-sizing: border-box; +// box-sizing: border-box; +// } +//} +// +///*------------------------------------------------------------------------------ +// * 'fixed' extension +// *----------------------------------------------------------------------------*/ +// +//.fancytree-ext-fixed-wrapper { +// .fancytree-ext-fixed-hidden { +// display: none; +// } +// div.fancytree-ext-fixed-scroll-border-bottom { +// border-bottom: 3px solid rgba(0, 0, 0, 0.75); +// } +// div.fancytree-ext-fixed-scroll-border-right { +// border-right: 3px solid rgba(0, 0, 0, 0.75); +// } +// div.fancytree-ext-fixed-wrapper-tl { +// position: absolute; +// overflow: hidden; +// z-index: 3; +// top: 0px; +// left: 0px; +// } +// div.fancytree-ext-fixed-wrapper-tr { +// position: absolute; +// overflow: hidden; +// z-index: 2; +// top: 0px; +// } +// div.fancytree-ext-fixed-wrapper-bl { +// position: absolute; +// overflow: hidden; +// z-index: 2; +// left: 0px; +// } +// div.fancytree-ext-fixed-wrapper-br { +// position: absolute; +// overflow: scroll; +// z-index: 1; +// } +//} diff --git a/plugins/55/indexmenu/scripts/fancytree/skin-bootstrap/ui.fancytree.css b/plugins/55/indexmenu/scripts/fancytree/skin-bootstrap/ui.fancytree.css new file mode 100644 index 0000000..81e1090 --- /dev/null +++ b/plugins/55/indexmenu/scripts/fancytree/skin-bootstrap/ui.fancytree.css @@ -0,0 +1,680 @@ +/*! + * Fancytree "bootstrap" skin. + * + * DON'T EDIT THE CSS FILE DIRECTLY, since it is automatically generated from + * the LESS templates. + */ +/******************************************************************************* + * Common Styles for Fancytree Skins. + * + * This section is automatically generated from the `skin-common.less` template. + * + * Copyright (c) 2008-2023, Martin Wendt (https://wwWendt.de) + * Released under the MIT license + * https://github.com/mar10/fancytree/wiki/LicenseInfo + * + * @version 2.38.3 + * @date 2023-02-01T20:52:50Z +******************************************************************************/ +/*------------------------------------------------------------------------------ + * Helpers + *----------------------------------------------------------------------------*/ +.fancytree-helper-hidden { + display: none; +} +.fancytree-helper-indeterminate-cb { + color: #777; +} +.fancytree-helper-disabled { + color: #333333; +} +/* Helper to allow spinning loader icon with glyph-, ligature-, and SVG-icons. */ +.fancytree-helper-spin { + -webkit-animation: spin 1000ms infinite linear; + animation: spin 1000ms infinite linear; +} +@-webkit-keyframes spin { + 0% { + -webkit-transform: rotate(0deg); + transform: rotate(0deg); + } + 100% { + -webkit-transform: rotate(359deg); + transform: rotate(359deg); + } +} +@keyframes spin { + 0% { + -webkit-transform: rotate(0deg); + transform: rotate(0deg); + } + 100% { + -webkit-transform: rotate(359deg); + transform: rotate(359deg); + } +} +/*------------------------------------------------------------------------------ + * Container and UL / LI + *----------------------------------------------------------------------------*/ +ul.fancytree-container { + font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; + font-size: 14px; + white-space: nowrap; + padding: 3px; + margin: 0; + background-color: white; + border: 1px dotted gray; + min-height: 0%; + position: relative; +} +ul.fancytree-container ul { + padding: 0 0 0 16px; + margin: 0; +} +ul.fancytree-container ul > li:before { + content: none; +} +ul.fancytree-container li { + list-style-image: none; + list-style-position: outside; + list-style-type: none; + -moz-background-clip: border; + -moz-background-inline-policy: continuous; + -moz-background-origin: padding; + background-attachment: scroll; + background-color: transparent; + background-position: 0em 0em; + background-repeat: repeat-y; + background-image: none; + margin: 0; +} +ul.fancytree-container li.fancytree-lastsib { + background-image: none; +} +.ui-fancytree-disabled ul.fancytree-container { + opacity: 0.5; + background-color: silver; +} +ul.fancytree-connectors.fancytree-container li { + background-image: url("../skin-bootstrap/vline.gif"); + background-position: 0 0; +} +ul.fancytree-container li.fancytree-lastsib, +ul.fancytree-no-connector > li { + background-image: none; +} +li.fancytree-animating { + position: relative; +} +/*------------------------------------------------------------------------------ + * Common icon definitions + *----------------------------------------------------------------------------*/ +span.fancytree-empty, +span.fancytree-vline, +span.fancytree-expander, +span.fancytree-icon, +span.fancytree-checkbox, +span.fancytree-drag-helper-img, +#fancytree-drop-marker { + width: 1em; + height: 1em; + display: inline-block; + vertical-align: top; + background-repeat: no-repeat; + background-position: 0em 0em; +} +span.fancytree-icon, +span.fancytree-checkbox, +span.fancytree-expander, +span.fancytree-custom-icon { + margin-top: 2px; +} +/* Used by icon option: */ +span.fancytree-custom-icon { + width: 1em; + height: 1em; + display: inline-block; + margin-left: 0.5em; + background-position: 0em 0em; +} +/* Used by 'icon' node option: */ +img.fancytree-icon { + width: 1em; + height: 1em; + margin-left: 0.5em; + margin-top: 2px; + vertical-align: top; + border-style: none; +} +/*------------------------------------------------------------------------------ + * Expander icon + * + * Note: IE6 doesn't correctly evaluate multiples class names, + * so we create combined class names that can be used in the CSS. + * + * Prefix: fancytree-exp- + * 1st character: 'e': expanded, 'c': collapsed, 'n': no children + * 2nd character (optional): 'd': lazy (Delayed) + * 3rd character (optional): 'l': Last sibling + *----------------------------------------------------------------------------*/ +span.fancytree-expander { + cursor: pointer; +} +.fancytree-exp-n span.fancytree-expander, +.fancytree-exp-nl span.fancytree-expander { + background-image: none; + cursor: default; +} +.fancytree-connectors .fancytree-exp-n span.fancytree-expander, +.fancytree-connectors .fancytree-exp-nl span.fancytree-expander { + margin-top: 0; +} +/* Fade out expanders, when container is not hovered or active */ +.fancytree-fade-expander span.fancytree-expander { + transition: opacity 1.5s; + opacity: 0; +} +.fancytree-fade-expander:hover span.fancytree-expander, +.fancytree-fade-expander.fancytree-treefocus span.fancytree-expander, +.fancytree-fade-expander .fancytree-treefocus span.fancytree-expander, +.fancytree-fade-expander [class*="fancytree-statusnode-"] span.fancytree-expander { + transition: opacity 0.6s; + opacity: 1; +} +/*------------------------------------------------------------------------------ + * Checkbox icon + *----------------------------------------------------------------------------*/ +span.fancytree-checkbox { + margin-left: 0.5em; +} +.fancytree-unselectable span.fancytree-checkbox { + opacity: 0.4; + filter: alpha(opacity=40); +} +.fancytree-container.fancytree-checkbox-auto-hide span.fancytree-checkbox { + visibility: hidden; +} +.fancytree-container.fancytree-checkbox-auto-hide .fancytree-node:hover span.fancytree-checkbox, +.fancytree-container.fancytree-checkbox-auto-hide tr:hover td span.fancytree-checkbox, +.fancytree-container.fancytree-checkbox-auto-hide .fancytree-node.fancytree-selected span.fancytree-checkbox, +.fancytree-container.fancytree-checkbox-auto-hide tr.fancytree-selected td span.fancytree-checkbox { + visibility: unset; +} +.fancytree-container.fancytree-checkbox-auto-hide.fancytree-treefocus .fancytree-node.fancytree-active span.fancytree-checkbox, +.fancytree-container.fancytree-checkbox-auto-hide.fancytree-treefocus tr.fancytree-active td span.fancytree-checkbox { + visibility: unset; +} +/*------------------------------------------------------------------------------ + * Node type icon + * Note: IE6 doesn't correctly evaluate multiples class names, + * so we create combined class names that can be used in the CSS. + * + * Prefix: fancytree-ico- + * 1st character: 'e': expanded, 'c': collapsed + * 2nd character (optional): 'f': folder + *----------------------------------------------------------------------------*/ +span.fancytree-icon { + margin-left: 0.5em; +} +/* Documents */ +/* Folders */ +.fancytree-loading span.fancytree-expander, +.fancytree-loading span.fancytree-expander:hover, +.fancytree-statusnode-loading span.fancytree-icon, +.fancytree-statusnode-loading span.fancytree-icon:hover, +span.fancytree-icon.fancytree-icon-loading { + background-image: none; +} +/* Status node icons */ +/*------------------------------------------------------------------------------ + * Node titles and highlighting + *----------------------------------------------------------------------------*/ +span.fancytree-node { + /* See #117 */ + display: inherit; + width: 100%; + margin-top: 0px; + min-height: 1em; +} +span.fancytree-title { + color: #333333; + cursor: pointer; + display: inline-block; + vertical-align: top; + min-height: 1em; + padding: 0 3px 0 3px; + margin: 0px 0 0 0.5em; + border: 1px solid transparent; + -webkit-border-radius: 3px; + -moz-border-radius: 3px; + -ms-border-radius: 3px; + -o-border-radius: 3px; + border-radius: 3px; +} +span.fancytree-node.fancytree-error span.fancytree-title { + color: #d9534f; +} +/*------------------------------------------------------------------------------ + * Drag'n'drop support + *----------------------------------------------------------------------------*/ +/* ext-dnd5: */ +span.fancytree-childcounter { + color: #fff; + background: #337ab7; + border: 1px solid gray; + border-radius: 10px; + padding: 2px; + text-align: center; +} +/* ext-dnd: */ +div.fancytree-drag-helper span.fancytree-childcounter, +div.fancytree-drag-helper span.fancytree-dnd-modifier { + display: inline-block; + color: #fff; + background: #337ab7; + border: 1px solid gray; + min-width: 10px; + height: 10px; + line-height: 1; + vertical-align: baseline; + border-radius: 10px; + padding: 2px; + text-align: center; + font-size: 9px; +} +div.fancytree-drag-helper span.fancytree-childcounter { + position: absolute; + top: -6px; + right: -6px; +} +div.fancytree-drag-helper span.fancytree-dnd-modifier { + background: #5cb85c; + border: none; + font-weight: bolder; +} +/*** Drop marker icon *********************************************************/ +#fancytree-drop-marker { + width: 2em; + position: absolute; + margin: 0; +} +#fancytree-drop-marker.fancytree-drop-after, +#fancytree-drop-marker.fancytree-drop-before { + width: 4em; +} +/*** Source node while dragging ***********************************************/ +span.fancytree-drag-source.fancytree-drag-remove { + opacity: 0.15; +} +/*** Target node while dragging cursor is over it *****************************/ +/*------------------------------------------------------------------------------ + * 'rtl' option + *----------------------------------------------------------------------------*/ +.fancytree-container.fancytree-rtl .fancytree-title { + /*unicode-bidi: bidi-override;*/ + /* optional: reverse title letters */ +} +.fancytree-container.fancytree-rtl .fancytree-exp-n span.fancytree-expander, +.fancytree-container.fancytree-rtl .fancytree-exp-nl span.fancytree-expander { + background-image: none; +} +ul.fancytree-container.fancytree-rtl ul { + padding: 0 16px 0 0; +} +ul.fancytree-container.fancytree-rtl.fancytree-connectors li { + background-position: right 0; + background-image: url("../skin-bootstrap/vline-rtl.gif"); +} +ul.fancytree-container.fancytree-rtl li.fancytree-lastsib, +ul.fancytree-container.fancytree-rtl.fancytree-no-connector > li { + background-image: none; +} +/*------------------------------------------------------------------------------ + * 'table' extension + *----------------------------------------------------------------------------*/ +table.fancytree-ext-table { + font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; + font-size: 14px; + border-collapse: collapse; + /* ext-ariagrid */ +} +table.fancytree-ext-table span.fancytree-node { + display: inline-block; + box-sizing: border-box; +} +table.fancytree-ext-table td.fancytree-status-merged { + text-align: center; + font-style: italic; + color: #333333; +} +table.fancytree-ext-table tr.fancytree-statusnode-error td.fancytree-status-merged { + color: #d9534f; +} +table.fancytree-ext-table.fancytree-ext-ariagrid.fancytree-cell-mode > tbody > tr.fancytree-active > td { + background-color: #eee; +} +table.fancytree-ext-table.fancytree-ext-ariagrid.fancytree-cell-mode > tbody > tr > td.fancytree-active-cell { + background-color: #cbe8f6; +} +table.fancytree-ext-table.fancytree-ext-ariagrid.fancytree-cell-mode.fancytree-cell-nav-mode > tbody > tr > td.fancytree-active-cell { + background-color: #3875d7; +} +/*------------------------------------------------------------------------------ + * 'columnview' extension + *----------------------------------------------------------------------------*/ +table.fancytree-ext-columnview tbody tr td { + position: relative; + border: 1px solid gray; + vertical-align: top; + overflow: auto; +} +table.fancytree-ext-columnview tbody tr td > ul { + padding: 0; +} +table.fancytree-ext-columnview tbody tr td > ul li { + list-style-image: none; + list-style-position: outside; + list-style-type: none; + -moz-background-clip: border; + -moz-background-inline-policy: continuous; + -moz-background-origin: padding; + background-attachment: scroll; + background-color: transparent; + background-position: 0em 0em; + background-repeat: repeat-y; + background-image: none; + /* no v-lines */ + margin: 0; +} +table.fancytree-ext-columnview span.fancytree-node { + position: relative; + /* allow positioning of embedded spans */ + display: inline-block; +} +table.fancytree-ext-columnview span.fancytree-node.fancytree-expanded { + background-color: #e0e0e0; +} +table.fancytree-ext-columnview span.fancytree-node.fancytree-active { + background-color: #cbe8f6; +} +table.fancytree-ext-columnview .fancytree-has-children span.fancytree-cv-right { + position: absolute; + right: 3px; +} +/*------------------------------------------------------------------------------ + * 'filter' extension + *----------------------------------------------------------------------------*/ +.fancytree-ext-filter-dimm span.fancytree-node span.fancytree-title { + color: #333333; + font-weight: lighter; +} +.fancytree-ext-filter-dimm tr.fancytree-submatch span.fancytree-title, +.fancytree-ext-filter-dimm span.fancytree-node.fancytree-submatch span.fancytree-title { + color: black; + font-weight: normal; +} +.fancytree-ext-filter-dimm tr.fancytree-match span.fancytree-title, +.fancytree-ext-filter-dimm span.fancytree-node.fancytree-match span.fancytree-title { + color: black; + font-weight: bold; +} +.fancytree-ext-filter-hide tr.fancytree-hide, +.fancytree-ext-filter-hide span.fancytree-node.fancytree-hide { + display: none; +} +.fancytree-ext-filter-hide tr.fancytree-submatch span.fancytree-title, +.fancytree-ext-filter-hide span.fancytree-node.fancytree-submatch span.fancytree-title { + color: #333333; + font-weight: lighter; +} +.fancytree-ext-filter-hide tr.fancytree-match span.fancytree-title, +.fancytree-ext-filter-hide span.fancytree-node.fancytree-match span.fancytree-title { + color: black; + font-weight: normal; +} +/* Hide expanders if all child nodes are hidden by filter */ +.fancytree-ext-filter-hide-expanders tr.fancytree-match span.fancytree-expander, +.fancytree-ext-filter-hide-expanders span.fancytree-node.fancytree-match span.fancytree-expander { + visibility: hidden; +} +.fancytree-ext-filter-hide-expanders tr.fancytree-submatch span.fancytree-expander, +.fancytree-ext-filter-hide-expanders span.fancytree-node.fancytree-submatch span.fancytree-expander { + visibility: visible; +} +.fancytree-ext-childcounter span.fancytree-icon, +.fancytree-ext-filter span.fancytree-icon, +.fancytree-ext-childcounter span.fancytree-custom-icon, +.fancytree-ext-filter span.fancytree-custom-icon { + position: relative; +} +.fancytree-ext-childcounter span.fancytree-childcounter, +.fancytree-ext-filter span.fancytree-childcounter { + color: #fff; + background: #777; + border: 1px solid gray; + position: absolute; + top: -6px; + right: -6px; + min-width: 10px; + height: 10px; + line-height: 1; + vertical-align: baseline; + border-radius: 10px; + padding: 2px; + text-align: center; + font-size: 9px; +} +/*------------------------------------------------------------------------------ + * 'wide' extension + *----------------------------------------------------------------------------*/ +ul.fancytree-ext-wide { + position: relative; + min-width: 100%; + z-index: 2; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; +} +ul.fancytree-ext-wide span.fancytree-node > span { + position: relative; + z-index: 2; +} +ul.fancytree-ext-wide span.fancytree-node span.fancytree-title { + position: absolute; + z-index: 1; + left: 0px; + min-width: 100%; + margin-left: 0; + margin-right: 0; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; +} +/*------------------------------------------------------------------------------ + * 'fixed' extension + *----------------------------------------------------------------------------*/ +.fancytree-ext-fixed-wrapper .fancytree-ext-fixed-hidden { + display: none; +} +.fancytree-ext-fixed-wrapper div.fancytree-ext-fixed-scroll-border-bottom { + border-bottom: 3px solid rgba(0, 0, 0, 0.75); +} +.fancytree-ext-fixed-wrapper div.fancytree-ext-fixed-scroll-border-right { + border-right: 3px solid rgba(0, 0, 0, 0.75); +} +.fancytree-ext-fixed-wrapper div.fancytree-ext-fixed-wrapper-tl { + position: absolute; + overflow: hidden; + z-index: 3; + top: 0px; + left: 0px; +} +.fancytree-ext-fixed-wrapper div.fancytree-ext-fixed-wrapper-tr { + position: absolute; + overflow: hidden; + z-index: 2; + top: 0px; +} +.fancytree-ext-fixed-wrapper div.fancytree-ext-fixed-wrapper-bl { + position: absolute; + overflow: hidden; + z-index: 2; + left: 0px; +} +.fancytree-ext-fixed-wrapper div.fancytree-ext-fixed-wrapper-br { + position: absolute; + overflow: scroll; + z-index: 1; +} +/******************************************************************************* + * Styles specific to this skin. + * + * This section is automatically generated from the `ui-fancytree.less` template. + ******************************************************************************/ +/******************************************************************************* + * Plain tree + * Modifier classes on <ul> container: + * table-hover : Enable a light mouse hover effect + * fancytree-colorize-selected: Give selected (checked) rows a color + */ +ul.fancytree-container ul { + padding: 0 0 0 1.5em; + margin: 0; +} +/* Prevent focus frame */ +.fancytree-container:focus { + outline: none; +} +.fancytree-container .fancytree-active span.fancytree-title input, +.fancytree-container.fancytree-colorize-selected .fancytree-selected span.fancytree-title input { + color: black; +} +.fancytree-container span.fancytree-statusnode-error span.fancytree-expander { + color: #d9534f; +} +div.fancytree-drag-helper.fancytree-drop-reject, +div.fancytree-drag-helper.fancytree-drop-reject span.fancytree-title { + color: #d9534f; +} +span.fancytree-node.fancytree-drag-source { + background-color: #5bc0de !important; +} +span.fancytree-node.fancytree-drop-target.fancytree-drop-reject span.fancytree.title { + background-color: #d9534f !important; +} +span.fancytree-expander { + color: #999; +} +.fancytree-expanded span.fancytree-expander { + color: #333333; +} +span.fancytree-node span.fancytree-expander:hover { + color: cyan; +} +.fancytree-plain.fancytree-colorize-selected span.fancytree-node.fancytree-selected, +.fancytree-plain.fancytree-colorize-selected span.fancytree-node.fancytree-selected span.fancytree-title { + background-color: #80c780; + border-color: #80c780; + color: #fff; +} +.fancytree-plain.fancytree-colorize-selected span.fancytree-node.fancytree-selected:hover span.fancytree-title { + background-color: #6ec06e; +} +.fancytree-plain.fancytree-colorize-selected span.fancytree-node.fancytree-active.fancytree-selected span.fancytree-title { + color: #80c780; +} +.fancytree-plain.fancytree-colorize-selected.fancytree-treefocus span.fancytree-title:hover { + background-color: #f5f5f5; +} +.fancytree-plain.fancytree-colorize-selected.fancytree-treefocus span.fancytree-node.fancytree-selected span.fancytree-title { + background-color: #5cb85c; +} +.fancytree-plain.fancytree-colorize-selected.fancytree-treefocus span.fancytree-node.fancytree-selected:hover span.fancytree-title { + background-color: #4cae4c; +} +.fancytree-plain.fancytree-colorize-selected.fancytree-treefocus span.fancytree-node.fancytree-active.fancytree-selected span.fancytree-title { + color: #5cb85c; +} +.fancytree-plain.fancytree-container span.fancytree-node { + margin-top: 2px; + margin-bottom: 2px; +} +.fancytree-plain.fancytree-container span.fancytree-title { + border: 1px solid transparent; + border-radius: 3px; + outline-radius: 3px; +} +.fancytree-plain.fancytree-container span.fancytree-title:hover { + background-color: #f5f5f5; +} +.fancytree-plain.fancytree-container span.fancytree-node.fancytree-active span.fancytree-title { + background-color: #5094ce; + color: #fff; +} +.fancytree-plain.fancytree-container span.fancytree-node.fancytree-active:hover span.fancytree-title { + background-color: #3c87c8; +} +.fancytree-plain.fancytree-container.fancytree-ext-wide span.fancytree-node.fancytree-active { + color: #fff; +} +.fancytree-plain.fancytree-container.fancytree-treefocus span.fancytree-node.fancytree-focused span.fancytree-title { + border-color: #337ab7; +} +.fancytree-plain.fancytree-container.fancytree-treefocus span.fancytree-node.fancytree-active span.fancytree-title { + background-color: #337ab7; + border-color: #337ab7; +} +.fancytree-plain.fancytree-container.fancytree-treefocus span.fancytree-node.fancytree-active:hover span.fancytree-title { + background-color: #2e6da4; +} +/******************************************************************************* + * 'table' extension + * Modifier classes on <table>: + * table-hover : Enable a light mouse hover effect + * fancytree-colorize-selected: Give selected (checked) rows a color + */ +table.fancytree-ext-table > tbody > tr > td span.fancytree-title { + border: none; +} +table.fancytree-ext-table.fancytree-colorize-selected > tbody > tr.fancytree-selected > td { + background-color: #80c780; +} +table.fancytree-ext-table.fancytree-colorize-selected > tbody > tr.fancytree-selected > td, +table.fancytree-ext-table.fancytree-colorize-selected > tbody > tr.fancytree-selected > td span.fancytree-title { + color: #fff; +} +table.fancytree-ext-table.fancytree-colorize-selected.fancytree-treefocus > tbody > tr.fancytree-selected > td { + background-color: #5cb85c; +} +table.fancytree-ext-table.fancytree-colorize-selected.table-hover > tbody > tr.fancytree-selected:hover > td { + background-color: #6ec06e; +} +table.fancytree-ext-table.fancytree-colorize-selected.fancytree-treefocus.table-hover > tbody > tr.fancytree-selected:hover > td { + background-color: #4cae4c; +} +table.fancytree-ext-table.fancytree-colorize-selected.fancytree-treefocus.table-hover > tbody > tr.fancytree-selected.fancytree-active:hover > td, +table.fancytree-ext-table.fancytree-colorize-selected.table-hover > tbody > tr.fancytree-selected.fancytree-active:hover > td { + background-color: #2e6da4; +} +table.fancytree-ext-table.fancytree-colorize-selected > tbody > tr.fancytree-active.fancytree-selected { + outline-width: 2px; + outline-offset: -2px; + outline-style: solid; + outline-color: #80c780; +} +table.fancytree-ext-table.fancytree-container > tbody > tr.fancytree-active > td { + background-color: #5094ce; +} +table.fancytree-ext-table.fancytree-container > tbody > tr.fancytree-active > td, +table.fancytree-ext-table.fancytree-container > tbody > tr.fancytree-active > td span.fancytree-title { + color: #fff; +} +table.fancytree-ext-table.fancytree-treefocus.fancytree-container > tbody > tr.fancytree-focused span.fancytree-title { + outline: 1px dotted #000; +} +table.fancytree-ext-table.fancytree-treefocus.fancytree-container > tbody > tr.fancytree-active > td { + background-color: #337ab7; +} +table.fancytree-ext-table.fancytree-treefocus.fancytree-container.table-hover > tbody > tr.fancytree-active:hover > td { + background-color: #2e6da4; +} diff --git a/plugins/55/indexmenu/scripts/fancytree/skin-bootstrap/ui.fancytree.less b/plugins/55/indexmenu/scripts/fancytree/skin-bootstrap/ui.fancytree.less new file mode 100644 index 0000000..d2ad725 --- /dev/null +++ b/plugins/55/indexmenu/scripts/fancytree/skin-bootstrap/ui.fancytree.less @@ -0,0 +1,356 @@ +/*! + * Fancytree "bootstrap" skin. + * + * DON'T EDIT THE CSS FILE DIRECTLY, since it is automatically generated from + * the LESS templates. + */ + +// Import common styles +@import "skin-common.less"; + + +/******************************************************************************* + * Styles specific to this skin. + * + * This section is automatically generated from the `ui-fancytree.less` template. + ******************************************************************************/ + + +// local vars +// @fancy-my-icon-size: 16px; + +//------------------------------------------------------------------------------ +// Original bootstrap colors +// See http://getbootstrap.com/css/#less-variables-colors and +// https://github.com/twbs/bootstrap/blob/master/less/variables.less +@gray-base: #000; +@gray-darker: lighten(@gray-base, 13.5%); // #222 +@gray-dark: lighten(@gray-base, 20%); // #333 +@gray: lighten(@gray-base, 33.5%); // #555 +@gray-light: lighten(@gray-base, 46.7%); // #777 +@gray-lighter: lighten(@gray-base, 93.5%); // #eee + +@brand-primary: darken(#428bca, 6.5%); // blue, #337ab7 +@brand-success: #5cb85c; // green +@brand-info: #5bc0de; // light blue +@brand-warning: #f0ad4e; // orange +@brand-danger: #d9534f; // red + +@font-family-sans-serif: "Helvetica Neue", Helvetica, Arial, sans-serif; +@font-family-serif: Georgia, "Times New Roman", Times, serif; +//** Default monospace fonts for `<code>`, `<kbd>`, and `<pre>`. +@font-family-monospace: Menlo, Monaco, Consolas, "Courier New", monospace; +@font-family-base: @font-family-sans-serif; + +@font-size-base: 14px; +@font-size-large: ceil((@font-size-base * 1.25)); // ~18px +@font-size-small: ceil((@font-size-base * 0.85)); // ~12px + +@border-radius-base: 4px; +@border-radius-large: 6px; +@border-radius-small: 3px; + +@text-color: @gray-dark; +//** Default background color used for all tables. +@table-bg: transparent; +//** Background color used for `.table-striped`. +@table-bg-accent: #f9f9f9; +//** Background color used for `.table-hover`. +@table-bg-hover: #f5f5f5; +@table-bg-active: @table-bg-hover; + +//** Border color for table and cell borders. +@table-border-color: #ddd; + +//------------------------------------------------------------------------------ + +// Override the variable after the import. +// NOTE: Variables are always resolved as the last definition, even if it is +// after where it is used. +@fancy-use-sprites: false; // false: suppress all background images (i.e. icons) +@fancy-loading-url: none; + +@fancy-line-height: 1em; // height of a nodes selection bar including borders +@fancy-node-v-spacing: 0px; // gap between two node borders +@fancy-icon-width: 1em; +@fancy-icon-height: 1em; +@fancy-icon-spacing: 0.5em; // margin between icon/icon or icon/title +@fancy-icon-ofs-top: 2px; // extra vertical offset for expander, checkbox and icon +@fancy-title-ofs-top: 0px; // extra vertical offset for title +@fancy-node-border-width: 1px; +@fancy-node-border-radius: @border-radius-small; +@fancy-node-outline-width: 1px; + +@fancy-font-family: @font-family-base; +@fancy-font-size: @font-size-base; +@fancy-font-color: @text-color; +@fancy-font-color-dimm: @gray-dark; +@fancy-font-error-color: @brand-danger; + +@fancy-active-text: #fff; +@fancy-active-color: @brand-primary; +@fancy-select-color: @brand-success; +@fancy-hover-color: @table-bg-hover; + +// We need to define this variable here (not in skin-common.less) to make it +// work with grunt and webpack: +@fancy-image-prefix: "./skin-bootstrap/"; + +/******************************************************************************* + * Plain tree + * Modifier classes on <ul> container: + * table-hover : Enable a light mouse hover effect + * fancytree-colorize-selected: Give selected (checked) rows a color + */ +ul.fancytree-container ul { + padding: 0 0 0 1.5em; + margin: 0; +} +/* Prevent focus frame */ +.fancytree-container:focus { + outline: none; +} + +// Active and (optionally) selected nodes are white on colored bg. Undo this for input controls: +.fancytree-container .fancytree-active span.fancytree-title input, +.fancytree-container.fancytree-colorize-selected .fancytree-selected span.fancytree-title input { + color: black; +} + +// Error status node +.fancytree-container span.fancytree-statusnode-error span.fancytree-expander { + color: @fancy-font-error-color; +} + +// set icon color to font color as well +span.fancytree-node { + color: @fancy-font-color; +} + +//// ------------------------------------------------------------------------------ +//// * Drag'n'drop support +//// *---------------------------------------------------------------------------- +//// div.fancytree-drag-helper { +//// } +//// div.fancytree-drag-helper a { +//// border: 1px solid gray; +//// background-color: white; +//// padding-left: 5px; +//// padding-right: 5px; +//// opacity: 0.8; +//// } +//// span.fancytree-drag-helper-img { +//// // position: relative; +//// // left: -16px; +//// } +//div.fancytree-drag-helper.fancytree-drop-reject, +//div.fancytree-drag-helper.fancytree-drop-reject span.fancytree-title +//{ +// color: @fancy-font-error-color; +//} +//// div.fancytree-drop-accept span.fancytree-drag-helper-img { +//// .useSprite(2, 7); +//// } +//// div.fancytree-drop-reject span.fancytree-drag-helper-img { +//// .useSprite(1, 7); +//// } +// +//// //--- Drop marker icon --------------------------------------------------------- +//// #fancytree-drop-marker { +//// width: 2 * @fancy-icon-width; // was 24px, but 32 should be correct +//// position: absolute; +//// .useSprite(0, 8); +//// margin: 0; +//// &.fancytree-drop-after, +//// &.fancytree-drop-before { +//// width: 4 * @fancy-icon-width; // 64px; +//// .useSprite(0, 9); +//// } +//// &.fancytree-drop-copy { +//// .useSprite(4, 8); +//// } +//// &.fancytree-drop-move { +//// .useSprite(2, 8); +//// } +//// } +//// +////--- Source node while dragging ----------------------------------------------- +// +//span.fancytree-node.fancytree-drag-source { +// background-color: @brand-info !important; +// span.fancytree.title { +// // outline: 1px solid @brand-info; +// // color: @brand-primary; +// } +//} +// +////--- Target node while dragging cursor is over it ----------------------------- +// +//span.fancytree-node.fancytree-drop-target { +// &.fancytree-drop-accept span.fancytree.title { +// // background-color: @brand-danger !important; +// // outline: 1px solid @brand-success; +// // color: white !important; +// } +// &.fancytree-drop-reject span.fancytree.title { +// background-color: @brand-danger !important; +// // outline: 1px solid @brand-danger; +// // color: white !important; +// } +//} +// +//span.fancytree-expander { +// color: #999; // colpased expander is gray +//} +//.fancytree-expanded span.fancytree-expander { +// color: @fancy-font-color; +//} +//span.fancytree-node span.fancytree-expander:hover { +// color: cyan; +//} + +// Inactive tree: +.fancytree-plain { + &.fancytree-colorize-selected { + span.fancytree-node.fancytree-selected, + span.fancytree-node.fancytree-selected span.fancytree-title { // selected nodes inside inactive tree + background-color: lighten(@fancy-select-color, 10%); + border-color: lighten(@fancy-select-color, 10%); + color: @fancy-active-text; + } + span.fancytree-node.fancytree-selected:hover span.fancytree-title { + background-color: lighten(@fancy-select-color, 5%); + } + span.fancytree-node.fancytree-active.fancytree-selected span.fancytree-title { // active nodes inside inactive tree + color: lighten(@fancy-select-color, 10%); + } + &.fancytree-treefocus { + span.fancytree-title:hover { + background-color: @fancy-hover-color; + } + span.fancytree-node.fancytree-selected span.fancytree-title { + background-color: @fancy-select-color; + } + span.fancytree-node.fancytree-selected:hover span.fancytree-title { + background-color: darken(@fancy-select-color, 5%); + } + span.fancytree-node.fancytree-active.fancytree-selected span.fancytree-title { + color: @fancy-select-color; + } + } + } + + &.fancytree-container { // adding this class to increase specificity, so we can override .fancytree-colorize-selected + span.fancytree-node { + margin-top: 2px; + margin-bottom: 2px; + } + span.fancytree-title { + border: @fancy-node-border-width solid transparent; // avoid jumping, when a border is added on hover + border-radius: @border-radius-small; + outline-radius: @border-radius-small; + } + span.fancytree-title:hover { + background-color: @fancy-hover-color; + } + span.fancytree-node.fancytree-active span.fancytree-title { // active nodes inside inactive tree + background-color: lighten(@fancy-active-color, 10%); + color: @fancy-active-text; + } + span.fancytree-node.fancytree-active:hover span.fancytree-title { + background-color: lighten(@fancy-active-color, 5%); + } + &.fancytree-ext-wide span.fancytree-node.fancytree-active { // in wide mode, icons of active nodes must be white-on-color + color: @fancy-active-text; + } + + // Active tree: + &.fancytree-treefocus { + span.fancytree-node.fancytree-focused span.fancytree-title { + border-color: @brand-primary; + } + span.fancytree-node.fancytree-active span.fancytree-title { + background-color: @fancy-active-color; + border-color: @fancy-active-color; + } + span.fancytree-node.fancytree-active:hover span.fancytree-title { + background-color: darken(@fancy-active-color, 5%); + } + } + } +} + +///******************************************************************************* +// * 'table' extension +// * Modifier classes on <table>: +// * table-hover : Enable a light mouse hover effect +// * fancytree-colorize-selected: Give selected (checked) rows a color +// */ +//table.fancytree-ext-table { +// >tbody >tr >td span.fancytree-title { +// border: none; +// } +// +// // Give a separate color for selected (checked) rows +// // Define *before* the .fancytree-active rules, because active color should +// // override selected color. +// &.fancytree-colorize-selected { +// >tbody >tr.fancytree-selected >td { +// // dimmed, if inside inactive tree +// background-color: lighten(@fancy-select-color, 10%); +// // white text for selected nodes +// &, +// span.fancytree-title { +// color: @fancy-active-text; +// } +// } +// &.fancytree-treefocus >tbody >tr.fancytree-selected >td { +// background-color: @fancy-select-color; +// } +// &.table-hover >tbody >tr.fancytree-selected:hover >td { +// // dimmed, if inside inactive tree +// background-color: lighten(@fancy-select-color, 5%); +// } +// &.fancytree-treefocus.table-hover >tbody >tr.fancytree-selected:hover >td { +// background-color: darken(@fancy-select-color, 5%); +// } +// &.fancytree-treefocus.table-hover >tbody >tr.fancytree-selected.fancytree-active:hover >td, +// &.table-hover >tbody >tr.fancytree-selected.fancytree-active:hover >td { +// background-color: darken(@fancy-active-color, 5%); +// } +// >tbody >tr.fancytree-active.fancytree-selected { +// outline-width: 2px; +// outline-offset: -2px; +// outline-style: solid; +// outline-color: lighten(@fancy-select-color, 10%); +// } +// } +// +// // General tree (slightly dimmed, since we also define colors for inactive +// // mode here). +// +// &.fancytree-container >tbody >tr.fancytree-active >td { +// background-color: lighten(@fancy-active-color, 10%); +// // white text for selected nodes +// &, +// span.fancytree-title { +// color: @fancy-active-text; +// } +// } +// +// // Reset to standard colors if tree has keyboard focus. +// // We add .fancytree-container to increase specificity, so we can override +// // .fancytree-colorize-selected defined above +// +// &.fancytree-treefocus.fancytree-container { +// >tbody >tr.fancytree-focused span.fancytree-title { +// outline: 1px dotted #000; +// } +// >tbody >tr.fancytree-active >td { +// background-color: @fancy-active-color; +// } +// &.table-hover >tbody >tr.fancytree-active:hover >td { +// background-color: darken(@fancy-active-color, 5%); +// } +// } +//} diff --git a/plugins/55/indexmenu/scripts/fancytree/skin-bootstrap/ui.fancytree.min.css b/plugins/55/indexmenu/scripts/fancytree/skin-bootstrap/ui.fancytree.min.css new file mode 100644 index 0000000..60f01d7 --- /dev/null +++ b/plugins/55/indexmenu/scripts/fancytree/skin-bootstrap/ui.fancytree.min.css @@ -0,0 +1,6 @@ +/*! + * Fancytree "bootstrap" skin. + * + * DON'T EDIT THE CSS FILE DIRECTLY, since it is automatically generated from + * the LESS templates. + */.fancytree-helper-hidden{display:none}.fancytree-helper-indeterminate-cb{color:#777}.fancytree-helper-disabled{color:#333}.fancytree-helper-spin{-webkit-animation:spin 1s infinite linear;animation:spin 1s infinite linear}@-webkit-keyframes spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}ul.fancytree-container{font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;white-space:nowrap;padding:3px;margin:0;background-color:#fff;border:1px dotted gray;min-height:0;position:relative}ul.fancytree-container ul{padding:0 0 0 16px;margin:0}ul.fancytree-container ul>li:before{content:none}ul.fancytree-container li{list-style-image:none;list-style-position:outside;list-style-type:none;-moz-background-clip:border;-moz-background-inline-policy:continuous;-moz-background-origin:padding;background-attachment:scroll;background-color:transparent;background-position:0 0;background-repeat:repeat-y;background-image:none;margin:0}ul.fancytree-container li.fancytree-lastsib{background-image:none}.ui-fancytree-disabled ul.fancytree-container{opacity:.5;background-color:silver}ul.fancytree-connectors.fancytree-container li{background-image:url("../skin-bootstrap/vline.gif");background-position:0 0}ul.fancytree-container li.fancytree-lastsib,ul.fancytree-no-connector>li{background-image:none}li.fancytree-animating{position:relative}#fancytree-drop-marker,span.fancytree-checkbox,span.fancytree-drag-helper-img,span.fancytree-empty,span.fancytree-expander,span.fancytree-icon,span.fancytree-vline{width:1em;height:1em;display:inline-block;vertical-align:top;background-repeat:no-repeat;background-position:0 0}span.fancytree-checkbox,span.fancytree-custom-icon,span.fancytree-expander,span.fancytree-icon{margin-top:2px}span.fancytree-custom-icon{width:1em;height:1em;display:inline-block;margin-left:.5em;background-position:0 0}img.fancytree-icon{width:1em;height:1em;margin-left:.5em;margin-top:2px;vertical-align:top;border-style:none}span.fancytree-expander{cursor:pointer}.fancytree-exp-n span.fancytree-expander,.fancytree-exp-nl span.fancytree-expander{background-image:none;cursor:default}.fancytree-connectors .fancytree-exp-n span.fancytree-expander,.fancytree-connectors .fancytree-exp-nl span.fancytree-expander{margin-top:0}.fancytree-fade-expander span.fancytree-expander{transition:opacity 1.5s;opacity:0}.fancytree-fade-expander .fancytree-treefocus span.fancytree-expander,.fancytree-fade-expander [class*=fancytree-statusnode-] span.fancytree-expander,.fancytree-fade-expander.fancytree-treefocus span.fancytree-expander,.fancytree-fade-expander:hover span.fancytree-expander{transition:opacity .6s;opacity:1}span.fancytree-checkbox{margin-left:.5em}.fancytree-unselectable span.fancytree-checkbox{opacity:.4}.fancytree-container.fancytree-checkbox-auto-hide span.fancytree-checkbox{visibility:hidden}.fancytree-container.fancytree-checkbox-auto-hide .fancytree-node.fancytree-selected span.fancytree-checkbox,.fancytree-container.fancytree-checkbox-auto-hide .fancytree-node:hover span.fancytree-checkbox,.fancytree-container.fancytree-checkbox-auto-hide tr.fancytree-selected td span.fancytree-checkbox,.fancytree-container.fancytree-checkbox-auto-hide tr:hover td span.fancytree-checkbox{visibility:unset}.fancytree-container.fancytree-checkbox-auto-hide.fancytree-treefocus .fancytree-node.fancytree-active span.fancytree-checkbox,.fancytree-container.fancytree-checkbox-auto-hide.fancytree-treefocus tr.fancytree-active td span.fancytree-checkbox{visibility:unset}span.fancytree-icon{margin-left:.5em}.fancytree-loading span.fancytree-expander,.fancytree-loading span.fancytree-expander:hover,.fancytree-statusnode-loading span.fancytree-icon,.fancytree-statusnode-loading span.fancytree-icon:hover,span.fancytree-icon.fancytree-icon-loading{background-image:none}span.fancytree-node{display:inherit;width:100%;margin-top:0;min-height:1em}span.fancytree-title{color:#333;cursor:pointer;display:inline-block;vertical-align:top;min-height:1em;padding:0 3px 0 3px;margin:0 0 0 .5em;border:1px solid transparent;-webkit-border-radius:3px;-moz-border-radius:3px;-ms-border-radius:3px;-o-border-radius:3px;border-radius:3px}span.fancytree-node.fancytree-error span.fancytree-title{color:#d9534f}span.fancytree-childcounter{color:#fff;background:#337ab7;border:1px solid gray;border-radius:10px;padding:2px;text-align:center}div.fancytree-drag-helper span.fancytree-childcounter,div.fancytree-drag-helper span.fancytree-dnd-modifier{display:inline-block;color:#fff;background:#337ab7;border:1px solid gray;min-width:10px;height:10px;line-height:1;vertical-align:baseline;border-radius:10px;padding:2px;text-align:center;font-size:9px}div.fancytree-drag-helper span.fancytree-childcounter{position:absolute;top:-6px;right:-6px}div.fancytree-drag-helper span.fancytree-dnd-modifier{background:#5cb85c;border:none;font-weight:bolder}#fancytree-drop-marker{width:2em;position:absolute;margin:0}#fancytree-drop-marker.fancytree-drop-after,#fancytree-drop-marker.fancytree-drop-before{width:4em}span.fancytree-drag-source.fancytree-drag-remove{opacity:.15}.fancytree-container.fancytree-rtl .fancytree-exp-n span.fancytree-expander,.fancytree-container.fancytree-rtl .fancytree-exp-nl span.fancytree-expander{background-image:none}ul.fancytree-container.fancytree-rtl ul{padding:0 16px 0 0}ul.fancytree-container.fancytree-rtl.fancytree-connectors li{background-position:right 0;background-image:url("../skin-bootstrap/vline-rtl.gif")}ul.fancytree-container.fancytree-rtl li.fancytree-lastsib,ul.fancytree-container.fancytree-rtl.fancytree-no-connector>li{background-image:none}table.fancytree-ext-table{font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;border-collapse:collapse}table.fancytree-ext-table span.fancytree-node{display:inline-block;box-sizing:border-box}table.fancytree-ext-table td.fancytree-status-merged{text-align:center;font-style:italic;color:#333}table.fancytree-ext-table tr.fancytree-statusnode-error td.fancytree-status-merged{color:#d9534f}table.fancytree-ext-table.fancytree-ext-ariagrid.fancytree-cell-mode>tbody>tr.fancytree-active>td{background-color:#eee}table.fancytree-ext-table.fancytree-ext-ariagrid.fancytree-cell-mode>tbody>tr>td.fancytree-active-cell{background-color:#cbe8f6}table.fancytree-ext-table.fancytree-ext-ariagrid.fancytree-cell-mode.fancytree-cell-nav-mode>tbody>tr>td.fancytree-active-cell{background-color:#3875d7}table.fancytree-ext-columnview tbody tr td{position:relative;border:1px solid gray;vertical-align:top;overflow:auto}table.fancytree-ext-columnview tbody tr td>ul{padding:0}table.fancytree-ext-columnview tbody tr td>ul li{list-style-image:none;list-style-position:outside;list-style-type:none;-moz-background-clip:border;-moz-background-inline-policy:continuous;-moz-background-origin:padding;background-attachment:scroll;background-color:transparent;background-position:0 0;background-repeat:repeat-y;background-image:none;margin:0}table.fancytree-ext-columnview span.fancytree-node{position:relative;display:inline-block}table.fancytree-ext-columnview span.fancytree-node.fancytree-expanded{background-color:#e0e0e0}table.fancytree-ext-columnview span.fancytree-node.fancytree-active{background-color:#cbe8f6}table.fancytree-ext-columnview .fancytree-has-children span.fancytree-cv-right{position:absolute;right:3px}.fancytree-ext-filter-dimm span.fancytree-node span.fancytree-title{color:#333;font-weight:lighter}.fancytree-ext-filter-dimm span.fancytree-node.fancytree-submatch span.fancytree-title,.fancytree-ext-filter-dimm tr.fancytree-submatch span.fancytree-title{color:#000;font-weight:400}.fancytree-ext-filter-dimm span.fancytree-node.fancytree-match span.fancytree-title,.fancytree-ext-filter-dimm tr.fancytree-match span.fancytree-title{color:#000;font-weight:700}.fancytree-ext-filter-hide span.fancytree-node.fancytree-hide,.fancytree-ext-filter-hide tr.fancytree-hide{display:none}.fancytree-ext-filter-hide span.fancytree-node.fancytree-submatch span.fancytree-title,.fancytree-ext-filter-hide tr.fancytree-submatch span.fancytree-title{color:#333;font-weight:lighter}.fancytree-ext-filter-hide span.fancytree-node.fancytree-match span.fancytree-title,.fancytree-ext-filter-hide tr.fancytree-match span.fancytree-title{color:#000;font-weight:400}.fancytree-ext-filter-hide-expanders span.fancytree-node.fancytree-match span.fancytree-expander,.fancytree-ext-filter-hide-expanders tr.fancytree-match span.fancytree-expander{visibility:hidden}.fancytree-ext-filter-hide-expanders span.fancytree-node.fancytree-submatch span.fancytree-expander,.fancytree-ext-filter-hide-expanders tr.fancytree-submatch span.fancytree-expander{visibility:visible}.fancytree-ext-childcounter span.fancytree-custom-icon,.fancytree-ext-childcounter span.fancytree-icon,.fancytree-ext-filter span.fancytree-custom-icon,.fancytree-ext-filter span.fancytree-icon{position:relative}.fancytree-ext-childcounter span.fancytree-childcounter,.fancytree-ext-filter span.fancytree-childcounter{color:#fff;background:#777;border:1px solid gray;position:absolute;top:-6px;right:-6px;min-width:10px;height:10px;line-height:1;vertical-align:baseline;border-radius:10px;padding:2px;text-align:center;font-size:9px}ul.fancytree-ext-wide{position:relative;min-width:100%;z-index:2;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}ul.fancytree-ext-wide span.fancytree-node>span{position:relative;z-index:2}ul.fancytree-ext-wide span.fancytree-node span.fancytree-title{position:absolute;z-index:1;left:0;min-width:100%;margin-left:0;margin-right:0;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.fancytree-ext-fixed-wrapper .fancytree-ext-fixed-hidden{display:none}.fancytree-ext-fixed-wrapper div.fancytree-ext-fixed-scroll-border-bottom{border-bottom:3px solid rgba(0,0,0,.75)}.fancytree-ext-fixed-wrapper div.fancytree-ext-fixed-scroll-border-right{border-right:3px solid rgba(0,0,0,.75)}.fancytree-ext-fixed-wrapper div.fancytree-ext-fixed-wrapper-tl{position:absolute;overflow:hidden;z-index:3;top:0;left:0}.fancytree-ext-fixed-wrapper div.fancytree-ext-fixed-wrapper-tr{position:absolute;overflow:hidden;z-index:2;top:0}.fancytree-ext-fixed-wrapper div.fancytree-ext-fixed-wrapper-bl{position:absolute;overflow:hidden;z-index:2;left:0}.fancytree-ext-fixed-wrapper div.fancytree-ext-fixed-wrapper-br{position:absolute;overflow:scroll;z-index:1}ul.fancytree-container ul{padding:0 0 0 1.5em;margin:0}.fancytree-container:focus{outline:0}.fancytree-container .fancytree-active span.fancytree-title input,.fancytree-container.fancytree-colorize-selected .fancytree-selected span.fancytree-title input{color:#000}.fancytree-container span.fancytree-statusnode-error span.fancytree-expander{color:#d9534f}div.fancytree-drag-helper.fancytree-drop-reject,div.fancytree-drag-helper.fancytree-drop-reject span.fancytree-title{color:#d9534f}span.fancytree-node.fancytree-drag-source{background-color:#5bc0de!important}span.fancytree-node.fancytree-drop-target.fancytree-drop-reject span.fancytree.title{background-color:#d9534f!important}span.fancytree-expander{color:#999}.fancytree-expanded span.fancytree-expander{color:#333}span.fancytree-node span.fancytree-expander:hover{color:#0ff}.fancytree-plain.fancytree-colorize-selected span.fancytree-node.fancytree-selected,.fancytree-plain.fancytree-colorize-selected span.fancytree-node.fancytree-selected span.fancytree-title{background-color:#80c780;border-color:#80c780;color:#fff}.fancytree-plain.fancytree-colorize-selected span.fancytree-node.fancytree-selected:hover span.fancytree-title{background-color:#6ec06e}.fancytree-plain.fancytree-colorize-selected span.fancytree-node.fancytree-active.fancytree-selected span.fancytree-title{color:#80c780}.fancytree-plain.fancytree-colorize-selected.fancytree-treefocus span.fancytree-title:hover{background-color:#f5f5f5}.fancytree-plain.fancytree-colorize-selected.fancytree-treefocus span.fancytree-node.fancytree-selected span.fancytree-title{background-color:#5cb85c}.fancytree-plain.fancytree-colorize-selected.fancytree-treefocus span.fancytree-node.fancytree-selected:hover span.fancytree-title{background-color:#4cae4c}.fancytree-plain.fancytree-colorize-selected.fancytree-treefocus span.fancytree-node.fancytree-active.fancytree-selected span.fancytree-title{color:#5cb85c}.fancytree-plain.fancytree-container span.fancytree-node{margin-top:2px;margin-bottom:2px}.fancytree-plain.fancytree-container span.fancytree-title{border:1px solid transparent;border-radius:3px;outline-radius:3px}.fancytree-plain.fancytree-container span.fancytree-title:hover{background-color:#f5f5f5}.fancytree-plain.fancytree-container span.fancytree-node.fancytree-active span.fancytree-title{background-color:#5094ce;color:#fff}.fancytree-plain.fancytree-container span.fancytree-node.fancytree-active:hover span.fancytree-title{background-color:#3c87c8}.fancytree-plain.fancytree-container.fancytree-ext-wide span.fancytree-node.fancytree-active{color:#fff}.fancytree-plain.fancytree-container.fancytree-treefocus span.fancytree-node.fancytree-focused span.fancytree-title{border-color:#337ab7}.fancytree-plain.fancytree-container.fancytree-treefocus span.fancytree-node.fancytree-active span.fancytree-title{background-color:#337ab7;border-color:#337ab7}.fancytree-plain.fancytree-container.fancytree-treefocus span.fancytree-node.fancytree-active:hover span.fancytree-title{background-color:#2e6da4}table.fancytree-ext-table>tbody>tr>td span.fancytree-title{border:none}table.fancytree-ext-table.fancytree-colorize-selected>tbody>tr.fancytree-selected>td{background-color:#80c780}table.fancytree-ext-table.fancytree-colorize-selected>tbody>tr.fancytree-selected>td,table.fancytree-ext-table.fancytree-colorize-selected>tbody>tr.fancytree-selected>td span.fancytree-title{color:#fff}table.fancytree-ext-table.fancytree-colorize-selected.fancytree-treefocus>tbody>tr.fancytree-selected>td{background-color:#5cb85c}table.fancytree-ext-table.fancytree-colorize-selected.table-hover>tbody>tr.fancytree-selected:hover>td{background-color:#6ec06e}table.fancytree-ext-table.fancytree-colorize-selected.fancytree-treefocus.table-hover>tbody>tr.fancytree-selected:hover>td{background-color:#4cae4c}table.fancytree-ext-table.fancytree-colorize-selected.fancytree-treefocus.table-hover>tbody>tr.fancytree-selected.fancytree-active:hover>td,table.fancytree-ext-table.fancytree-colorize-selected.table-hover>tbody>tr.fancytree-selected.fancytree-active:hover>td{background-color:#2e6da4}table.fancytree-ext-table.fancytree-colorize-selected>tbody>tr.fancytree-active.fancytree-selected{outline-width:2px;outline-offset:-2px;outline-style:solid;outline-color:#80c780}table.fancytree-ext-table.fancytree-container>tbody>tr.fancytree-active>td{background-color:#5094ce}table.fancytree-ext-table.fancytree-container>tbody>tr.fancytree-active>td,table.fancytree-ext-table.fancytree-container>tbody>tr.fancytree-active>td span.fancytree-title{color:#fff}table.fancytree-ext-table.fancytree-treefocus.fancytree-container>tbody>tr.fancytree-focused span.fancytree-title{outline:1px dotted #000}table.fancytree-ext-table.fancytree-treefocus.fancytree-container>tbody>tr.fancytree-active>td{background-color:#337ab7}table.fancytree-ext-table.fancytree-treefocus.fancytree-container.table-hover>tbody>tr.fancytree-active:hover>td{background-color:#2e6da4}
\ No newline at end of file diff --git a/plugins/55/indexmenu/scripts/fancytree/skin-bootstrap/vline-rtl.gif b/plugins/55/indexmenu/scripts/fancytree/skin-bootstrap/vline-rtl.gif Binary files differnew file mode 100644 index 0000000..0400cb3 --- /dev/null +++ b/plugins/55/indexmenu/scripts/fancytree/skin-bootstrap/vline-rtl.gif diff --git a/plugins/55/indexmenu/scripts/fancytree/skin-bootstrap/vline.gif b/plugins/55/indexmenu/scripts/fancytree/skin-bootstrap/vline.gif Binary files differnew file mode 100644 index 0000000..1b00ae5 --- /dev/null +++ b/plugins/55/indexmenu/scripts/fancytree/skin-bootstrap/vline.gif diff --git a/plugins/55/indexmenu/scripts/fancytree/skin-common.less b/plugins/55/indexmenu/scripts/fancytree/skin-common.less new file mode 100644 index 0000000..c1f9690 --- /dev/null +++ b/plugins/55/indexmenu/scripts/fancytree/skin-common.less @@ -0,0 +1,972 @@ +/******************************************************************************* + * Common Styles for Fancytree Skins. + * + * This section is automatically generated from the `skin-common.less` template. + * + * Copyright (c) 2008-2023, Martin Wendt (https://wwWendt.de) + * Released under the MIT license + * https://github.com/mar10/fancytree/wiki/LicenseInfo + * + * @version 2.38.3 + * @date 2023-02-01T20:52:50Z +******************************************************************************/ + +// Variables (defaults, may be overwritten by the including .less files) +@fancy-use-sprites: true; // false: suppress all background images (i.e. icons) +// @fancy-hide-connectors: true; // false: show vertical connector lines + +@fancy-level-indent: 16px; +@fancy-line-height: 16px; // height of a nodes selection bar including borders +@fancy-node-v-spacing: 1px; // gap between two node borders +@fancy-icon-width: 16px; +@fancy-icon-height: 16px; +@fancy-icon-spacing: 3px; // margin between icon/icon or icon/title +@fancy-icon-ofs-top: 0px; // extra vertical offset for expander, checkbox and icon +@fancy-title-ofs-top: 0px; // extra vertical offset for title +@fancy-node-border-width: 1px; +@fancy-node-border-radius: 0px; +@fancy-node-outline-width: 1px; + +// @fancy-line-ofs-top: (@fancy-line-height - @fancy-icon-height) / 2; + +// webpack uses /dist/skin-common.less as root path +// grunt-less uses /dist/skin-Xxx/ui.fancyree.less as root path +// So we define our theme LESS files for webpack compatibility, i.e. +// define the image path n every main LESS file instead of here. +// Prefix may be set to "", "/", "./", or any other value +// Note: this variable must be defined by the main LESS files: +// @fancy-image-prefix: ""; + +// Use 'url(...)' to link to the throbber image, or +// use data-uri(...)' to inline the data in css instead: +/* CHANGE use url, as less does not handel data-uri() correct. DokuWiki can eventually inline it */ + @fancy-loading-url: url("@{fancy-image-prefix}loading.gif"); +//@fancy-loading-url: data-uri("@{fancy-image-prefix}loading.gif"); + +// Set to `true` to use `data-uri(...)` instead of a `url(...)` link: +@fancy-inline-sprites: false; // data-uri() is not handle correct by phpless + +@fancy-font-size: 10pt; +@fancy-font-family: tahoma, arial, helvetica; +@fancy-font-color: black; +@fancy-font-color-dimm: #c0c0c0; +@fancy-font-error-color: red; + +//------------------------------------------------------------------------------ +// Mixins +//------------------------------------------------------------------------------ +.setBgPos(@x, @y, @cond:true) when (@cond) { + background-position: (@x * -@fancy-icon-width) (@y * -@fancy-icon-height); +} +.clearBgImage(@cond:true) when (@cond) { + background-image: none; +} +.setBgImageUrl(@url) when (@fancy-use-sprites) and not (@fancy-inline-sprites) { + background-image: url("@{fancy-image-prefix}@{url}"); +} +.setBgImageUrl(@url) when (@fancy-use-sprites) and (@fancy-inline-sprites) { + background-image: data-uri("@{fancy-image-prefix}@{url}"); +} +.useSprite(@x, @y) when (@fancy-use-sprites) { + .setBgPos(@x, @y); +} +.rounded-corners(@radius) { + -webkit-border-radius: @radius; + -moz-border-radius: @radius; + -ms-border-radius: @radius; + -o-border-radius: @radius; + border-radius: @radius; +} +.spanStyleMixin(@color, @bgcolor, @bordercolor) { + border-color: @bordercolor; + background: @bgcolor; + color: @color; +} +.spanStyleMixin(@color, @bgcolor, @bordercolor, @startColor, @stopColor) { + .spanStyleMixin(@color, @bgcolor, @bordercolor); + // @c-start: argb(@startColor); + // @c-end: argb(@stopColor); + background: -moz-linear-gradient( + top, + @startColor 0%, + @stopColor 100% + ); // FF3.6+ + background: -webkit-gradient( + linear, + left top, + left bottom, + color-stop(0%, @startColor), + color-stop(100%, @stopColor) + ); // Chrome,Safari4+ + background: -webkit-linear-gradient( + top, + @startColor 0%, + @stopColor 100% + ); // Chrome10+,Safari5.1+ + background: -o-linear-gradient( + top, + @startColor 0%, + @stopColor 100% + ); // Opera 11.10+ + background: -ms-linear-gradient( + top, + @startColor 0%, + @stopColor 100% + ); // IE10+ + background: linear-gradient( + to bottom, + @startColor 0%, + @stopColor 100% + ); // W3C + filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='@{startColor}', endColorstr='@{stopColor}',GradientType=0 ); // IE6-9 +} + +/*------------------------------------------------------------------------------ + * Helpers + *----------------------------------------------------------------------------*/ +// Redefine, in case jQuery-UI is not included +// .ui-helper-hidden, +.fancytree-helper-hidden { + display: none; +} +.fancytree-helper-indeterminate-cb { + // tri-state checkbox + color: #777; +} +.fancytree-helper-disabled { + color: @fancy-font-color-dimm; +} + +/* Helper to allow spinning loader icon with glyph-, ligature-, and SVG-icons. */ +/* CHANGE: renamed spin to spin-fancytree */ +.fancytree-helper-spin { + -webkit-animation: spin-fancytree 1000ms infinite linear; + animation: spin-fancytree 1000ms infinite linear; +} +/* CHANGE: commented because it is wrong prefixed by phpless +@-webkit-keyframes spin { + 0% { + -webkit-transform: rotate(0deg); + transform: rotate(0deg); + } + 100% { + -webkit-transform: rotate(359deg); + transform: rotate(359deg); + } +} +@keyframes spin { + 0% { + -webkit-transform: rotate(0deg); + transform: rotate(0deg); + } + 100% { + -webkit-transform: rotate(359deg); + transform: rotate(359deg); + } +} +*/ +/*------------------------------------------------------------------------------ + * Container and UL / LI + *----------------------------------------------------------------------------*/ + +ul.fancytree-container { + font-family: @fancy-font-family; + font-size: @fancy-font-size; + white-space: nowrap; + padding: 3px; + margin: 0; // DT issue 201 + //background-color: white; CHANGE + //border: 1px dotted gray; CHANGE + // overflow: auto; // ext-dnd5: otherwise this is always the scroll parent + // height: 100%; // DT issue 263, 470 + min-height: 0%; // #192 + position: relative; // #235 + ul { + padding: 0 0 0 @fancy-level-indent; + margin: 0; + } + ul > li:before { + // #538 + content: none; + } + li { + list-style-image: none; + list-style-position: outside; + list-style-type: none; + -moz-background-clip: border; + -moz-background-inline-policy: continuous; + -moz-background-origin: padding; + background-attachment: scroll; + background-color: transparent; + .setBgPos(0, 0); + background-repeat: repeat-y; + background-image: none; // no v-lines + + margin: 0; + // padding: 1px 0 0 0; // issue #246 + } + // Suppress lines for last child node + li.fancytree-lastsib { + background-image: none; + } +} + +// Style, when control is disabled +.ui-fancytree-disabled ul.fancytree-container { + opacity: 0.5; + // filter: alpha(opacity=50); // Yields a css warning + background-color: silver; +} + +ul.fancytree-connectors.fancytree-container { + li { + // Use 'data-uri(...)' to embed the image into CSS instead of linking to 'loading.gif': + /* CHANGE: phpless does not handle data-uri() correct */ + //background-image: data-uri("@{fancy-image-prefix}vline.gif"); + background-image: url("@{fancy-image-prefix}vline.gif"); + background-position: 0 0; + } +} + +// Suppress lines for last child node +ul.fancytree-container li.fancytree-lastsib, +// Suppress lines if level is fixed expanded (option minExpandLevel) +ul.fancytree-no-connector > li { + background-image: none; +} + +// Fix jQuery UI 'blind' animation for jQuery UI (#717) +li.fancytree-animating { + position: relative; +} + +/*------------------------------------------------------------------------------ + * Common icon definitions + *----------------------------------------------------------------------------*/ + +span.fancytree-empty, +span.fancytree-vline, +span.fancytree-expander, +span.fancytree-icon, +span.fancytree-checkbox, +// span.fancytree-radio, +span.fancytree-drag-helper-img, +#fancytree-drop-marker { + width: @fancy-icon-width; + height: @fancy-icon-height; + // display: -moz-inline-box; // @ FF 1+2 removed for issue 221 + // -moz-box-align: start; /* issue 221 */ + display: inline-block; // Required to make a span sizeable + vertical-align: top; + background-repeat: no-repeat; + // background-position: left; + .setBgImageUrl("icons.gif"); + .setBgPos(0, 0); +} +span.fancytree-icon, +span.fancytree-checkbox, +span.fancytree-expander, +// span.fancytree-radio, +span.fancytree-custom-icon { + margin-top: @fancy-icon-ofs-top; +} +/* Used by icon option: */ +span.fancytree-custom-icon { + width: @fancy-icon-width; + height: @fancy-icon-height; + display: inline-block; + margin-left: @fancy-icon-spacing; + .setBgPos(0, 0); +} +/* Used by 'icon' node option: */ +img.fancytree-icon { + width: @fancy-icon-width; + height: @fancy-icon-height; + margin-left: @fancy-icon-spacing; + margin-top: @fancy-icon-ofs-top; + vertical-align: top; + border-style: none; +} + +/*------------------------------------------------------------------------------ + * Expander icon + * + * Note: IE6 doesn't correctly evaluate multiples class names, + * so we create combined class names that can be used in the CSS. + * + * Prefix: fancytree-exp- + * 1st character: 'e': expanded, 'c': collapsed, 'n': no children + * 2nd character (optional): 'd': lazy (Delayed) + * 3rd character (optional): 'l': Last sibling + *----------------------------------------------------------------------------*/ + +span.fancytree-expander { + // .useSprite(0, 5); + cursor: pointer; +} +// span.fancytree-expander:hover { +// // .useSprite(1, 5); +// } + +// --- End nodes (use connectors instead of expanders) + +.fancytree-exp-n span.fancytree-expander, +.fancytree-exp-nl span.fancytree-expander { + // .clearBgImage( @fancy-hide-connectors ); + background-image: none; + cursor: default; +} +.fancytree-connectors { + .fancytree-exp-n span.fancytree-expander, + .fancytree-exp-nl span.fancytree-expander { + .setBgImageUrl("icons.gif"); + margin-top: 0; + } + .fancytree-exp-n span.fancytree-expander, // End-node, not last sibling + .fancytree-exp-n span.fancytree-expander:hover { + .useSprite(0, 4); + } + .fancytree-exp-nl span.fancytree-expander, // End-node, last sibling + .fancytree-exp-nl span.fancytree-expander:hover { + .useSprite(1, 4); + } +} + +// --- Collapsed + +.fancytree-exp-c span.fancytree-expander { + // Collapsed, not delayed, not last sibling + .useSprite(0, 5); +} +.fancytree-exp-c span.fancytree-expander:hover { + .useSprite(1, 5); +} +.fancytree-exp-cl span.fancytree-expander { + // Collapsed, not delayed, last sibling + .useSprite(0, 6); +} +.fancytree-exp-cl span.fancytree-expander:hover { + .useSprite(1, 6); +} +.fancytree-exp-cd span.fancytree-expander { + // Collapsed, delayed, not last sibling + .useSprite(4, 5); +} +.fancytree-exp-cd span.fancytree-expander:hover { + .useSprite(5, 5); +} +.fancytree-exp-cdl span.fancytree-expander { + // Collapsed, delayed, last sibling + .useSprite(4, 6); +} +.fancytree-exp-cdl span.fancytree-expander:hover { + .useSprite(5, 6); +} + +// --- Expanded + +.fancytree-exp-e span.fancytree-expander, // Expanded, not delayed, not last sibling +.fancytree-exp-ed span.fancytree-expander { + // Expanded, delayed, not last sibling + .useSprite(2, 5); +} +.fancytree-exp-e span.fancytree-expander:hover, +.fancytree-exp-ed span.fancytree-expander:hover { + .useSprite(3, 5); +} +.fancytree-exp-el span.fancytree-expander, // Expanded, not delayed, last sibling +.fancytree-exp-edl span.fancytree-expander { + // Expanded, delayed, last sibling + .useSprite(2, 6); +} +.fancytree-exp-el span.fancytree-expander:hover, +.fancytree-exp-edl span.fancytree-expander:hover { + .useSprite(3, 6); +} + +/* Fade out expanders, when container is not hovered or active */ +.fancytree-fade-expander { + span.fancytree-expander { + transition: opacity 1.5s; + opacity: 0; + } + &:hover span.fancytree-expander, + &.fancytree-treefocus span.fancytree-expander, + .fancytree-treefocus span.fancytree-expander, + [class*="fancytree-statusnode-"] span.fancytree-expander { + transition: opacity 0.6s; + opacity: 1; + } +} + +//// CHANGE: not used. +///*------------------------------------------------------------------------------ +// * Checkbox icon +// *----------------------------------------------------------------------------*/ +// +//span.fancytree-checkbox { +// margin-left: @fancy-icon-spacing; +// .useSprite(0, 2); +// &:hover { +// .useSprite(1, 2); +// } +// &.fancytree-radio { +// .useSprite(0, 3); +// } +// &.fancytree-radio:hover { +// .useSprite(1, 3); +// } +//} +//.fancytree-partsel span.fancytree-checkbox { +// .useSprite(4, 2); +// &:hover { +// .useSprite(5, 2); +// } +// &.fancytree-radio { +// .useSprite(4, 3); +// } +// &.fancytree-radio:hover { +// .useSprite(5, 3); +// } +//} +//// selected after partsel, so it takes precedence: +//.fancytree-selected span.fancytree-checkbox { +// .useSprite(2, 2); +// &:hover { +// .useSprite(3, 2); +// } +// &.fancytree-radio { +// .useSprite(2, 3); +// } +// &.fancytree-radio:hover { +// .useSprite(3, 3); +// } +//} +//// Unselectable is dimmed, without hover effects +//.fancytree-unselectable { +// span.fancytree-checkbox { +// opacity: 0.4; +// filter: alpha(opacity=40); +// } +// span.fancytree-checkbox:hover { +// .useSprite(0, 2); +// } +// span.fancytree-checkbox.fancytree-radio:hover { +// .useSprite(0, 3); +// } +// &.fancytree-partsel span.fancytree-checkbox:hover { +// .useSprite(4, 2); +// } +// &.fancytree-selected span.fancytree-checkbox:hover { +// .useSprite(2, 2); +// } +// &.fancytree-selected span.fancytree-checkbox.fancytree-radio:hover { +// .useSprite(2, 3); +// } +//} +// +//// Auto-hide checkboxes unless selected or hovered +//.fancytree-container.fancytree-checkbox-auto-hide { +// span.fancytree-checkbox { +// visibility: hidden; +// } +// .fancytree-node:hover span.fancytree-checkbox, +// tr:hover td span.fancytree-checkbox, +// .fancytree-node.fancytree-selected span.fancytree-checkbox, +// tr.fancytree-selected td span.fancytree-checkbox { +// visibility: unset; +// } +// &.fancytree-treefocus { +// .fancytree-node.fancytree-active span.fancytree-checkbox, +// tr.fancytree-active td span.fancytree-checkbox { +// visibility: unset; +// } +// } +//} + +/*------------------------------------------------------------------------------ + * Node type icon + * Note: IE6 doesn't correctly evaluate multiples class names, + * so we create combined class names that can be used in the CSS. + * + * Prefix: fancytree-ico- + * 1st character: 'e': expanded, 'c': collapsed + * 2nd character (optional): 'f': folder + *----------------------------------------------------------------------------*/ + +span.fancytree-icon { + // Default icon + margin-left: @fancy-icon-spacing; + .useSprite(0, 0); +} + +/* Documents */ +.fancytree-ico-c span.fancytree-icon { + // Collapsed folder (empty) + // .useSprite(0, 0); +} +.fancytree-ico-c span.fancytree-icon:hover { + .useSprite(1, 0); +} +.fancytree-has-children.fancytree-ico-c span.fancytree-icon { + // Collapsed folder (not empty) + .useSprite(2, 0); +} +.fancytree-has-children.fancytree-ico-c span.fancytree-icon:hover { + .useSprite(3, 0); +} +.fancytree-ico-e span.fancytree-icon { + // Expanded folder + .useSprite(4, 0); +} +.fancytree-ico-e span.fancytree-icon:hover { + .useSprite(5, 0); +} + +/* Folders */ +.fancytree-ico-cf span.fancytree-icon { + // Collapsed folder (empty) + .useSprite(0, 1); +} +.fancytree-ico-cf span.fancytree-icon:hover { + .useSprite(1, 1); +} +.fancytree-has-children.fancytree-ico-cf span.fancytree-icon { + // Collapsed folder (not empty) + .useSprite(2, 1); +} +.fancytree-has-children.fancytree-ico-cf span.fancytree-icon:hover { + .useSprite(3, 1); +} +.fancytree-ico-ef span.fancytree-icon { + // Expanded folder + .useSprite(4, 1); +} +.fancytree-ico-ef span.fancytree-icon:hover { + .useSprite(5, 1); +} + +// 'Loading' status overrides all others +.fancytree-loading span.fancytree-expander, +.fancytree-loading span.fancytree-expander:hover, +.fancytree-statusnode-loading span.fancytree-icon, +.fancytree-statusnode-loading span.fancytree-icon:hover, +span.fancytree-icon.fancytree-icon-loading { + background-image: @fancy-loading-url; + .useSprite(0, 0); +} + +/* Status node icons */ + +.fancytree-statusnode-error span.fancytree-icon, +.fancytree-statusnode-error span.fancytree-icon:hover { + .useSprite(0, 7); +} + +/*------------------------------------------------------------------------------ + * Node titles and highlighting + *----------------------------------------------------------------------------*/ + +span.fancytree-node { + /* See #117 */ + display: inherit; // #117, resolves to 'display: list-item;' for standard trees + width: 100%; + margin-top: @fancy-node-v-spacing; + min-height: @fancy-line-height; +} +span.fancytree-title { + color: @fancy-font-color; // inherit doesn't work on IE + cursor: pointer; + display: inline-block; // Better alignment, when title contains <br> + vertical-align: top; + min-height: @fancy-line-height; + padding: 0 3px 0 3px; // Otherwise italic font will be outside right bounds + margin: @fancy-title-ofs-top 0 0 @fancy-icon-spacing; + // margin: 0px; + // margin-top: @fancy-line-ofs-top; + // margin-left: @fancy-icon-spacing; + border: @fancy-node-border-width solid transparent; // avoid jumping, when a border is added on hover + .rounded-corners(@fancy-node-border-radius); + // outline: 0; // @ Firefox, prevent dotted border after click + // Set transparent border to prevent jumping when active node gets a border + // (we can do this, because this theme doesn't use vertical lines) + // border: 1px solid white; // Note: 'transparent' would not work in IE6 +} +span.fancytree-node.fancytree-error span.fancytree-title { + color: @fancy-font-error-color; +} + +//// CHANGE: not used. +///*------------------------------------------------------------------------------ +// * Drag'n'drop support +// *----------------------------------------------------------------------------*/ +///* ext-dnd5: */ +//span.fancytree-childcounter { +// color: #fff; +// background: #337ab7; // bootstrap blue +// border: 1px solid gray; +// border-radius: 10px; +// padding: 2px; +// text-align: center; +//} +// +///* ext-dnd: */ +//div.fancytree-drag-helper { +// span.fancytree-childcounter, +// span.fancytree-dnd-modifier { +// display: inline-block; +// color: #fff; +// background: #337ab7; // bootstrap blue +// border: 1px solid gray; +// min-width: 10px; +// // min-height: 16px; +// height: 10px; +// line-height: 1; +// vertical-align: baseline; +// border-radius: 10px; +// padding: 2px; +// text-align: center; +// font-size: 9px; +// } +// span.fancytree-childcounter { +// position: absolute; +// // left: 16px; +// top: -6px; +// right: -6px; +// } +// span.fancytree-dnd-modifier { +// background: #5cb85c; // bootstrap green +// border: none; +// // min-height: 16px; +// // font-size: 12px; +// font-weight: bolder; +// } +// &.fancytree-drop-accept { +// span.fancytree-drag-helper-img { +// .useSprite(2, 7); +// } +// } +// &.fancytree-drop-reject { +// span.fancytree-drag-helper-img { +// .useSprite(1, 7); +// } +// } +//} +// +///*** Drop marker icon *********************************************************/ +//#fancytree-drop-marker { +// width: 2 * @fancy-icon-width; // was 24px, but 32 should be correct +// position: absolute; +// .useSprite(0, 8); +// margin: 0; +// &.fancytree-drop-after, +// &.fancytree-drop-before { +// width: 4 * @fancy-icon-width; // 64px; +// .useSprite(0, 9); +// } +// &.fancytree-drop-copy { +// .useSprite(4, 8); +// } +// &.fancytree-drop-move { +// .useSprite(2, 8); +// } +//} +// +///*** Source node while dragging ***********************************************/ +// +//span.fancytree-drag-source { +// &.fancytree-drag-remove { +// // text-decoration: line-through; +// opacity: 0.15; +// } +//} +// +///*** Target node while dragging cursor is over it *****************************/ +// +//span.fancytree-drop-target { +// &.fancytree-drop-accept { +// // outline: 1px dotted #5cb85c; // bootstrap sucess +// } +//} +//span.fancytree-drop-reject { +// // outline: 1px dotted #d9534f; // boostrap warning +//} + +/*------------------------------------------------------------------------------ + * 'rtl' option + *----------------------------------------------------------------------------*/ + +.fancytree-container.fancytree-rtl { + .fancytree-title { + /*unicode-bidi: bidi-override;*/ /* optional: reverse title letters */ + } + span.fancytree-connector, + span.fancytree-expander, + span.fancytree-icon, + span.fancytree-drag-helper-img { + .setBgImageUrl("icons-rtl.gif"); + } + .fancytree-exp-n span.fancytree-expander, + .fancytree-exp-nl span.fancytree-expander { + background-image: none; + } + &.fancytree-connectors .fancytree-exp-n span.fancytree-expander, + &.fancytree-connectors .fancytree-exp-nl span.fancytree-expander { + .setBgImageUrl("icons-rtl.gif"); + } +} +ul.fancytree-container.fancytree-rtl { + ul { + padding: 0 16px 0 0; + } + &.fancytree-connectors li { + background-position: right 0; + background-image: url("@{fancy-image-prefix}vline-rtl.gif"); + } + // Suppress lines for last child node + li.fancytree-lastsib, + // Suppress lines if level is fixed expanded (option minExpandLevel) + &.fancytree-no-connector > li { + background-image: none; + } +} +#fancytree-drop-marker.fancytree-rtl { + .setBgImageUrl("icons-rtl.gif"); +} + +//// CHANGE: not used. +///*------------------------------------------------------------------------------ +// * 'table' extension +// *----------------------------------------------------------------------------*/ +// +//table.fancytree-ext-table { +// font-family: @fancy-font-family; +// font-size: @fancy-font-size; +// border-collapse: collapse; +// span.fancytree-node { +// display: inline-block; // #117 +// box-sizing: border-box; // #562 +// } +// td.fancytree-status-merged { +// text-align: center; +// // font-weight: bold; +// font-style: italic; +// // line-height: 100px; +// color: @fancy-font-color-dimm; +// } +// tr.fancytree-statusnode-error td.fancytree-status-merged { +// color: @fancy-font-error-color; +// } +// /* ext-ariagrid */ +// &.fancytree-ext-ariagrid.fancytree-cell-mode { +// > tbody > tr.fancytree-active > td { +// background-color: #eee; +// } +// > tbody > tr > td.fancytree-active-cell { +// background-color: #cbe8f6; +// } +// &.fancytree-cell-nav-mode > tbody > tr > td.fancytree-active-cell { +// background-color: #3875d7; +// } +// } +//} +// +///*------------------------------------------------------------------------------ +// * 'columnview' extension +// *----------------------------------------------------------------------------*/ +// +//table.fancytree-ext-columnview { +// // border-collapse: collapse; +// // width: 100%; +// tbody tr td { +// position: relative; +// border: 1px solid gray; +// vertical-align: top; +// overflow: auto; +// > ul { +// padding: 0; +// li { +// list-style-image: none; +// list-style-position: outside; +// list-style-type: none; +// -moz-background-clip: border; +// -moz-background-inline-policy: continuous; +// -moz-background-origin: padding; +// background-attachment: scroll; +// background-color: transparent; +// .setBgPos(0, 0); +// background-repeat: repeat-y; +// background-image: none; /* no v-lines */ +// +// margin: 0; +// // padding: 1px 0 0 0; // issue #246 +// } +// } +// } +// span.fancytree-node { +// position: relative; /* allow positioning of embedded spans */ +// display: inline-block; // #117 +// } +// span.fancytree-node.fancytree-expanded { +// background-color: #e0e0e0; +// } +// span.fancytree-node.fancytree-active { +// background-color: #cbe8f6; +// // background-color: royalblue; +// } +// .fancytree-has-children span.fancytree-cv-right { +// position: absolute; +// right: 3px; +// .useSprite(0, 5); +// &:hover { +// .useSprite(1, 5); +// } +// } +//} +// +///*------------------------------------------------------------------------------ +// * 'filter' extension +// *----------------------------------------------------------------------------*/ +// +//.fancytree-ext-filter-dimm { +// span.fancytree-node span.fancytree-title { +// color: @fancy-font-color-dimm; +// font-weight: lighter; +// } +// tr.fancytree-submatch span.fancytree-title, +// span.fancytree-node.fancytree-submatch span.fancytree-title { +// color: black; +// font-weight: normal; +// } +// tr.fancytree-match span.fancytree-title, +// span.fancytree-node.fancytree-match span.fancytree-title { +// color: black; +// font-weight: bold; +// } +//} +//.fancytree-ext-filter-hide { +// tr.fancytree-hide, +// span.fancytree-node.fancytree-hide { +// display: none; +// } +// tr.fancytree-submatch span.fancytree-title, +// span.fancytree-node.fancytree-submatch span.fancytree-title { +// color: @fancy-font-color-dimm; +// font-weight: lighter; +// } +// tr.fancytree-match span.fancytree-title, +// span.fancytree-node.fancytree-match span.fancytree-title { +// color: black; +// font-weight: normal; +// } +//} +///* Hide expanders if all child nodes are hidden by filter */ +//.fancytree-ext-filter-hide-expanders { +// tr.fancytree-match span.fancytree-expander, +// span.fancytree-node.fancytree-match span.fancytree-expander { +// visibility: hidden; +// } +// tr.fancytree-submatch span.fancytree-expander, +// span.fancytree-node.fancytree-submatch span.fancytree-expander { +// visibility: visible; +// } +//} +// +//.fancytree-ext-childcounter, +//.fancytree-ext-filter { +// // span.fancytree-title mark { +// // font-style: normal; +// // background-color: #ead61c; // yellow +// // border-radius: 3px; +// // } +// span.fancytree-icon, +// span.fancytree-custom-icon { +// position: relative; +// } +// span.fancytree-childcounter { +// color: #fff; +// background: #777; // #337ab7; // bootstrap blue +// border: 1px solid gray; +// position: absolute; +// top: -6px; +// right: -6px; +// min-width: 10px; +// height: 10px; +// line-height: 1; +// vertical-align: baseline; +// border-radius: 10px; +// padding: 2px; +// text-align: center; +// font-size: 9px; +// } +//} +///*------------------------------------------------------------------------------ +// * 'wide' extension +// *----------------------------------------------------------------------------*/ +// +//ul.fancytree-ext-wide { +// position: relative; +// min-width: 100%; +// z-index: 2; +// +// -webkit-box-sizing: border-box; +// -moz-box-sizing: border-box; +// box-sizing: border-box; +// +// span.fancytree-node > span { +// position: relative; +// z-index: 2; +// } +// span.fancytree-node span.fancytree-title { +// position: absolute; // Allow left: 0. Note: prevents smooth dropdown animation +// z-index: 1; // Behind expander and checkbox +// left: 0px; +// min-width: 100%; +// margin-left: 0; +// margin-right: 0; +// +// -webkit-box-sizing: border-box; +// -moz-box-sizing: border-box; +// box-sizing: border-box; +// } +//} +// +///*------------------------------------------------------------------------------ +// * 'fixed' extension +// *----------------------------------------------------------------------------*/ +// +//.fancytree-ext-fixed-wrapper { +// .fancytree-ext-fixed-hidden { +// display: none; +// } +// div.fancytree-ext-fixed-scroll-border-bottom { +// border-bottom: 3px solid rgba(0, 0, 0, 0.75); +// } +// div.fancytree-ext-fixed-scroll-border-right { +// border-right: 3px solid rgba(0, 0, 0, 0.75); +// } +// div.fancytree-ext-fixed-wrapper-tl { +// position: absolute; +// overflow: hidden; +// z-index: 3; +// top: 0px; +// left: 0px; +// } +// div.fancytree-ext-fixed-wrapper-tr { +// position: absolute; +// overflow: hidden; +// z-index: 2; +// top: 0px; +// } +// div.fancytree-ext-fixed-wrapper-bl { +// position: absolute; +// overflow: hidden; +// z-index: 2; +// left: 0px; +// } +// div.fancytree-ext-fixed-wrapper-br { +// position: absolute; +// overflow: scroll; +// z-index: 1; +// } +//} diff --git a/plugins/55/indexmenu/scripts/fancytree/skin-custom-1/README.md b/plugins/55/indexmenu/scripts/fancytree/skin-custom-1/README.md new file mode 100644 index 0000000..c1703a7 --- /dev/null +++ b/plugins/55/indexmenu/scripts/fancytree/skin-custom-1/README.md @@ -0,0 +1,14 @@ +### Creating Custom Skins + +1. Create a folder like this (recommended name: 'src/skin-custom-...') +2. For a start, copy files from one of the existing skin folders (src/skin-...) + to the custom folder: + - ui.fancytree.less (required) + - icons.gif (if needed) + - loading.gif (if needed) +3. cd to your fancytree folder and run `grunt dev` from the console.<br> + Note: NPM and Grunt are required. + Read [how to install the toolset](https://github.com/mar10/fancytree/wiki/HowtoContribute#install-the-source-code-and-tools-for-debugging-and-contributing). +4. Edit and save your ui.fancytree.less file.<br> + The `ui.fancytree.css` will be generated and updated automatically from + the LESS file. diff --git a/plugins/55/indexmenu/scripts/fancytree/skin-lion/icons-rtl.gif b/plugins/55/indexmenu/scripts/fancytree/skin-lion/icons-rtl.gif Binary files differnew file mode 100644 index 0000000..a4eeb9e --- /dev/null +++ b/plugins/55/indexmenu/scripts/fancytree/skin-lion/icons-rtl.gif diff --git a/plugins/55/indexmenu/scripts/fancytree/skin-lion/icons.gif b/plugins/55/indexmenu/scripts/fancytree/skin-lion/icons.gif Binary files differnew file mode 100644 index 0000000..1ca2af6 --- /dev/null +++ b/plugins/55/indexmenu/scripts/fancytree/skin-lion/icons.gif diff --git a/plugins/55/indexmenu/scripts/fancytree/skin-lion/loading.gif b/plugins/55/indexmenu/scripts/fancytree/skin-lion/loading.gif Binary files differnew file mode 100644 index 0000000..5b33f7e --- /dev/null +++ b/plugins/55/indexmenu/scripts/fancytree/skin-lion/loading.gif diff --git a/plugins/55/indexmenu/scripts/fancytree/skin-lion/skin-common.less b/plugins/55/indexmenu/scripts/fancytree/skin-lion/skin-common.less new file mode 100644 index 0000000..fc0da50 --- /dev/null +++ b/plugins/55/indexmenu/scripts/fancytree/skin-lion/skin-common.less @@ -0,0 +1,972 @@ +/******************************************************************************* + * Common Styles for Fancytree Skins. + * + * This section is automatically generated from the `skin-common.less` template. + * + * Copyright (c) 2008-2023, Martin Wendt (https://wwWendt.de) + * Released under the MIT license + * https://github.com/mar10/fancytree/wiki/LicenseInfo + * + * @version 2.38.3 + * @date 2023-02-01T20:52:50Z +******************************************************************************/ + +// Variables (defaults, may be overwritten by the including .less files) +@fancy-use-sprites: true; // false: suppress all background images (i.e. icons) +// @fancy-hide-connectors: true; // false: show vertical connector lines + +@fancy-level-indent: 16px; +@fancy-line-height: 16px; // height of a nodes selection bar including borders +@fancy-node-v-spacing: 1px; // gap between two node borders +@fancy-icon-width: 16px; +@fancy-icon-height: 16px; +@fancy-icon-spacing: 3px; // margin between icon/icon or icon/title +@fancy-icon-ofs-top: 0px; // extra vertical offset for expander, checkbox and icon +@fancy-title-ofs-top: 0px; // extra vertical offset for title +@fancy-node-border-width: 1px; +@fancy-node-border-radius: 0px; +@fancy-node-outline-width: 1px; + +// @fancy-line-ofs-top: (@fancy-line-height - @fancy-icon-height) / 2; + +// webpack uses /dist/skin-common.less as root path +// grunt-less uses /dist/skin-Xxx/ui.fancyree.less as root path +// So we define our theme LESS files for webpack compatibility, i.e. +// define the image path n every main LESS file instead of here. +// Prefix may be set to "", "/", "./", or any other value +// Note: this variable must be defined by the main LESS files: +// @fancy-image-prefix: ""; + +// Use 'url(...)' to link to the throbber image, or +// use data-uri(...)' to inline the data in css instead: +/* CHANGE use url, as less does not handel data-uri() correct. DokuWiki can eventually inline it */ + @fancy-loading-url: url("@{fancy-image-prefix}loading.gif"); +//@fancy-loading-url: data-uri("@{fancy-image-prefix}loading.gif"); + +// Set to `true` to use `data-uri(...)` instead of a `url(...)` link: +@fancy-inline-sprites: false; // data-uri() is not handle correct by phpless + +@fancy-font-size: 10pt; +@fancy-font-family: tahoma, arial, helvetica; +@fancy-font-color: black; +@fancy-font-color-dimm: #c0c0c0; +@fancy-font-error-color: red; + +//------------------------------------------------------------------------------ +// Mixins +//------------------------------------------------------------------------------ +.setBgPos(@x, @y, @cond:true) when (@cond) { + background-position: (@x * -@fancy-icon-width) (@y * -@fancy-icon-height); +} +.clearBgImage(@cond:true) when (@cond) { + background-image: none; +} +.setBgImageUrl(@url) when (@fancy-use-sprites) and not (@fancy-inline-sprites) { + background-image: url("@{fancy-image-prefix}@{url}"); +} +.setBgImageUrl(@url) when (@fancy-use-sprites) and (@fancy-inline-sprites) { + background-image: data-uri("@{fancy-image-prefix}@{url}"); +} +.useSprite(@x, @y) when (@fancy-use-sprites) { + .setBgPos(@x, @y); +} +.rounded-corners(@radius) { + -webkit-border-radius: @radius; + -moz-border-radius: @radius; + -ms-border-radius: @radius; + -o-border-radius: @radius; + border-radius: @radius; +} +.spanStyleMixin(@color, @bgcolor, @bordercolor) { + border-color: @bordercolor; + background: @bgcolor; + color: @color; +} +.spanStyleMixin(@color, @bgcolor, @bordercolor, @startColor, @stopColor) { + .spanStyleMixin(@color, @bgcolor, @bordercolor); + // @c-start: argb(@startColor); + // @c-end: argb(@stopColor); + background: -moz-linear-gradient( + top, + @startColor 0%, + @stopColor 100% + ); // FF3.6+ + background: -webkit-gradient( + linear, + left top, + left bottom, + color-stop(0%, @startColor), + color-stop(100%, @stopColor) + ); // Chrome,Safari4+ + background: -webkit-linear-gradient( + top, + @startColor 0%, + @stopColor 100% + ); // Chrome10+,Safari5.1+ + background: -o-linear-gradient( + top, + @startColor 0%, + @stopColor 100% + ); // Opera 11.10+ + background: -ms-linear-gradient( + top, + @startColor 0%, + @stopColor 100% + ); // IE10+ + background: linear-gradient( + to bottom, + @startColor 0%, + @stopColor 100% + ); // W3C + filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='@{startColor}', endColorstr='@{stopColor}',GradientType=0 ); // IE6-9 +} + +/*------------------------------------------------------------------------------ + * Helpers + *----------------------------------------------------------------------------*/ +// Redefine, in case jQuery-UI is not included +// .ui-helper-hidden, +.fancytree-helper-hidden { + display: none; +} +.fancytree-helper-indeterminate-cb { + // tri-state checkbox + color: #777; +} +.fancytree-helper-disabled { + color: @fancy-font-color-dimm; +} + +/* Helper to allow spinning loader icon with glyph-, ligature-, and SVG-icons. */ +/* CHANGE: renamed spin to spin-fancytree */ +.fancytree-helper-spin { + -webkit-animation: spin-fancytree 1000ms infinite linear; + animation: spin-fancytree 1000ms infinite linear; +} +/* CHANGE: commented because it is wrong prefixed by phpless +@-webkit-keyframes spin { + 0% { + -webkit-transform: rotate(0deg); + transform: rotate(0deg); + } + 100% { + -webkit-transform: rotate(359deg); + transform: rotate(359deg); + } +} +@keyframes spin { + 0% { + -webkit-transform: rotate(0deg); + transform: rotate(0deg); + } + 100% { + -webkit-transform: rotate(359deg); + transform: rotate(359deg); + } +} +*/ +/*------------------------------------------------------------------------------ + * Container and UL / LI + *----------------------------------------------------------------------------*/ + +ul.fancytree-container { + font-family: @fancy-font-family; + font-size: @fancy-font-size; + white-space: nowrap; + padding: 3px; + margin: 0; // DT issue 201 + //background-color: white; CHANGE + //border: 1px dotted gray; CHANGE + // overflow: auto; // ext-dnd5: otherwise this is always the scroll parent + // height: 100%; // DT issue 263, 470 + min-height: 0%; // #192 + position: relative; // #235 + ul { + padding: 0 0 0 @fancy-level-indent; + margin: 0; + } + ul > li:before { + // #538 + content: none; + } + li { + list-style-image: none; + list-style-position: outside; + list-style-type: none; + -moz-background-clip: border; + -moz-background-inline-policy: continuous; + -moz-background-origin: padding; + background-attachment: scroll; + background-color: transparent; + .setBgPos(0, 0); + background-repeat: repeat-y; + background-image: none; // no v-lines + + margin: 0; + // padding: 1px 0 0 0; // issue #246 + } + // Suppress lines for last child node + li.fancytree-lastsib { + background-image: none; + } +} + +// Style, when control is disabled +.ui-fancytree-disabled ul.fancytree-container { + opacity: 0.5; + // filter: alpha(opacity=50); // Yields a css warning + background-color: silver; +} + +ul.fancytree-connectors.fancytree-container { + li { + // Use 'data-uri(...)' to embed the image into CSS instead of linking to 'loading.gif': + /* CHANGE: phpless does not handle data-uri() correct */ + //background-image: data-uri("@{fancy-image-prefix}vline.gif"); + background-image: url("@{fancy-image-prefix}vline.gif"); + background-position: 0 0; + } +} + +// Suppress lines for last child node +ul.fancytree-container li.fancytree-lastsib, +// Suppress lines if level is fixed expanded (option minExpandLevel) +ul.fancytree-no-connector > li { + background-image: none; +} + +// Fix jQuery UI 'blind' animation for jQuery UI (#717) +li.fancytree-animating { + position: relative; +} + +/*------------------------------------------------------------------------------ + * Common icon definitions + *----------------------------------------------------------------------------*/ + +span.fancytree-empty, +span.fancytree-vline, +span.fancytree-expander, +span.fancytree-icon, +span.fancytree-checkbox, +// span.fancytree-radio, +span.fancytree-drag-helper-img, +#fancytree-drop-marker { + width: @fancy-icon-width; + height: @fancy-icon-height; + // display: -moz-inline-box; // @ FF 1+2 removed for issue 221 + // -moz-box-align: start; /* issue 221 */ + display: inline-block; // Required to make a span sizeable + vertical-align: top; + background-repeat: no-repeat; + // background-position: left; + .setBgImageUrl("icons.gif"); + .setBgPos(0, 0); +} +span.fancytree-icon, +span.fancytree-checkbox, +span.fancytree-expander, +// span.fancytree-radio, +span.fancytree-custom-icon { + margin-top: @fancy-icon-ofs-top; +} +/* Used by icon option: */ +span.fancytree-custom-icon { + width: @fancy-icon-width; + height: @fancy-icon-height; + display: inline-block; + margin-left: @fancy-icon-spacing; + .setBgPos(0, 0); +} +/* Used by 'icon' node option: */ +img.fancytree-icon { + width: @fancy-icon-width; + height: @fancy-icon-height; + margin-left: @fancy-icon-spacing; + margin-top: @fancy-icon-ofs-top; + vertical-align: top; + border-style: none; +} + +/*------------------------------------------------------------------------------ + * Expander icon + * + * Note: IE6 doesn't correctly evaluate multiples class names, + * so we create combined class names that can be used in the CSS. + * + * Prefix: fancytree-exp- + * 1st character: 'e': expanded, 'c': collapsed, 'n': no children + * 2nd character (optional): 'd': lazy (Delayed) + * 3rd character (optional): 'l': Last sibling + *----------------------------------------------------------------------------*/ + +span.fancytree-expander { + // .useSprite(0, 5); + cursor: pointer; +} +// span.fancytree-expander:hover { +// // .useSprite(1, 5); +// } + +// --- End nodes (use connectors instead of expanders) + +.fancytree-exp-n span.fancytree-expander, +.fancytree-exp-nl span.fancytree-expander { + // .clearBgImage( @fancy-hide-connectors ); + background-image: none; + cursor: default; +} +.fancytree-connectors { + .fancytree-exp-n span.fancytree-expander, + .fancytree-exp-nl span.fancytree-expander { + .setBgImageUrl("icons.gif"); + margin-top: 0; + } + .fancytree-exp-n span.fancytree-expander, // End-node, not last sibling + .fancytree-exp-n span.fancytree-expander:hover { + .useSprite(0, 4); + } + .fancytree-exp-nl span.fancytree-expander, // End-node, last sibling + .fancytree-exp-nl span.fancytree-expander:hover { + .useSprite(1, 4); + } +} + +// --- Collapsed + +.fancytree-exp-c span.fancytree-expander { + // Collapsed, not delayed, not last sibling + .useSprite(0, 5); +} +.fancytree-exp-c span.fancytree-expander:hover { + .useSprite(1, 5); +} +.fancytree-exp-cl span.fancytree-expander { + // Collapsed, not delayed, last sibling + .useSprite(0, 6); +} +.fancytree-exp-cl span.fancytree-expander:hover { + .useSprite(1, 6); +} +.fancytree-exp-cd span.fancytree-expander { + // Collapsed, delayed, not last sibling + .useSprite(4, 5); +} +.fancytree-exp-cd span.fancytree-expander:hover { + .useSprite(5, 5); +} +.fancytree-exp-cdl span.fancytree-expander { + // Collapsed, delayed, last sibling + .useSprite(4, 6); +} +.fancytree-exp-cdl span.fancytree-expander:hover { + .useSprite(5, 6); +} + +// --- Expanded + +.fancytree-exp-e span.fancytree-expander, // Expanded, not delayed, not last sibling +.fancytree-exp-ed span.fancytree-expander { + // Expanded, delayed, not last sibling + .useSprite(2, 5); +} +.fancytree-exp-e span.fancytree-expander:hover, +.fancytree-exp-ed span.fancytree-expander:hover { + .useSprite(3, 5); +} +.fancytree-exp-el span.fancytree-expander, // Expanded, not delayed, last sibling +.fancytree-exp-edl span.fancytree-expander { + // Expanded, delayed, last sibling + .useSprite(2, 6); +} +.fancytree-exp-el span.fancytree-expander:hover, +.fancytree-exp-edl span.fancytree-expander:hover { + .useSprite(3, 6); +} + +/* Fade out expanders, when container is not hovered or active */ +.fancytree-fade-expander { + span.fancytree-expander { + transition: opacity 1.5s; + opacity: 0; + } + &:hover span.fancytree-expander, + &.fancytree-treefocus span.fancytree-expander, + .fancytree-treefocus span.fancytree-expander, + [class*="fancytree-statusnode-"] span.fancytree-expander { + transition: opacity 0.6s; + opacity: 1; + } +} + +//// CHANGE: not used. +///*------------------------------------------------------------------------------ +// * Checkbox icon +// *----------------------------------------------------------------------------*/ +// +//span.fancytree-checkbox { +// margin-left: @fancy-icon-spacing; +// .useSprite(0, 2); +// &:hover { +// .useSprite(1, 2); +// } +// &.fancytree-radio { +// .useSprite(0, 3); +// } +// &.fancytree-radio:hover { +// .useSprite(1, 3); +// } +//} +//.fancytree-partsel span.fancytree-checkbox { +// .useSprite(4, 2); +// &:hover { +// .useSprite(5, 2); +// } +// &.fancytree-radio { +// .useSprite(4, 3); +// } +// &.fancytree-radio:hover { +// .useSprite(5, 3); +// } +//} +//// selected after partsel, so it takes precedence: +//.fancytree-selected span.fancytree-checkbox { +// .useSprite(2, 2); +// &:hover { +// .useSprite(3, 2); +// } +// &.fancytree-radio { +// .useSprite(2, 3); +// } +// &.fancytree-radio:hover { +// .useSprite(3, 3); +// } +//} +//// Unselectable is dimmed, without hover effects +//.fancytree-unselectable { +// span.fancytree-checkbox { +// opacity: 0.4; +// filter: alpha(opacity=40); +// } +// span.fancytree-checkbox:hover { +// .useSprite(0, 2); +// } +// span.fancytree-checkbox.fancytree-radio:hover { +// .useSprite(0, 3); +// } +// &.fancytree-partsel span.fancytree-checkbox:hover { +// .useSprite(4, 2); +// } +// &.fancytree-selected span.fancytree-checkbox:hover { +// .useSprite(2, 2); +// } +// &.fancytree-selected span.fancytree-checkbox.fancytree-radio:hover { +// .useSprite(2, 3); +// } +//} +// +//// Auto-hide checkboxes unless selected or hovered +//.fancytree-container.fancytree-checkbox-auto-hide { +// span.fancytree-checkbox { +// visibility: hidden; +// } +// .fancytree-node:hover span.fancytree-checkbox, +// tr:hover td span.fancytree-checkbox, +// .fancytree-node.fancytree-selected span.fancytree-checkbox, +// tr.fancytree-selected td span.fancytree-checkbox { +// visibility: unset; +// } +// &.fancytree-treefocus { +// .fancytree-node.fancytree-active span.fancytree-checkbox, +// tr.fancytree-active td span.fancytree-checkbox { +// visibility: unset; +// } +// } +//} + +/*------------------------------------------------------------------------------ + * Node type icon + * Note: IE6 doesn't correctly evaluate multiples class names, + * so we create combined class names that can be used in the CSS. + * + * Prefix: fancytree-ico- + * 1st character: 'e': expanded, 'c': collapsed + * 2nd character (optional): 'f': folder + *----------------------------------------------------------------------------*/ + +span.fancytree-icon { + // Default icon + margin-left: @fancy-icon-spacing; + .useSprite(0, 0); +} + +/* Documents */ +.fancytree-ico-c span.fancytree-icon { + // Collapsed folder (empty) + // .useSprite(0, 0); +} +.fancytree-ico-c span.fancytree-icon:hover { + .useSprite(1, 0); +} +.fancytree-has-children.fancytree-ico-c span.fancytree-icon { + // Collapsed folder (not empty) + .useSprite(2, 0); +} +.fancytree-has-children.fancytree-ico-c span.fancytree-icon:hover { + .useSprite(3, 0); +} +.fancytree-ico-e span.fancytree-icon { + // Expanded folder + .useSprite(4, 0); +} +.fancytree-ico-e span.fancytree-icon:hover { + .useSprite(5, 0); +} + +/* Folders */ +.fancytree-ico-cf span.fancytree-icon { + // Collapsed folder (empty) + .useSprite(0, 1); +} +.fancytree-ico-cf span.fancytree-icon:hover { + .useSprite(1, 1); +} +.fancytree-has-children.fancytree-ico-cf span.fancytree-icon { + // Collapsed folder (not empty) + .useSprite(2, 1); +} +.fancytree-has-children.fancytree-ico-cf span.fancytree-icon:hover { + .useSprite(3, 1); +} +.fancytree-ico-ef span.fancytree-icon { + // Expanded folder + .useSprite(4, 1); +} +.fancytree-ico-ef span.fancytree-icon:hover { + .useSprite(5, 1); +} + +// 'Loading' status overrides all others +.fancytree-loading span.fancytree-expander, +.fancytree-loading span.fancytree-expander:hover, +.fancytree-statusnode-loading span.fancytree-icon, +.fancytree-statusnode-loading span.fancytree-icon:hover, +span.fancytree-icon.fancytree-icon-loading { + background-image: @fancy-loading-url; + .useSprite(0, 0); +} + +/* Status node icons */ + +.fancytree-statusnode-error span.fancytree-icon, +.fancytree-statusnode-error span.fancytree-icon:hover { + .useSprite(0, 7); +} + +/*------------------------------------------------------------------------------ + * Node titles and highlighting + *----------------------------------------------------------------------------*/ + +span.fancytree-node { + /* See #117 */ + display: inherit; // #117, resolves to 'display: list-item;' for standard trees + width: 100%; + margin-top: @fancy-node-v-spacing; + min-height: @fancy-line-height; +} +span.fancytree-title { + color: @fancy-font-color; // inherit doesn't work on IE + cursor: pointer; + display: inline-block; // Better alignment, when title contains <br> + vertical-align: top; + min-height: @fancy-line-height; + padding: 0 3px 0 3px; // Otherwise italic font will be outside right bounds + margin: @fancy-title-ofs-top 0 0 @fancy-icon-spacing; + // margin: 0px; + // margin-top: @fancy-line-ofs-top; + // margin-left: @fancy-icon-spacing; + border: @fancy-node-border-width solid transparent; // avoid jumping, when a border is added on hover + .rounded-corners(@fancy-node-border-radius); + // outline: 0; // @ Firefox, prevent dotted border after click + // Set transparent border to prevent jumping when active node gets a border + // (we can do this, because this theme doesn't use vertical lines) + // border: 1px solid white; // Note: 'transparent' would not work in IE6 +} +span.fancytree-node.fancytree-error span.fancytree-title { + color: @fancy-font-error-color; +} + +//// CHANGE: not used. +///*------------------------------------------------------------------------------ +// * Drag'n'drop support +// *----------------------------------------------------------------------------*/ +///* ext-dnd5: */ +//span.fancytree-childcounter { +// color: #fff; +// background: #337ab7; // bootstrap blue +// border: 1px solid gray; +// border-radius: 10px; +// padding: 2px; +// text-align: center; +//} +// +///* ext-dnd: */ +//div.fancytree-drag-helper { +// span.fancytree-childcounter, +// span.fancytree-dnd-modifier { +// display: inline-block; +// color: #fff; +// background: #337ab7; // bootstrap blue +// border: 1px solid gray; +// min-width: 10px; +// // min-height: 16px; +// height: 10px; +// line-height: 1; +// vertical-align: baseline; +// border-radius: 10px; +// padding: 2px; +// text-align: center; +// font-size: 9px; +// } +// span.fancytree-childcounter { +// position: absolute; +// // left: 16px; +// top: -6px; +// right: -6px; +// } +// span.fancytree-dnd-modifier { +// background: #5cb85c; // bootstrap green +// border: none; +// // min-height: 16px; +// // font-size: 12px; +// font-weight: bolder; +// } +// &.fancytree-drop-accept { +// span.fancytree-drag-helper-img { +// .useSprite(2, 7); +// } +// } +// &.fancytree-drop-reject { +// span.fancytree-drag-helper-img { +// .useSprite(1, 7); +// } +// } +//} +// +///*** Drop marker icon *********************************************************/ +//#fancytree-drop-marker { +// width: 2 * @fancy-icon-width; // was 24px, but 32 should be correct +// position: absolute; +// .useSprite(0, 8); +// margin: 0; +// &.fancytree-drop-after, +// &.fancytree-drop-before { +// width: 4 * @fancy-icon-width; // 64px; +// .useSprite(0, 9); +// } +// &.fancytree-drop-copy { +// .useSprite(4, 8); +// } +// &.fancytree-drop-move { +// .useSprite(2, 8); +// } +//} +// +///*** Source node while dragging ***********************************************/ +// +//span.fancytree-drag-source { +// &.fancytree-drag-remove { +// // text-decoration: line-through; +// opacity: 0.15; +// } +//} +// +///*** Target node while dragging cursor is over it *****************************/ +// +//span.fancytree-drop-target { +// &.fancytree-drop-accept { +// // outline: 1px dotted #5cb85c; // bootstrap sucess +// } +//} +//span.fancytree-drop-reject { +// // outline: 1px dotted #d9534f; // boostrap warning +//} + +/*------------------------------------------------------------------------------ + * 'rtl' option + *----------------------------------------------------------------------------*/ + +.fancytree-container.fancytree-rtl { + .fancytree-title { + /*unicode-bidi: bidi-override;*/ /* optional: reverse title letters */ + } + span.fancytree-connector, + span.fancytree-expander, + span.fancytree-icon, + span.fancytree-drag-helper-img { + .setBgImageUrl("icons-rtl.gif"); + } + .fancytree-exp-n span.fancytree-expander, + .fancytree-exp-nl span.fancytree-expander { + background-image: none; + } + &.fancytree-connectors .fancytree-exp-n span.fancytree-expander, + &.fancytree-connectors .fancytree-exp-nl span.fancytree-expander { + .setBgImageUrl("icons-rtl.gif"); + } +} +ul.fancytree-container.fancytree-rtl { + ul { + padding: 0 16px 0 0; + } + &.fancytree-connectors li { + background-position: right 0; + background-image: url("@{fancy-image-prefix}vline-rtl.gif"); + } + // Suppress lines for last child node + li.fancytree-lastsib, + // Suppress lines if level is fixed expanded (option minExpandLevel) + &.fancytree-no-connector > li { + background-image: none; + } +} +#fancytree-drop-marker.fancytree-rtl { + .setBgImageUrl("icons-rtl.gif"); +} + +//// CHANGE: not used. +///*------------------------------------------------------------------------------ +// * 'table' extension +// *----------------------------------------------------------------------------*/ +// +//table.fancytree-ext-table { +// font-family: @fancy-font-family; +// font-size: @fancy-font-size; +// border-collapse: collapse; +// span.fancytree-node { +// display: inline-block; // #117 +// box-sizing: border-box; // #562 +// } +// td.fancytree-status-merged { +// text-align: center; +// // font-weight: bold; +// font-style: italic; +// // line-height: 100px; +// color: @fancy-font-color-dimm; +// } +// tr.fancytree-statusnode-error td.fancytree-status-merged { +// color: @fancy-font-error-color; +// } +// /* ext-ariagrid */ +// &.fancytree-ext-ariagrid.fancytree-cell-mode { +// > tbody > tr.fancytree-active > td { +// background-color: #eee; +// } +// > tbody > tr > td.fancytree-active-cell { +// background-color: #cbe8f6; +// } +// &.fancytree-cell-nav-mode > tbody > tr > td.fancytree-active-cell { +// background-color: #3875d7; +// } +// } +//} +// +///*------------------------------------------------------------------------------ +// * 'columnview' extension +// *----------------------------------------------------------------------------*/ +// +//table.fancytree-ext-columnview { +// // border-collapse: collapse; +// // width: 100%; +// tbody tr td { +// position: relative; +// border: 1px solid gray; +// vertical-align: top; +// overflow: auto; +// > ul { +// padding: 0; +// li { +// list-style-image: none; +// list-style-position: outside; +// list-style-type: none; +// -moz-background-clip: border; +// -moz-background-inline-policy: continuous; +// -moz-background-origin: padding; +// background-attachment: scroll; +// background-color: transparent; +// .setBgPos(0, 0); +// background-repeat: repeat-y; +// background-image: none; /* no v-lines */ +// +// margin: 0; +// // padding: 1px 0 0 0; // issue #246 +// } +// } +// } +// span.fancytree-node { +// position: relative; /* allow positioning of embedded spans */ +// display: inline-block; // #117 +// } +// span.fancytree-node.fancytree-expanded { +// background-color: #e0e0e0; +// } +// span.fancytree-node.fancytree-active { +// background-color: #cbe8f6; +// // background-color: royalblue; +// } +// .fancytree-has-children span.fancytree-cv-right { +// position: absolute; +// right: 3px; +// .useSprite(0, 5); +// &:hover { +// .useSprite(1, 5); +// } +// } +//} +// +///*------------------------------------------------------------------------------ +// * 'filter' extension +// *----------------------------------------------------------------------------*/ +// +//.fancytree-ext-filter-dimm { +// span.fancytree-node span.fancytree-title { +// color: @fancy-font-color-dimm; +// font-weight: lighter; +// } +// tr.fancytree-submatch span.fancytree-title, +// span.fancytree-node.fancytree-submatch span.fancytree-title { +// color: black; +// font-weight: normal; +// } +// tr.fancytree-match span.fancytree-title, +// span.fancytree-node.fancytree-match span.fancytree-title { +// color: black; +// font-weight: bold; +// } +//} +//.fancytree-ext-filter-hide { +// tr.fancytree-hide, +// span.fancytree-node.fancytree-hide { +// display: none; +// } +// tr.fancytree-submatch span.fancytree-title, +// span.fancytree-node.fancytree-submatch span.fancytree-title { +// color: @fancy-font-color-dimm; +// font-weight: lighter; +// } +// tr.fancytree-match span.fancytree-title, +// span.fancytree-node.fancytree-match span.fancytree-title { +// color: black; +// font-weight: normal; +// } +//} +///* Hide expanders if all child nodes are hidden by filter */ +//.fancytree-ext-filter-hide-expanders { +// tr.fancytree-match span.fancytree-expander, +// span.fancytree-node.fancytree-match span.fancytree-expander { +// visibility: hidden; +// } +// tr.fancytree-submatch span.fancytree-expander, +// span.fancytree-node.fancytree-submatch span.fancytree-expander { +// visibility: visible; +// } +//} +// +//.fancytree-ext-childcounter, +//.fancytree-ext-filter { +// // span.fancytree-title mark { +// // font-style: normal; +// // background-color: #ead61c; // yellow +// // border-radius: 3px; +// // } +// span.fancytree-icon, +// span.fancytree-custom-icon { +// position: relative; +// } +// span.fancytree-childcounter { +// color: #fff; +// background: #777; // #337ab7; // bootstrap blue +// border: 1px solid gray; +// position: absolute; +// top: -6px; +// right: -6px; +// min-width: 10px; +// height: 10px; +// line-height: 1; +// vertical-align: baseline; +// border-radius: 10px; +// padding: 2px; +// text-align: center; +// font-size: 9px; +// } +//} +///*------------------------------------------------------------------------------ +// * 'wide' extension +// *----------------------------------------------------------------------------*/ +// +//ul.fancytree-ext-wide { +// position: relative; +// min-width: 100%; +// z-index: 2; +// +// -webkit-box-sizing: border-box; +// -moz-box-sizing: border-box; +// box-sizing: border-box; +// +// span.fancytree-node > span { +// position: relative; +// z-index: 2; +// } +// span.fancytree-node span.fancytree-title { +// position: absolute; // Allow left: 0. Note: prevents smooth dropdown animation +// z-index: 1; // Behind expander and checkbox +// left: 0px; +// min-width: 100%; +// margin-left: 0; +// margin-right: 0; +// +// -webkit-box-sizing: border-box; +// -moz-box-sizing: border-box; +// box-sizing: border-box; +// } +//} +// +///*------------------------------------------------------------------------------ +// * 'fixed' extension +// *----------------------------------------------------------------------------*/ +// +//.fancytree-ext-fixed-wrapper { +// .fancytree-ext-fixed-hidden { +// display: none; +// } +// div.fancytree-ext-fixed-scroll-border-bottom { +// border-bottom: 3px solid rgba(0, 0, 0, 0.75); +// } +// div.fancytree-ext-fixed-scroll-border-right { +// border-right: 3px solid rgba(0, 0, 0, 0.75); +// } +// div.fancytree-ext-fixed-wrapper-tl { +// position: absolute; +// overflow: hidden; +// z-index: 3; +// top: 0px; +// left: 0px; +// } +// div.fancytree-ext-fixed-wrapper-tr { +// position: absolute; +// overflow: hidden; +// z-index: 2; +// top: 0px; +// } +// div.fancytree-ext-fixed-wrapper-bl { +// position: absolute; +// overflow: hidden; +// z-index: 2; +// left: 0px; +// } +// div.fancytree-ext-fixed-wrapper-br { +// position: absolute; +// overflow: scroll; +// z-index: 1; +// } +//} diff --git a/plugins/55/indexmenu/scripts/fancytree/skin-lion/ui.fancytree.css b/plugins/55/indexmenu/scripts/fancytree/skin-lion/ui.fancytree.css new file mode 100644 index 0000000..708fb69 --- /dev/null +++ b/plugins/55/indexmenu/scripts/fancytree/skin-lion/ui.fancytree.css @@ -0,0 +1,757 @@ +/*! + * Fancytree "Lion" skin. + * + * DON'T EDIT THE CSS FILE DIRECTLY, since it is automatically generated from + * the LESS templates. + */ +/* + Lion colors: + gray highlight bar: #D4D4D4 + blue highlight-bar and -border #3875D7 + +*/ +/******************************************************************************* + * Common Styles for Fancytree Skins. + * + * This section is automatically generated from the `skin-common.less` template. + * + * Copyright (c) 2008-2023, Martin Wendt (https://wwWendt.de) + * Released under the MIT license + * https://github.com/mar10/fancytree/wiki/LicenseInfo + * + * @version 2.38.3 + * @date 2023-02-01T20:52:50Z +******************************************************************************/ +/*------------------------------------------------------------------------------ + * Helpers + *----------------------------------------------------------------------------*/ +.fancytree-helper-hidden { + display: none; +} +.fancytree-helper-indeterminate-cb { + color: #777; +} +.fancytree-helper-disabled { + color: #c0c0c0; +} +/* Helper to allow spinning loader icon with glyph-, ligature-, and SVG-icons. */ +.fancytree-helper-spin { + -webkit-animation: spin 1000ms infinite linear; + animation: spin 1000ms infinite linear; +} +@-webkit-keyframes spin { + 0% { + -webkit-transform: rotate(0deg); + transform: rotate(0deg); + } + 100% { + -webkit-transform: rotate(359deg); + transform: rotate(359deg); + } +} +@keyframes spin { + 0% { + -webkit-transform: rotate(0deg); + transform: rotate(0deg); + } + 100% { + -webkit-transform: rotate(359deg); + transform: rotate(359deg); + } +} +/*------------------------------------------------------------------------------ + * Container and UL / LI + *----------------------------------------------------------------------------*/ +ul.fancytree-container { + font-family: tahoma, arial, helvetica; + font-size: 10pt; + white-space: nowrap; + padding: 3px; + margin: 0; + background-color: white; + border: 1px dotted gray; + min-height: 0%; + position: relative; +} +ul.fancytree-container ul { + padding: 0 0 0 16px; + margin: 0; +} +ul.fancytree-container ul > li:before { + content: none; +} +ul.fancytree-container li { + list-style-image: none; + list-style-position: outside; + list-style-type: none; + -moz-background-clip: border; + -moz-background-inline-policy: continuous; + -moz-background-origin: padding; + background-attachment: scroll; + background-color: transparent; + background-position: 0px 0px; + background-repeat: repeat-y; + background-image: none; + margin: 0; +} +ul.fancytree-container li.fancytree-lastsib { + background-image: none; +} +.ui-fancytree-disabled ul.fancytree-container { + opacity: 0.5; + background-color: silver; +} +ul.fancytree-connectors.fancytree-container li { + background-image: url("../skin-lion/vline.gif"); + background-position: 0 0; +} +ul.fancytree-container li.fancytree-lastsib, +ul.fancytree-no-connector > li { + background-image: none; +} +li.fancytree-animating { + position: relative; +} +/*------------------------------------------------------------------------------ + * Common icon definitions + *----------------------------------------------------------------------------*/ +span.fancytree-empty, +span.fancytree-vline, +span.fancytree-expander, +span.fancytree-icon, +span.fancytree-checkbox, +span.fancytree-drag-helper-img, +#fancytree-drop-marker { + width: 16px; + height: 16px; + display: inline-block; + vertical-align: top; + background-repeat: no-repeat; + background-image: url("../skin-lion/icons.gif"); + background-position: 0px 0px; +} +span.fancytree-icon, +span.fancytree-checkbox, +span.fancytree-expander, +span.fancytree-custom-icon { + margin-top: 0px; +} +/* Used by icon option: */ +span.fancytree-custom-icon { + width: 16px; + height: 16px; + display: inline-block; + margin-left: 3px; + background-position: 0px 0px; +} +/* Used by 'icon' node option: */ +img.fancytree-icon { + width: 16px; + height: 16px; + margin-left: 3px; + margin-top: 0px; + vertical-align: top; + border-style: none; +} +/*------------------------------------------------------------------------------ + * Expander icon + * + * Note: IE6 doesn't correctly evaluate multiples class names, + * so we create combined class names that can be used in the CSS. + * + * Prefix: fancytree-exp- + * 1st character: 'e': expanded, 'c': collapsed, 'n': no children + * 2nd character (optional): 'd': lazy (Delayed) + * 3rd character (optional): 'l': Last sibling + *----------------------------------------------------------------------------*/ +span.fancytree-expander { + cursor: pointer; +} +.fancytree-exp-n span.fancytree-expander, +.fancytree-exp-nl span.fancytree-expander { + background-image: none; + cursor: default; +} +.fancytree-connectors .fancytree-exp-n span.fancytree-expander, +.fancytree-connectors .fancytree-exp-nl span.fancytree-expander { + background-image: url("../skin-lion/icons.gif"); + margin-top: 0; +} +.fancytree-connectors .fancytree-exp-n span.fancytree-expander, +.fancytree-connectors .fancytree-exp-n span.fancytree-expander:hover { + background-position: 0px -64px; +} +.fancytree-connectors .fancytree-exp-nl span.fancytree-expander, +.fancytree-connectors .fancytree-exp-nl span.fancytree-expander:hover { + background-position: -16px -64px; +} +.fancytree-exp-c span.fancytree-expander { + background-position: 0px -80px; +} +.fancytree-exp-c span.fancytree-expander:hover { + background-position: -16px -80px; +} +.fancytree-exp-cl span.fancytree-expander { + background-position: 0px -96px; +} +.fancytree-exp-cl span.fancytree-expander:hover { + background-position: -16px -96px; +} +.fancytree-exp-cd span.fancytree-expander { + background-position: -64px -80px; +} +.fancytree-exp-cd span.fancytree-expander:hover { + background-position: -80px -80px; +} +.fancytree-exp-cdl span.fancytree-expander { + background-position: -64px -96px; +} +.fancytree-exp-cdl span.fancytree-expander:hover { + background-position: -80px -96px; +} +.fancytree-exp-e span.fancytree-expander, +.fancytree-exp-ed span.fancytree-expander { + background-position: -32px -80px; +} +.fancytree-exp-e span.fancytree-expander:hover, +.fancytree-exp-ed span.fancytree-expander:hover { + background-position: -48px -80px; +} +.fancytree-exp-el span.fancytree-expander, +.fancytree-exp-edl span.fancytree-expander { + background-position: -32px -96px; +} +.fancytree-exp-el span.fancytree-expander:hover, +.fancytree-exp-edl span.fancytree-expander:hover { + background-position: -48px -96px; +} +/* Fade out expanders, when container is not hovered or active */ +.fancytree-fade-expander span.fancytree-expander { + transition: opacity 1.5s; + opacity: 0; +} +.fancytree-fade-expander:hover span.fancytree-expander, +.fancytree-fade-expander.fancytree-treefocus span.fancytree-expander, +.fancytree-fade-expander .fancytree-treefocus span.fancytree-expander, +.fancytree-fade-expander [class*="fancytree-statusnode-"] span.fancytree-expander { + transition: opacity 0.6s; + opacity: 1; +} +/*------------------------------------------------------------------------------ + * Checkbox icon + *----------------------------------------------------------------------------*/ +span.fancytree-checkbox { + margin-left: 3px; + background-position: 0px -32px; +} +span.fancytree-checkbox:hover { + background-position: -16px -32px; +} +span.fancytree-checkbox.fancytree-radio { + background-position: 0px -48px; +} +span.fancytree-checkbox.fancytree-radio:hover { + background-position: -16px -48px; +} +.fancytree-partsel span.fancytree-checkbox { + background-position: -64px -32px; +} +.fancytree-partsel span.fancytree-checkbox:hover { + background-position: -80px -32px; +} +.fancytree-partsel span.fancytree-checkbox.fancytree-radio { + background-position: -64px -48px; +} +.fancytree-partsel span.fancytree-checkbox.fancytree-radio:hover { + background-position: -80px -48px; +} +.fancytree-selected span.fancytree-checkbox { + background-position: -32px -32px; +} +.fancytree-selected span.fancytree-checkbox:hover { + background-position: -48px -32px; +} +.fancytree-selected span.fancytree-checkbox.fancytree-radio { + background-position: -32px -48px; +} +.fancytree-selected span.fancytree-checkbox.fancytree-radio:hover { + background-position: -48px -48px; +} +.fancytree-unselectable span.fancytree-checkbox { + opacity: 0.4; + filter: alpha(opacity=40); +} +.fancytree-unselectable span.fancytree-checkbox:hover { + background-position: 0px -32px; +} +.fancytree-unselectable span.fancytree-checkbox.fancytree-radio:hover { + background-position: 0px -48px; +} +.fancytree-unselectable.fancytree-partsel span.fancytree-checkbox:hover { + background-position: -64px -32px; +} +.fancytree-unselectable.fancytree-selected span.fancytree-checkbox:hover { + background-position: -32px -32px; +} +.fancytree-unselectable.fancytree-selected span.fancytree-checkbox.fancytree-radio:hover { + background-position: -32px -48px; +} +.fancytree-container.fancytree-checkbox-auto-hide span.fancytree-checkbox { + visibility: hidden; +} +.fancytree-container.fancytree-checkbox-auto-hide .fancytree-node:hover span.fancytree-checkbox, +.fancytree-container.fancytree-checkbox-auto-hide tr:hover td span.fancytree-checkbox, +.fancytree-container.fancytree-checkbox-auto-hide .fancytree-node.fancytree-selected span.fancytree-checkbox, +.fancytree-container.fancytree-checkbox-auto-hide tr.fancytree-selected td span.fancytree-checkbox { + visibility: unset; +} +.fancytree-container.fancytree-checkbox-auto-hide.fancytree-treefocus .fancytree-node.fancytree-active span.fancytree-checkbox, +.fancytree-container.fancytree-checkbox-auto-hide.fancytree-treefocus tr.fancytree-active td span.fancytree-checkbox { + visibility: unset; +} +/*------------------------------------------------------------------------------ + * Node type icon + * Note: IE6 doesn't correctly evaluate multiples class names, + * so we create combined class names that can be used in the CSS. + * + * Prefix: fancytree-ico- + * 1st character: 'e': expanded, 'c': collapsed + * 2nd character (optional): 'f': folder + *----------------------------------------------------------------------------*/ +span.fancytree-icon { + margin-left: 3px; + background-position: 0px 0px; +} +/* Documents */ +.fancytree-ico-c span.fancytree-icon:hover { + background-position: -16px 0px; +} +.fancytree-has-children.fancytree-ico-c span.fancytree-icon { + background-position: -32px 0px; +} +.fancytree-has-children.fancytree-ico-c span.fancytree-icon:hover { + background-position: -48px 0px; +} +.fancytree-ico-e span.fancytree-icon { + background-position: -64px 0px; +} +.fancytree-ico-e span.fancytree-icon:hover { + background-position: -80px 0px; +} +/* Folders */ +.fancytree-ico-cf span.fancytree-icon { + background-position: 0px -16px; +} +.fancytree-ico-cf span.fancytree-icon:hover { + background-position: -16px -16px; +} +.fancytree-has-children.fancytree-ico-cf span.fancytree-icon { + background-position: -32px -16px; +} +.fancytree-has-children.fancytree-ico-cf span.fancytree-icon:hover { + background-position: -48px -16px; +} +.fancytree-ico-ef span.fancytree-icon { + background-position: -64px -16px; +} +.fancytree-ico-ef span.fancytree-icon:hover { + background-position: -80px -16px; +} +.fancytree-loading span.fancytree-expander, +.fancytree-loading span.fancytree-expander:hover, +.fancytree-statusnode-loading span.fancytree-icon, +.fancytree-statusnode-loading span.fancytree-icon:hover, +span.fancytree-icon.fancytree-icon-loading { + background-image: url("../skin-lion/loading.gif"); + background-position: 0px 0px; +} +/* Status node icons */ +.fancytree-statusnode-error span.fancytree-icon, +.fancytree-statusnode-error span.fancytree-icon:hover { + background-position: 0px -112px; +} +/*------------------------------------------------------------------------------ + * Node titles and highlighting + *----------------------------------------------------------------------------*/ +span.fancytree-node { + /* See #117 */ + display: inherit; + width: 100%; + margin-top: 1px; + min-height: 16px; +} +span.fancytree-title { + color: black; + cursor: pointer; + display: inline-block; + vertical-align: top; + min-height: 16px; + padding: 0 3px 0 3px; + margin: 0px 0 0 3px; + border: 1px solid transparent; + -webkit-border-radius: 0px; + -moz-border-radius: 0px; + -ms-border-radius: 0px; + -o-border-radius: 0px; + border-radius: 0px; +} +span.fancytree-node.fancytree-error span.fancytree-title { + color: red; +} +/*------------------------------------------------------------------------------ + * Drag'n'drop support + *----------------------------------------------------------------------------*/ +/* ext-dnd5: */ +span.fancytree-childcounter { + color: #fff; + background: #337ab7; + border: 1px solid gray; + border-radius: 10px; + padding: 2px; + text-align: center; +} +/* ext-dnd: */ +div.fancytree-drag-helper span.fancytree-childcounter, +div.fancytree-drag-helper span.fancytree-dnd-modifier { + display: inline-block; + color: #fff; + background: #337ab7; + border: 1px solid gray; + min-width: 10px; + height: 10px; + line-height: 1; + vertical-align: baseline; + border-radius: 10px; + padding: 2px; + text-align: center; + font-size: 9px; +} +div.fancytree-drag-helper span.fancytree-childcounter { + position: absolute; + top: -6px; + right: -6px; +} +div.fancytree-drag-helper span.fancytree-dnd-modifier { + background: #5cb85c; + border: none; + font-weight: bolder; +} +div.fancytree-drag-helper.fancytree-drop-accept span.fancytree-drag-helper-img { + background-position: -32px -112px; +} +div.fancytree-drag-helper.fancytree-drop-reject span.fancytree-drag-helper-img { + background-position: -16px -112px; +} +/*** Drop marker icon *********************************************************/ +#fancytree-drop-marker { + width: 32px; + position: absolute; + background-position: 0px -128px; + margin: 0; +} +#fancytree-drop-marker.fancytree-drop-after, +#fancytree-drop-marker.fancytree-drop-before { + width: 64px; + background-position: 0px -144px; +} +#fancytree-drop-marker.fancytree-drop-copy { + background-position: -64px -128px; +} +#fancytree-drop-marker.fancytree-drop-move { + background-position: -32px -128px; +} +/*** Source node while dragging ***********************************************/ +span.fancytree-drag-source.fancytree-drag-remove { + opacity: 0.15; +} +/*** Target node while dragging cursor is over it *****************************/ +/*------------------------------------------------------------------------------ + * 'rtl' option + *----------------------------------------------------------------------------*/ +.fancytree-container.fancytree-rtl .fancytree-title { + /*unicode-bidi: bidi-override;*/ + /* optional: reverse title letters */ +} +.fancytree-container.fancytree-rtl span.fancytree-connector, +.fancytree-container.fancytree-rtl span.fancytree-expander, +.fancytree-container.fancytree-rtl span.fancytree-icon, +.fancytree-container.fancytree-rtl span.fancytree-drag-helper-img { + background-image: url("../skin-lion/icons-rtl.gif"); +} +.fancytree-container.fancytree-rtl .fancytree-exp-n span.fancytree-expander, +.fancytree-container.fancytree-rtl .fancytree-exp-nl span.fancytree-expander { + background-image: none; +} +.fancytree-container.fancytree-rtl.fancytree-connectors .fancytree-exp-n span.fancytree-expander, +.fancytree-container.fancytree-rtl.fancytree-connectors .fancytree-exp-nl span.fancytree-expander { + background-image: url("../skin-lion/icons-rtl.gif"); +} +ul.fancytree-container.fancytree-rtl ul { + padding: 0 16px 0 0; +} +ul.fancytree-container.fancytree-rtl.fancytree-connectors li { + background-position: right 0; + background-image: url("../skin-lion/vline-rtl.gif"); +} +ul.fancytree-container.fancytree-rtl li.fancytree-lastsib, +ul.fancytree-container.fancytree-rtl.fancytree-no-connector > li { + background-image: none; +} +#fancytree-drop-marker.fancytree-rtl { + background-image: url("../skin-lion/icons-rtl.gif"); +} +/*------------------------------------------------------------------------------ + * 'table' extension + *----------------------------------------------------------------------------*/ +table.fancytree-ext-table { + font-family: tahoma, arial, helvetica; + font-size: 10pt; + border-collapse: collapse; + /* ext-ariagrid */ +} +table.fancytree-ext-table span.fancytree-node { + display: inline-block; + box-sizing: border-box; +} +table.fancytree-ext-table td.fancytree-status-merged { + text-align: center; + font-style: italic; + color: #c0c0c0; +} +table.fancytree-ext-table tr.fancytree-statusnode-error td.fancytree-status-merged { + color: red; +} +table.fancytree-ext-table.fancytree-ext-ariagrid.fancytree-cell-mode > tbody > tr.fancytree-active > td { + background-color: #eee; +} +table.fancytree-ext-table.fancytree-ext-ariagrid.fancytree-cell-mode > tbody > tr > td.fancytree-active-cell { + background-color: #cbe8f6; +} +table.fancytree-ext-table.fancytree-ext-ariagrid.fancytree-cell-mode.fancytree-cell-nav-mode > tbody > tr > td.fancytree-active-cell { + background-color: #3875d7; +} +/*------------------------------------------------------------------------------ + * 'columnview' extension + *----------------------------------------------------------------------------*/ +table.fancytree-ext-columnview tbody tr td { + position: relative; + border: 1px solid gray; + vertical-align: top; + overflow: auto; +} +table.fancytree-ext-columnview tbody tr td > ul { + padding: 0; +} +table.fancytree-ext-columnview tbody tr td > ul li { + list-style-image: none; + list-style-position: outside; + list-style-type: none; + -moz-background-clip: border; + -moz-background-inline-policy: continuous; + -moz-background-origin: padding; + background-attachment: scroll; + background-color: transparent; + background-position: 0px 0px; + background-repeat: repeat-y; + background-image: none; + /* no v-lines */ + margin: 0; +} +table.fancytree-ext-columnview span.fancytree-node { + position: relative; + /* allow positioning of embedded spans */ + display: inline-block; +} +table.fancytree-ext-columnview span.fancytree-node.fancytree-expanded { + background-color: #e0e0e0; +} +table.fancytree-ext-columnview span.fancytree-node.fancytree-active { + background-color: #cbe8f6; +} +table.fancytree-ext-columnview .fancytree-has-children span.fancytree-cv-right { + position: absolute; + right: 3px; + background-position: 0px -80px; +} +table.fancytree-ext-columnview .fancytree-has-children span.fancytree-cv-right:hover { + background-position: -16px -80px; +} +/*------------------------------------------------------------------------------ + * 'filter' extension + *----------------------------------------------------------------------------*/ +.fancytree-ext-filter-dimm span.fancytree-node span.fancytree-title { + color: #c0c0c0; + font-weight: lighter; +} +.fancytree-ext-filter-dimm tr.fancytree-submatch span.fancytree-title, +.fancytree-ext-filter-dimm span.fancytree-node.fancytree-submatch span.fancytree-title { + color: black; + font-weight: normal; +} +.fancytree-ext-filter-dimm tr.fancytree-match span.fancytree-title, +.fancytree-ext-filter-dimm span.fancytree-node.fancytree-match span.fancytree-title { + color: black; + font-weight: bold; +} +.fancytree-ext-filter-hide tr.fancytree-hide, +.fancytree-ext-filter-hide span.fancytree-node.fancytree-hide { + display: none; +} +.fancytree-ext-filter-hide tr.fancytree-submatch span.fancytree-title, +.fancytree-ext-filter-hide span.fancytree-node.fancytree-submatch span.fancytree-title { + color: #c0c0c0; + font-weight: lighter; +} +.fancytree-ext-filter-hide tr.fancytree-match span.fancytree-title, +.fancytree-ext-filter-hide span.fancytree-node.fancytree-match span.fancytree-title { + color: black; + font-weight: normal; +} +/* Hide expanders if all child nodes are hidden by filter */ +.fancytree-ext-filter-hide-expanders tr.fancytree-match span.fancytree-expander, +.fancytree-ext-filter-hide-expanders span.fancytree-node.fancytree-match span.fancytree-expander { + visibility: hidden; +} +.fancytree-ext-filter-hide-expanders tr.fancytree-submatch span.fancytree-expander, +.fancytree-ext-filter-hide-expanders span.fancytree-node.fancytree-submatch span.fancytree-expander { + visibility: visible; +} +.fancytree-ext-childcounter span.fancytree-icon, +.fancytree-ext-filter span.fancytree-icon, +.fancytree-ext-childcounter span.fancytree-custom-icon, +.fancytree-ext-filter span.fancytree-custom-icon { + position: relative; +} +.fancytree-ext-childcounter span.fancytree-childcounter, +.fancytree-ext-filter span.fancytree-childcounter { + color: #fff; + background: #777; + border: 1px solid gray; + position: absolute; + top: -6px; + right: -6px; + min-width: 10px; + height: 10px; + line-height: 1; + vertical-align: baseline; + border-radius: 10px; + padding: 2px; + text-align: center; + font-size: 9px; +} +/*------------------------------------------------------------------------------ + * 'wide' extension + *----------------------------------------------------------------------------*/ +ul.fancytree-ext-wide { + position: relative; + min-width: 100%; + z-index: 2; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; +} +ul.fancytree-ext-wide span.fancytree-node > span { + position: relative; + z-index: 2; +} +ul.fancytree-ext-wide span.fancytree-node span.fancytree-title { + position: absolute; + z-index: 1; + left: 0px; + min-width: 100%; + margin-left: 0; + margin-right: 0; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; +} +/*------------------------------------------------------------------------------ + * 'fixed' extension + *----------------------------------------------------------------------------*/ +.fancytree-ext-fixed-wrapper .fancytree-ext-fixed-hidden { + display: none; +} +.fancytree-ext-fixed-wrapper div.fancytree-ext-fixed-scroll-border-bottom { + border-bottom: 3px solid rgba(0, 0, 0, 0.75); +} +.fancytree-ext-fixed-wrapper div.fancytree-ext-fixed-scroll-border-right { + border-right: 3px solid rgba(0, 0, 0, 0.75); +} +.fancytree-ext-fixed-wrapper div.fancytree-ext-fixed-wrapper-tl { + position: absolute; + overflow: hidden; + z-index: 3; + top: 0px; + left: 0px; +} +.fancytree-ext-fixed-wrapper div.fancytree-ext-fixed-wrapper-tr { + position: absolute; + overflow: hidden; + z-index: 2; + top: 0px; +} +.fancytree-ext-fixed-wrapper div.fancytree-ext-fixed-wrapper-bl { + position: absolute; + overflow: hidden; + z-index: 2; + left: 0px; +} +.fancytree-ext-fixed-wrapper div.fancytree-ext-fixed-wrapper-br { + position: absolute; + overflow: scroll; + z-index: 1; +} +/******************************************************************************* + * Styles specific to this skin. + * + * This section is automatically generated from the `ui-fancytree.less` template. + ******************************************************************************/ +/******************************************************************************* + * Node titles + */ +span.fancytree-title { + border: 1px solid transparent; + border-radius: 0; +} +span.fancytree-focused span.fancytree-title { + outline: 1px dotted black; +} +span.fancytree-selected span.fancytree-title, +span.fancytree-active span.fancytree-title { + background-color: #D4D4D4; +} +span.fancytree-selected span.fancytree-title { + font-style: italic; +} +.fancytree-treefocus span.fancytree-selected span.fancytree-title, +.fancytree-treefocus span.fancytree-active span.fancytree-title { + color: white; + background-color: #3875D7; +} +/******************************************************************************* + * 'table' extension + */ +table.fancytree-ext-table { + border-collapse: collapse; +} +table.fancytree-ext-table tbody tr.fancytree-focused { + background-color: #99DEFD; +} +table.fancytree-ext-table tbody tr.fancytree-active { + background-color: royalblue; +} +table.fancytree-ext-table tbody tr.fancytree-selected { + background-color: #99DEFD; +} +/******************************************************************************* + * 'columnview' extension + */ +table.fancytree-ext-columnview tbody tr td { + border: 1px solid gray; +} +table.fancytree-ext-columnview span.fancytree-node.fancytree-expanded { + background-color: #ccc; +} +table.fancytree-ext-columnview span.fancytree-node.fancytree-active { + background-color: royalblue; +} diff --git a/plugins/55/indexmenu/scripts/fancytree/skin-lion/ui.fancytree.less b/plugins/55/indexmenu/scripts/fancytree/skin-lion/ui.fancytree.less new file mode 100644 index 0000000..aa511e3 --- /dev/null +++ b/plugins/55/indexmenu/scripts/fancytree/skin-lion/ui.fancytree.less @@ -0,0 +1,100 @@ + /*! + * Fancytree "Lion" skin. + * + * DON'T EDIT THE CSS FILE DIRECTLY, since it is automatically generated from + * the LESS templates. + */ + +/* + Lion colors: + gray highlight bar: #D4D4D4 + blue highlight-bar and -border #3875D7 + +*/ +// Import common styles +@import "skin-common.less"; + + +/******************************************************************************* + * Styles specific to this skin. + * + * This section is automatically generated from the `ui-fancytree.less` template. + ******************************************************************************/ + +// Override the variable after the import. +// NOTE: Variables are always resolved as the last definition, even if it is +// after where it is used. +@fancy-use-sprites: true; // false: suppress all background images (i.e. icons) + +@fancy-icon-width: 16px; +@fancy-icon-height: 16px; +@fancy-line-height: 16px; +@fancy-icon-spacing: 3px; + +// We need to define this variable here (not in skin-common.less) to make it +// work with grunt and webpack: +@fancy-image-prefix: "./skin-lion/"; + +// Use 'data-uri(...)' to embed the image into CSS instead of linking to 'loading.gif': +// @fancy-loading-url: data-uri("@{fancy-image-prefix}loading.gif"); +// Set to `true` to use `data-uri(...)` which will embed icons.gif into CSS +// instead of linking to that file: +// @fancy-inline-sprites: true; + +//default 10pt, which is used in a relative manner resulting in 13.3 in dokuwiki-template. +@fancy-font-size: 93%; + +/******************************************************************************* + * Node titles + */ +span.fancytree-title { + border: 1px solid transparent; // reserve some space for status borders + border-radius: 0; +} +span.fancytree-focused span.fancytree-title { + outline: 1px dotted black; +} +span.fancytree-selected span.fancytree-title, +span.fancytree-active span.fancytree-title { + background-color: #D4D4D4; // gray +} +span.fancytree-selected span.fancytree-title { + font-style: italic; +} +.fancytree-treefocus span.fancytree-selected span.fancytree-title, +.fancytree-treefocus span.fancytree-active span.fancytree-title { + color: white; + background-color: #3875D7; // blue +} + +///******************************************************************************* +// * 'table' extension +// */ +//table.fancytree-ext-table { +// border-collapse: collapse; +// tbody { +// tr.fancytree-focused { +// background-color: #99DEFD; +// } +// tr.fancytree-active { +// background-color: royalblue; +// } +// tr.fancytree-selected { +// background-color: #99DEFD; +// } +// } +//} +// +///******************************************************************************* +// * 'columnview' extension +// */ +// +//table.fancytree-ext-columnview tbody tr td { +// border: 1px solid gray; +//} +//table.fancytree-ext-columnview span.fancytree-node.fancytree-expanded { +// background-color: #ccc; +//} +//table.fancytree-ext-columnview span.fancytree-node.fancytree-active { +// background-color: royalblue; +//} diff --git a/plugins/55/indexmenu/scripts/fancytree/skin-lion/ui.fancytree.min.css b/plugins/55/indexmenu/scripts/fancytree/skin-lion/ui.fancytree.min.css new file mode 100644 index 0000000..6fa65e0 --- /dev/null +++ b/plugins/55/indexmenu/scripts/fancytree/skin-lion/ui.fancytree.min.css @@ -0,0 +1,6 @@ +/*! + * Fancytree "Lion" skin. + * + * DON'T EDIT THE CSS FILE DIRECTLY, since it is automatically generated from + * the LESS templates. + */.fancytree-helper-hidden{display:none}.fancytree-helper-indeterminate-cb{color:#777}.fancytree-helper-disabled{color:silver}.fancytree-helper-spin{-webkit-animation:spin 1s infinite linear;animation:spin 1s infinite linear}@-webkit-keyframes spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}ul.fancytree-container{font-family:tahoma,arial,helvetica;font-size:10pt;white-space:nowrap;padding:3px;margin:0;background-color:#fff;border:1px dotted gray;min-height:0;position:relative}ul.fancytree-container ul{padding:0 0 0 16px;margin:0}ul.fancytree-container ul>li:before{content:none}ul.fancytree-container li{list-style-image:none;list-style-position:outside;list-style-type:none;-moz-background-clip:border;-moz-background-inline-policy:continuous;-moz-background-origin:padding;background-attachment:scroll;background-color:transparent;background-position:0 0;background-repeat:repeat-y;background-image:none;margin:0}ul.fancytree-container li.fancytree-lastsib{background-image:none}.ui-fancytree-disabled ul.fancytree-container{opacity:.5;background-color:silver}ul.fancytree-connectors.fancytree-container li{background-image:url("../skin-lion/vline.gif");background-position:0 0}ul.fancytree-container li.fancytree-lastsib,ul.fancytree-no-connector>li{background-image:none}li.fancytree-animating{position:relative}#fancytree-drop-marker,span.fancytree-checkbox,span.fancytree-drag-helper-img,span.fancytree-empty,span.fancytree-expander,span.fancytree-icon,span.fancytree-vline{width:16px;height:16px;display:inline-block;vertical-align:top;background-repeat:no-repeat;background-image:url("../skin-lion/icons.gif");background-position:0 0}span.fancytree-checkbox,span.fancytree-custom-icon,span.fancytree-expander,span.fancytree-icon{margin-top:0}span.fancytree-custom-icon{width:16px;height:16px;display:inline-block;margin-left:3px;background-position:0 0}img.fancytree-icon{width:16px;height:16px;margin-left:3px;margin-top:0;vertical-align:top;border-style:none}span.fancytree-expander{cursor:pointer}.fancytree-exp-n span.fancytree-expander,.fancytree-exp-nl span.fancytree-expander{background-image:none;cursor:default}.fancytree-connectors .fancytree-exp-n span.fancytree-expander,.fancytree-connectors .fancytree-exp-nl span.fancytree-expander{background-image:url("../skin-lion/icons.gif");margin-top:0}.fancytree-connectors .fancytree-exp-n span.fancytree-expander,.fancytree-connectors .fancytree-exp-n span.fancytree-expander:hover{background-position:0 -64px}.fancytree-connectors .fancytree-exp-nl span.fancytree-expander,.fancytree-connectors .fancytree-exp-nl span.fancytree-expander:hover{background-position:-16px -64px}.fancytree-exp-c span.fancytree-expander{background-position:0 -80px}.fancytree-exp-c span.fancytree-expander:hover{background-position:-16px -80px}.fancytree-exp-cl span.fancytree-expander{background-position:0 -96px}.fancytree-exp-cl span.fancytree-expander:hover{background-position:-16px -96px}.fancytree-exp-cd span.fancytree-expander{background-position:-64px -80px}.fancytree-exp-cd span.fancytree-expander:hover{background-position:-80px -80px}.fancytree-exp-cdl span.fancytree-expander{background-position:-64px -96px}.fancytree-exp-cdl span.fancytree-expander:hover{background-position:-80px -96px}.fancytree-exp-e span.fancytree-expander,.fancytree-exp-ed span.fancytree-expander{background-position:-32px -80px}.fancytree-exp-e span.fancytree-expander:hover,.fancytree-exp-ed span.fancytree-expander:hover{background-position:-48px -80px}.fancytree-exp-edl span.fancytree-expander,.fancytree-exp-el span.fancytree-expander{background-position:-32px -96px}.fancytree-exp-edl span.fancytree-expander:hover,.fancytree-exp-el span.fancytree-expander:hover{background-position:-48px -96px}.fancytree-fade-expander span.fancytree-expander{transition:opacity 1.5s;opacity:0}.fancytree-fade-expander .fancytree-treefocus span.fancytree-expander,.fancytree-fade-expander [class*=fancytree-statusnode-] span.fancytree-expander,.fancytree-fade-expander.fancytree-treefocus span.fancytree-expander,.fancytree-fade-expander:hover span.fancytree-expander{transition:opacity .6s;opacity:1}span.fancytree-checkbox{margin-left:3px;background-position:0 -32px}span.fancytree-checkbox:hover{background-position:-16px -32px}span.fancytree-checkbox.fancytree-radio{background-position:0 -48px}span.fancytree-checkbox.fancytree-radio:hover{background-position:-16px -48px}.fancytree-partsel span.fancytree-checkbox{background-position:-64px -32px}.fancytree-partsel span.fancytree-checkbox:hover{background-position:-80px -32px}.fancytree-partsel span.fancytree-checkbox.fancytree-radio{background-position:-64px -48px}.fancytree-partsel span.fancytree-checkbox.fancytree-radio:hover{background-position:-80px -48px}.fancytree-selected span.fancytree-checkbox{background-position:-32px -32px}.fancytree-selected span.fancytree-checkbox:hover{background-position:-48px -32px}.fancytree-selected span.fancytree-checkbox.fancytree-radio{background-position:-32px -48px}.fancytree-selected span.fancytree-checkbox.fancytree-radio:hover{background-position:-48px -48px}.fancytree-unselectable span.fancytree-checkbox{opacity:.4}.fancytree-unselectable span.fancytree-checkbox:hover{background-position:0 -32px}.fancytree-unselectable span.fancytree-checkbox.fancytree-radio:hover{background-position:0 -48px}.fancytree-unselectable.fancytree-partsel span.fancytree-checkbox:hover{background-position:-64px -32px}.fancytree-unselectable.fancytree-selected span.fancytree-checkbox:hover{background-position:-32px -32px}.fancytree-unselectable.fancytree-selected span.fancytree-checkbox.fancytree-radio:hover{background-position:-32px -48px}.fancytree-container.fancytree-checkbox-auto-hide span.fancytree-checkbox{visibility:hidden}.fancytree-container.fancytree-checkbox-auto-hide .fancytree-node.fancytree-selected span.fancytree-checkbox,.fancytree-container.fancytree-checkbox-auto-hide .fancytree-node:hover span.fancytree-checkbox,.fancytree-container.fancytree-checkbox-auto-hide tr.fancytree-selected td span.fancytree-checkbox,.fancytree-container.fancytree-checkbox-auto-hide tr:hover td span.fancytree-checkbox{visibility:unset}.fancytree-container.fancytree-checkbox-auto-hide.fancytree-treefocus .fancytree-node.fancytree-active span.fancytree-checkbox,.fancytree-container.fancytree-checkbox-auto-hide.fancytree-treefocus tr.fancytree-active td span.fancytree-checkbox{visibility:unset}span.fancytree-icon{margin-left:3px;background-position:0 0}.fancytree-ico-c span.fancytree-icon:hover{background-position:-16px 0}.fancytree-has-children.fancytree-ico-c span.fancytree-icon{background-position:-32px 0}.fancytree-has-children.fancytree-ico-c span.fancytree-icon:hover{background-position:-48px 0}.fancytree-ico-e span.fancytree-icon{background-position:-64px 0}.fancytree-ico-e span.fancytree-icon:hover{background-position:-80px 0}.fancytree-ico-cf span.fancytree-icon{background-position:0 -16px}.fancytree-ico-cf span.fancytree-icon:hover{background-position:-16px -16px}.fancytree-has-children.fancytree-ico-cf span.fancytree-icon{background-position:-32px -16px}.fancytree-has-children.fancytree-ico-cf span.fancytree-icon:hover{background-position:-48px -16px}.fancytree-ico-ef span.fancytree-icon{background-position:-64px -16px}.fancytree-ico-ef span.fancytree-icon:hover{background-position:-80px -16px}.fancytree-loading span.fancytree-expander,.fancytree-loading span.fancytree-expander:hover,.fancytree-statusnode-loading span.fancytree-icon,.fancytree-statusnode-loading span.fancytree-icon:hover,span.fancytree-icon.fancytree-icon-loading{background-image:url("../skin-lion/loading.gif");background-position:0 0}.fancytree-statusnode-error span.fancytree-icon,.fancytree-statusnode-error span.fancytree-icon:hover{background-position:0 -112px}span.fancytree-node{display:inherit;width:100%;margin-top:1px;min-height:16px}span.fancytree-title{color:#000;cursor:pointer;display:inline-block;vertical-align:top;min-height:16px;padding:0 3px 0 3px;margin:0 0 0 3px;border:1px solid transparent;-webkit-border-radius:0px;-moz-border-radius:0;-ms-border-radius:0px;-o-border-radius:0;border-radius:0}span.fancytree-node.fancytree-error span.fancytree-title{color:red}span.fancytree-childcounter{color:#fff;background:#337ab7;border:1px solid gray;border-radius:10px;padding:2px;text-align:center}div.fancytree-drag-helper span.fancytree-childcounter,div.fancytree-drag-helper span.fancytree-dnd-modifier{display:inline-block;color:#fff;background:#337ab7;border:1px solid gray;min-width:10px;height:10px;line-height:1;vertical-align:baseline;border-radius:10px;padding:2px;text-align:center;font-size:9px}div.fancytree-drag-helper span.fancytree-childcounter{position:absolute;top:-6px;right:-6px}div.fancytree-drag-helper span.fancytree-dnd-modifier{background:#5cb85c;border:none;font-weight:bolder}div.fancytree-drag-helper.fancytree-drop-accept span.fancytree-drag-helper-img{background-position:-32px -112px}div.fancytree-drag-helper.fancytree-drop-reject span.fancytree-drag-helper-img{background-position:-16px -112px}#fancytree-drop-marker{width:32px;position:absolute;background-position:0 -128px;margin:0}#fancytree-drop-marker.fancytree-drop-after,#fancytree-drop-marker.fancytree-drop-before{width:64px;background-position:0 -144px}#fancytree-drop-marker.fancytree-drop-copy{background-position:-64px -128px}#fancytree-drop-marker.fancytree-drop-move{background-position:-32px -128px}span.fancytree-drag-source.fancytree-drag-remove{opacity:.15}.fancytree-container.fancytree-rtl span.fancytree-connector,.fancytree-container.fancytree-rtl span.fancytree-drag-helper-img,.fancytree-container.fancytree-rtl span.fancytree-expander,.fancytree-container.fancytree-rtl span.fancytree-icon{background-image:url("../skin-lion/icons-rtl.gif")}.fancytree-container.fancytree-rtl .fancytree-exp-n span.fancytree-expander,.fancytree-container.fancytree-rtl .fancytree-exp-nl span.fancytree-expander{background-image:none}.fancytree-container.fancytree-rtl.fancytree-connectors .fancytree-exp-n span.fancytree-expander,.fancytree-container.fancytree-rtl.fancytree-connectors .fancytree-exp-nl span.fancytree-expander{background-image:url("../skin-lion/icons-rtl.gif")}ul.fancytree-container.fancytree-rtl ul{padding:0 16px 0 0}ul.fancytree-container.fancytree-rtl.fancytree-connectors li{background-position:right 0;background-image:url("../skin-lion/vline-rtl.gif")}ul.fancytree-container.fancytree-rtl li.fancytree-lastsib,ul.fancytree-container.fancytree-rtl.fancytree-no-connector>li{background-image:none}#fancytree-drop-marker.fancytree-rtl{background-image:url("../skin-lion/icons-rtl.gif")}table.fancytree-ext-table{font-family:tahoma,arial,helvetica;font-size:10pt;border-collapse:collapse}table.fancytree-ext-table span.fancytree-node{display:inline-block;box-sizing:border-box}table.fancytree-ext-table td.fancytree-status-merged{text-align:center;font-style:italic;color:silver}table.fancytree-ext-table tr.fancytree-statusnode-error td.fancytree-status-merged{color:red}table.fancytree-ext-table.fancytree-ext-ariagrid.fancytree-cell-mode>tbody>tr.fancytree-active>td{background-color:#eee}table.fancytree-ext-table.fancytree-ext-ariagrid.fancytree-cell-mode>tbody>tr>td.fancytree-active-cell{background-color:#cbe8f6}table.fancytree-ext-table.fancytree-ext-ariagrid.fancytree-cell-mode.fancytree-cell-nav-mode>tbody>tr>td.fancytree-active-cell{background-color:#3875d7}table.fancytree-ext-columnview tbody tr td{position:relative;border:1px solid gray;vertical-align:top;overflow:auto}table.fancytree-ext-columnview tbody tr td>ul{padding:0}table.fancytree-ext-columnview tbody tr td>ul li{list-style-image:none;list-style-position:outside;list-style-type:none;-moz-background-clip:border;-moz-background-inline-policy:continuous;-moz-background-origin:padding;background-attachment:scroll;background-color:transparent;background-position:0 0;background-repeat:repeat-y;background-image:none;margin:0}table.fancytree-ext-columnview span.fancytree-node{position:relative;display:inline-block}table.fancytree-ext-columnview span.fancytree-node.fancytree-expanded{background-color:#e0e0e0}table.fancytree-ext-columnview span.fancytree-node.fancytree-active{background-color:#cbe8f6}table.fancytree-ext-columnview .fancytree-has-children span.fancytree-cv-right{position:absolute;right:3px;background-position:0 -80px}table.fancytree-ext-columnview .fancytree-has-children span.fancytree-cv-right:hover{background-position:-16px -80px}.fancytree-ext-filter-dimm span.fancytree-node span.fancytree-title{color:silver;font-weight:lighter}.fancytree-ext-filter-dimm span.fancytree-node.fancytree-submatch span.fancytree-title,.fancytree-ext-filter-dimm tr.fancytree-submatch span.fancytree-title{color:#000;font-weight:400}.fancytree-ext-filter-dimm span.fancytree-node.fancytree-match span.fancytree-title,.fancytree-ext-filter-dimm tr.fancytree-match span.fancytree-title{color:#000;font-weight:700}.fancytree-ext-filter-hide span.fancytree-node.fancytree-hide,.fancytree-ext-filter-hide tr.fancytree-hide{display:none}.fancytree-ext-filter-hide span.fancytree-node.fancytree-submatch span.fancytree-title,.fancytree-ext-filter-hide tr.fancytree-submatch span.fancytree-title{color:silver;font-weight:lighter}.fancytree-ext-filter-hide span.fancytree-node.fancytree-match span.fancytree-title,.fancytree-ext-filter-hide tr.fancytree-match span.fancytree-title{color:#000;font-weight:400}.fancytree-ext-filter-hide-expanders span.fancytree-node.fancytree-match span.fancytree-expander,.fancytree-ext-filter-hide-expanders tr.fancytree-match span.fancytree-expander{visibility:hidden}.fancytree-ext-filter-hide-expanders span.fancytree-node.fancytree-submatch span.fancytree-expander,.fancytree-ext-filter-hide-expanders tr.fancytree-submatch span.fancytree-expander{visibility:visible}.fancytree-ext-childcounter span.fancytree-custom-icon,.fancytree-ext-childcounter span.fancytree-icon,.fancytree-ext-filter span.fancytree-custom-icon,.fancytree-ext-filter span.fancytree-icon{position:relative}.fancytree-ext-childcounter span.fancytree-childcounter,.fancytree-ext-filter span.fancytree-childcounter{color:#fff;background:#777;border:1px solid gray;position:absolute;top:-6px;right:-6px;min-width:10px;height:10px;line-height:1;vertical-align:baseline;border-radius:10px;padding:2px;text-align:center;font-size:9px}ul.fancytree-ext-wide{position:relative;min-width:100%;z-index:2;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}ul.fancytree-ext-wide span.fancytree-node>span{position:relative;z-index:2}ul.fancytree-ext-wide span.fancytree-node span.fancytree-title{position:absolute;z-index:1;left:0;min-width:100%;margin-left:0;margin-right:0;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.fancytree-ext-fixed-wrapper .fancytree-ext-fixed-hidden{display:none}.fancytree-ext-fixed-wrapper div.fancytree-ext-fixed-scroll-border-bottom{border-bottom:3px solid rgba(0,0,0,.75)}.fancytree-ext-fixed-wrapper div.fancytree-ext-fixed-scroll-border-right{border-right:3px solid rgba(0,0,0,.75)}.fancytree-ext-fixed-wrapper div.fancytree-ext-fixed-wrapper-tl{position:absolute;overflow:hidden;z-index:3;top:0;left:0}.fancytree-ext-fixed-wrapper div.fancytree-ext-fixed-wrapper-tr{position:absolute;overflow:hidden;z-index:2;top:0}.fancytree-ext-fixed-wrapper div.fancytree-ext-fixed-wrapper-bl{position:absolute;overflow:hidden;z-index:2;left:0}.fancytree-ext-fixed-wrapper div.fancytree-ext-fixed-wrapper-br{position:absolute;overflow:scroll;z-index:1}span.fancytree-title{border:1px solid transparent;border-radius:0}span.fancytree-focused span.fancytree-title{outline:1px dotted black}span.fancytree-active span.fancytree-title,span.fancytree-selected span.fancytree-title{background-color:#d4d4d4}span.fancytree-selected span.fancytree-title{font-style:italic}.fancytree-treefocus span.fancytree-active span.fancytree-title,.fancytree-treefocus span.fancytree-selected span.fancytree-title{color:#fff;background-color:#3875d7}table.fancytree-ext-table{border-collapse:collapse}table.fancytree-ext-table tbody tr.fancytree-focused{background-color:#99defd}table.fancytree-ext-table tbody tr.fancytree-active{background-color:#4169e1}table.fancytree-ext-table tbody tr.fancytree-selected{background-color:#99defd}table.fancytree-ext-columnview tbody tr td{border:1px solid gray}table.fancytree-ext-columnview span.fancytree-node.fancytree-expanded{background-color:#ccc}table.fancytree-ext-columnview span.fancytree-node.fancytree-active{background-color:#4169e1}
\ No newline at end of file diff --git a/plugins/55/indexmenu/scripts/fancytree/skin-lion/vline-rtl.gif b/plugins/55/indexmenu/scripts/fancytree/skin-lion/vline-rtl.gif Binary files differnew file mode 100644 index 0000000..f9b4232 --- /dev/null +++ b/plugins/55/indexmenu/scripts/fancytree/skin-lion/vline-rtl.gif diff --git a/plugins/55/indexmenu/scripts/fancytree/skin-lion/vline.gif b/plugins/55/indexmenu/scripts/fancytree/skin-lion/vline.gif Binary files differnew file mode 100644 index 0000000..f9b4232 --- /dev/null +++ b/plugins/55/indexmenu/scripts/fancytree/skin-lion/vline.gif diff --git a/plugins/55/indexmenu/scripts/fancytree/skin-material/skin-common.less b/plugins/55/indexmenu/scripts/fancytree/skin-material/skin-common.less new file mode 100644 index 0000000..fc0da50 --- /dev/null +++ b/plugins/55/indexmenu/scripts/fancytree/skin-material/skin-common.less @@ -0,0 +1,972 @@ +/******************************************************************************* + * Common Styles for Fancytree Skins. + * + * This section is automatically generated from the `skin-common.less` template. + * + * Copyright (c) 2008-2023, Martin Wendt (https://wwWendt.de) + * Released under the MIT license + * https://github.com/mar10/fancytree/wiki/LicenseInfo + * + * @version 2.38.3 + * @date 2023-02-01T20:52:50Z +******************************************************************************/ + +// Variables (defaults, may be overwritten by the including .less files) +@fancy-use-sprites: true; // false: suppress all background images (i.e. icons) +// @fancy-hide-connectors: true; // false: show vertical connector lines + +@fancy-level-indent: 16px; +@fancy-line-height: 16px; // height of a nodes selection bar including borders +@fancy-node-v-spacing: 1px; // gap between two node borders +@fancy-icon-width: 16px; +@fancy-icon-height: 16px; +@fancy-icon-spacing: 3px; // margin between icon/icon or icon/title +@fancy-icon-ofs-top: 0px; // extra vertical offset for expander, checkbox and icon +@fancy-title-ofs-top: 0px; // extra vertical offset for title +@fancy-node-border-width: 1px; +@fancy-node-border-radius: 0px; +@fancy-node-outline-width: 1px; + +// @fancy-line-ofs-top: (@fancy-line-height - @fancy-icon-height) / 2; + +// webpack uses /dist/skin-common.less as root path +// grunt-less uses /dist/skin-Xxx/ui.fancyree.less as root path +// So we define our theme LESS files for webpack compatibility, i.e. +// define the image path n every main LESS file instead of here. +// Prefix may be set to "", "/", "./", or any other value +// Note: this variable must be defined by the main LESS files: +// @fancy-image-prefix: ""; + +// Use 'url(...)' to link to the throbber image, or +// use data-uri(...)' to inline the data in css instead: +/* CHANGE use url, as less does not handel data-uri() correct. DokuWiki can eventually inline it */ + @fancy-loading-url: url("@{fancy-image-prefix}loading.gif"); +//@fancy-loading-url: data-uri("@{fancy-image-prefix}loading.gif"); + +// Set to `true` to use `data-uri(...)` instead of a `url(...)` link: +@fancy-inline-sprites: false; // data-uri() is not handle correct by phpless + +@fancy-font-size: 10pt; +@fancy-font-family: tahoma, arial, helvetica; +@fancy-font-color: black; +@fancy-font-color-dimm: #c0c0c0; +@fancy-font-error-color: red; + +//------------------------------------------------------------------------------ +// Mixins +//------------------------------------------------------------------------------ +.setBgPos(@x, @y, @cond:true) when (@cond) { + background-position: (@x * -@fancy-icon-width) (@y * -@fancy-icon-height); +} +.clearBgImage(@cond:true) when (@cond) { + background-image: none; +} +.setBgImageUrl(@url) when (@fancy-use-sprites) and not (@fancy-inline-sprites) { + background-image: url("@{fancy-image-prefix}@{url}"); +} +.setBgImageUrl(@url) when (@fancy-use-sprites) and (@fancy-inline-sprites) { + background-image: data-uri("@{fancy-image-prefix}@{url}"); +} +.useSprite(@x, @y) when (@fancy-use-sprites) { + .setBgPos(@x, @y); +} +.rounded-corners(@radius) { + -webkit-border-radius: @radius; + -moz-border-radius: @radius; + -ms-border-radius: @radius; + -o-border-radius: @radius; + border-radius: @radius; +} +.spanStyleMixin(@color, @bgcolor, @bordercolor) { + border-color: @bordercolor; + background: @bgcolor; + color: @color; +} +.spanStyleMixin(@color, @bgcolor, @bordercolor, @startColor, @stopColor) { + .spanStyleMixin(@color, @bgcolor, @bordercolor); + // @c-start: argb(@startColor); + // @c-end: argb(@stopColor); + background: -moz-linear-gradient( + top, + @startColor 0%, + @stopColor 100% + ); // FF3.6+ + background: -webkit-gradient( + linear, + left top, + left bottom, + color-stop(0%, @startColor), + color-stop(100%, @stopColor) + ); // Chrome,Safari4+ + background: -webkit-linear-gradient( + top, + @startColor 0%, + @stopColor 100% + ); // Chrome10+,Safari5.1+ + background: -o-linear-gradient( + top, + @startColor 0%, + @stopColor 100% + ); // Opera 11.10+ + background: -ms-linear-gradient( + top, + @startColor 0%, + @stopColor 100% + ); // IE10+ + background: linear-gradient( + to bottom, + @startColor 0%, + @stopColor 100% + ); // W3C + filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='@{startColor}', endColorstr='@{stopColor}',GradientType=0 ); // IE6-9 +} + +/*------------------------------------------------------------------------------ + * Helpers + *----------------------------------------------------------------------------*/ +// Redefine, in case jQuery-UI is not included +// .ui-helper-hidden, +.fancytree-helper-hidden { + display: none; +} +.fancytree-helper-indeterminate-cb { + // tri-state checkbox + color: #777; +} +.fancytree-helper-disabled { + color: @fancy-font-color-dimm; +} + +/* Helper to allow spinning loader icon with glyph-, ligature-, and SVG-icons. */ +/* CHANGE: renamed spin to spin-fancytree */ +.fancytree-helper-spin { + -webkit-animation: spin-fancytree 1000ms infinite linear; + animation: spin-fancytree 1000ms infinite linear; +} +/* CHANGE: commented because it is wrong prefixed by phpless +@-webkit-keyframes spin { + 0% { + -webkit-transform: rotate(0deg); + transform: rotate(0deg); + } + 100% { + -webkit-transform: rotate(359deg); + transform: rotate(359deg); + } +} +@keyframes spin { + 0% { + -webkit-transform: rotate(0deg); + transform: rotate(0deg); + } + 100% { + -webkit-transform: rotate(359deg); + transform: rotate(359deg); + } +} +*/ +/*------------------------------------------------------------------------------ + * Container and UL / LI + *----------------------------------------------------------------------------*/ + +ul.fancytree-container { + font-family: @fancy-font-family; + font-size: @fancy-font-size; + white-space: nowrap; + padding: 3px; + margin: 0; // DT issue 201 + //background-color: white; CHANGE + //border: 1px dotted gray; CHANGE + // overflow: auto; // ext-dnd5: otherwise this is always the scroll parent + // height: 100%; // DT issue 263, 470 + min-height: 0%; // #192 + position: relative; // #235 + ul { + padding: 0 0 0 @fancy-level-indent; + margin: 0; + } + ul > li:before { + // #538 + content: none; + } + li { + list-style-image: none; + list-style-position: outside; + list-style-type: none; + -moz-background-clip: border; + -moz-background-inline-policy: continuous; + -moz-background-origin: padding; + background-attachment: scroll; + background-color: transparent; + .setBgPos(0, 0); + background-repeat: repeat-y; + background-image: none; // no v-lines + + margin: 0; + // padding: 1px 0 0 0; // issue #246 + } + // Suppress lines for last child node + li.fancytree-lastsib { + background-image: none; + } +} + +// Style, when control is disabled +.ui-fancytree-disabled ul.fancytree-container { + opacity: 0.5; + // filter: alpha(opacity=50); // Yields a css warning + background-color: silver; +} + +ul.fancytree-connectors.fancytree-container { + li { + // Use 'data-uri(...)' to embed the image into CSS instead of linking to 'loading.gif': + /* CHANGE: phpless does not handle data-uri() correct */ + //background-image: data-uri("@{fancy-image-prefix}vline.gif"); + background-image: url("@{fancy-image-prefix}vline.gif"); + background-position: 0 0; + } +} + +// Suppress lines for last child node +ul.fancytree-container li.fancytree-lastsib, +// Suppress lines if level is fixed expanded (option minExpandLevel) +ul.fancytree-no-connector > li { + background-image: none; +} + +// Fix jQuery UI 'blind' animation for jQuery UI (#717) +li.fancytree-animating { + position: relative; +} + +/*------------------------------------------------------------------------------ + * Common icon definitions + *----------------------------------------------------------------------------*/ + +span.fancytree-empty, +span.fancytree-vline, +span.fancytree-expander, +span.fancytree-icon, +span.fancytree-checkbox, +// span.fancytree-radio, +span.fancytree-drag-helper-img, +#fancytree-drop-marker { + width: @fancy-icon-width; + height: @fancy-icon-height; + // display: -moz-inline-box; // @ FF 1+2 removed for issue 221 + // -moz-box-align: start; /* issue 221 */ + display: inline-block; // Required to make a span sizeable + vertical-align: top; + background-repeat: no-repeat; + // background-position: left; + .setBgImageUrl("icons.gif"); + .setBgPos(0, 0); +} +span.fancytree-icon, +span.fancytree-checkbox, +span.fancytree-expander, +// span.fancytree-radio, +span.fancytree-custom-icon { + margin-top: @fancy-icon-ofs-top; +} +/* Used by icon option: */ +span.fancytree-custom-icon { + width: @fancy-icon-width; + height: @fancy-icon-height; + display: inline-block; + margin-left: @fancy-icon-spacing; + .setBgPos(0, 0); +} +/* Used by 'icon' node option: */ +img.fancytree-icon { + width: @fancy-icon-width; + height: @fancy-icon-height; + margin-left: @fancy-icon-spacing; + margin-top: @fancy-icon-ofs-top; + vertical-align: top; + border-style: none; +} + +/*------------------------------------------------------------------------------ + * Expander icon + * + * Note: IE6 doesn't correctly evaluate multiples class names, + * so we create combined class names that can be used in the CSS. + * + * Prefix: fancytree-exp- + * 1st character: 'e': expanded, 'c': collapsed, 'n': no children + * 2nd character (optional): 'd': lazy (Delayed) + * 3rd character (optional): 'l': Last sibling + *----------------------------------------------------------------------------*/ + +span.fancytree-expander { + // .useSprite(0, 5); + cursor: pointer; +} +// span.fancytree-expander:hover { +// // .useSprite(1, 5); +// } + +// --- End nodes (use connectors instead of expanders) + +.fancytree-exp-n span.fancytree-expander, +.fancytree-exp-nl span.fancytree-expander { + // .clearBgImage( @fancy-hide-connectors ); + background-image: none; + cursor: default; +} +.fancytree-connectors { + .fancytree-exp-n span.fancytree-expander, + .fancytree-exp-nl span.fancytree-expander { + .setBgImageUrl("icons.gif"); + margin-top: 0; + } + .fancytree-exp-n span.fancytree-expander, // End-node, not last sibling + .fancytree-exp-n span.fancytree-expander:hover { + .useSprite(0, 4); + } + .fancytree-exp-nl span.fancytree-expander, // End-node, last sibling + .fancytree-exp-nl span.fancytree-expander:hover { + .useSprite(1, 4); + } +} + +// --- Collapsed + +.fancytree-exp-c span.fancytree-expander { + // Collapsed, not delayed, not last sibling + .useSprite(0, 5); +} +.fancytree-exp-c span.fancytree-expander:hover { + .useSprite(1, 5); +} +.fancytree-exp-cl span.fancytree-expander { + // Collapsed, not delayed, last sibling + .useSprite(0, 6); +} +.fancytree-exp-cl span.fancytree-expander:hover { + .useSprite(1, 6); +} +.fancytree-exp-cd span.fancytree-expander { + // Collapsed, delayed, not last sibling + .useSprite(4, 5); +} +.fancytree-exp-cd span.fancytree-expander:hover { + .useSprite(5, 5); +} +.fancytree-exp-cdl span.fancytree-expander { + // Collapsed, delayed, last sibling + .useSprite(4, 6); +} +.fancytree-exp-cdl span.fancytree-expander:hover { + .useSprite(5, 6); +} + +// --- Expanded + +.fancytree-exp-e span.fancytree-expander, // Expanded, not delayed, not last sibling +.fancytree-exp-ed span.fancytree-expander { + // Expanded, delayed, not last sibling + .useSprite(2, 5); +} +.fancytree-exp-e span.fancytree-expander:hover, +.fancytree-exp-ed span.fancytree-expander:hover { + .useSprite(3, 5); +} +.fancytree-exp-el span.fancytree-expander, // Expanded, not delayed, last sibling +.fancytree-exp-edl span.fancytree-expander { + // Expanded, delayed, last sibling + .useSprite(2, 6); +} +.fancytree-exp-el span.fancytree-expander:hover, +.fancytree-exp-edl span.fancytree-expander:hover { + .useSprite(3, 6); +} + +/* Fade out expanders, when container is not hovered or active */ +.fancytree-fade-expander { + span.fancytree-expander { + transition: opacity 1.5s; + opacity: 0; + } + &:hover span.fancytree-expander, + &.fancytree-treefocus span.fancytree-expander, + .fancytree-treefocus span.fancytree-expander, + [class*="fancytree-statusnode-"] span.fancytree-expander { + transition: opacity 0.6s; + opacity: 1; + } +} + +//// CHANGE: not used. +///*------------------------------------------------------------------------------ +// * Checkbox icon +// *----------------------------------------------------------------------------*/ +// +//span.fancytree-checkbox { +// margin-left: @fancy-icon-spacing; +// .useSprite(0, 2); +// &:hover { +// .useSprite(1, 2); +// } +// &.fancytree-radio { +// .useSprite(0, 3); +// } +// &.fancytree-radio:hover { +// .useSprite(1, 3); +// } +//} +//.fancytree-partsel span.fancytree-checkbox { +// .useSprite(4, 2); +// &:hover { +// .useSprite(5, 2); +// } +// &.fancytree-radio { +// .useSprite(4, 3); +// } +// &.fancytree-radio:hover { +// .useSprite(5, 3); +// } +//} +//// selected after partsel, so it takes precedence: +//.fancytree-selected span.fancytree-checkbox { +// .useSprite(2, 2); +// &:hover { +// .useSprite(3, 2); +// } +// &.fancytree-radio { +// .useSprite(2, 3); +// } +// &.fancytree-radio:hover { +// .useSprite(3, 3); +// } +//} +//// Unselectable is dimmed, without hover effects +//.fancytree-unselectable { +// span.fancytree-checkbox { +// opacity: 0.4; +// filter: alpha(opacity=40); +// } +// span.fancytree-checkbox:hover { +// .useSprite(0, 2); +// } +// span.fancytree-checkbox.fancytree-radio:hover { +// .useSprite(0, 3); +// } +// &.fancytree-partsel span.fancytree-checkbox:hover { +// .useSprite(4, 2); +// } +// &.fancytree-selected span.fancytree-checkbox:hover { +// .useSprite(2, 2); +// } +// &.fancytree-selected span.fancytree-checkbox.fancytree-radio:hover { +// .useSprite(2, 3); +// } +//} +// +//// Auto-hide checkboxes unless selected or hovered +//.fancytree-container.fancytree-checkbox-auto-hide { +// span.fancytree-checkbox { +// visibility: hidden; +// } +// .fancytree-node:hover span.fancytree-checkbox, +// tr:hover td span.fancytree-checkbox, +// .fancytree-node.fancytree-selected span.fancytree-checkbox, +// tr.fancytree-selected td span.fancytree-checkbox { +// visibility: unset; +// } +// &.fancytree-treefocus { +// .fancytree-node.fancytree-active span.fancytree-checkbox, +// tr.fancytree-active td span.fancytree-checkbox { +// visibility: unset; +// } +// } +//} + +/*------------------------------------------------------------------------------ + * Node type icon + * Note: IE6 doesn't correctly evaluate multiples class names, + * so we create combined class names that can be used in the CSS. + * + * Prefix: fancytree-ico- + * 1st character: 'e': expanded, 'c': collapsed + * 2nd character (optional): 'f': folder + *----------------------------------------------------------------------------*/ + +span.fancytree-icon { + // Default icon + margin-left: @fancy-icon-spacing; + .useSprite(0, 0); +} + +/* Documents */ +.fancytree-ico-c span.fancytree-icon { + // Collapsed folder (empty) + // .useSprite(0, 0); +} +.fancytree-ico-c span.fancytree-icon:hover { + .useSprite(1, 0); +} +.fancytree-has-children.fancytree-ico-c span.fancytree-icon { + // Collapsed folder (not empty) + .useSprite(2, 0); +} +.fancytree-has-children.fancytree-ico-c span.fancytree-icon:hover { + .useSprite(3, 0); +} +.fancytree-ico-e span.fancytree-icon { + // Expanded folder + .useSprite(4, 0); +} +.fancytree-ico-e span.fancytree-icon:hover { + .useSprite(5, 0); +} + +/* Folders */ +.fancytree-ico-cf span.fancytree-icon { + // Collapsed folder (empty) + .useSprite(0, 1); +} +.fancytree-ico-cf span.fancytree-icon:hover { + .useSprite(1, 1); +} +.fancytree-has-children.fancytree-ico-cf span.fancytree-icon { + // Collapsed folder (not empty) + .useSprite(2, 1); +} +.fancytree-has-children.fancytree-ico-cf span.fancytree-icon:hover { + .useSprite(3, 1); +} +.fancytree-ico-ef span.fancytree-icon { + // Expanded folder + .useSprite(4, 1); +} +.fancytree-ico-ef span.fancytree-icon:hover { + .useSprite(5, 1); +} + +// 'Loading' status overrides all others +.fancytree-loading span.fancytree-expander, +.fancytree-loading span.fancytree-expander:hover, +.fancytree-statusnode-loading span.fancytree-icon, +.fancytree-statusnode-loading span.fancytree-icon:hover, +span.fancytree-icon.fancytree-icon-loading { + background-image: @fancy-loading-url; + .useSprite(0, 0); +} + +/* Status node icons */ + +.fancytree-statusnode-error span.fancytree-icon, +.fancytree-statusnode-error span.fancytree-icon:hover { + .useSprite(0, 7); +} + +/*------------------------------------------------------------------------------ + * Node titles and highlighting + *----------------------------------------------------------------------------*/ + +span.fancytree-node { + /* See #117 */ + display: inherit; // #117, resolves to 'display: list-item;' for standard trees + width: 100%; + margin-top: @fancy-node-v-spacing; + min-height: @fancy-line-height; +} +span.fancytree-title { + color: @fancy-font-color; // inherit doesn't work on IE + cursor: pointer; + display: inline-block; // Better alignment, when title contains <br> + vertical-align: top; + min-height: @fancy-line-height; + padding: 0 3px 0 3px; // Otherwise italic font will be outside right bounds + margin: @fancy-title-ofs-top 0 0 @fancy-icon-spacing; + // margin: 0px; + // margin-top: @fancy-line-ofs-top; + // margin-left: @fancy-icon-spacing; + border: @fancy-node-border-width solid transparent; // avoid jumping, when a border is added on hover + .rounded-corners(@fancy-node-border-radius); + // outline: 0; // @ Firefox, prevent dotted border after click + // Set transparent border to prevent jumping when active node gets a border + // (we can do this, because this theme doesn't use vertical lines) + // border: 1px solid white; // Note: 'transparent' would not work in IE6 +} +span.fancytree-node.fancytree-error span.fancytree-title { + color: @fancy-font-error-color; +} + +//// CHANGE: not used. +///*------------------------------------------------------------------------------ +// * Drag'n'drop support +// *----------------------------------------------------------------------------*/ +///* ext-dnd5: */ +//span.fancytree-childcounter { +// color: #fff; +// background: #337ab7; // bootstrap blue +// border: 1px solid gray; +// border-radius: 10px; +// padding: 2px; +// text-align: center; +//} +// +///* ext-dnd: */ +//div.fancytree-drag-helper { +// span.fancytree-childcounter, +// span.fancytree-dnd-modifier { +// display: inline-block; +// color: #fff; +// background: #337ab7; // bootstrap blue +// border: 1px solid gray; +// min-width: 10px; +// // min-height: 16px; +// height: 10px; +// line-height: 1; +// vertical-align: baseline; +// border-radius: 10px; +// padding: 2px; +// text-align: center; +// font-size: 9px; +// } +// span.fancytree-childcounter { +// position: absolute; +// // left: 16px; +// top: -6px; +// right: -6px; +// } +// span.fancytree-dnd-modifier { +// background: #5cb85c; // bootstrap green +// border: none; +// // min-height: 16px; +// // font-size: 12px; +// font-weight: bolder; +// } +// &.fancytree-drop-accept { +// span.fancytree-drag-helper-img { +// .useSprite(2, 7); +// } +// } +// &.fancytree-drop-reject { +// span.fancytree-drag-helper-img { +// .useSprite(1, 7); +// } +// } +//} +// +///*** Drop marker icon *********************************************************/ +//#fancytree-drop-marker { +// width: 2 * @fancy-icon-width; // was 24px, but 32 should be correct +// position: absolute; +// .useSprite(0, 8); +// margin: 0; +// &.fancytree-drop-after, +// &.fancytree-drop-before { +// width: 4 * @fancy-icon-width; // 64px; +// .useSprite(0, 9); +// } +// &.fancytree-drop-copy { +// .useSprite(4, 8); +// } +// &.fancytree-drop-move { +// .useSprite(2, 8); +// } +//} +// +///*** Source node while dragging ***********************************************/ +// +//span.fancytree-drag-source { +// &.fancytree-drag-remove { +// // text-decoration: line-through; +// opacity: 0.15; +// } +//} +// +///*** Target node while dragging cursor is over it *****************************/ +// +//span.fancytree-drop-target { +// &.fancytree-drop-accept { +// // outline: 1px dotted #5cb85c; // bootstrap sucess +// } +//} +//span.fancytree-drop-reject { +// // outline: 1px dotted #d9534f; // boostrap warning +//} + +/*------------------------------------------------------------------------------ + * 'rtl' option + *----------------------------------------------------------------------------*/ + +.fancytree-container.fancytree-rtl { + .fancytree-title { + /*unicode-bidi: bidi-override;*/ /* optional: reverse title letters */ + } + span.fancytree-connector, + span.fancytree-expander, + span.fancytree-icon, + span.fancytree-drag-helper-img { + .setBgImageUrl("icons-rtl.gif"); + } + .fancytree-exp-n span.fancytree-expander, + .fancytree-exp-nl span.fancytree-expander { + background-image: none; + } + &.fancytree-connectors .fancytree-exp-n span.fancytree-expander, + &.fancytree-connectors .fancytree-exp-nl span.fancytree-expander { + .setBgImageUrl("icons-rtl.gif"); + } +} +ul.fancytree-container.fancytree-rtl { + ul { + padding: 0 16px 0 0; + } + &.fancytree-connectors li { + background-position: right 0; + background-image: url("@{fancy-image-prefix}vline-rtl.gif"); + } + // Suppress lines for last child node + li.fancytree-lastsib, + // Suppress lines if level is fixed expanded (option minExpandLevel) + &.fancytree-no-connector > li { + background-image: none; + } +} +#fancytree-drop-marker.fancytree-rtl { + .setBgImageUrl("icons-rtl.gif"); +} + +//// CHANGE: not used. +///*------------------------------------------------------------------------------ +// * 'table' extension +// *----------------------------------------------------------------------------*/ +// +//table.fancytree-ext-table { +// font-family: @fancy-font-family; +// font-size: @fancy-font-size; +// border-collapse: collapse; +// span.fancytree-node { +// display: inline-block; // #117 +// box-sizing: border-box; // #562 +// } +// td.fancytree-status-merged { +// text-align: center; +// // font-weight: bold; +// font-style: italic; +// // line-height: 100px; +// color: @fancy-font-color-dimm; +// } +// tr.fancytree-statusnode-error td.fancytree-status-merged { +// color: @fancy-font-error-color; +// } +// /* ext-ariagrid */ +// &.fancytree-ext-ariagrid.fancytree-cell-mode { +// > tbody > tr.fancytree-active > td { +// background-color: #eee; +// } +// > tbody > tr > td.fancytree-active-cell { +// background-color: #cbe8f6; +// } +// &.fancytree-cell-nav-mode > tbody > tr > td.fancytree-active-cell { +// background-color: #3875d7; +// } +// } +//} +// +///*------------------------------------------------------------------------------ +// * 'columnview' extension +// *----------------------------------------------------------------------------*/ +// +//table.fancytree-ext-columnview { +// // border-collapse: collapse; +// // width: 100%; +// tbody tr td { +// position: relative; +// border: 1px solid gray; +// vertical-align: top; +// overflow: auto; +// > ul { +// padding: 0; +// li { +// list-style-image: none; +// list-style-position: outside; +// list-style-type: none; +// -moz-background-clip: border; +// -moz-background-inline-policy: continuous; +// -moz-background-origin: padding; +// background-attachment: scroll; +// background-color: transparent; +// .setBgPos(0, 0); +// background-repeat: repeat-y; +// background-image: none; /* no v-lines */ +// +// margin: 0; +// // padding: 1px 0 0 0; // issue #246 +// } +// } +// } +// span.fancytree-node { +// position: relative; /* allow positioning of embedded spans */ +// display: inline-block; // #117 +// } +// span.fancytree-node.fancytree-expanded { +// background-color: #e0e0e0; +// } +// span.fancytree-node.fancytree-active { +// background-color: #cbe8f6; +// // background-color: royalblue; +// } +// .fancytree-has-children span.fancytree-cv-right { +// position: absolute; +// right: 3px; +// .useSprite(0, 5); +// &:hover { +// .useSprite(1, 5); +// } +// } +//} +// +///*------------------------------------------------------------------------------ +// * 'filter' extension +// *----------------------------------------------------------------------------*/ +// +//.fancytree-ext-filter-dimm { +// span.fancytree-node span.fancytree-title { +// color: @fancy-font-color-dimm; +// font-weight: lighter; +// } +// tr.fancytree-submatch span.fancytree-title, +// span.fancytree-node.fancytree-submatch span.fancytree-title { +// color: black; +// font-weight: normal; +// } +// tr.fancytree-match span.fancytree-title, +// span.fancytree-node.fancytree-match span.fancytree-title { +// color: black; +// font-weight: bold; +// } +//} +//.fancytree-ext-filter-hide { +// tr.fancytree-hide, +// span.fancytree-node.fancytree-hide { +// display: none; +// } +// tr.fancytree-submatch span.fancytree-title, +// span.fancytree-node.fancytree-submatch span.fancytree-title { +// color: @fancy-font-color-dimm; +// font-weight: lighter; +// } +// tr.fancytree-match span.fancytree-title, +// span.fancytree-node.fancytree-match span.fancytree-title { +// color: black; +// font-weight: normal; +// } +//} +///* Hide expanders if all child nodes are hidden by filter */ +//.fancytree-ext-filter-hide-expanders { +// tr.fancytree-match span.fancytree-expander, +// span.fancytree-node.fancytree-match span.fancytree-expander { +// visibility: hidden; +// } +// tr.fancytree-submatch span.fancytree-expander, +// span.fancytree-node.fancytree-submatch span.fancytree-expander { +// visibility: visible; +// } +//} +// +//.fancytree-ext-childcounter, +//.fancytree-ext-filter { +// // span.fancytree-title mark { +// // font-style: normal; +// // background-color: #ead61c; // yellow +// // border-radius: 3px; +// // } +// span.fancytree-icon, +// span.fancytree-custom-icon { +// position: relative; +// } +// span.fancytree-childcounter { +// color: #fff; +// background: #777; // #337ab7; // bootstrap blue +// border: 1px solid gray; +// position: absolute; +// top: -6px; +// right: -6px; +// min-width: 10px; +// height: 10px; +// line-height: 1; +// vertical-align: baseline; +// border-radius: 10px; +// padding: 2px; +// text-align: center; +// font-size: 9px; +// } +//} +///*------------------------------------------------------------------------------ +// * 'wide' extension +// *----------------------------------------------------------------------------*/ +// +//ul.fancytree-ext-wide { +// position: relative; +// min-width: 100%; +// z-index: 2; +// +// -webkit-box-sizing: border-box; +// -moz-box-sizing: border-box; +// box-sizing: border-box; +// +// span.fancytree-node > span { +// position: relative; +// z-index: 2; +// } +// span.fancytree-node span.fancytree-title { +// position: absolute; // Allow left: 0. Note: prevents smooth dropdown animation +// z-index: 1; // Behind expander and checkbox +// left: 0px; +// min-width: 100%; +// margin-left: 0; +// margin-right: 0; +// +// -webkit-box-sizing: border-box; +// -moz-box-sizing: border-box; +// box-sizing: border-box; +// } +//} +// +///*------------------------------------------------------------------------------ +// * 'fixed' extension +// *----------------------------------------------------------------------------*/ +// +//.fancytree-ext-fixed-wrapper { +// .fancytree-ext-fixed-hidden { +// display: none; +// } +// div.fancytree-ext-fixed-scroll-border-bottom { +// border-bottom: 3px solid rgba(0, 0, 0, 0.75); +// } +// div.fancytree-ext-fixed-scroll-border-right { +// border-right: 3px solid rgba(0, 0, 0, 0.75); +// } +// div.fancytree-ext-fixed-wrapper-tl { +// position: absolute; +// overflow: hidden; +// z-index: 3; +// top: 0px; +// left: 0px; +// } +// div.fancytree-ext-fixed-wrapper-tr { +// position: absolute; +// overflow: hidden; +// z-index: 2; +// top: 0px; +// } +// div.fancytree-ext-fixed-wrapper-bl { +// position: absolute; +// overflow: hidden; +// z-index: 2; +// left: 0px; +// } +// div.fancytree-ext-fixed-wrapper-br { +// position: absolute; +// overflow: scroll; +// z-index: 1; +// } +//} diff --git a/plugins/55/indexmenu/scripts/fancytree/skin-material/ui.fancytree.css b/plugins/55/indexmenu/scripts/fancytree/skin-material/ui.fancytree.css new file mode 100644 index 0000000..e104e1a --- /dev/null +++ b/plugins/55/indexmenu/scripts/fancytree/skin-material/ui.fancytree.css @@ -0,0 +1,581 @@ +/*! + * Fancytree "material" skin. + * + * DON'T EDIT THE CSS FILE DIRECTLY, since it is automatically generated from + * the LESS templates. + */ +/******************************************************************************* + * Common Styles for Fancytree Skins. + * + * This section is automatically generated from the `skin-common.less` template. + * + * Copyright (c) 2008-2023, Martin Wendt (https://wwWendt.de) + * Released under the MIT license + * https://github.com/mar10/fancytree/wiki/LicenseInfo + * + * @version 2.38.3 + * @date 2023-02-01T20:52:50Z +******************************************************************************/ +/*------------------------------------------------------------------------------ + * Helpers + *----------------------------------------------------------------------------*/ +.fancytree-helper-hidden { + display: none; +} +.fancytree-helper-indeterminate-cb { + color: #777; +} +.fancytree-helper-disabled { + color: silver; +} +/* Helper to allow spinning loader icon with glyph-, ligature-, and SVG-icons. */ +.fancytree-helper-spin { + -webkit-animation: spin 1000ms infinite linear; + animation: spin 1000ms infinite linear; +} +@-webkit-keyframes spin { + 0% { + -webkit-transform: rotate(0deg); + transform: rotate(0deg); + } + 100% { + -webkit-transform: rotate(359deg); + transform: rotate(359deg); + } +} +@keyframes spin { + 0% { + -webkit-transform: rotate(0deg); + transform: rotate(0deg); + } + 100% { + -webkit-transform: rotate(359deg); + transform: rotate(359deg); + } +} +/*------------------------------------------------------------------------------ + * Container and UL / LI + *----------------------------------------------------------------------------*/ +ul.fancytree-container { + font-family: "Roboto Regular", tahoma, arial, helvetica; + font-size: 24px; + white-space: nowrap; + padding: 3px; + margin: 0; + background-color: white; + border: 1px dotted gray; + min-height: 0%; + position: relative; +} +ul.fancytree-container ul { + padding: 0 0 0 24px; + margin: 0; +} +ul.fancytree-container ul > li:before { + content: none; +} +ul.fancytree-container li { + list-style-image: none; + list-style-position: outside; + list-style-type: none; + -moz-background-clip: border; + -moz-background-inline-policy: continuous; + -moz-background-origin: padding; + background-attachment: scroll; + background-color: transparent; + background-position: 0px 0px; + background-repeat: repeat-y; + background-image: none; + margin: 0; +} +ul.fancytree-container li.fancytree-lastsib { + background-image: none; +} +.ui-fancytree-disabled ul.fancytree-container { + opacity: 0.5; + background-color: silver; +} +ul.fancytree-connectors.fancytree-container li { + background-image: url("../skin-material/vline.gif"); + background-position: 0 0; +} +ul.fancytree-container li.fancytree-lastsib, +ul.fancytree-no-connector > li { + background-image: none; +} +li.fancytree-animating { + position: relative; +} +/*------------------------------------------------------------------------------ + * Common icon definitions + *----------------------------------------------------------------------------*/ +span.fancytree-empty, +span.fancytree-vline, +span.fancytree-expander, +span.fancytree-icon, +span.fancytree-checkbox, +span.fancytree-drag-helper-img, +#fancytree-drop-marker { + width: 24px; + height: 24px; + display: inline-block; + vertical-align: top; + background-repeat: no-repeat; + background-position: 0px 0px; +} +span.fancytree-icon, +span.fancytree-checkbox, +span.fancytree-expander, +span.fancytree-custom-icon { + margin-top: 0px; +} +/* Used by icon option: */ +span.fancytree-custom-icon { + width: 24px; + height: 24px; + display: inline-block; + margin-left: 3px; + background-position: 0px 0px; +} +/* Used by 'icon' node option: */ +img.fancytree-icon { + width: 24px; + height: 24px; + margin-left: 3px; + margin-top: 0px; + vertical-align: top; + border-style: none; +} +/*------------------------------------------------------------------------------ + * Expander icon + * + * Note: IE6 doesn't correctly evaluate multiples class names, + * so we create combined class names that can be used in the CSS. + * + * Prefix: fancytree-exp- + * 1st character: 'e': expanded, 'c': collapsed, 'n': no children + * 2nd character (optional): 'd': lazy (Delayed) + * 3rd character (optional): 'l': Last sibling + *----------------------------------------------------------------------------*/ +span.fancytree-expander { + cursor: pointer; +} +.fancytree-exp-n span.fancytree-expander, +.fancytree-exp-nl span.fancytree-expander { + background-image: none; + cursor: default; +} +.fancytree-connectors .fancytree-exp-n span.fancytree-expander, +.fancytree-connectors .fancytree-exp-nl span.fancytree-expander { + margin-top: 0; +} +/* Fade out expanders, when container is not hovered or active */ +.fancytree-fade-expander span.fancytree-expander { + transition: opacity 1.5s; + opacity: 0; +} +.fancytree-fade-expander:hover span.fancytree-expander, +.fancytree-fade-expander.fancytree-treefocus span.fancytree-expander, +.fancytree-fade-expander .fancytree-treefocus span.fancytree-expander, +.fancytree-fade-expander [class*="fancytree-statusnode-"] span.fancytree-expander { + transition: opacity 0.6s; + opacity: 1; +} +/*------------------------------------------------------------------------------ + * Checkbox icon + *----------------------------------------------------------------------------*/ +span.fancytree-checkbox { + margin-left: 3px; +} +.fancytree-unselectable span.fancytree-checkbox { + opacity: 0.4; + filter: alpha(opacity=40); +} +.fancytree-container.fancytree-checkbox-auto-hide span.fancytree-checkbox { + visibility: hidden; +} +.fancytree-container.fancytree-checkbox-auto-hide .fancytree-node:hover span.fancytree-checkbox, +.fancytree-container.fancytree-checkbox-auto-hide tr:hover td span.fancytree-checkbox, +.fancytree-container.fancytree-checkbox-auto-hide .fancytree-node.fancytree-selected span.fancytree-checkbox, +.fancytree-container.fancytree-checkbox-auto-hide tr.fancytree-selected td span.fancytree-checkbox { + visibility: unset; +} +.fancytree-container.fancytree-checkbox-auto-hide.fancytree-treefocus .fancytree-node.fancytree-active span.fancytree-checkbox, +.fancytree-container.fancytree-checkbox-auto-hide.fancytree-treefocus tr.fancytree-active td span.fancytree-checkbox { + visibility: unset; +} +/*------------------------------------------------------------------------------ + * Node type icon + * Note: IE6 doesn't correctly evaluate multiples class names, + * so we create combined class names that can be used in the CSS. + * + * Prefix: fancytree-ico- + * 1st character: 'e': expanded, 'c': collapsed + * 2nd character (optional): 'f': folder + *----------------------------------------------------------------------------*/ +span.fancytree-icon { + margin-left: 3px; +} +/* Documents */ +/* Folders */ +.fancytree-loading span.fancytree-expander, +.fancytree-loading span.fancytree-expander:hover, +.fancytree-statusnode-loading span.fancytree-icon, +.fancytree-statusnode-loading span.fancytree-icon:hover, +span.fancytree-icon.fancytree-icon-loading { + background-image: none; +} +/* Status node icons */ +/*------------------------------------------------------------------------------ + * Node titles and highlighting + *----------------------------------------------------------------------------*/ +span.fancytree-node { + /* See #117 */ + display: inherit; + width: 100%; + margin-top: 1px; + min-height: 24px; +} +span.fancytree-title { + color: #212121; + cursor: pointer; + display: inline-block; + vertical-align: top; + min-height: 24px; + padding: 0 3px 0 3px; + margin: 0px 0 0 3px; + border: 1px solid transparent; + -webkit-border-radius: 0px; + -moz-border-radius: 0px; + -ms-border-radius: 0px; + -o-border-radius: 0px; + border-radius: 0px; +} +span.fancytree-node.fancytree-error span.fancytree-title { + color: red; +} +/*------------------------------------------------------------------------------ + * Drag'n'drop support + *----------------------------------------------------------------------------*/ +/* ext-dnd5: */ +span.fancytree-childcounter { + color: #fff; + background: #337ab7; + border: 1px solid gray; + border-radius: 10px; + padding: 2px; + text-align: center; +} +/* ext-dnd: */ +div.fancytree-drag-helper span.fancytree-childcounter, +div.fancytree-drag-helper span.fancytree-dnd-modifier { + display: inline-block; + color: #fff; + background: #337ab7; + border: 1px solid gray; + min-width: 10px; + height: 10px; + line-height: 1; + vertical-align: baseline; + border-radius: 10px; + padding: 2px; + text-align: center; + font-size: 9px; +} +div.fancytree-drag-helper span.fancytree-childcounter { + position: absolute; + top: -6px; + right: -6px; +} +div.fancytree-drag-helper span.fancytree-dnd-modifier { + background: #5cb85c; + border: none; + font-weight: bolder; +} +/*** Drop marker icon *********************************************************/ +#fancytree-drop-marker { + width: 48px; + position: absolute; + margin: 0; +} +#fancytree-drop-marker.fancytree-drop-after, +#fancytree-drop-marker.fancytree-drop-before { + width: 96px; +} +/*** Source node while dragging ***********************************************/ +span.fancytree-drag-source.fancytree-drag-remove { + opacity: 0.15; +} +/*** Target node while dragging cursor is over it *****************************/ +/*------------------------------------------------------------------------------ + * 'rtl' option + *----------------------------------------------------------------------------*/ +.fancytree-container.fancytree-rtl .fancytree-title { + /*unicode-bidi: bidi-override;*/ + /* optional: reverse title letters */ +} +.fancytree-container.fancytree-rtl .fancytree-exp-n span.fancytree-expander, +.fancytree-container.fancytree-rtl .fancytree-exp-nl span.fancytree-expander { + background-image: none; +} +ul.fancytree-container.fancytree-rtl ul { + padding: 0 16px 0 0; +} +ul.fancytree-container.fancytree-rtl.fancytree-connectors li { + background-position: right 0; + background-image: url("../skin-material/vline-rtl.gif"); +} +ul.fancytree-container.fancytree-rtl li.fancytree-lastsib, +ul.fancytree-container.fancytree-rtl.fancytree-no-connector > li { + background-image: none; +} +/*------------------------------------------------------------------------------ + * 'table' extension + *----------------------------------------------------------------------------*/ +table.fancytree-ext-table { + font-family: "Roboto Regular", tahoma, arial, helvetica; + font-size: 24px; + border-collapse: collapse; + /* ext-ariagrid */ +} +table.fancytree-ext-table span.fancytree-node { + display: inline-block; + box-sizing: border-box; +} +table.fancytree-ext-table td.fancytree-status-merged { + text-align: center; + font-style: italic; + color: silver; +} +table.fancytree-ext-table tr.fancytree-statusnode-error td.fancytree-status-merged { + color: red; +} +table.fancytree-ext-table.fancytree-ext-ariagrid.fancytree-cell-mode > tbody > tr.fancytree-active > td { + background-color: #eee; +} +table.fancytree-ext-table.fancytree-ext-ariagrid.fancytree-cell-mode > tbody > tr > td.fancytree-active-cell { + background-color: #cbe8f6; +} +table.fancytree-ext-table.fancytree-ext-ariagrid.fancytree-cell-mode.fancytree-cell-nav-mode > tbody > tr > td.fancytree-active-cell { + background-color: #3875d7; +} +/*------------------------------------------------------------------------------ + * 'columnview' extension + *----------------------------------------------------------------------------*/ +table.fancytree-ext-columnview tbody tr td { + position: relative; + border: 1px solid gray; + vertical-align: top; + overflow: auto; +} +table.fancytree-ext-columnview tbody tr td > ul { + padding: 0; +} +table.fancytree-ext-columnview tbody tr td > ul li { + list-style-image: none; + list-style-position: outside; + list-style-type: none; + -moz-background-clip: border; + -moz-background-inline-policy: continuous; + -moz-background-origin: padding; + background-attachment: scroll; + background-color: transparent; + background-position: 0px 0px; + background-repeat: repeat-y; + background-image: none; + /* no v-lines */ + margin: 0; +} +table.fancytree-ext-columnview span.fancytree-node { + position: relative; + /* allow positioning of embedded spans */ + display: inline-block; +} +table.fancytree-ext-columnview span.fancytree-node.fancytree-expanded { + background-color: #e0e0e0; +} +table.fancytree-ext-columnview span.fancytree-node.fancytree-active { + background-color: #cbe8f6; +} +table.fancytree-ext-columnview .fancytree-has-children span.fancytree-cv-right { + position: absolute; + right: 3px; +} +/*------------------------------------------------------------------------------ + * 'filter' extension + *----------------------------------------------------------------------------*/ +.fancytree-ext-filter-dimm span.fancytree-node span.fancytree-title { + color: silver; + font-weight: lighter; +} +.fancytree-ext-filter-dimm tr.fancytree-submatch span.fancytree-title, +.fancytree-ext-filter-dimm span.fancytree-node.fancytree-submatch span.fancytree-title { + color: black; + font-weight: normal; +} +.fancytree-ext-filter-dimm tr.fancytree-match span.fancytree-title, +.fancytree-ext-filter-dimm span.fancytree-node.fancytree-match span.fancytree-title { + color: black; + font-weight: bold; +} +.fancytree-ext-filter-hide tr.fancytree-hide, +.fancytree-ext-filter-hide span.fancytree-node.fancytree-hide { + display: none; +} +.fancytree-ext-filter-hide tr.fancytree-submatch span.fancytree-title, +.fancytree-ext-filter-hide span.fancytree-node.fancytree-submatch span.fancytree-title { + color: silver; + font-weight: lighter; +} +.fancytree-ext-filter-hide tr.fancytree-match span.fancytree-title, +.fancytree-ext-filter-hide span.fancytree-node.fancytree-match span.fancytree-title { + color: black; + font-weight: normal; +} +/* Hide expanders if all child nodes are hidden by filter */ +.fancytree-ext-filter-hide-expanders tr.fancytree-match span.fancytree-expander, +.fancytree-ext-filter-hide-expanders span.fancytree-node.fancytree-match span.fancytree-expander { + visibility: hidden; +} +.fancytree-ext-filter-hide-expanders tr.fancytree-submatch span.fancytree-expander, +.fancytree-ext-filter-hide-expanders span.fancytree-node.fancytree-submatch span.fancytree-expander { + visibility: visible; +} +.fancytree-ext-childcounter span.fancytree-icon, +.fancytree-ext-filter span.fancytree-icon, +.fancytree-ext-childcounter span.fancytree-custom-icon, +.fancytree-ext-filter span.fancytree-custom-icon { + position: relative; +} +.fancytree-ext-childcounter span.fancytree-childcounter, +.fancytree-ext-filter span.fancytree-childcounter { + color: #fff; + background: #777; + border: 1px solid gray; + position: absolute; + top: -6px; + right: -6px; + min-width: 10px; + height: 10px; + line-height: 1; + vertical-align: baseline; + border-radius: 10px; + padding: 2px; + text-align: center; + font-size: 9px; +} +/*------------------------------------------------------------------------------ + * 'wide' extension + *----------------------------------------------------------------------------*/ +ul.fancytree-ext-wide { + position: relative; + min-width: 100%; + z-index: 2; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; +} +ul.fancytree-ext-wide span.fancytree-node > span { + position: relative; + z-index: 2; +} +ul.fancytree-ext-wide span.fancytree-node span.fancytree-title { + position: absolute; + z-index: 1; + left: 0px; + min-width: 100%; + margin-left: 0; + margin-right: 0; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; +} +/*------------------------------------------------------------------------------ + * 'fixed' extension + *----------------------------------------------------------------------------*/ +.fancytree-ext-fixed-wrapper .fancytree-ext-fixed-hidden { + display: none; +} +.fancytree-ext-fixed-wrapper div.fancytree-ext-fixed-scroll-border-bottom { + border-bottom: 3px solid rgba(0, 0, 0, 0.75); +} +.fancytree-ext-fixed-wrapper div.fancytree-ext-fixed-scroll-border-right { + border-right: 3px solid rgba(0, 0, 0, 0.75); +} +.fancytree-ext-fixed-wrapper div.fancytree-ext-fixed-wrapper-tl { + position: absolute; + overflow: hidden; + z-index: 3; + top: 0px; + left: 0px; +} +.fancytree-ext-fixed-wrapper div.fancytree-ext-fixed-wrapper-tr { + position: absolute; + overflow: hidden; + z-index: 2; + top: 0px; +} +.fancytree-ext-fixed-wrapper div.fancytree-ext-fixed-wrapper-bl { + position: absolute; + overflow: hidden; + z-index: 2; + left: 0px; +} +.fancytree-ext-fixed-wrapper div.fancytree-ext-fixed-wrapper-br { + position: absolute; + overflow: scroll; + z-index: 1; +} +/******************************************************************************* + * Styles specific to this skin. + * + * This section is automatically generated from the `ui-fancytree.less` template. + ******************************************************************************/ +/* +https://material.io/guidelines/components/data-tables.html#data-tables-structure +*/ +ul.fancytree-container ul { + padding: 0.3em 0 0 1em; + margin: 0; + font-size: 24px; + color: #212121; +} +/******************************************************************************* + * Node titles + */ +.fancytree-plain span.fancytree-selected span.fancytree-title { + background-color: #f5f5f5; +} +.fancytree-plain span.fancytree-selected span.fancytree-title:hover, +.fancytree-plain span.fancytree-active span.fancytree-title { + background-color: #eeeeee; +} +.fancytree-container span.fancytree-checkbox { + color: #ff4081; +} +/******************************************************************************* + * 'table' extension + */ +table.fancytree-ext-table { + border-collapse: collapse; +} +table.fancytree-ext-table tbody tr.fancytree-focused, +table.fancytree-ext-table tbody tr.fancytree-selected { + background-color: #f5f5f5; +} +table.fancytree-ext-table tbody tr.fancytree-active, +table.fancytree-ext-table tbody tr:hover { + background-color: #eeeeee; +} +/******************************************************************************* + * 'columnview' extension + */ +table.fancytree-ext-columnview tbody tr td { + border: 1px solid gray; +} +table.fancytree-ext-columnview span.fancytree-node.fancytree-expanded { + background-color: #ccc; +} +table.fancytree-ext-columnview span.fancytree-node.fancytree-active { + background-color: royalblue; +} diff --git a/plugins/55/indexmenu/scripts/fancytree/skin-material/ui.fancytree.less b/plugins/55/indexmenu/scripts/fancytree/skin-material/ui.fancytree.less new file mode 100644 index 0000000..c929e84 --- /dev/null +++ b/plugins/55/indexmenu/scripts/fancytree/skin-material/ui.fancytree.less @@ -0,0 +1,131 @@ +/*! + * Fancytree "material" skin. + * + * DON'T EDIT THE CSS FILE DIRECTLY, since it is automatically generated from + * the LESS templates. + */ + +// Import common styles +@import "skin-common.less"; + +// We need to define this variable here (not in skin-common.less) to make it +// work with grunt and webpack: +@fancy-image-prefix: "./skin-material/"; + +/******************************************************************************* + * Styles specific to this skin. + * + * This section is automatically generated from the `ui-fancytree.less` template. + ******************************************************************************/ +/* +https://material.io/guidelines/components/data-tables.html#data-tables-structure +*/ +// local vars +@fancy-cst-size: 18px; +@fancy-cst-primary-color: #3f51b5; // primary app color (of indigo-pink) +@fancy-cst-secondary-color: #ff4081; // secondary app color (of indigo-pink): checkbox +@fancy-cst-black-87: #212121; // 87% black: table content +@fancy-cst-black-54: #757575; // 54% black: column headers +@fancy-cst-select-bg: #f5f5f5; // Grey 100: selected row backround +@fancy-cst-hover-bg: #eeeeee; // Grey 200: hovered row backround + +// Override the variable after the import. +// NOTE: Variables are always resolved as the last definition, even if it is +// after where it is used. +@fancy-use-sprites: false; // false: suppress all background images (i.e. icons) +@fancy-loading-url: none; + +@fancy-level-indent: @fancy-cst-size; //@fancy-cst-size; +@fancy-line-height: @fancy-cst-size; // height of a nodes selection bar including borders +@fancy-node-v-spacing: 1px; // gap between two node borders +@fancy-icon-width: @fancy-cst-size; +@fancy-icon-height: @fancy-cst-size; +@fancy-icon-spacing: 3px; // margin between icon/icon or icon/title +@fancy-icon-ofs-top: 0px; // extra vertical offset for expander, checkbox and icon +@fancy-title-ofs-top: 0px; // extra vertical offset for title +@fancy-node-border-width: 1px; +@fancy-node-border-radius: 0px; +@fancy-node-outline-width: 1px; + +// @fancy-loading-url: data-uri("@{fancy-image-prefix}loading.gif"); + +// Set to `true` to use `data-uri(...)` instead of a `url(...)` link: +@fancy-inline-sprites: false; + +//default 10pt, which is used in a relative manner resulting in 13.3 in dokuwiki-template. +@fancy-font-size: 93%; //@fancy-cst-size; +@fancy-font-family: "Roboto Regular", tahoma, arial, helvetica; +@fancy-font-color: @fancy-cst-black-87; +@fancy-font-color-dimm: silver; +@fancy-font-error-color: red; + + +ul.fancytree-container ul +{ + padding: 0 0 0 1em; //0.3em 0 0 1em; + margin: 0; + //font-size: @fancy-cst-size; + //color: @fancy-cst-black-87; +} + +ul.fancytree-container span.fancytree-icon.material-icons +{ + font-size: @fancy-cst-size; + color: @fancy-cst-black-87; +} + + +// set icon color to font color as well +span.fancytree-node { + color: @fancy-font-color; +} +span.fancytree-expander { + font-size: @fancy-cst-size; +} + +/******************************************************************************* + * Node titles + */ + + .fancytree-plain { + span.fancytree-selected span.fancytree-title { + background-color: @fancy-cst-select-bg; + } + span.fancytree-selected span.fancytree-title:hover, + span.fancytree-active span.fancytree-title { + background-color: @fancy-cst-hover-bg; + } +} + +.fancytree-container span.fancytree-checkbox { + color: @fancy-cst-secondary-color; +} + +///******************************************************************************* +// * 'table' extension +// */ +//table.fancytree-ext-table { +// border-collapse: collapse; +// tbody { +// tr.fancytree-focused, tr.fancytree-selected { +// background-color: @fancy-cst-select-bg; +// } +// tr.fancytree-active, tr:hover { +// background-color: @fancy-cst-hover-bg; +// } +// } +//} +// +///******************************************************************************* +// * 'columnview' extension +// */ +// +//table.fancytree-ext-columnview tbody tr td { +// border: 1px solid gray; +//} +//table.fancytree-ext-columnview span.fancytree-node.fancytree-expanded { +// background-color: #ccc; +//} +//table.fancytree-ext-columnview span.fancytree-node.fancytree-active { +// background-color: royalblue; +//} diff --git a/plugins/55/indexmenu/scripts/fancytree/skin-material/ui.fancytree.min.css b/plugins/55/indexmenu/scripts/fancytree/skin-material/ui.fancytree.min.css new file mode 100644 index 0000000..15b8226 --- /dev/null +++ b/plugins/55/indexmenu/scripts/fancytree/skin-material/ui.fancytree.min.css @@ -0,0 +1,6 @@ +/*! + * Fancytree "material" skin. + * + * DON'T EDIT THE CSS FILE DIRECTLY, since it is automatically generated from + * the LESS templates. + */.fancytree-helper-hidden{display:none}.fancytree-helper-indeterminate-cb{color:#777}.fancytree-helper-disabled{color:silver}.fancytree-helper-spin{-webkit-animation:spin 1s infinite linear;animation:spin 1s infinite linear}@-webkit-keyframes spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}ul.fancytree-container{font-family:"Roboto Regular",tahoma,arial,helvetica;font-size:24px;white-space:nowrap;padding:3px;margin:0;background-color:#fff;border:1px dotted gray;min-height:0;position:relative}ul.fancytree-container ul{padding:0 0 0 24px;margin:0}ul.fancytree-container ul>li:before{content:none}ul.fancytree-container li{list-style-image:none;list-style-position:outside;list-style-type:none;-moz-background-clip:border;-moz-background-inline-policy:continuous;-moz-background-origin:padding;background-attachment:scroll;background-color:transparent;background-position:0 0;background-repeat:repeat-y;background-image:none;margin:0}ul.fancytree-container li.fancytree-lastsib{background-image:none}.ui-fancytree-disabled ul.fancytree-container{opacity:.5;background-color:silver}ul.fancytree-connectors.fancytree-container li{background-image:url("../skin-material/vline.gif");background-position:0 0}ul.fancytree-container li.fancytree-lastsib,ul.fancytree-no-connector>li{background-image:none}li.fancytree-animating{position:relative}#fancytree-drop-marker,span.fancytree-checkbox,span.fancytree-drag-helper-img,span.fancytree-empty,span.fancytree-expander,span.fancytree-icon,span.fancytree-vline{width:24px;height:24px;display:inline-block;vertical-align:top;background-repeat:no-repeat;background-position:0 0}span.fancytree-checkbox,span.fancytree-custom-icon,span.fancytree-expander,span.fancytree-icon{margin-top:0}span.fancytree-custom-icon{width:24px;height:24px;display:inline-block;margin-left:3px;background-position:0 0}img.fancytree-icon{width:24px;height:24px;margin-left:3px;margin-top:0;vertical-align:top;border-style:none}span.fancytree-expander{cursor:pointer}.fancytree-exp-n span.fancytree-expander,.fancytree-exp-nl span.fancytree-expander{background-image:none;cursor:default}.fancytree-connectors .fancytree-exp-n span.fancytree-expander,.fancytree-connectors .fancytree-exp-nl span.fancytree-expander{margin-top:0}.fancytree-fade-expander span.fancytree-expander{transition:opacity 1.5s;opacity:0}.fancytree-fade-expander .fancytree-treefocus span.fancytree-expander,.fancytree-fade-expander [class*=fancytree-statusnode-] span.fancytree-expander,.fancytree-fade-expander.fancytree-treefocus span.fancytree-expander,.fancytree-fade-expander:hover span.fancytree-expander{transition:opacity .6s;opacity:1}span.fancytree-checkbox{margin-left:3px}.fancytree-unselectable span.fancytree-checkbox{opacity:.4}.fancytree-container.fancytree-checkbox-auto-hide span.fancytree-checkbox{visibility:hidden}.fancytree-container.fancytree-checkbox-auto-hide .fancytree-node.fancytree-selected span.fancytree-checkbox,.fancytree-container.fancytree-checkbox-auto-hide .fancytree-node:hover span.fancytree-checkbox,.fancytree-container.fancytree-checkbox-auto-hide tr.fancytree-selected td span.fancytree-checkbox,.fancytree-container.fancytree-checkbox-auto-hide tr:hover td span.fancytree-checkbox{visibility:unset}.fancytree-container.fancytree-checkbox-auto-hide.fancytree-treefocus .fancytree-node.fancytree-active span.fancytree-checkbox,.fancytree-container.fancytree-checkbox-auto-hide.fancytree-treefocus tr.fancytree-active td span.fancytree-checkbox{visibility:unset}span.fancytree-icon{margin-left:3px}.fancytree-loading span.fancytree-expander,.fancytree-loading span.fancytree-expander:hover,.fancytree-statusnode-loading span.fancytree-icon,.fancytree-statusnode-loading span.fancytree-icon:hover,span.fancytree-icon.fancytree-icon-loading{background-image:none}span.fancytree-node{display:inherit;width:100%;margin-top:1px;min-height:24px}span.fancytree-title{color:#212121;cursor:pointer;display:inline-block;vertical-align:top;min-height:24px;padding:0 3px 0 3px;margin:0 0 0 3px;border:1px solid transparent;-webkit-border-radius:0px;-moz-border-radius:0;-ms-border-radius:0px;-o-border-radius:0;border-radius:0}span.fancytree-node.fancytree-error span.fancytree-title{color:red}span.fancytree-childcounter{color:#fff;background:#337ab7;border:1px solid gray;border-radius:10px;padding:2px;text-align:center}div.fancytree-drag-helper span.fancytree-childcounter,div.fancytree-drag-helper span.fancytree-dnd-modifier{display:inline-block;color:#fff;background:#337ab7;border:1px solid gray;min-width:10px;height:10px;line-height:1;vertical-align:baseline;border-radius:10px;padding:2px;text-align:center;font-size:9px}div.fancytree-drag-helper span.fancytree-childcounter{position:absolute;top:-6px;right:-6px}div.fancytree-drag-helper span.fancytree-dnd-modifier{background:#5cb85c;border:none;font-weight:bolder}#fancytree-drop-marker{width:48px;position:absolute;margin:0}#fancytree-drop-marker.fancytree-drop-after,#fancytree-drop-marker.fancytree-drop-before{width:96px}span.fancytree-drag-source.fancytree-drag-remove{opacity:.15}.fancytree-container.fancytree-rtl .fancytree-exp-n span.fancytree-expander,.fancytree-container.fancytree-rtl .fancytree-exp-nl span.fancytree-expander{background-image:none}ul.fancytree-container.fancytree-rtl ul{padding:0 16px 0 0}ul.fancytree-container.fancytree-rtl.fancytree-connectors li{background-position:right 0;background-image:url("../skin-material/vline-rtl.gif")}ul.fancytree-container.fancytree-rtl li.fancytree-lastsib,ul.fancytree-container.fancytree-rtl.fancytree-no-connector>li{background-image:none}table.fancytree-ext-table{font-family:"Roboto Regular",tahoma,arial,helvetica;font-size:24px;border-collapse:collapse}table.fancytree-ext-table span.fancytree-node{display:inline-block;box-sizing:border-box}table.fancytree-ext-table td.fancytree-status-merged{text-align:center;font-style:italic;color:silver}table.fancytree-ext-table tr.fancytree-statusnode-error td.fancytree-status-merged{color:red}table.fancytree-ext-table.fancytree-ext-ariagrid.fancytree-cell-mode>tbody>tr.fancytree-active>td{background-color:#eee}table.fancytree-ext-table.fancytree-ext-ariagrid.fancytree-cell-mode>tbody>tr>td.fancytree-active-cell{background-color:#cbe8f6}table.fancytree-ext-table.fancytree-ext-ariagrid.fancytree-cell-mode.fancytree-cell-nav-mode>tbody>tr>td.fancytree-active-cell{background-color:#3875d7}table.fancytree-ext-columnview tbody tr td{position:relative;border:1px solid gray;vertical-align:top;overflow:auto}table.fancytree-ext-columnview tbody tr td>ul{padding:0}table.fancytree-ext-columnview tbody tr td>ul li{list-style-image:none;list-style-position:outside;list-style-type:none;-moz-background-clip:border;-moz-background-inline-policy:continuous;-moz-background-origin:padding;background-attachment:scroll;background-color:transparent;background-position:0 0;background-repeat:repeat-y;background-image:none;margin:0}table.fancytree-ext-columnview span.fancytree-node{position:relative;display:inline-block}table.fancytree-ext-columnview span.fancytree-node.fancytree-expanded{background-color:#e0e0e0}table.fancytree-ext-columnview span.fancytree-node.fancytree-active{background-color:#cbe8f6}table.fancytree-ext-columnview .fancytree-has-children span.fancytree-cv-right{position:absolute;right:3px}.fancytree-ext-filter-dimm span.fancytree-node span.fancytree-title{color:silver;font-weight:lighter}.fancytree-ext-filter-dimm span.fancytree-node.fancytree-submatch span.fancytree-title,.fancytree-ext-filter-dimm tr.fancytree-submatch span.fancytree-title{color:#000;font-weight:400}.fancytree-ext-filter-dimm span.fancytree-node.fancytree-match span.fancytree-title,.fancytree-ext-filter-dimm tr.fancytree-match span.fancytree-title{color:#000;font-weight:700}.fancytree-ext-filter-hide span.fancytree-node.fancytree-hide,.fancytree-ext-filter-hide tr.fancytree-hide{display:none}.fancytree-ext-filter-hide span.fancytree-node.fancytree-submatch span.fancytree-title,.fancytree-ext-filter-hide tr.fancytree-submatch span.fancytree-title{color:silver;font-weight:lighter}.fancytree-ext-filter-hide span.fancytree-node.fancytree-match span.fancytree-title,.fancytree-ext-filter-hide tr.fancytree-match span.fancytree-title{color:#000;font-weight:400}.fancytree-ext-filter-hide-expanders span.fancytree-node.fancytree-match span.fancytree-expander,.fancytree-ext-filter-hide-expanders tr.fancytree-match span.fancytree-expander{visibility:hidden}.fancytree-ext-filter-hide-expanders span.fancytree-node.fancytree-submatch span.fancytree-expander,.fancytree-ext-filter-hide-expanders tr.fancytree-submatch span.fancytree-expander{visibility:visible}.fancytree-ext-childcounter span.fancytree-custom-icon,.fancytree-ext-childcounter span.fancytree-icon,.fancytree-ext-filter span.fancytree-custom-icon,.fancytree-ext-filter span.fancytree-icon{position:relative}.fancytree-ext-childcounter span.fancytree-childcounter,.fancytree-ext-filter span.fancytree-childcounter{color:#fff;background:#777;border:1px solid gray;position:absolute;top:-6px;right:-6px;min-width:10px;height:10px;line-height:1;vertical-align:baseline;border-radius:10px;padding:2px;text-align:center;font-size:9px}ul.fancytree-ext-wide{position:relative;min-width:100%;z-index:2;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}ul.fancytree-ext-wide span.fancytree-node>span{position:relative;z-index:2}ul.fancytree-ext-wide span.fancytree-node span.fancytree-title{position:absolute;z-index:1;left:0;min-width:100%;margin-left:0;margin-right:0;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.fancytree-ext-fixed-wrapper .fancytree-ext-fixed-hidden{display:none}.fancytree-ext-fixed-wrapper div.fancytree-ext-fixed-scroll-border-bottom{border-bottom:3px solid rgba(0,0,0,.75)}.fancytree-ext-fixed-wrapper div.fancytree-ext-fixed-scroll-border-right{border-right:3px solid rgba(0,0,0,.75)}.fancytree-ext-fixed-wrapper div.fancytree-ext-fixed-wrapper-tl{position:absolute;overflow:hidden;z-index:3;top:0;left:0}.fancytree-ext-fixed-wrapper div.fancytree-ext-fixed-wrapper-tr{position:absolute;overflow:hidden;z-index:2;top:0}.fancytree-ext-fixed-wrapper div.fancytree-ext-fixed-wrapper-bl{position:absolute;overflow:hidden;z-index:2;left:0}.fancytree-ext-fixed-wrapper div.fancytree-ext-fixed-wrapper-br{position:absolute;overflow:scroll;z-index:1}ul.fancytree-container ul{padding:.3em 0 0 1em;margin:0;font-size:24px;color:#212121}.fancytree-plain span.fancytree-selected span.fancytree-title{background-color:#f5f5f5}.fancytree-plain span.fancytree-active span.fancytree-title,.fancytree-plain span.fancytree-selected span.fancytree-title:hover{background-color:#eee}.fancytree-container span.fancytree-checkbox{color:#ff4081}table.fancytree-ext-table{border-collapse:collapse}table.fancytree-ext-table tbody tr.fancytree-focused,table.fancytree-ext-table tbody tr.fancytree-selected{background-color:#f5f5f5}table.fancytree-ext-table tbody tr.fancytree-active,table.fancytree-ext-table tbody tr:hover{background-color:#eee}table.fancytree-ext-columnview tbody tr td{border:1px solid gray}table.fancytree-ext-columnview span.fancytree-node.fancytree-expanded{background-color:#ccc}table.fancytree-ext-columnview span.fancytree-node.fancytree-active{background-color:#4169e1}
\ No newline at end of file diff --git a/plugins/55/indexmenu/scripts/fancytree/skin-material/vline-rtl.gif b/plugins/55/indexmenu/scripts/fancytree/skin-material/vline-rtl.gif Binary files differnew file mode 100644 index 0000000..0400cb3 --- /dev/null +++ b/plugins/55/indexmenu/scripts/fancytree/skin-material/vline-rtl.gif diff --git a/plugins/55/indexmenu/scripts/fancytree/skin-material/vline.gif b/plugins/55/indexmenu/scripts/fancytree/skin-material/vline.gif Binary files differnew file mode 100644 index 0000000..1b00ae5 --- /dev/null +++ b/plugins/55/indexmenu/scripts/fancytree/skin-material/vline.gif diff --git a/plugins/55/indexmenu/scripts/fancytree/skin-mdi/skin-common.less b/plugins/55/indexmenu/scripts/fancytree/skin-mdi/skin-common.less new file mode 100644 index 0000000..fc0da50 --- /dev/null +++ b/plugins/55/indexmenu/scripts/fancytree/skin-mdi/skin-common.less @@ -0,0 +1,972 @@ +/******************************************************************************* + * Common Styles for Fancytree Skins. + * + * This section is automatically generated from the `skin-common.less` template. + * + * Copyright (c) 2008-2023, Martin Wendt (https://wwWendt.de) + * Released under the MIT license + * https://github.com/mar10/fancytree/wiki/LicenseInfo + * + * @version 2.38.3 + * @date 2023-02-01T20:52:50Z +******************************************************************************/ + +// Variables (defaults, may be overwritten by the including .less files) +@fancy-use-sprites: true; // false: suppress all background images (i.e. icons) +// @fancy-hide-connectors: true; // false: show vertical connector lines + +@fancy-level-indent: 16px; +@fancy-line-height: 16px; // height of a nodes selection bar including borders +@fancy-node-v-spacing: 1px; // gap between two node borders +@fancy-icon-width: 16px; +@fancy-icon-height: 16px; +@fancy-icon-spacing: 3px; // margin between icon/icon or icon/title +@fancy-icon-ofs-top: 0px; // extra vertical offset for expander, checkbox and icon +@fancy-title-ofs-top: 0px; // extra vertical offset for title +@fancy-node-border-width: 1px; +@fancy-node-border-radius: 0px; +@fancy-node-outline-width: 1px; + +// @fancy-line-ofs-top: (@fancy-line-height - @fancy-icon-height) / 2; + +// webpack uses /dist/skin-common.less as root path +// grunt-less uses /dist/skin-Xxx/ui.fancyree.less as root path +// So we define our theme LESS files for webpack compatibility, i.e. +// define the image path n every main LESS file instead of here. +// Prefix may be set to "", "/", "./", or any other value +// Note: this variable must be defined by the main LESS files: +// @fancy-image-prefix: ""; + +// Use 'url(...)' to link to the throbber image, or +// use data-uri(...)' to inline the data in css instead: +/* CHANGE use url, as less does not handel data-uri() correct. DokuWiki can eventually inline it */ + @fancy-loading-url: url("@{fancy-image-prefix}loading.gif"); +//@fancy-loading-url: data-uri("@{fancy-image-prefix}loading.gif"); + +// Set to `true` to use `data-uri(...)` instead of a `url(...)` link: +@fancy-inline-sprites: false; // data-uri() is not handle correct by phpless + +@fancy-font-size: 10pt; +@fancy-font-family: tahoma, arial, helvetica; +@fancy-font-color: black; +@fancy-font-color-dimm: #c0c0c0; +@fancy-font-error-color: red; + +//------------------------------------------------------------------------------ +// Mixins +//------------------------------------------------------------------------------ +.setBgPos(@x, @y, @cond:true) when (@cond) { + background-position: (@x * -@fancy-icon-width) (@y * -@fancy-icon-height); +} +.clearBgImage(@cond:true) when (@cond) { + background-image: none; +} +.setBgImageUrl(@url) when (@fancy-use-sprites) and not (@fancy-inline-sprites) { + background-image: url("@{fancy-image-prefix}@{url}"); +} +.setBgImageUrl(@url) when (@fancy-use-sprites) and (@fancy-inline-sprites) { + background-image: data-uri("@{fancy-image-prefix}@{url}"); +} +.useSprite(@x, @y) when (@fancy-use-sprites) { + .setBgPos(@x, @y); +} +.rounded-corners(@radius) { + -webkit-border-radius: @radius; + -moz-border-radius: @radius; + -ms-border-radius: @radius; + -o-border-radius: @radius; + border-radius: @radius; +} +.spanStyleMixin(@color, @bgcolor, @bordercolor) { + border-color: @bordercolor; + background: @bgcolor; + color: @color; +} +.spanStyleMixin(@color, @bgcolor, @bordercolor, @startColor, @stopColor) { + .spanStyleMixin(@color, @bgcolor, @bordercolor); + // @c-start: argb(@startColor); + // @c-end: argb(@stopColor); + background: -moz-linear-gradient( + top, + @startColor 0%, + @stopColor 100% + ); // FF3.6+ + background: -webkit-gradient( + linear, + left top, + left bottom, + color-stop(0%, @startColor), + color-stop(100%, @stopColor) + ); // Chrome,Safari4+ + background: -webkit-linear-gradient( + top, + @startColor 0%, + @stopColor 100% + ); // Chrome10+,Safari5.1+ + background: -o-linear-gradient( + top, + @startColor 0%, + @stopColor 100% + ); // Opera 11.10+ + background: -ms-linear-gradient( + top, + @startColor 0%, + @stopColor 100% + ); // IE10+ + background: linear-gradient( + to bottom, + @startColor 0%, + @stopColor 100% + ); // W3C + filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='@{startColor}', endColorstr='@{stopColor}',GradientType=0 ); // IE6-9 +} + +/*------------------------------------------------------------------------------ + * Helpers + *----------------------------------------------------------------------------*/ +// Redefine, in case jQuery-UI is not included +// .ui-helper-hidden, +.fancytree-helper-hidden { + display: none; +} +.fancytree-helper-indeterminate-cb { + // tri-state checkbox + color: #777; +} +.fancytree-helper-disabled { + color: @fancy-font-color-dimm; +} + +/* Helper to allow spinning loader icon with glyph-, ligature-, and SVG-icons. */ +/* CHANGE: renamed spin to spin-fancytree */ +.fancytree-helper-spin { + -webkit-animation: spin-fancytree 1000ms infinite linear; + animation: spin-fancytree 1000ms infinite linear; +} +/* CHANGE: commented because it is wrong prefixed by phpless +@-webkit-keyframes spin { + 0% { + -webkit-transform: rotate(0deg); + transform: rotate(0deg); + } + 100% { + -webkit-transform: rotate(359deg); + transform: rotate(359deg); + } +} +@keyframes spin { + 0% { + -webkit-transform: rotate(0deg); + transform: rotate(0deg); + } + 100% { + -webkit-transform: rotate(359deg); + transform: rotate(359deg); + } +} +*/ +/*------------------------------------------------------------------------------ + * Container and UL / LI + *----------------------------------------------------------------------------*/ + +ul.fancytree-container { + font-family: @fancy-font-family; + font-size: @fancy-font-size; + white-space: nowrap; + padding: 3px; + margin: 0; // DT issue 201 + //background-color: white; CHANGE + //border: 1px dotted gray; CHANGE + // overflow: auto; // ext-dnd5: otherwise this is always the scroll parent + // height: 100%; // DT issue 263, 470 + min-height: 0%; // #192 + position: relative; // #235 + ul { + padding: 0 0 0 @fancy-level-indent; + margin: 0; + } + ul > li:before { + // #538 + content: none; + } + li { + list-style-image: none; + list-style-position: outside; + list-style-type: none; + -moz-background-clip: border; + -moz-background-inline-policy: continuous; + -moz-background-origin: padding; + background-attachment: scroll; + background-color: transparent; + .setBgPos(0, 0); + background-repeat: repeat-y; + background-image: none; // no v-lines + + margin: 0; + // padding: 1px 0 0 0; // issue #246 + } + // Suppress lines for last child node + li.fancytree-lastsib { + background-image: none; + } +} + +// Style, when control is disabled +.ui-fancytree-disabled ul.fancytree-container { + opacity: 0.5; + // filter: alpha(opacity=50); // Yields a css warning + background-color: silver; +} + +ul.fancytree-connectors.fancytree-container { + li { + // Use 'data-uri(...)' to embed the image into CSS instead of linking to 'loading.gif': + /* CHANGE: phpless does not handle data-uri() correct */ + //background-image: data-uri("@{fancy-image-prefix}vline.gif"); + background-image: url("@{fancy-image-prefix}vline.gif"); + background-position: 0 0; + } +} + +// Suppress lines for last child node +ul.fancytree-container li.fancytree-lastsib, +// Suppress lines if level is fixed expanded (option minExpandLevel) +ul.fancytree-no-connector > li { + background-image: none; +} + +// Fix jQuery UI 'blind' animation for jQuery UI (#717) +li.fancytree-animating { + position: relative; +} + +/*------------------------------------------------------------------------------ + * Common icon definitions + *----------------------------------------------------------------------------*/ + +span.fancytree-empty, +span.fancytree-vline, +span.fancytree-expander, +span.fancytree-icon, +span.fancytree-checkbox, +// span.fancytree-radio, +span.fancytree-drag-helper-img, +#fancytree-drop-marker { + width: @fancy-icon-width; + height: @fancy-icon-height; + // display: -moz-inline-box; // @ FF 1+2 removed for issue 221 + // -moz-box-align: start; /* issue 221 */ + display: inline-block; // Required to make a span sizeable + vertical-align: top; + background-repeat: no-repeat; + // background-position: left; + .setBgImageUrl("icons.gif"); + .setBgPos(0, 0); +} +span.fancytree-icon, +span.fancytree-checkbox, +span.fancytree-expander, +// span.fancytree-radio, +span.fancytree-custom-icon { + margin-top: @fancy-icon-ofs-top; +} +/* Used by icon option: */ +span.fancytree-custom-icon { + width: @fancy-icon-width; + height: @fancy-icon-height; + display: inline-block; + margin-left: @fancy-icon-spacing; + .setBgPos(0, 0); +} +/* Used by 'icon' node option: */ +img.fancytree-icon { + width: @fancy-icon-width; + height: @fancy-icon-height; + margin-left: @fancy-icon-spacing; + margin-top: @fancy-icon-ofs-top; + vertical-align: top; + border-style: none; +} + +/*------------------------------------------------------------------------------ + * Expander icon + * + * Note: IE6 doesn't correctly evaluate multiples class names, + * so we create combined class names that can be used in the CSS. + * + * Prefix: fancytree-exp- + * 1st character: 'e': expanded, 'c': collapsed, 'n': no children + * 2nd character (optional): 'd': lazy (Delayed) + * 3rd character (optional): 'l': Last sibling + *----------------------------------------------------------------------------*/ + +span.fancytree-expander { + // .useSprite(0, 5); + cursor: pointer; +} +// span.fancytree-expander:hover { +// // .useSprite(1, 5); +// } + +// --- End nodes (use connectors instead of expanders) + +.fancytree-exp-n span.fancytree-expander, +.fancytree-exp-nl span.fancytree-expander { + // .clearBgImage( @fancy-hide-connectors ); + background-image: none; + cursor: default; +} +.fancytree-connectors { + .fancytree-exp-n span.fancytree-expander, + .fancytree-exp-nl span.fancytree-expander { + .setBgImageUrl("icons.gif"); + margin-top: 0; + } + .fancytree-exp-n span.fancytree-expander, // End-node, not last sibling + .fancytree-exp-n span.fancytree-expander:hover { + .useSprite(0, 4); + } + .fancytree-exp-nl span.fancytree-expander, // End-node, last sibling + .fancytree-exp-nl span.fancytree-expander:hover { + .useSprite(1, 4); + } +} + +// --- Collapsed + +.fancytree-exp-c span.fancytree-expander { + // Collapsed, not delayed, not last sibling + .useSprite(0, 5); +} +.fancytree-exp-c span.fancytree-expander:hover { + .useSprite(1, 5); +} +.fancytree-exp-cl span.fancytree-expander { + // Collapsed, not delayed, last sibling + .useSprite(0, 6); +} +.fancytree-exp-cl span.fancytree-expander:hover { + .useSprite(1, 6); +} +.fancytree-exp-cd span.fancytree-expander { + // Collapsed, delayed, not last sibling + .useSprite(4, 5); +} +.fancytree-exp-cd span.fancytree-expander:hover { + .useSprite(5, 5); +} +.fancytree-exp-cdl span.fancytree-expander { + // Collapsed, delayed, last sibling + .useSprite(4, 6); +} +.fancytree-exp-cdl span.fancytree-expander:hover { + .useSprite(5, 6); +} + +// --- Expanded + +.fancytree-exp-e span.fancytree-expander, // Expanded, not delayed, not last sibling +.fancytree-exp-ed span.fancytree-expander { + // Expanded, delayed, not last sibling + .useSprite(2, 5); +} +.fancytree-exp-e span.fancytree-expander:hover, +.fancytree-exp-ed span.fancytree-expander:hover { + .useSprite(3, 5); +} +.fancytree-exp-el span.fancytree-expander, // Expanded, not delayed, last sibling +.fancytree-exp-edl span.fancytree-expander { + // Expanded, delayed, last sibling + .useSprite(2, 6); +} +.fancytree-exp-el span.fancytree-expander:hover, +.fancytree-exp-edl span.fancytree-expander:hover { + .useSprite(3, 6); +} + +/* Fade out expanders, when container is not hovered or active */ +.fancytree-fade-expander { + span.fancytree-expander { + transition: opacity 1.5s; + opacity: 0; + } + &:hover span.fancytree-expander, + &.fancytree-treefocus span.fancytree-expander, + .fancytree-treefocus span.fancytree-expander, + [class*="fancytree-statusnode-"] span.fancytree-expander { + transition: opacity 0.6s; + opacity: 1; + } +} + +//// CHANGE: not used. +///*------------------------------------------------------------------------------ +// * Checkbox icon +// *----------------------------------------------------------------------------*/ +// +//span.fancytree-checkbox { +// margin-left: @fancy-icon-spacing; +// .useSprite(0, 2); +// &:hover { +// .useSprite(1, 2); +// } +// &.fancytree-radio { +// .useSprite(0, 3); +// } +// &.fancytree-radio:hover { +// .useSprite(1, 3); +// } +//} +//.fancytree-partsel span.fancytree-checkbox { +// .useSprite(4, 2); +// &:hover { +// .useSprite(5, 2); +// } +// &.fancytree-radio { +// .useSprite(4, 3); +// } +// &.fancytree-radio:hover { +// .useSprite(5, 3); +// } +//} +//// selected after partsel, so it takes precedence: +//.fancytree-selected span.fancytree-checkbox { +// .useSprite(2, 2); +// &:hover { +// .useSprite(3, 2); +// } +// &.fancytree-radio { +// .useSprite(2, 3); +// } +// &.fancytree-radio:hover { +// .useSprite(3, 3); +// } +//} +//// Unselectable is dimmed, without hover effects +//.fancytree-unselectable { +// span.fancytree-checkbox { +// opacity: 0.4; +// filter: alpha(opacity=40); +// } +// span.fancytree-checkbox:hover { +// .useSprite(0, 2); +// } +// span.fancytree-checkbox.fancytree-radio:hover { +// .useSprite(0, 3); +// } +// &.fancytree-partsel span.fancytree-checkbox:hover { +// .useSprite(4, 2); +// } +// &.fancytree-selected span.fancytree-checkbox:hover { +// .useSprite(2, 2); +// } +// &.fancytree-selected span.fancytree-checkbox.fancytree-radio:hover { +// .useSprite(2, 3); +// } +//} +// +//// Auto-hide checkboxes unless selected or hovered +//.fancytree-container.fancytree-checkbox-auto-hide { +// span.fancytree-checkbox { +// visibility: hidden; +// } +// .fancytree-node:hover span.fancytree-checkbox, +// tr:hover td span.fancytree-checkbox, +// .fancytree-node.fancytree-selected span.fancytree-checkbox, +// tr.fancytree-selected td span.fancytree-checkbox { +// visibility: unset; +// } +// &.fancytree-treefocus { +// .fancytree-node.fancytree-active span.fancytree-checkbox, +// tr.fancytree-active td span.fancytree-checkbox { +// visibility: unset; +// } +// } +//} + +/*------------------------------------------------------------------------------ + * Node type icon + * Note: IE6 doesn't correctly evaluate multiples class names, + * so we create combined class names that can be used in the CSS. + * + * Prefix: fancytree-ico- + * 1st character: 'e': expanded, 'c': collapsed + * 2nd character (optional): 'f': folder + *----------------------------------------------------------------------------*/ + +span.fancytree-icon { + // Default icon + margin-left: @fancy-icon-spacing; + .useSprite(0, 0); +} + +/* Documents */ +.fancytree-ico-c span.fancytree-icon { + // Collapsed folder (empty) + // .useSprite(0, 0); +} +.fancytree-ico-c span.fancytree-icon:hover { + .useSprite(1, 0); +} +.fancytree-has-children.fancytree-ico-c span.fancytree-icon { + // Collapsed folder (not empty) + .useSprite(2, 0); +} +.fancytree-has-children.fancytree-ico-c span.fancytree-icon:hover { + .useSprite(3, 0); +} +.fancytree-ico-e span.fancytree-icon { + // Expanded folder + .useSprite(4, 0); +} +.fancytree-ico-e span.fancytree-icon:hover { + .useSprite(5, 0); +} + +/* Folders */ +.fancytree-ico-cf span.fancytree-icon { + // Collapsed folder (empty) + .useSprite(0, 1); +} +.fancytree-ico-cf span.fancytree-icon:hover { + .useSprite(1, 1); +} +.fancytree-has-children.fancytree-ico-cf span.fancytree-icon { + // Collapsed folder (not empty) + .useSprite(2, 1); +} +.fancytree-has-children.fancytree-ico-cf span.fancytree-icon:hover { + .useSprite(3, 1); +} +.fancytree-ico-ef span.fancytree-icon { + // Expanded folder + .useSprite(4, 1); +} +.fancytree-ico-ef span.fancytree-icon:hover { + .useSprite(5, 1); +} + +// 'Loading' status overrides all others +.fancytree-loading span.fancytree-expander, +.fancytree-loading span.fancytree-expander:hover, +.fancytree-statusnode-loading span.fancytree-icon, +.fancytree-statusnode-loading span.fancytree-icon:hover, +span.fancytree-icon.fancytree-icon-loading { + background-image: @fancy-loading-url; + .useSprite(0, 0); +} + +/* Status node icons */ + +.fancytree-statusnode-error span.fancytree-icon, +.fancytree-statusnode-error span.fancytree-icon:hover { + .useSprite(0, 7); +} + +/*------------------------------------------------------------------------------ + * Node titles and highlighting + *----------------------------------------------------------------------------*/ + +span.fancytree-node { + /* See #117 */ + display: inherit; // #117, resolves to 'display: list-item;' for standard trees + width: 100%; + margin-top: @fancy-node-v-spacing; + min-height: @fancy-line-height; +} +span.fancytree-title { + color: @fancy-font-color; // inherit doesn't work on IE + cursor: pointer; + display: inline-block; // Better alignment, when title contains <br> + vertical-align: top; + min-height: @fancy-line-height; + padding: 0 3px 0 3px; // Otherwise italic font will be outside right bounds + margin: @fancy-title-ofs-top 0 0 @fancy-icon-spacing; + // margin: 0px; + // margin-top: @fancy-line-ofs-top; + // margin-left: @fancy-icon-spacing; + border: @fancy-node-border-width solid transparent; // avoid jumping, when a border is added on hover + .rounded-corners(@fancy-node-border-radius); + // outline: 0; // @ Firefox, prevent dotted border after click + // Set transparent border to prevent jumping when active node gets a border + // (we can do this, because this theme doesn't use vertical lines) + // border: 1px solid white; // Note: 'transparent' would not work in IE6 +} +span.fancytree-node.fancytree-error span.fancytree-title { + color: @fancy-font-error-color; +} + +//// CHANGE: not used. +///*------------------------------------------------------------------------------ +// * Drag'n'drop support +// *----------------------------------------------------------------------------*/ +///* ext-dnd5: */ +//span.fancytree-childcounter { +// color: #fff; +// background: #337ab7; // bootstrap blue +// border: 1px solid gray; +// border-radius: 10px; +// padding: 2px; +// text-align: center; +//} +// +///* ext-dnd: */ +//div.fancytree-drag-helper { +// span.fancytree-childcounter, +// span.fancytree-dnd-modifier { +// display: inline-block; +// color: #fff; +// background: #337ab7; // bootstrap blue +// border: 1px solid gray; +// min-width: 10px; +// // min-height: 16px; +// height: 10px; +// line-height: 1; +// vertical-align: baseline; +// border-radius: 10px; +// padding: 2px; +// text-align: center; +// font-size: 9px; +// } +// span.fancytree-childcounter { +// position: absolute; +// // left: 16px; +// top: -6px; +// right: -6px; +// } +// span.fancytree-dnd-modifier { +// background: #5cb85c; // bootstrap green +// border: none; +// // min-height: 16px; +// // font-size: 12px; +// font-weight: bolder; +// } +// &.fancytree-drop-accept { +// span.fancytree-drag-helper-img { +// .useSprite(2, 7); +// } +// } +// &.fancytree-drop-reject { +// span.fancytree-drag-helper-img { +// .useSprite(1, 7); +// } +// } +//} +// +///*** Drop marker icon *********************************************************/ +//#fancytree-drop-marker { +// width: 2 * @fancy-icon-width; // was 24px, but 32 should be correct +// position: absolute; +// .useSprite(0, 8); +// margin: 0; +// &.fancytree-drop-after, +// &.fancytree-drop-before { +// width: 4 * @fancy-icon-width; // 64px; +// .useSprite(0, 9); +// } +// &.fancytree-drop-copy { +// .useSprite(4, 8); +// } +// &.fancytree-drop-move { +// .useSprite(2, 8); +// } +//} +// +///*** Source node while dragging ***********************************************/ +// +//span.fancytree-drag-source { +// &.fancytree-drag-remove { +// // text-decoration: line-through; +// opacity: 0.15; +// } +//} +// +///*** Target node while dragging cursor is over it *****************************/ +// +//span.fancytree-drop-target { +// &.fancytree-drop-accept { +// // outline: 1px dotted #5cb85c; // bootstrap sucess +// } +//} +//span.fancytree-drop-reject { +// // outline: 1px dotted #d9534f; // boostrap warning +//} + +/*------------------------------------------------------------------------------ + * 'rtl' option + *----------------------------------------------------------------------------*/ + +.fancytree-container.fancytree-rtl { + .fancytree-title { + /*unicode-bidi: bidi-override;*/ /* optional: reverse title letters */ + } + span.fancytree-connector, + span.fancytree-expander, + span.fancytree-icon, + span.fancytree-drag-helper-img { + .setBgImageUrl("icons-rtl.gif"); + } + .fancytree-exp-n span.fancytree-expander, + .fancytree-exp-nl span.fancytree-expander { + background-image: none; + } + &.fancytree-connectors .fancytree-exp-n span.fancytree-expander, + &.fancytree-connectors .fancytree-exp-nl span.fancytree-expander { + .setBgImageUrl("icons-rtl.gif"); + } +} +ul.fancytree-container.fancytree-rtl { + ul { + padding: 0 16px 0 0; + } + &.fancytree-connectors li { + background-position: right 0; + background-image: url("@{fancy-image-prefix}vline-rtl.gif"); + } + // Suppress lines for last child node + li.fancytree-lastsib, + // Suppress lines if level is fixed expanded (option minExpandLevel) + &.fancytree-no-connector > li { + background-image: none; + } +} +#fancytree-drop-marker.fancytree-rtl { + .setBgImageUrl("icons-rtl.gif"); +} + +//// CHANGE: not used. +///*------------------------------------------------------------------------------ +// * 'table' extension +// *----------------------------------------------------------------------------*/ +// +//table.fancytree-ext-table { +// font-family: @fancy-font-family; +// font-size: @fancy-font-size; +// border-collapse: collapse; +// span.fancytree-node { +// display: inline-block; // #117 +// box-sizing: border-box; // #562 +// } +// td.fancytree-status-merged { +// text-align: center; +// // font-weight: bold; +// font-style: italic; +// // line-height: 100px; +// color: @fancy-font-color-dimm; +// } +// tr.fancytree-statusnode-error td.fancytree-status-merged { +// color: @fancy-font-error-color; +// } +// /* ext-ariagrid */ +// &.fancytree-ext-ariagrid.fancytree-cell-mode { +// > tbody > tr.fancytree-active > td { +// background-color: #eee; +// } +// > tbody > tr > td.fancytree-active-cell { +// background-color: #cbe8f6; +// } +// &.fancytree-cell-nav-mode > tbody > tr > td.fancytree-active-cell { +// background-color: #3875d7; +// } +// } +//} +// +///*------------------------------------------------------------------------------ +// * 'columnview' extension +// *----------------------------------------------------------------------------*/ +// +//table.fancytree-ext-columnview { +// // border-collapse: collapse; +// // width: 100%; +// tbody tr td { +// position: relative; +// border: 1px solid gray; +// vertical-align: top; +// overflow: auto; +// > ul { +// padding: 0; +// li { +// list-style-image: none; +// list-style-position: outside; +// list-style-type: none; +// -moz-background-clip: border; +// -moz-background-inline-policy: continuous; +// -moz-background-origin: padding; +// background-attachment: scroll; +// background-color: transparent; +// .setBgPos(0, 0); +// background-repeat: repeat-y; +// background-image: none; /* no v-lines */ +// +// margin: 0; +// // padding: 1px 0 0 0; // issue #246 +// } +// } +// } +// span.fancytree-node { +// position: relative; /* allow positioning of embedded spans */ +// display: inline-block; // #117 +// } +// span.fancytree-node.fancytree-expanded { +// background-color: #e0e0e0; +// } +// span.fancytree-node.fancytree-active { +// background-color: #cbe8f6; +// // background-color: royalblue; +// } +// .fancytree-has-children span.fancytree-cv-right { +// position: absolute; +// right: 3px; +// .useSprite(0, 5); +// &:hover { +// .useSprite(1, 5); +// } +// } +//} +// +///*------------------------------------------------------------------------------ +// * 'filter' extension +// *----------------------------------------------------------------------------*/ +// +//.fancytree-ext-filter-dimm { +// span.fancytree-node span.fancytree-title { +// color: @fancy-font-color-dimm; +// font-weight: lighter; +// } +// tr.fancytree-submatch span.fancytree-title, +// span.fancytree-node.fancytree-submatch span.fancytree-title { +// color: black; +// font-weight: normal; +// } +// tr.fancytree-match span.fancytree-title, +// span.fancytree-node.fancytree-match span.fancytree-title { +// color: black; +// font-weight: bold; +// } +//} +//.fancytree-ext-filter-hide { +// tr.fancytree-hide, +// span.fancytree-node.fancytree-hide { +// display: none; +// } +// tr.fancytree-submatch span.fancytree-title, +// span.fancytree-node.fancytree-submatch span.fancytree-title { +// color: @fancy-font-color-dimm; +// font-weight: lighter; +// } +// tr.fancytree-match span.fancytree-title, +// span.fancytree-node.fancytree-match span.fancytree-title { +// color: black; +// font-weight: normal; +// } +//} +///* Hide expanders if all child nodes are hidden by filter */ +//.fancytree-ext-filter-hide-expanders { +// tr.fancytree-match span.fancytree-expander, +// span.fancytree-node.fancytree-match span.fancytree-expander { +// visibility: hidden; +// } +// tr.fancytree-submatch span.fancytree-expander, +// span.fancytree-node.fancytree-submatch span.fancytree-expander { +// visibility: visible; +// } +//} +// +//.fancytree-ext-childcounter, +//.fancytree-ext-filter { +// // span.fancytree-title mark { +// // font-style: normal; +// // background-color: #ead61c; // yellow +// // border-radius: 3px; +// // } +// span.fancytree-icon, +// span.fancytree-custom-icon { +// position: relative; +// } +// span.fancytree-childcounter { +// color: #fff; +// background: #777; // #337ab7; // bootstrap blue +// border: 1px solid gray; +// position: absolute; +// top: -6px; +// right: -6px; +// min-width: 10px; +// height: 10px; +// line-height: 1; +// vertical-align: baseline; +// border-radius: 10px; +// padding: 2px; +// text-align: center; +// font-size: 9px; +// } +//} +///*------------------------------------------------------------------------------ +// * 'wide' extension +// *----------------------------------------------------------------------------*/ +// +//ul.fancytree-ext-wide { +// position: relative; +// min-width: 100%; +// z-index: 2; +// +// -webkit-box-sizing: border-box; +// -moz-box-sizing: border-box; +// box-sizing: border-box; +// +// span.fancytree-node > span { +// position: relative; +// z-index: 2; +// } +// span.fancytree-node span.fancytree-title { +// position: absolute; // Allow left: 0. Note: prevents smooth dropdown animation +// z-index: 1; // Behind expander and checkbox +// left: 0px; +// min-width: 100%; +// margin-left: 0; +// margin-right: 0; +// +// -webkit-box-sizing: border-box; +// -moz-box-sizing: border-box; +// box-sizing: border-box; +// } +//} +// +///*------------------------------------------------------------------------------ +// * 'fixed' extension +// *----------------------------------------------------------------------------*/ +// +//.fancytree-ext-fixed-wrapper { +// .fancytree-ext-fixed-hidden { +// display: none; +// } +// div.fancytree-ext-fixed-scroll-border-bottom { +// border-bottom: 3px solid rgba(0, 0, 0, 0.75); +// } +// div.fancytree-ext-fixed-scroll-border-right { +// border-right: 3px solid rgba(0, 0, 0, 0.75); +// } +// div.fancytree-ext-fixed-wrapper-tl { +// position: absolute; +// overflow: hidden; +// z-index: 3; +// top: 0px; +// left: 0px; +// } +// div.fancytree-ext-fixed-wrapper-tr { +// position: absolute; +// overflow: hidden; +// z-index: 2; +// top: 0px; +// } +// div.fancytree-ext-fixed-wrapper-bl { +// position: absolute; +// overflow: hidden; +// z-index: 2; +// left: 0px; +// } +// div.fancytree-ext-fixed-wrapper-br { +// position: absolute; +// overflow: scroll; +// z-index: 1; +// } +//} diff --git a/plugins/55/indexmenu/scripts/fancytree/skin-mdi/ui.fancytree.less b/plugins/55/indexmenu/scripts/fancytree/skin-mdi/ui.fancytree.less new file mode 100644 index 0000000..56615f4 --- /dev/null +++ b/plugins/55/indexmenu/scripts/fancytree/skin-mdi/ui.fancytree.less @@ -0,0 +1,131 @@ +/*! + * Fancytree "material" skin. + * + * DON'T EDIT THE CSS FILE DIRECTLY, since it is automatically generated from + * the LESS templates. + */ + +// Import common styles +@import "skin-common.less"; + +// We need to define this variable here (not in skin-common.less) to make it +// work with grunt and webpack: +@fancy-image-prefix: "./skin-mdi/"; + +/******************************************************************************* + * Styles specific to this skin. + * + * This section is automatically generated from the `ui-fancytree.less` template. + ******************************************************************************/ +/* +https://material.io/guidelines/components/data-tables.html#data-tables-structure +*/ +// local vars +@fancy-cst-size: 18px; +@fancy-cst-primary-color: #3f51b5; // primary app color (of indigo-pink) +@fancy-cst-secondary-color: #ff4081; // secondary app color (of indigo-pink): checkbox +@fancy-cst-black-87: #212121; // 87% black: table content +@fancy-cst-black-54: #757575; // 54% black: column headers +@fancy-cst-select-bg: #f5f5f5; // Grey 100: selected row backround +@fancy-cst-hover-bg: #eeeeee; // Grey 200: hovered row backround + +// Override the variable after the import. +// NOTE: Variables are always resolved as the last definition, even if it is +// after where it is used. +@fancy-use-sprites: false; // false: suppress all background images (i.e. icons) +@fancy-loading-url: none; + +@fancy-level-indent: @fancy-cst-size; //@fancy-cst-size; +@fancy-line-height: @fancy-cst-size; // height of a nodes selection bar including borders +@fancy-node-v-spacing: 1px; // gap between two node borders +@fancy-icon-width: @fancy-cst-size; +@fancy-icon-height: @fancy-cst-size; +@fancy-icon-spacing: 3px; // margin between icon/icon or icon/title +@fancy-icon-ofs-top: -2px; // extra vertical offset for expander, checkbox and icon +@fancy-title-ofs-top: 0px; // extra vertical offset for title +@fancy-node-border-width: 1px; +@fancy-node-border-radius: 0px; +@fancy-node-outline-width: 1px; + +// @fancy-loading-url: data-uri("@{fancy-image-prefix}loading.gif"); + +// Set to `true` to use `data-uri(...)` instead of a `url(...)` link: +@fancy-inline-sprites: false; + +//default 10pt, which is used in a relative manner resulting in 13.3 in dokuwiki-template. +@fancy-font-size: 93%; //@fancy-cst-size; +@fancy-font-family: "Roboto Regular", tahoma, arial, helvetica; +@fancy-font-color: @fancy-cst-black-87; +@fancy-font-color-dimm: silver; +@fancy-font-error-color: red; + + +ul.fancytree-container ul +{ + padding: 0 0 0 1em; //0.3em 0 0 1em; + margin: 0; + //font-size: @fancy-cst-size; + //color: @fancy-cst-black-87; +} + +ul.fancytree-container span.fancytree-icon.mdi +{ + font-size: @fancy-cst-size; + color: @fancy-cst-black-87; +} + + +// set icon color to font color as well +span.fancytree-node { + color: @fancy-font-color; +} +span.fancytree-expander { + font-size: @fancy-cst-size; +} + +/******************************************************************************* + * Node titles + */ + + .fancytree-plain { + span.fancytree-selected span.fancytree-title { + background-color: @fancy-cst-select-bg; + } + span.fancytree-selected span.fancytree-title:hover, + span.fancytree-active span.fancytree-title { + background-color: @fancy-cst-hover-bg; + } +} + +.fancytree-container span.fancytree-checkbox { + color: @fancy-cst-secondary-color; +} + +///******************************************************************************* +// * 'table' extension +// */ +//table.fancytree-ext-table { +// border-collapse: collapse; +// tbody { +// tr.fancytree-focused, tr.fancytree-selected { +// background-color: @fancy-cst-select-bg; +// } +// tr.fancytree-active, tr:hover { +// background-color: @fancy-cst-hover-bg; +// } +// } +//} +// +///******************************************************************************* +// * 'columnview' extension +// */ +// +//table.fancytree-ext-columnview tbody tr td { +// border: 1px solid gray; +//} +//table.fancytree-ext-columnview span.fancytree-node.fancytree-expanded { +// background-color: #ccc; +//} +//table.fancytree-ext-columnview span.fancytree-node.fancytree-active { +// background-color: royalblue; +//} diff --git a/plugins/55/indexmenu/scripts/fancytree/skin-mdi/vline-rtl.gif b/plugins/55/indexmenu/scripts/fancytree/skin-mdi/vline-rtl.gif Binary files differnew file mode 100644 index 0000000..0400cb3 --- /dev/null +++ b/plugins/55/indexmenu/scripts/fancytree/skin-mdi/vline-rtl.gif diff --git a/plugins/55/indexmenu/scripts/fancytree/skin-mdi/vline.gif b/plugins/55/indexmenu/scripts/fancytree/skin-mdi/vline.gif Binary files differnew file mode 100644 index 0000000..1b00ae5 --- /dev/null +++ b/plugins/55/indexmenu/scripts/fancytree/skin-mdi/vline.gif diff --git a/plugins/55/indexmenu/scripts/fancytree/skin-themeroller/icons-rtl.gif b/plugins/55/indexmenu/scripts/fancytree/skin-themeroller/icons-rtl.gif Binary files differnew file mode 100644 index 0000000..443e1e4 --- /dev/null +++ b/plugins/55/indexmenu/scripts/fancytree/skin-themeroller/icons-rtl.gif diff --git a/plugins/55/indexmenu/scripts/fancytree/skin-themeroller/icons.gif b/plugins/55/indexmenu/scripts/fancytree/skin-themeroller/icons.gif Binary files differnew file mode 100644 index 0000000..0097b1f --- /dev/null +++ b/plugins/55/indexmenu/scripts/fancytree/skin-themeroller/icons.gif diff --git a/plugins/55/indexmenu/scripts/fancytree/skin-themeroller/loading.gif b/plugins/55/indexmenu/scripts/fancytree/skin-themeroller/loading.gif Binary files differnew file mode 100644 index 0000000..ef88497 --- /dev/null +++ b/plugins/55/indexmenu/scripts/fancytree/skin-themeroller/loading.gif diff --git a/plugins/55/indexmenu/scripts/fancytree/skin-themeroller/ui.fancytree.css b/plugins/55/indexmenu/scripts/fancytree/skin-themeroller/ui.fancytree.css new file mode 100644 index 0000000..00f79bd --- /dev/null +++ b/plugins/55/indexmenu/scripts/fancytree/skin-themeroller/ui.fancytree.css @@ -0,0 +1,716 @@ +/*! + * Fancytree "ThemeRoller" skin. + * This file should be included after a jQuery Themeroller style sheet. + * It is meant to be used together with the ext-themeroller extension. + * + * DON'T EDIT THE CSS FILE DIRECTLY, since it is automatically generated from + * the LESS templates. + */ +/******************************************************************************* + * Common Styles for Fancytree Skins. + * + * This section is automatically generated from the `skin-common.less` template. + * + * Copyright (c) 2008-2023, Martin Wendt (https://wwWendt.de) + * Released under the MIT license + * https://github.com/mar10/fancytree/wiki/LicenseInfo + * + * @version 2.38.3 + * @date 2023-02-01T20:52:50Z +******************************************************************************/ +/*------------------------------------------------------------------------------ + * Helpers + *----------------------------------------------------------------------------*/ +.fancytree-helper-hidden { + display: none; +} +.fancytree-helper-indeterminate-cb { + color: #777; +} +.fancytree-helper-disabled { + color: #c0c0c0; +} +/* Helper to allow spinning loader icon with glyph-, ligature-, and SVG-icons. */ +.fancytree-helper-spin { + -webkit-animation: spin 1000ms infinite linear; + animation: spin 1000ms infinite linear; +} +@-webkit-keyframes spin { + 0% { + -webkit-transform: rotate(0deg); + transform: rotate(0deg); + } + 100% { + -webkit-transform: rotate(359deg); + transform: rotate(359deg); + } +} +@keyframes spin { + 0% { + -webkit-transform: rotate(0deg); + transform: rotate(0deg); + } + 100% { + -webkit-transform: rotate(359deg); + transform: rotate(359deg); + } +} +/*------------------------------------------------------------------------------ + * Container and UL / LI + *----------------------------------------------------------------------------*/ +ul.fancytree-container { + font-family: tahoma, arial, helvetica; + font-size: 10pt; + white-space: nowrap; + padding: 3px; + margin: 0; + background-color: white; + border: 1px dotted gray; + min-height: 0%; + position: relative; +} +ul.fancytree-container ul { + padding: 0 0 0 16px; + margin: 0; +} +ul.fancytree-container ul > li:before { + content: none; +} +ul.fancytree-container li { + list-style-image: none; + list-style-position: outside; + list-style-type: none; + -moz-background-clip: border; + -moz-background-inline-policy: continuous; + -moz-background-origin: padding; + background-attachment: scroll; + background-color: transparent; + background-position: 0px 0px; + background-repeat: repeat-y; + background-image: none; + margin: 0; +} +ul.fancytree-container li.fancytree-lastsib { + background-image: none; +} +.ui-fancytree-disabled ul.fancytree-container { + opacity: 0.5; + background-color: silver; +} +ul.fancytree-connectors.fancytree-container li { + background-image: url("../skin-themeroller/vline.gif"); + background-position: 0 0; +} +ul.fancytree-container li.fancytree-lastsib, +ul.fancytree-no-connector > li { + background-image: none; +} +li.fancytree-animating { + position: relative; +} +/*------------------------------------------------------------------------------ + * Common icon definitions + *----------------------------------------------------------------------------*/ +span.fancytree-empty, +span.fancytree-vline, +span.fancytree-expander, +span.fancytree-icon, +span.fancytree-checkbox, +span.fancytree-drag-helper-img, +#fancytree-drop-marker { + width: 16px; + height: 16px; + display: inline-block; + vertical-align: top; + background-repeat: no-repeat; + background-image: url("../skin-themeroller/icons.gif"); + background-position: 0px 0px; +} +span.fancytree-icon, +span.fancytree-checkbox, +span.fancytree-expander, +span.fancytree-custom-icon { + margin-top: 2px; +} +/* Used by icon option: */ +span.fancytree-custom-icon { + width: 16px; + height: 16px; + display: inline-block; + margin-left: 3px; + background-position: 0px 0px; +} +/* Used by 'icon' node option: */ +img.fancytree-icon { + width: 16px; + height: 16px; + margin-left: 3px; + margin-top: 2px; + vertical-align: top; + border-style: none; +} +/*------------------------------------------------------------------------------ + * Expander icon + * + * Note: IE6 doesn't correctly evaluate multiples class names, + * so we create combined class names that can be used in the CSS. + * + * Prefix: fancytree-exp- + * 1st character: 'e': expanded, 'c': collapsed, 'n': no children + * 2nd character (optional): 'd': lazy (Delayed) + * 3rd character (optional): 'l': Last sibling + *----------------------------------------------------------------------------*/ +span.fancytree-expander { + cursor: pointer; +} +.fancytree-exp-n span.fancytree-expander, +.fancytree-exp-nl span.fancytree-expander { + background-image: none; + cursor: default; +} +.fancytree-connectors .fancytree-exp-n span.fancytree-expander, +.fancytree-connectors .fancytree-exp-nl span.fancytree-expander { + background-image: url("../skin-themeroller/icons.gif"); + margin-top: 0; +} +.fancytree-connectors .fancytree-exp-n span.fancytree-expander, +.fancytree-connectors .fancytree-exp-n span.fancytree-expander:hover { + background-position: 0px -64px; +} +.fancytree-connectors .fancytree-exp-nl span.fancytree-expander, +.fancytree-connectors .fancytree-exp-nl span.fancytree-expander:hover { + background-position: -16px -64px; +} +.fancytree-exp-c span.fancytree-expander { + background-position: 0px -80px; +} +.fancytree-exp-c span.fancytree-expander:hover { + background-position: -16px -80px; +} +.fancytree-exp-cl span.fancytree-expander { + background-position: 0px -96px; +} +.fancytree-exp-cl span.fancytree-expander:hover { + background-position: -16px -96px; +} +.fancytree-exp-cd span.fancytree-expander { + background-position: -64px -80px; +} +.fancytree-exp-cd span.fancytree-expander:hover { + background-position: -80px -80px; +} +.fancytree-exp-cdl span.fancytree-expander { + background-position: -64px -96px; +} +.fancytree-exp-cdl span.fancytree-expander:hover { + background-position: -80px -96px; +} +.fancytree-exp-e span.fancytree-expander, +.fancytree-exp-ed span.fancytree-expander { + background-position: -32px -80px; +} +.fancytree-exp-e span.fancytree-expander:hover, +.fancytree-exp-ed span.fancytree-expander:hover { + background-position: -48px -80px; +} +.fancytree-exp-el span.fancytree-expander, +.fancytree-exp-edl span.fancytree-expander { + background-position: -32px -96px; +} +.fancytree-exp-el span.fancytree-expander:hover, +.fancytree-exp-edl span.fancytree-expander:hover { + background-position: -48px -96px; +} +/* Fade out expanders, when container is not hovered or active */ +.fancytree-fade-expander span.fancytree-expander { + transition: opacity 1.5s; + opacity: 0; +} +.fancytree-fade-expander:hover span.fancytree-expander, +.fancytree-fade-expander.fancytree-treefocus span.fancytree-expander, +.fancytree-fade-expander .fancytree-treefocus span.fancytree-expander, +.fancytree-fade-expander [class*="fancytree-statusnode-"] span.fancytree-expander { + transition: opacity 0.6s; + opacity: 1; +} +/*------------------------------------------------------------------------------ + * Checkbox icon + *----------------------------------------------------------------------------*/ +span.fancytree-checkbox { + margin-left: 3px; + background-position: 0px -32px; +} +span.fancytree-checkbox:hover { + background-position: -16px -32px; +} +span.fancytree-checkbox.fancytree-radio { + background-position: 0px -48px; +} +span.fancytree-checkbox.fancytree-radio:hover { + background-position: -16px -48px; +} +.fancytree-partsel span.fancytree-checkbox { + background-position: -64px -32px; +} +.fancytree-partsel span.fancytree-checkbox:hover { + background-position: -80px -32px; +} +.fancytree-partsel span.fancytree-checkbox.fancytree-radio { + background-position: -64px -48px; +} +.fancytree-partsel span.fancytree-checkbox.fancytree-radio:hover { + background-position: -80px -48px; +} +.fancytree-selected span.fancytree-checkbox { + background-position: -32px -32px; +} +.fancytree-selected span.fancytree-checkbox:hover { + background-position: -48px -32px; +} +.fancytree-selected span.fancytree-checkbox.fancytree-radio { + background-position: -32px -48px; +} +.fancytree-selected span.fancytree-checkbox.fancytree-radio:hover { + background-position: -48px -48px; +} +.fancytree-unselectable span.fancytree-checkbox { + opacity: 0.4; + filter: alpha(opacity=40); +} +.fancytree-unselectable span.fancytree-checkbox:hover { + background-position: 0px -32px; +} +.fancytree-unselectable span.fancytree-checkbox.fancytree-radio:hover { + background-position: 0px -48px; +} +.fancytree-unselectable.fancytree-partsel span.fancytree-checkbox:hover { + background-position: -64px -32px; +} +.fancytree-unselectable.fancytree-selected span.fancytree-checkbox:hover { + background-position: -32px -32px; +} +.fancytree-unselectable.fancytree-selected span.fancytree-checkbox.fancytree-radio:hover { + background-position: -32px -48px; +} +.fancytree-container.fancytree-checkbox-auto-hide span.fancytree-checkbox { + visibility: hidden; +} +.fancytree-container.fancytree-checkbox-auto-hide .fancytree-node:hover span.fancytree-checkbox, +.fancytree-container.fancytree-checkbox-auto-hide tr:hover td span.fancytree-checkbox, +.fancytree-container.fancytree-checkbox-auto-hide .fancytree-node.fancytree-selected span.fancytree-checkbox, +.fancytree-container.fancytree-checkbox-auto-hide tr.fancytree-selected td span.fancytree-checkbox { + visibility: unset; +} +.fancytree-container.fancytree-checkbox-auto-hide.fancytree-treefocus .fancytree-node.fancytree-active span.fancytree-checkbox, +.fancytree-container.fancytree-checkbox-auto-hide.fancytree-treefocus tr.fancytree-active td span.fancytree-checkbox { + visibility: unset; +} +/*------------------------------------------------------------------------------ + * Node type icon + * Note: IE6 doesn't correctly evaluate multiples class names, + * so we create combined class names that can be used in the CSS. + * + * Prefix: fancytree-ico- + * 1st character: 'e': expanded, 'c': collapsed + * 2nd character (optional): 'f': folder + *----------------------------------------------------------------------------*/ +span.fancytree-icon { + margin-left: 3px; + background-position: 0px 0px; +} +/* Documents */ +.fancytree-ico-c span.fancytree-icon:hover { + background-position: -16px 0px; +} +.fancytree-has-children.fancytree-ico-c span.fancytree-icon { + background-position: -32px 0px; +} +.fancytree-has-children.fancytree-ico-c span.fancytree-icon:hover { + background-position: -48px 0px; +} +.fancytree-ico-e span.fancytree-icon { + background-position: -64px 0px; +} +.fancytree-ico-e span.fancytree-icon:hover { + background-position: -80px 0px; +} +/* Folders */ +.fancytree-ico-cf span.fancytree-icon { + background-position: 0px -16px; +} +.fancytree-ico-cf span.fancytree-icon:hover { + background-position: -16px -16px; +} +.fancytree-has-children.fancytree-ico-cf span.fancytree-icon { + background-position: -32px -16px; +} +.fancytree-has-children.fancytree-ico-cf span.fancytree-icon:hover { + background-position: -48px -16px; +} +.fancytree-ico-ef span.fancytree-icon { + background-position: -64px -16px; +} +.fancytree-ico-ef span.fancytree-icon:hover { + background-position: -80px -16px; +} +.fancytree-loading span.fancytree-expander, +.fancytree-loading span.fancytree-expander:hover, +.fancytree-statusnode-loading span.fancytree-icon, +.fancytree-statusnode-loading span.fancytree-icon:hover, +span.fancytree-icon.fancytree-icon-loading { + background-image: url("../skin-themeroller/loading.gif"); + background-position: 0px 0px; +} +/* Status node icons */ +.fancytree-statusnode-error span.fancytree-icon, +.fancytree-statusnode-error span.fancytree-icon:hover { + background-position: 0px -112px; +} +/*------------------------------------------------------------------------------ + * Node titles and highlighting + *----------------------------------------------------------------------------*/ +span.fancytree-node { + /* See #117 */ + display: inherit; + width: 100%; + margin-top: 0px; + min-height: 20px; +} +span.fancytree-title { + color: black; + cursor: pointer; + display: inline-block; + vertical-align: top; + min-height: 20px; + padding: 0 3px 0 3px; + margin: 0px 0 0 3px; + border: 1px solid transparent; + -webkit-border-radius: 0px; + -moz-border-radius: 0px; + -ms-border-radius: 0px; + -o-border-radius: 0px; + border-radius: 0px; +} +span.fancytree-node.fancytree-error span.fancytree-title { + color: red; +} +/*------------------------------------------------------------------------------ + * Drag'n'drop support + *----------------------------------------------------------------------------*/ +/* ext-dnd5: */ +span.fancytree-childcounter { + color: #fff; + background: #337ab7; + border: 1px solid gray; + border-radius: 10px; + padding: 2px; + text-align: center; +} +/* ext-dnd: */ +div.fancytree-drag-helper span.fancytree-childcounter, +div.fancytree-drag-helper span.fancytree-dnd-modifier { + display: inline-block; + color: #fff; + background: #337ab7; + border: 1px solid gray; + min-width: 10px; + height: 10px; + line-height: 1; + vertical-align: baseline; + border-radius: 10px; + padding: 2px; + text-align: center; + font-size: 9px; +} +div.fancytree-drag-helper span.fancytree-childcounter { + position: absolute; + top: -6px; + right: -6px; +} +div.fancytree-drag-helper span.fancytree-dnd-modifier { + background: #5cb85c; + border: none; + font-weight: bolder; +} +div.fancytree-drag-helper.fancytree-drop-accept span.fancytree-drag-helper-img { + background-position: -32px -112px; +} +div.fancytree-drag-helper.fancytree-drop-reject span.fancytree-drag-helper-img { + background-position: -16px -112px; +} +/*** Drop marker icon *********************************************************/ +#fancytree-drop-marker { + width: 32px; + position: absolute; + background-position: 0px -128px; + margin: 0; +} +#fancytree-drop-marker.fancytree-drop-after, +#fancytree-drop-marker.fancytree-drop-before { + width: 64px; + background-position: 0px -144px; +} +#fancytree-drop-marker.fancytree-drop-copy { + background-position: -64px -128px; +} +#fancytree-drop-marker.fancytree-drop-move { + background-position: -32px -128px; +} +/*** Source node while dragging ***********************************************/ +span.fancytree-drag-source.fancytree-drag-remove { + opacity: 0.15; +} +/*** Target node while dragging cursor is over it *****************************/ +/*------------------------------------------------------------------------------ + * 'rtl' option + *----------------------------------------------------------------------------*/ +.fancytree-container.fancytree-rtl .fancytree-title { + /*unicode-bidi: bidi-override;*/ + /* optional: reverse title letters */ +} +.fancytree-container.fancytree-rtl span.fancytree-connector, +.fancytree-container.fancytree-rtl span.fancytree-expander, +.fancytree-container.fancytree-rtl span.fancytree-icon, +.fancytree-container.fancytree-rtl span.fancytree-drag-helper-img { + background-image: url("../skin-themeroller/icons-rtl.gif"); +} +.fancytree-container.fancytree-rtl .fancytree-exp-n span.fancytree-expander, +.fancytree-container.fancytree-rtl .fancytree-exp-nl span.fancytree-expander { + background-image: none; +} +.fancytree-container.fancytree-rtl.fancytree-connectors .fancytree-exp-n span.fancytree-expander, +.fancytree-container.fancytree-rtl.fancytree-connectors .fancytree-exp-nl span.fancytree-expander { + background-image: url("../skin-themeroller/icons-rtl.gif"); +} +ul.fancytree-container.fancytree-rtl ul { + padding: 0 16px 0 0; +} +ul.fancytree-container.fancytree-rtl.fancytree-connectors li { + background-position: right 0; + background-image: url("../skin-themeroller/vline-rtl.gif"); +} +ul.fancytree-container.fancytree-rtl li.fancytree-lastsib, +ul.fancytree-container.fancytree-rtl.fancytree-no-connector > li { + background-image: none; +} +#fancytree-drop-marker.fancytree-rtl { + background-image: url("../skin-themeroller/icons-rtl.gif"); +} +/*------------------------------------------------------------------------------ + * 'table' extension + *----------------------------------------------------------------------------*/ +table.fancytree-ext-table { + font-family: tahoma, arial, helvetica; + font-size: 10pt; + border-collapse: collapse; + /* ext-ariagrid */ +} +table.fancytree-ext-table span.fancytree-node { + display: inline-block; + box-sizing: border-box; +} +table.fancytree-ext-table td.fancytree-status-merged { + text-align: center; + font-style: italic; + color: #c0c0c0; +} +table.fancytree-ext-table tr.fancytree-statusnode-error td.fancytree-status-merged { + color: red; +} +table.fancytree-ext-table.fancytree-ext-ariagrid.fancytree-cell-mode > tbody > tr.fancytree-active > td { + background-color: #eee; +} +table.fancytree-ext-table.fancytree-ext-ariagrid.fancytree-cell-mode > tbody > tr > td.fancytree-active-cell { + background-color: #cbe8f6; +} +table.fancytree-ext-table.fancytree-ext-ariagrid.fancytree-cell-mode.fancytree-cell-nav-mode > tbody > tr > td.fancytree-active-cell { + background-color: #3875d7; +} +/*------------------------------------------------------------------------------ + * 'columnview' extension + *----------------------------------------------------------------------------*/ +table.fancytree-ext-columnview tbody tr td { + position: relative; + border: 1px solid gray; + vertical-align: top; + overflow: auto; +} +table.fancytree-ext-columnview tbody tr td > ul { + padding: 0; +} +table.fancytree-ext-columnview tbody tr td > ul li { + list-style-image: none; + list-style-position: outside; + list-style-type: none; + -moz-background-clip: border; + -moz-background-inline-policy: continuous; + -moz-background-origin: padding; + background-attachment: scroll; + background-color: transparent; + background-position: 0px 0px; + background-repeat: repeat-y; + background-image: none; + /* no v-lines */ + margin: 0; +} +table.fancytree-ext-columnview span.fancytree-node { + position: relative; + /* allow positioning of embedded spans */ + display: inline-block; +} +table.fancytree-ext-columnview span.fancytree-node.fancytree-expanded { + background-color: #e0e0e0; +} +table.fancytree-ext-columnview span.fancytree-node.fancytree-active { + background-color: #cbe8f6; +} +table.fancytree-ext-columnview .fancytree-has-children span.fancytree-cv-right { + position: absolute; + right: 3px; + background-position: 0px -80px; +} +table.fancytree-ext-columnview .fancytree-has-children span.fancytree-cv-right:hover { + background-position: -16px -80px; +} +/*------------------------------------------------------------------------------ + * 'filter' extension + *----------------------------------------------------------------------------*/ +.fancytree-ext-filter-dimm span.fancytree-node span.fancytree-title { + color: #c0c0c0; + font-weight: lighter; +} +.fancytree-ext-filter-dimm tr.fancytree-submatch span.fancytree-title, +.fancytree-ext-filter-dimm span.fancytree-node.fancytree-submatch span.fancytree-title { + color: black; + font-weight: normal; +} +.fancytree-ext-filter-dimm tr.fancytree-match span.fancytree-title, +.fancytree-ext-filter-dimm span.fancytree-node.fancytree-match span.fancytree-title { + color: black; + font-weight: bold; +} +.fancytree-ext-filter-hide tr.fancytree-hide, +.fancytree-ext-filter-hide span.fancytree-node.fancytree-hide { + display: none; +} +.fancytree-ext-filter-hide tr.fancytree-submatch span.fancytree-title, +.fancytree-ext-filter-hide span.fancytree-node.fancytree-submatch span.fancytree-title { + color: #c0c0c0; + font-weight: lighter; +} +.fancytree-ext-filter-hide tr.fancytree-match span.fancytree-title, +.fancytree-ext-filter-hide span.fancytree-node.fancytree-match span.fancytree-title { + color: black; + font-weight: normal; +} +/* Hide expanders if all child nodes are hidden by filter */ +.fancytree-ext-filter-hide-expanders tr.fancytree-match span.fancytree-expander, +.fancytree-ext-filter-hide-expanders span.fancytree-node.fancytree-match span.fancytree-expander { + visibility: hidden; +} +.fancytree-ext-filter-hide-expanders tr.fancytree-submatch span.fancytree-expander, +.fancytree-ext-filter-hide-expanders span.fancytree-node.fancytree-submatch span.fancytree-expander { + visibility: visible; +} +.fancytree-ext-childcounter span.fancytree-icon, +.fancytree-ext-filter span.fancytree-icon, +.fancytree-ext-childcounter span.fancytree-custom-icon, +.fancytree-ext-filter span.fancytree-custom-icon { + position: relative; +} +.fancytree-ext-childcounter span.fancytree-childcounter, +.fancytree-ext-filter span.fancytree-childcounter { + color: #fff; + background: #777; + border: 1px solid gray; + position: absolute; + top: -6px; + right: -6px; + min-width: 10px; + height: 10px; + line-height: 1; + vertical-align: baseline; + border-radius: 10px; + padding: 2px; + text-align: center; + font-size: 9px; +} +/*------------------------------------------------------------------------------ + * 'wide' extension + *----------------------------------------------------------------------------*/ +ul.fancytree-ext-wide { + position: relative; + min-width: 100%; + z-index: 2; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; +} +ul.fancytree-ext-wide span.fancytree-node > span { + position: relative; + z-index: 2; +} +ul.fancytree-ext-wide span.fancytree-node span.fancytree-title { + position: absolute; + z-index: 1; + left: 0px; + min-width: 100%; + margin-left: 0; + margin-right: 0; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; +} +/*------------------------------------------------------------------------------ + * 'fixed' extension + *----------------------------------------------------------------------------*/ +.fancytree-ext-fixed-wrapper .fancytree-ext-fixed-hidden { + display: none; +} +.fancytree-ext-fixed-wrapper div.fancytree-ext-fixed-scroll-border-bottom { + border-bottom: 3px solid rgba(0, 0, 0, 0.75); +} +.fancytree-ext-fixed-wrapper div.fancytree-ext-fixed-scroll-border-right { + border-right: 3px solid rgba(0, 0, 0, 0.75); +} +.fancytree-ext-fixed-wrapper div.fancytree-ext-fixed-wrapper-tl { + position: absolute; + overflow: hidden; + z-index: 3; + top: 0px; + left: 0px; +} +.fancytree-ext-fixed-wrapper div.fancytree-ext-fixed-wrapper-tr { + position: absolute; + overflow: hidden; + z-index: 2; + top: 0px; +} +.fancytree-ext-fixed-wrapper div.fancytree-ext-fixed-wrapper-bl { + position: absolute; + overflow: hidden; + z-index: 2; + left: 0px; +} +.fancytree-ext-fixed-wrapper div.fancytree-ext-fixed-wrapper-br { + position: absolute; + overflow: scroll; + z-index: 1; +} +/******************************************************************************* + * Styles specific to this skin. + * + * This section is automatically generated from the `ui-fancytree.less` template. + ******************************************************************************/ +/******************************************************************************* + * Node titles + */ +.fancytree-plain span.fancytree-node { + border: 1px solid transparent; +} +/******************************************************************************* + * 'table' extension + */ +table.fancytree-ext-table tbody tr td { + border: 1px solid transparent; +} diff --git a/plugins/55/indexmenu/scripts/fancytree/skin-themeroller/ui.fancytree.less b/plugins/55/indexmenu/scripts/fancytree/skin-themeroller/ui.fancytree.less new file mode 100644 index 0000000..d82ee14 --- /dev/null +++ b/plugins/55/indexmenu/scripts/fancytree/skin-themeroller/ui.fancytree.less @@ -0,0 +1,64 @@ +/*! + * Fancytree "ThemeRoller" skin. + * This file should be included after a jQuery Themeroller style sheet. + * It is meant to be used together with the ext-themeroller extension. + * + * DON'T EDIT THE CSS FILE DIRECTLY, since it is automatically generated from + * the LESS templates. + */ + +// Import common styles +@import "../skin-common.less"; + + +/******************************************************************************* + * Styles specific to this skin. + * + * This section is automatically generated from the `ui-fancytree.less` template. + ******************************************************************************/ + + +// Override the variable after the import. +// NOTE: Variables are always resolved as the last definition, even if it is +// after where it is used. +@fancy-use-sprites: true; // false: suppress all background images (i.e. icons) + +@fancy-line-height: 20px; // height of a nodes selection bar including borders +@fancy-node-v-spacing: 0px; // gap between two node borders +@fancy-icon-width: 16px; +@fancy-icon-height: 16px; +@fancy-icon-spacing: 3px; // margin between icon/icon or icon/title +@fancy-icon-ofs-top: 2px; // extra vertical offset for expander, checkbox and icon +@fancy-title-ofs-top: 0px; // extra vertical offset for title +@fancy-node-border-width: 1px; +@fancy-node-border-radius: 0px; +@fancy-node-outline-width: 1px; + + +// We need to define this variable here (not in skin-common.less) to make it +// work with grunt and webpack: +@fancy-image-prefix: "./skin-themeroller/"; + +// Use 'data-uri(...)' to embed the image into CSS instead of linking to 'loading.gif': +// @fancy-loading-url: data-uri("@{fancy-image-prefix}loading.gif"); +// Set to `true` to use `data-uri(...)` which will embed icons.gif into CSS +// instead of linking to that file: +// @fancy-inline-sprites: true; + +/******************************************************************************* + * Node titles + */ +.fancytree-plain { + span.fancytree-node { + border: @fancy-node-border-width solid transparent; // avoid jumping, when a border is added on hover + } +} + +/******************************************************************************* + * 'table' extension + */ +table.fancytree-ext-table tbody { + tr td { + border: 1px solid transparent; + } +} diff --git a/plugins/55/indexmenu/scripts/fancytree/skin-themeroller/ui.fancytree.min.css b/plugins/55/indexmenu/scripts/fancytree/skin-themeroller/ui.fancytree.min.css new file mode 100644 index 0000000..d22ab1f --- /dev/null +++ b/plugins/55/indexmenu/scripts/fancytree/skin-themeroller/ui.fancytree.min.css @@ -0,0 +1,8 @@ +/*! + * Fancytree "ThemeRoller" skin. + * This file should be included after a jQuery Themeroller style sheet. + * It is meant to be used together with the ext-themeroller extension. + * + * DON'T EDIT THE CSS FILE DIRECTLY, since it is automatically generated from + * the LESS templates. + */.fancytree-helper-hidden{display:none}.fancytree-helper-indeterminate-cb{color:#777}.fancytree-helper-disabled{color:silver}.fancytree-helper-spin{-webkit-animation:spin 1s infinite linear;animation:spin 1s infinite linear}@-webkit-keyframes spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}ul.fancytree-container{font-family:tahoma,arial,helvetica;font-size:10pt;white-space:nowrap;padding:3px;margin:0;background-color:#fff;border:1px dotted gray;min-height:0;position:relative}ul.fancytree-container ul{padding:0 0 0 16px;margin:0}ul.fancytree-container ul>li:before{content:none}ul.fancytree-container li{list-style-image:none;list-style-position:outside;list-style-type:none;-moz-background-clip:border;-moz-background-inline-policy:continuous;-moz-background-origin:padding;background-attachment:scroll;background-color:transparent;background-position:0 0;background-repeat:repeat-y;background-image:none;margin:0}ul.fancytree-container li.fancytree-lastsib{background-image:none}.ui-fancytree-disabled ul.fancytree-container{opacity:.5;background-color:silver}ul.fancytree-connectors.fancytree-container li{background-image:url("../skin-themeroller/vline.gif");background-position:0 0}ul.fancytree-container li.fancytree-lastsib,ul.fancytree-no-connector>li{background-image:none}li.fancytree-animating{position:relative}#fancytree-drop-marker,span.fancytree-checkbox,span.fancytree-drag-helper-img,span.fancytree-empty,span.fancytree-expander,span.fancytree-icon,span.fancytree-vline{width:16px;height:16px;display:inline-block;vertical-align:top;background-repeat:no-repeat;background-image:url("../skin-themeroller/icons.gif");background-position:0 0}span.fancytree-checkbox,span.fancytree-custom-icon,span.fancytree-expander,span.fancytree-icon{margin-top:2px}span.fancytree-custom-icon{width:16px;height:16px;display:inline-block;margin-left:3px;background-position:0 0}img.fancytree-icon{width:16px;height:16px;margin-left:3px;margin-top:2px;vertical-align:top;border-style:none}span.fancytree-expander{cursor:pointer}.fancytree-exp-n span.fancytree-expander,.fancytree-exp-nl span.fancytree-expander{background-image:none;cursor:default}.fancytree-connectors .fancytree-exp-n span.fancytree-expander,.fancytree-connectors .fancytree-exp-nl span.fancytree-expander{background-image:url("../skin-themeroller/icons.gif");margin-top:0}.fancytree-connectors .fancytree-exp-n span.fancytree-expander,.fancytree-connectors .fancytree-exp-n span.fancytree-expander:hover{background-position:0 -64px}.fancytree-connectors .fancytree-exp-nl span.fancytree-expander,.fancytree-connectors .fancytree-exp-nl span.fancytree-expander:hover{background-position:-16px -64px}.fancytree-exp-c span.fancytree-expander{background-position:0 -80px}.fancytree-exp-c span.fancytree-expander:hover{background-position:-16px -80px}.fancytree-exp-cl span.fancytree-expander{background-position:0 -96px}.fancytree-exp-cl span.fancytree-expander:hover{background-position:-16px -96px}.fancytree-exp-cd span.fancytree-expander{background-position:-64px -80px}.fancytree-exp-cd span.fancytree-expander:hover{background-position:-80px -80px}.fancytree-exp-cdl span.fancytree-expander{background-position:-64px -96px}.fancytree-exp-cdl span.fancytree-expander:hover{background-position:-80px -96px}.fancytree-exp-e span.fancytree-expander,.fancytree-exp-ed span.fancytree-expander{background-position:-32px -80px}.fancytree-exp-e span.fancytree-expander:hover,.fancytree-exp-ed span.fancytree-expander:hover{background-position:-48px -80px}.fancytree-exp-edl span.fancytree-expander,.fancytree-exp-el span.fancytree-expander{background-position:-32px -96px}.fancytree-exp-edl span.fancytree-expander:hover,.fancytree-exp-el span.fancytree-expander:hover{background-position:-48px -96px}.fancytree-fade-expander span.fancytree-expander{transition:opacity 1.5s;opacity:0}.fancytree-fade-expander .fancytree-treefocus span.fancytree-expander,.fancytree-fade-expander [class*=fancytree-statusnode-] span.fancytree-expander,.fancytree-fade-expander.fancytree-treefocus span.fancytree-expander,.fancytree-fade-expander:hover span.fancytree-expander{transition:opacity .6s;opacity:1}span.fancytree-checkbox{margin-left:3px;background-position:0 -32px}span.fancytree-checkbox:hover{background-position:-16px -32px}span.fancytree-checkbox.fancytree-radio{background-position:0 -48px}span.fancytree-checkbox.fancytree-radio:hover{background-position:-16px -48px}.fancytree-partsel span.fancytree-checkbox{background-position:-64px -32px}.fancytree-partsel span.fancytree-checkbox:hover{background-position:-80px -32px}.fancytree-partsel span.fancytree-checkbox.fancytree-radio{background-position:-64px -48px}.fancytree-partsel span.fancytree-checkbox.fancytree-radio:hover{background-position:-80px -48px}.fancytree-selected span.fancytree-checkbox{background-position:-32px -32px}.fancytree-selected span.fancytree-checkbox:hover{background-position:-48px -32px}.fancytree-selected span.fancytree-checkbox.fancytree-radio{background-position:-32px -48px}.fancytree-selected span.fancytree-checkbox.fancytree-radio:hover{background-position:-48px -48px}.fancytree-unselectable span.fancytree-checkbox{opacity:.4}.fancytree-unselectable span.fancytree-checkbox:hover{background-position:0 -32px}.fancytree-unselectable span.fancytree-checkbox.fancytree-radio:hover{background-position:0 -48px}.fancytree-unselectable.fancytree-partsel span.fancytree-checkbox:hover{background-position:-64px -32px}.fancytree-unselectable.fancytree-selected span.fancytree-checkbox:hover{background-position:-32px -32px}.fancytree-unselectable.fancytree-selected span.fancytree-checkbox.fancytree-radio:hover{background-position:-32px -48px}.fancytree-container.fancytree-checkbox-auto-hide span.fancytree-checkbox{visibility:hidden}.fancytree-container.fancytree-checkbox-auto-hide .fancytree-node.fancytree-selected span.fancytree-checkbox,.fancytree-container.fancytree-checkbox-auto-hide .fancytree-node:hover span.fancytree-checkbox,.fancytree-container.fancytree-checkbox-auto-hide tr.fancytree-selected td span.fancytree-checkbox,.fancytree-container.fancytree-checkbox-auto-hide tr:hover td span.fancytree-checkbox{visibility:unset}.fancytree-container.fancytree-checkbox-auto-hide.fancytree-treefocus .fancytree-node.fancytree-active span.fancytree-checkbox,.fancytree-container.fancytree-checkbox-auto-hide.fancytree-treefocus tr.fancytree-active td span.fancytree-checkbox{visibility:unset}span.fancytree-icon{margin-left:3px;background-position:0 0}.fancytree-ico-c span.fancytree-icon:hover{background-position:-16px 0}.fancytree-has-children.fancytree-ico-c span.fancytree-icon{background-position:-32px 0}.fancytree-has-children.fancytree-ico-c span.fancytree-icon:hover{background-position:-48px 0}.fancytree-ico-e span.fancytree-icon{background-position:-64px 0}.fancytree-ico-e span.fancytree-icon:hover{background-position:-80px 0}.fancytree-ico-cf span.fancytree-icon{background-position:0 -16px}.fancytree-ico-cf span.fancytree-icon:hover{background-position:-16px -16px}.fancytree-has-children.fancytree-ico-cf span.fancytree-icon{background-position:-32px -16px}.fancytree-has-children.fancytree-ico-cf span.fancytree-icon:hover{background-position:-48px -16px}.fancytree-ico-ef span.fancytree-icon{background-position:-64px -16px}.fancytree-ico-ef span.fancytree-icon:hover{background-position:-80px -16px}.fancytree-loading span.fancytree-expander,.fancytree-loading span.fancytree-expander:hover,.fancytree-statusnode-loading span.fancytree-icon,.fancytree-statusnode-loading span.fancytree-icon:hover,span.fancytree-icon.fancytree-icon-loading{background-image:url("../skin-themeroller/loading.gif");background-position:0 0}.fancytree-statusnode-error span.fancytree-icon,.fancytree-statusnode-error span.fancytree-icon:hover{background-position:0 -112px}span.fancytree-node{display:inherit;width:100%;margin-top:0;min-height:20px}span.fancytree-title{color:#000;cursor:pointer;display:inline-block;vertical-align:top;min-height:20px;padding:0 3px 0 3px;margin:0 0 0 3px;border:1px solid transparent;-webkit-border-radius:0px;-moz-border-radius:0;-ms-border-radius:0px;-o-border-radius:0;border-radius:0}span.fancytree-node.fancytree-error span.fancytree-title{color:red}span.fancytree-childcounter{color:#fff;background:#337ab7;border:1px solid gray;border-radius:10px;padding:2px;text-align:center}div.fancytree-drag-helper span.fancytree-childcounter,div.fancytree-drag-helper span.fancytree-dnd-modifier{display:inline-block;color:#fff;background:#337ab7;border:1px solid gray;min-width:10px;height:10px;line-height:1;vertical-align:baseline;border-radius:10px;padding:2px;text-align:center;font-size:9px}div.fancytree-drag-helper span.fancytree-childcounter{position:absolute;top:-6px;right:-6px}div.fancytree-drag-helper span.fancytree-dnd-modifier{background:#5cb85c;border:none;font-weight:bolder}div.fancytree-drag-helper.fancytree-drop-accept span.fancytree-drag-helper-img{background-position:-32px -112px}div.fancytree-drag-helper.fancytree-drop-reject span.fancytree-drag-helper-img{background-position:-16px -112px}#fancytree-drop-marker{width:32px;position:absolute;background-position:0 -128px;margin:0}#fancytree-drop-marker.fancytree-drop-after,#fancytree-drop-marker.fancytree-drop-before{width:64px;background-position:0 -144px}#fancytree-drop-marker.fancytree-drop-copy{background-position:-64px -128px}#fancytree-drop-marker.fancytree-drop-move{background-position:-32px -128px}span.fancytree-drag-source.fancytree-drag-remove{opacity:.15}.fancytree-container.fancytree-rtl span.fancytree-connector,.fancytree-container.fancytree-rtl span.fancytree-drag-helper-img,.fancytree-container.fancytree-rtl span.fancytree-expander,.fancytree-container.fancytree-rtl span.fancytree-icon{background-image:url("../skin-themeroller/icons-rtl.gif")}.fancytree-container.fancytree-rtl .fancytree-exp-n span.fancytree-expander,.fancytree-container.fancytree-rtl .fancytree-exp-nl span.fancytree-expander{background-image:none}.fancytree-container.fancytree-rtl.fancytree-connectors .fancytree-exp-n span.fancytree-expander,.fancytree-container.fancytree-rtl.fancytree-connectors .fancytree-exp-nl span.fancytree-expander{background-image:url("../skin-themeroller/icons-rtl.gif")}ul.fancytree-container.fancytree-rtl ul{padding:0 16px 0 0}ul.fancytree-container.fancytree-rtl.fancytree-connectors li{background-position:right 0;background-image:url("../skin-themeroller/vline-rtl.gif")}ul.fancytree-container.fancytree-rtl li.fancytree-lastsib,ul.fancytree-container.fancytree-rtl.fancytree-no-connector>li{background-image:none}#fancytree-drop-marker.fancytree-rtl{background-image:url("../skin-themeroller/icons-rtl.gif")}table.fancytree-ext-table{font-family:tahoma,arial,helvetica;font-size:10pt;border-collapse:collapse}table.fancytree-ext-table span.fancytree-node{display:inline-block;box-sizing:border-box}table.fancytree-ext-table td.fancytree-status-merged{text-align:center;font-style:italic;color:silver}table.fancytree-ext-table tr.fancytree-statusnode-error td.fancytree-status-merged{color:red}table.fancytree-ext-table.fancytree-ext-ariagrid.fancytree-cell-mode>tbody>tr.fancytree-active>td{background-color:#eee}table.fancytree-ext-table.fancytree-ext-ariagrid.fancytree-cell-mode>tbody>tr>td.fancytree-active-cell{background-color:#cbe8f6}table.fancytree-ext-table.fancytree-ext-ariagrid.fancytree-cell-mode.fancytree-cell-nav-mode>tbody>tr>td.fancytree-active-cell{background-color:#3875d7}table.fancytree-ext-columnview tbody tr td{position:relative;border:1px solid gray;vertical-align:top;overflow:auto}table.fancytree-ext-columnview tbody tr td>ul{padding:0}table.fancytree-ext-columnview tbody tr td>ul li{list-style-image:none;list-style-position:outside;list-style-type:none;-moz-background-clip:border;-moz-background-inline-policy:continuous;-moz-background-origin:padding;background-attachment:scroll;background-color:transparent;background-position:0 0;background-repeat:repeat-y;background-image:none;margin:0}table.fancytree-ext-columnview span.fancytree-node{position:relative;display:inline-block}table.fancytree-ext-columnview span.fancytree-node.fancytree-expanded{background-color:#e0e0e0}table.fancytree-ext-columnview span.fancytree-node.fancytree-active{background-color:#cbe8f6}table.fancytree-ext-columnview .fancytree-has-children span.fancytree-cv-right{position:absolute;right:3px;background-position:0 -80px}table.fancytree-ext-columnview .fancytree-has-children span.fancytree-cv-right:hover{background-position:-16px -80px}.fancytree-ext-filter-dimm span.fancytree-node span.fancytree-title{color:silver;font-weight:lighter}.fancytree-ext-filter-dimm span.fancytree-node.fancytree-submatch span.fancytree-title,.fancytree-ext-filter-dimm tr.fancytree-submatch span.fancytree-title{color:#000;font-weight:400}.fancytree-ext-filter-dimm span.fancytree-node.fancytree-match span.fancytree-title,.fancytree-ext-filter-dimm tr.fancytree-match span.fancytree-title{color:#000;font-weight:700}.fancytree-ext-filter-hide span.fancytree-node.fancytree-hide,.fancytree-ext-filter-hide tr.fancytree-hide{display:none}.fancytree-ext-filter-hide span.fancytree-node.fancytree-submatch span.fancytree-title,.fancytree-ext-filter-hide tr.fancytree-submatch span.fancytree-title{color:silver;font-weight:lighter}.fancytree-ext-filter-hide span.fancytree-node.fancytree-match span.fancytree-title,.fancytree-ext-filter-hide tr.fancytree-match span.fancytree-title{color:#000;font-weight:400}.fancytree-ext-filter-hide-expanders span.fancytree-node.fancytree-match span.fancytree-expander,.fancytree-ext-filter-hide-expanders tr.fancytree-match span.fancytree-expander{visibility:hidden}.fancytree-ext-filter-hide-expanders span.fancytree-node.fancytree-submatch span.fancytree-expander,.fancytree-ext-filter-hide-expanders tr.fancytree-submatch span.fancytree-expander{visibility:visible}.fancytree-ext-childcounter span.fancytree-custom-icon,.fancytree-ext-childcounter span.fancytree-icon,.fancytree-ext-filter span.fancytree-custom-icon,.fancytree-ext-filter span.fancytree-icon{position:relative}.fancytree-ext-childcounter span.fancytree-childcounter,.fancytree-ext-filter span.fancytree-childcounter{color:#fff;background:#777;border:1px solid gray;position:absolute;top:-6px;right:-6px;min-width:10px;height:10px;line-height:1;vertical-align:baseline;border-radius:10px;padding:2px;text-align:center;font-size:9px}ul.fancytree-ext-wide{position:relative;min-width:100%;z-index:2;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}ul.fancytree-ext-wide span.fancytree-node>span{position:relative;z-index:2}ul.fancytree-ext-wide span.fancytree-node span.fancytree-title{position:absolute;z-index:1;left:0;min-width:100%;margin-left:0;margin-right:0;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.fancytree-ext-fixed-wrapper .fancytree-ext-fixed-hidden{display:none}.fancytree-ext-fixed-wrapper div.fancytree-ext-fixed-scroll-border-bottom{border-bottom:3px solid rgba(0,0,0,.75)}.fancytree-ext-fixed-wrapper div.fancytree-ext-fixed-scroll-border-right{border-right:3px solid rgba(0,0,0,.75)}.fancytree-ext-fixed-wrapper div.fancytree-ext-fixed-wrapper-tl{position:absolute;overflow:hidden;z-index:3;top:0;left:0}.fancytree-ext-fixed-wrapper div.fancytree-ext-fixed-wrapper-tr{position:absolute;overflow:hidden;z-index:2;top:0}.fancytree-ext-fixed-wrapper div.fancytree-ext-fixed-wrapper-bl{position:absolute;overflow:hidden;z-index:2;left:0}.fancytree-ext-fixed-wrapper div.fancytree-ext-fixed-wrapper-br{position:absolute;overflow:scroll;z-index:1}.fancytree-plain span.fancytree-node{border:1px solid transparent}table.fancytree-ext-table tbody tr td{border:1px solid transparent}
\ No newline at end of file diff --git a/plugins/55/indexmenu/scripts/fancytree/skin-themeroller/vline-rtl.gif b/plugins/55/indexmenu/scripts/fancytree/skin-themeroller/vline-rtl.gif Binary files differnew file mode 100644 index 0000000..f9b4232 --- /dev/null +++ b/plugins/55/indexmenu/scripts/fancytree/skin-themeroller/vline-rtl.gif diff --git a/plugins/55/indexmenu/scripts/fancytree/skin-themeroller/vline.gif b/plugins/55/indexmenu/scripts/fancytree/skin-themeroller/vline.gif Binary files differnew file mode 100644 index 0000000..f9b4232 --- /dev/null +++ b/plugins/55/indexmenu/scripts/fancytree/skin-themeroller/vline.gif diff --git a/plugins/55/indexmenu/scripts/fancytree/skin-typicons/skin-common.less b/plugins/55/indexmenu/scripts/fancytree/skin-typicons/skin-common.less new file mode 100644 index 0000000..fc0da50 --- /dev/null +++ b/plugins/55/indexmenu/scripts/fancytree/skin-typicons/skin-common.less @@ -0,0 +1,972 @@ +/******************************************************************************* + * Common Styles for Fancytree Skins. + * + * This section is automatically generated from the `skin-common.less` template. + * + * Copyright (c) 2008-2023, Martin Wendt (https://wwWendt.de) + * Released under the MIT license + * https://github.com/mar10/fancytree/wiki/LicenseInfo + * + * @version 2.38.3 + * @date 2023-02-01T20:52:50Z +******************************************************************************/ + +// Variables (defaults, may be overwritten by the including .less files) +@fancy-use-sprites: true; // false: suppress all background images (i.e. icons) +// @fancy-hide-connectors: true; // false: show vertical connector lines + +@fancy-level-indent: 16px; +@fancy-line-height: 16px; // height of a nodes selection bar including borders +@fancy-node-v-spacing: 1px; // gap between two node borders +@fancy-icon-width: 16px; +@fancy-icon-height: 16px; +@fancy-icon-spacing: 3px; // margin between icon/icon or icon/title +@fancy-icon-ofs-top: 0px; // extra vertical offset for expander, checkbox and icon +@fancy-title-ofs-top: 0px; // extra vertical offset for title +@fancy-node-border-width: 1px; +@fancy-node-border-radius: 0px; +@fancy-node-outline-width: 1px; + +// @fancy-line-ofs-top: (@fancy-line-height - @fancy-icon-height) / 2; + +// webpack uses /dist/skin-common.less as root path +// grunt-less uses /dist/skin-Xxx/ui.fancyree.less as root path +// So we define our theme LESS files for webpack compatibility, i.e. +// define the image path n every main LESS file instead of here. +// Prefix may be set to "", "/", "./", or any other value +// Note: this variable must be defined by the main LESS files: +// @fancy-image-prefix: ""; + +// Use 'url(...)' to link to the throbber image, or +// use data-uri(...)' to inline the data in css instead: +/* CHANGE use url, as less does not handel data-uri() correct. DokuWiki can eventually inline it */ + @fancy-loading-url: url("@{fancy-image-prefix}loading.gif"); +//@fancy-loading-url: data-uri("@{fancy-image-prefix}loading.gif"); + +// Set to `true` to use `data-uri(...)` instead of a `url(...)` link: +@fancy-inline-sprites: false; // data-uri() is not handle correct by phpless + +@fancy-font-size: 10pt; +@fancy-font-family: tahoma, arial, helvetica; +@fancy-font-color: black; +@fancy-font-color-dimm: #c0c0c0; +@fancy-font-error-color: red; + +//------------------------------------------------------------------------------ +// Mixins +//------------------------------------------------------------------------------ +.setBgPos(@x, @y, @cond:true) when (@cond) { + background-position: (@x * -@fancy-icon-width) (@y * -@fancy-icon-height); +} +.clearBgImage(@cond:true) when (@cond) { + background-image: none; +} +.setBgImageUrl(@url) when (@fancy-use-sprites) and not (@fancy-inline-sprites) { + background-image: url("@{fancy-image-prefix}@{url}"); +} +.setBgImageUrl(@url) when (@fancy-use-sprites) and (@fancy-inline-sprites) { + background-image: data-uri("@{fancy-image-prefix}@{url}"); +} +.useSprite(@x, @y) when (@fancy-use-sprites) { + .setBgPos(@x, @y); +} +.rounded-corners(@radius) { + -webkit-border-radius: @radius; + -moz-border-radius: @radius; + -ms-border-radius: @radius; + -o-border-radius: @radius; + border-radius: @radius; +} +.spanStyleMixin(@color, @bgcolor, @bordercolor) { + border-color: @bordercolor; + background: @bgcolor; + color: @color; +} +.spanStyleMixin(@color, @bgcolor, @bordercolor, @startColor, @stopColor) { + .spanStyleMixin(@color, @bgcolor, @bordercolor); + // @c-start: argb(@startColor); + // @c-end: argb(@stopColor); + background: -moz-linear-gradient( + top, + @startColor 0%, + @stopColor 100% + ); // FF3.6+ + background: -webkit-gradient( + linear, + left top, + left bottom, + color-stop(0%, @startColor), + color-stop(100%, @stopColor) + ); // Chrome,Safari4+ + background: -webkit-linear-gradient( + top, + @startColor 0%, + @stopColor 100% + ); // Chrome10+,Safari5.1+ + background: -o-linear-gradient( + top, + @startColor 0%, + @stopColor 100% + ); // Opera 11.10+ + background: -ms-linear-gradient( + top, + @startColor 0%, + @stopColor 100% + ); // IE10+ + background: linear-gradient( + to bottom, + @startColor 0%, + @stopColor 100% + ); // W3C + filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='@{startColor}', endColorstr='@{stopColor}',GradientType=0 ); // IE6-9 +} + +/*------------------------------------------------------------------------------ + * Helpers + *----------------------------------------------------------------------------*/ +// Redefine, in case jQuery-UI is not included +// .ui-helper-hidden, +.fancytree-helper-hidden { + display: none; +} +.fancytree-helper-indeterminate-cb { + // tri-state checkbox + color: #777; +} +.fancytree-helper-disabled { + color: @fancy-font-color-dimm; +} + +/* Helper to allow spinning loader icon with glyph-, ligature-, and SVG-icons. */ +/* CHANGE: renamed spin to spin-fancytree */ +.fancytree-helper-spin { + -webkit-animation: spin-fancytree 1000ms infinite linear; + animation: spin-fancytree 1000ms infinite linear; +} +/* CHANGE: commented because it is wrong prefixed by phpless +@-webkit-keyframes spin { + 0% { + -webkit-transform: rotate(0deg); + transform: rotate(0deg); + } + 100% { + -webkit-transform: rotate(359deg); + transform: rotate(359deg); + } +} +@keyframes spin { + 0% { + -webkit-transform: rotate(0deg); + transform: rotate(0deg); + } + 100% { + -webkit-transform: rotate(359deg); + transform: rotate(359deg); + } +} +*/ +/*------------------------------------------------------------------------------ + * Container and UL / LI + *----------------------------------------------------------------------------*/ + +ul.fancytree-container { + font-family: @fancy-font-family; + font-size: @fancy-font-size; + white-space: nowrap; + padding: 3px; + margin: 0; // DT issue 201 + //background-color: white; CHANGE + //border: 1px dotted gray; CHANGE + // overflow: auto; // ext-dnd5: otherwise this is always the scroll parent + // height: 100%; // DT issue 263, 470 + min-height: 0%; // #192 + position: relative; // #235 + ul { + padding: 0 0 0 @fancy-level-indent; + margin: 0; + } + ul > li:before { + // #538 + content: none; + } + li { + list-style-image: none; + list-style-position: outside; + list-style-type: none; + -moz-background-clip: border; + -moz-background-inline-policy: continuous; + -moz-background-origin: padding; + background-attachment: scroll; + background-color: transparent; + .setBgPos(0, 0); + background-repeat: repeat-y; + background-image: none; // no v-lines + + margin: 0; + // padding: 1px 0 0 0; // issue #246 + } + // Suppress lines for last child node + li.fancytree-lastsib { + background-image: none; + } +} + +// Style, when control is disabled +.ui-fancytree-disabled ul.fancytree-container { + opacity: 0.5; + // filter: alpha(opacity=50); // Yields a css warning + background-color: silver; +} + +ul.fancytree-connectors.fancytree-container { + li { + // Use 'data-uri(...)' to embed the image into CSS instead of linking to 'loading.gif': + /* CHANGE: phpless does not handle data-uri() correct */ + //background-image: data-uri("@{fancy-image-prefix}vline.gif"); + background-image: url("@{fancy-image-prefix}vline.gif"); + background-position: 0 0; + } +} + +// Suppress lines for last child node +ul.fancytree-container li.fancytree-lastsib, +// Suppress lines if level is fixed expanded (option minExpandLevel) +ul.fancytree-no-connector > li { + background-image: none; +} + +// Fix jQuery UI 'blind' animation for jQuery UI (#717) +li.fancytree-animating { + position: relative; +} + +/*------------------------------------------------------------------------------ + * Common icon definitions + *----------------------------------------------------------------------------*/ + +span.fancytree-empty, +span.fancytree-vline, +span.fancytree-expander, +span.fancytree-icon, +span.fancytree-checkbox, +// span.fancytree-radio, +span.fancytree-drag-helper-img, +#fancytree-drop-marker { + width: @fancy-icon-width; + height: @fancy-icon-height; + // display: -moz-inline-box; // @ FF 1+2 removed for issue 221 + // -moz-box-align: start; /* issue 221 */ + display: inline-block; // Required to make a span sizeable + vertical-align: top; + background-repeat: no-repeat; + // background-position: left; + .setBgImageUrl("icons.gif"); + .setBgPos(0, 0); +} +span.fancytree-icon, +span.fancytree-checkbox, +span.fancytree-expander, +// span.fancytree-radio, +span.fancytree-custom-icon { + margin-top: @fancy-icon-ofs-top; +} +/* Used by icon option: */ +span.fancytree-custom-icon { + width: @fancy-icon-width; + height: @fancy-icon-height; + display: inline-block; + margin-left: @fancy-icon-spacing; + .setBgPos(0, 0); +} +/* Used by 'icon' node option: */ +img.fancytree-icon { + width: @fancy-icon-width; + height: @fancy-icon-height; + margin-left: @fancy-icon-spacing; + margin-top: @fancy-icon-ofs-top; + vertical-align: top; + border-style: none; +} + +/*------------------------------------------------------------------------------ + * Expander icon + * + * Note: IE6 doesn't correctly evaluate multiples class names, + * so we create combined class names that can be used in the CSS. + * + * Prefix: fancytree-exp- + * 1st character: 'e': expanded, 'c': collapsed, 'n': no children + * 2nd character (optional): 'd': lazy (Delayed) + * 3rd character (optional): 'l': Last sibling + *----------------------------------------------------------------------------*/ + +span.fancytree-expander { + // .useSprite(0, 5); + cursor: pointer; +} +// span.fancytree-expander:hover { +// // .useSprite(1, 5); +// } + +// --- End nodes (use connectors instead of expanders) + +.fancytree-exp-n span.fancytree-expander, +.fancytree-exp-nl span.fancytree-expander { + // .clearBgImage( @fancy-hide-connectors ); + background-image: none; + cursor: default; +} +.fancytree-connectors { + .fancytree-exp-n span.fancytree-expander, + .fancytree-exp-nl span.fancytree-expander { + .setBgImageUrl("icons.gif"); + margin-top: 0; + } + .fancytree-exp-n span.fancytree-expander, // End-node, not last sibling + .fancytree-exp-n span.fancytree-expander:hover { + .useSprite(0, 4); + } + .fancytree-exp-nl span.fancytree-expander, // End-node, last sibling + .fancytree-exp-nl span.fancytree-expander:hover { + .useSprite(1, 4); + } +} + +// --- Collapsed + +.fancytree-exp-c span.fancytree-expander { + // Collapsed, not delayed, not last sibling + .useSprite(0, 5); +} +.fancytree-exp-c span.fancytree-expander:hover { + .useSprite(1, 5); +} +.fancytree-exp-cl span.fancytree-expander { + // Collapsed, not delayed, last sibling + .useSprite(0, 6); +} +.fancytree-exp-cl span.fancytree-expander:hover { + .useSprite(1, 6); +} +.fancytree-exp-cd span.fancytree-expander { + // Collapsed, delayed, not last sibling + .useSprite(4, 5); +} +.fancytree-exp-cd span.fancytree-expander:hover { + .useSprite(5, 5); +} +.fancytree-exp-cdl span.fancytree-expander { + // Collapsed, delayed, last sibling + .useSprite(4, 6); +} +.fancytree-exp-cdl span.fancytree-expander:hover { + .useSprite(5, 6); +} + +// --- Expanded + +.fancytree-exp-e span.fancytree-expander, // Expanded, not delayed, not last sibling +.fancytree-exp-ed span.fancytree-expander { + // Expanded, delayed, not last sibling + .useSprite(2, 5); +} +.fancytree-exp-e span.fancytree-expander:hover, +.fancytree-exp-ed span.fancytree-expander:hover { + .useSprite(3, 5); +} +.fancytree-exp-el span.fancytree-expander, // Expanded, not delayed, last sibling +.fancytree-exp-edl span.fancytree-expander { + // Expanded, delayed, last sibling + .useSprite(2, 6); +} +.fancytree-exp-el span.fancytree-expander:hover, +.fancytree-exp-edl span.fancytree-expander:hover { + .useSprite(3, 6); +} + +/* Fade out expanders, when container is not hovered or active */ +.fancytree-fade-expander { + span.fancytree-expander { + transition: opacity 1.5s; + opacity: 0; + } + &:hover span.fancytree-expander, + &.fancytree-treefocus span.fancytree-expander, + .fancytree-treefocus span.fancytree-expander, + [class*="fancytree-statusnode-"] span.fancytree-expander { + transition: opacity 0.6s; + opacity: 1; + } +} + +//// CHANGE: not used. +///*------------------------------------------------------------------------------ +// * Checkbox icon +// *----------------------------------------------------------------------------*/ +// +//span.fancytree-checkbox { +// margin-left: @fancy-icon-spacing; +// .useSprite(0, 2); +// &:hover { +// .useSprite(1, 2); +// } +// &.fancytree-radio { +// .useSprite(0, 3); +// } +// &.fancytree-radio:hover { +// .useSprite(1, 3); +// } +//} +//.fancytree-partsel span.fancytree-checkbox { +// .useSprite(4, 2); +// &:hover { +// .useSprite(5, 2); +// } +// &.fancytree-radio { +// .useSprite(4, 3); +// } +// &.fancytree-radio:hover { +// .useSprite(5, 3); +// } +//} +//// selected after partsel, so it takes precedence: +//.fancytree-selected span.fancytree-checkbox { +// .useSprite(2, 2); +// &:hover { +// .useSprite(3, 2); +// } +// &.fancytree-radio { +// .useSprite(2, 3); +// } +// &.fancytree-radio:hover { +// .useSprite(3, 3); +// } +//} +//// Unselectable is dimmed, without hover effects +//.fancytree-unselectable { +// span.fancytree-checkbox { +// opacity: 0.4; +// filter: alpha(opacity=40); +// } +// span.fancytree-checkbox:hover { +// .useSprite(0, 2); +// } +// span.fancytree-checkbox.fancytree-radio:hover { +// .useSprite(0, 3); +// } +// &.fancytree-partsel span.fancytree-checkbox:hover { +// .useSprite(4, 2); +// } +// &.fancytree-selected span.fancytree-checkbox:hover { +// .useSprite(2, 2); +// } +// &.fancytree-selected span.fancytree-checkbox.fancytree-radio:hover { +// .useSprite(2, 3); +// } +//} +// +//// Auto-hide checkboxes unless selected or hovered +//.fancytree-container.fancytree-checkbox-auto-hide { +// span.fancytree-checkbox { +// visibility: hidden; +// } +// .fancytree-node:hover span.fancytree-checkbox, +// tr:hover td span.fancytree-checkbox, +// .fancytree-node.fancytree-selected span.fancytree-checkbox, +// tr.fancytree-selected td span.fancytree-checkbox { +// visibility: unset; +// } +// &.fancytree-treefocus { +// .fancytree-node.fancytree-active span.fancytree-checkbox, +// tr.fancytree-active td span.fancytree-checkbox { +// visibility: unset; +// } +// } +//} + +/*------------------------------------------------------------------------------ + * Node type icon + * Note: IE6 doesn't correctly evaluate multiples class names, + * so we create combined class names that can be used in the CSS. + * + * Prefix: fancytree-ico- + * 1st character: 'e': expanded, 'c': collapsed + * 2nd character (optional): 'f': folder + *----------------------------------------------------------------------------*/ + +span.fancytree-icon { + // Default icon + margin-left: @fancy-icon-spacing; + .useSprite(0, 0); +} + +/* Documents */ +.fancytree-ico-c span.fancytree-icon { + // Collapsed folder (empty) + // .useSprite(0, 0); +} +.fancytree-ico-c span.fancytree-icon:hover { + .useSprite(1, 0); +} +.fancytree-has-children.fancytree-ico-c span.fancytree-icon { + // Collapsed folder (not empty) + .useSprite(2, 0); +} +.fancytree-has-children.fancytree-ico-c span.fancytree-icon:hover { + .useSprite(3, 0); +} +.fancytree-ico-e span.fancytree-icon { + // Expanded folder + .useSprite(4, 0); +} +.fancytree-ico-e span.fancytree-icon:hover { + .useSprite(5, 0); +} + +/* Folders */ +.fancytree-ico-cf span.fancytree-icon { + // Collapsed folder (empty) + .useSprite(0, 1); +} +.fancytree-ico-cf span.fancytree-icon:hover { + .useSprite(1, 1); +} +.fancytree-has-children.fancytree-ico-cf span.fancytree-icon { + // Collapsed folder (not empty) + .useSprite(2, 1); +} +.fancytree-has-children.fancytree-ico-cf span.fancytree-icon:hover { + .useSprite(3, 1); +} +.fancytree-ico-ef span.fancytree-icon { + // Expanded folder + .useSprite(4, 1); +} +.fancytree-ico-ef span.fancytree-icon:hover { + .useSprite(5, 1); +} + +// 'Loading' status overrides all others +.fancytree-loading span.fancytree-expander, +.fancytree-loading span.fancytree-expander:hover, +.fancytree-statusnode-loading span.fancytree-icon, +.fancytree-statusnode-loading span.fancytree-icon:hover, +span.fancytree-icon.fancytree-icon-loading { + background-image: @fancy-loading-url; + .useSprite(0, 0); +} + +/* Status node icons */ + +.fancytree-statusnode-error span.fancytree-icon, +.fancytree-statusnode-error span.fancytree-icon:hover { + .useSprite(0, 7); +} + +/*------------------------------------------------------------------------------ + * Node titles and highlighting + *----------------------------------------------------------------------------*/ + +span.fancytree-node { + /* See #117 */ + display: inherit; // #117, resolves to 'display: list-item;' for standard trees + width: 100%; + margin-top: @fancy-node-v-spacing; + min-height: @fancy-line-height; +} +span.fancytree-title { + color: @fancy-font-color; // inherit doesn't work on IE + cursor: pointer; + display: inline-block; // Better alignment, when title contains <br> + vertical-align: top; + min-height: @fancy-line-height; + padding: 0 3px 0 3px; // Otherwise italic font will be outside right bounds + margin: @fancy-title-ofs-top 0 0 @fancy-icon-spacing; + // margin: 0px; + // margin-top: @fancy-line-ofs-top; + // margin-left: @fancy-icon-spacing; + border: @fancy-node-border-width solid transparent; // avoid jumping, when a border is added on hover + .rounded-corners(@fancy-node-border-radius); + // outline: 0; // @ Firefox, prevent dotted border after click + // Set transparent border to prevent jumping when active node gets a border + // (we can do this, because this theme doesn't use vertical lines) + // border: 1px solid white; // Note: 'transparent' would not work in IE6 +} +span.fancytree-node.fancytree-error span.fancytree-title { + color: @fancy-font-error-color; +} + +//// CHANGE: not used. +///*------------------------------------------------------------------------------ +// * Drag'n'drop support +// *----------------------------------------------------------------------------*/ +///* ext-dnd5: */ +//span.fancytree-childcounter { +// color: #fff; +// background: #337ab7; // bootstrap blue +// border: 1px solid gray; +// border-radius: 10px; +// padding: 2px; +// text-align: center; +//} +// +///* ext-dnd: */ +//div.fancytree-drag-helper { +// span.fancytree-childcounter, +// span.fancytree-dnd-modifier { +// display: inline-block; +// color: #fff; +// background: #337ab7; // bootstrap blue +// border: 1px solid gray; +// min-width: 10px; +// // min-height: 16px; +// height: 10px; +// line-height: 1; +// vertical-align: baseline; +// border-radius: 10px; +// padding: 2px; +// text-align: center; +// font-size: 9px; +// } +// span.fancytree-childcounter { +// position: absolute; +// // left: 16px; +// top: -6px; +// right: -6px; +// } +// span.fancytree-dnd-modifier { +// background: #5cb85c; // bootstrap green +// border: none; +// // min-height: 16px; +// // font-size: 12px; +// font-weight: bolder; +// } +// &.fancytree-drop-accept { +// span.fancytree-drag-helper-img { +// .useSprite(2, 7); +// } +// } +// &.fancytree-drop-reject { +// span.fancytree-drag-helper-img { +// .useSprite(1, 7); +// } +// } +//} +// +///*** Drop marker icon *********************************************************/ +//#fancytree-drop-marker { +// width: 2 * @fancy-icon-width; // was 24px, but 32 should be correct +// position: absolute; +// .useSprite(0, 8); +// margin: 0; +// &.fancytree-drop-after, +// &.fancytree-drop-before { +// width: 4 * @fancy-icon-width; // 64px; +// .useSprite(0, 9); +// } +// &.fancytree-drop-copy { +// .useSprite(4, 8); +// } +// &.fancytree-drop-move { +// .useSprite(2, 8); +// } +//} +// +///*** Source node while dragging ***********************************************/ +// +//span.fancytree-drag-source { +// &.fancytree-drag-remove { +// // text-decoration: line-through; +// opacity: 0.15; +// } +//} +// +///*** Target node while dragging cursor is over it *****************************/ +// +//span.fancytree-drop-target { +// &.fancytree-drop-accept { +// // outline: 1px dotted #5cb85c; // bootstrap sucess +// } +//} +//span.fancytree-drop-reject { +// // outline: 1px dotted #d9534f; // boostrap warning +//} + +/*------------------------------------------------------------------------------ + * 'rtl' option + *----------------------------------------------------------------------------*/ + +.fancytree-container.fancytree-rtl { + .fancytree-title { + /*unicode-bidi: bidi-override;*/ /* optional: reverse title letters */ + } + span.fancytree-connector, + span.fancytree-expander, + span.fancytree-icon, + span.fancytree-drag-helper-img { + .setBgImageUrl("icons-rtl.gif"); + } + .fancytree-exp-n span.fancytree-expander, + .fancytree-exp-nl span.fancytree-expander { + background-image: none; + } + &.fancytree-connectors .fancytree-exp-n span.fancytree-expander, + &.fancytree-connectors .fancytree-exp-nl span.fancytree-expander { + .setBgImageUrl("icons-rtl.gif"); + } +} +ul.fancytree-container.fancytree-rtl { + ul { + padding: 0 16px 0 0; + } + &.fancytree-connectors li { + background-position: right 0; + background-image: url("@{fancy-image-prefix}vline-rtl.gif"); + } + // Suppress lines for last child node + li.fancytree-lastsib, + // Suppress lines if level is fixed expanded (option minExpandLevel) + &.fancytree-no-connector > li { + background-image: none; + } +} +#fancytree-drop-marker.fancytree-rtl { + .setBgImageUrl("icons-rtl.gif"); +} + +//// CHANGE: not used. +///*------------------------------------------------------------------------------ +// * 'table' extension +// *----------------------------------------------------------------------------*/ +// +//table.fancytree-ext-table { +// font-family: @fancy-font-family; +// font-size: @fancy-font-size; +// border-collapse: collapse; +// span.fancytree-node { +// display: inline-block; // #117 +// box-sizing: border-box; // #562 +// } +// td.fancytree-status-merged { +// text-align: center; +// // font-weight: bold; +// font-style: italic; +// // line-height: 100px; +// color: @fancy-font-color-dimm; +// } +// tr.fancytree-statusnode-error td.fancytree-status-merged { +// color: @fancy-font-error-color; +// } +// /* ext-ariagrid */ +// &.fancytree-ext-ariagrid.fancytree-cell-mode { +// > tbody > tr.fancytree-active > td { +// background-color: #eee; +// } +// > tbody > tr > td.fancytree-active-cell { +// background-color: #cbe8f6; +// } +// &.fancytree-cell-nav-mode > tbody > tr > td.fancytree-active-cell { +// background-color: #3875d7; +// } +// } +//} +// +///*------------------------------------------------------------------------------ +// * 'columnview' extension +// *----------------------------------------------------------------------------*/ +// +//table.fancytree-ext-columnview { +// // border-collapse: collapse; +// // width: 100%; +// tbody tr td { +// position: relative; +// border: 1px solid gray; +// vertical-align: top; +// overflow: auto; +// > ul { +// padding: 0; +// li { +// list-style-image: none; +// list-style-position: outside; +// list-style-type: none; +// -moz-background-clip: border; +// -moz-background-inline-policy: continuous; +// -moz-background-origin: padding; +// background-attachment: scroll; +// background-color: transparent; +// .setBgPos(0, 0); +// background-repeat: repeat-y; +// background-image: none; /* no v-lines */ +// +// margin: 0; +// // padding: 1px 0 0 0; // issue #246 +// } +// } +// } +// span.fancytree-node { +// position: relative; /* allow positioning of embedded spans */ +// display: inline-block; // #117 +// } +// span.fancytree-node.fancytree-expanded { +// background-color: #e0e0e0; +// } +// span.fancytree-node.fancytree-active { +// background-color: #cbe8f6; +// // background-color: royalblue; +// } +// .fancytree-has-children span.fancytree-cv-right { +// position: absolute; +// right: 3px; +// .useSprite(0, 5); +// &:hover { +// .useSprite(1, 5); +// } +// } +//} +// +///*------------------------------------------------------------------------------ +// * 'filter' extension +// *----------------------------------------------------------------------------*/ +// +//.fancytree-ext-filter-dimm { +// span.fancytree-node span.fancytree-title { +// color: @fancy-font-color-dimm; +// font-weight: lighter; +// } +// tr.fancytree-submatch span.fancytree-title, +// span.fancytree-node.fancytree-submatch span.fancytree-title { +// color: black; +// font-weight: normal; +// } +// tr.fancytree-match span.fancytree-title, +// span.fancytree-node.fancytree-match span.fancytree-title { +// color: black; +// font-weight: bold; +// } +//} +//.fancytree-ext-filter-hide { +// tr.fancytree-hide, +// span.fancytree-node.fancytree-hide { +// display: none; +// } +// tr.fancytree-submatch span.fancytree-title, +// span.fancytree-node.fancytree-submatch span.fancytree-title { +// color: @fancy-font-color-dimm; +// font-weight: lighter; +// } +// tr.fancytree-match span.fancytree-title, +// span.fancytree-node.fancytree-match span.fancytree-title { +// color: black; +// font-weight: normal; +// } +//} +///* Hide expanders if all child nodes are hidden by filter */ +//.fancytree-ext-filter-hide-expanders { +// tr.fancytree-match span.fancytree-expander, +// span.fancytree-node.fancytree-match span.fancytree-expander { +// visibility: hidden; +// } +// tr.fancytree-submatch span.fancytree-expander, +// span.fancytree-node.fancytree-submatch span.fancytree-expander { +// visibility: visible; +// } +//} +// +//.fancytree-ext-childcounter, +//.fancytree-ext-filter { +// // span.fancytree-title mark { +// // font-style: normal; +// // background-color: #ead61c; // yellow +// // border-radius: 3px; +// // } +// span.fancytree-icon, +// span.fancytree-custom-icon { +// position: relative; +// } +// span.fancytree-childcounter { +// color: #fff; +// background: #777; // #337ab7; // bootstrap blue +// border: 1px solid gray; +// position: absolute; +// top: -6px; +// right: -6px; +// min-width: 10px; +// height: 10px; +// line-height: 1; +// vertical-align: baseline; +// border-radius: 10px; +// padding: 2px; +// text-align: center; +// font-size: 9px; +// } +//} +///*------------------------------------------------------------------------------ +// * 'wide' extension +// *----------------------------------------------------------------------------*/ +// +//ul.fancytree-ext-wide { +// position: relative; +// min-width: 100%; +// z-index: 2; +// +// -webkit-box-sizing: border-box; +// -moz-box-sizing: border-box; +// box-sizing: border-box; +// +// span.fancytree-node > span { +// position: relative; +// z-index: 2; +// } +// span.fancytree-node span.fancytree-title { +// position: absolute; // Allow left: 0. Note: prevents smooth dropdown animation +// z-index: 1; // Behind expander and checkbox +// left: 0px; +// min-width: 100%; +// margin-left: 0; +// margin-right: 0; +// +// -webkit-box-sizing: border-box; +// -moz-box-sizing: border-box; +// box-sizing: border-box; +// } +//} +// +///*------------------------------------------------------------------------------ +// * 'fixed' extension +// *----------------------------------------------------------------------------*/ +// +//.fancytree-ext-fixed-wrapper { +// .fancytree-ext-fixed-hidden { +// display: none; +// } +// div.fancytree-ext-fixed-scroll-border-bottom { +// border-bottom: 3px solid rgba(0, 0, 0, 0.75); +// } +// div.fancytree-ext-fixed-scroll-border-right { +// border-right: 3px solid rgba(0, 0, 0, 0.75); +// } +// div.fancytree-ext-fixed-wrapper-tl { +// position: absolute; +// overflow: hidden; +// z-index: 3; +// top: 0px; +// left: 0px; +// } +// div.fancytree-ext-fixed-wrapper-tr { +// position: absolute; +// overflow: hidden; +// z-index: 2; +// top: 0px; +// } +// div.fancytree-ext-fixed-wrapper-bl { +// position: absolute; +// overflow: hidden; +// z-index: 2; +// left: 0px; +// } +// div.fancytree-ext-fixed-wrapper-br { +// position: absolute; +// overflow: scroll; +// z-index: 1; +// } +//} diff --git a/plugins/55/indexmenu/scripts/fancytree/skin-typicons/ui.fancytree.less b/plugins/55/indexmenu/scripts/fancytree/skin-typicons/ui.fancytree.less new file mode 100644 index 0000000..976bc4f --- /dev/null +++ b/plugins/55/indexmenu/scripts/fancytree/skin-typicons/ui.fancytree.less @@ -0,0 +1,138 @@ +/*! + * Fancytree "awesome" skin. + * + * DON'T EDIT THE CSS FILE DIRECTLY, since it is automatically generated from + * the LESS templates. + */ + +// Import common styles +@import "skin-common.less"; + +// We need to define this variable here (not in skin-common.less) to make it +// work with grunt and webpack: +@fancy-image-prefix: "./skin-typicons/"; + + +/******************************************************************************* + * Styles specific to this skin. + * + * This section is automatically generated from the `ui-fancytree.less` template. + ******************************************************************************/ + +@fancy-use-sprites: false; // false: suppress all background images (i.e. icons) +@fancy-loading-url: none; + +@fancy-cst-size: 18px; + +@fancy-level-indent: @fancy-cst-size; //@fancy-cst-size; +@fancy-line-height: @fancy-cst-size; // height of a nodes selection bar including borders +@fancy-node-v-spacing: 1px; // gap between two node borders +@fancy-icon-width: @fancy-cst-size; +@fancy-icon-height: @fancy-cst-size; +@fancy-icon-spacing: 3px; // margin between icon/icon or icon/title +@fancy-icon-ofs-top: -6px; // extra vertical offset for expander, checkbox and icon +@fancy-title-ofs-top: 0px; // extra vertical offset for title +@fancy-node-border-width: 1px; +@fancy-node-border-radius: 0px; +@fancy-node-outline-width: 1px; + +// @fancy-loading-url: data-uri("@{fancy-image-prefix}loading.gif"); + +// Set to `true` to use `data-uri(...)` instead of a `url(...)` link: +@fancy-inline-sprites: false; + +//default 10pt, which is used in a relative manner resulting in 13.3 in dokuwiki-template. +@fancy-font-size: 93%; //@fancy-cst-size; +@fancy-font-family: tahoma, arial, helvetica; +@fancy-font-color: #000; +@fancy-font-color-dimm: silver; +@fancy-font-error-color: red; + +// set icon color to font color as well +span.fancytree-node { + color: @fancy-font-color; +} + +ul.fancytree-container ul +{ + padding: 0 0 0 1em; // 0.3em 0 0 1em; + margin: 0; +} + + +// The standard CSS assumes span.icon, but Fontawesome may use SVG or SPAN +.fancytree-expander, +.fancytree-checkbox, +.fancytree-icon { + min-width: @fancy-icon-width; + text-align: center; + font-size: (@fancy-cst-size +2px); +} +svg.fancytree-checkbox, // span... is already defined in skin-common-less +svg.fancytree-icon { + padding-left: @fancy-icon-spacing; +} +span.fancytree-expander { + font-size: (@fancy-cst-size *4/5); + margin-top: -1px; +} + +/******************************************************************************* + * Node titles + */ +span.fancytree-title { + border: 1px solid transparent; // reserve some space for status borders + border-radius: 0; +} +span.fancytree-focused span.fancytree-title { + outline: 1px dotted black; +} +// span.fancytree-selected span.fancytree-title, +span.fancytree-active span.fancytree-title { + background-color: #D4D4D4; // gray +} +// span.fancytree-selected span.fancytree-title { +// font-style: italic; +// } +// .fancytree-treefocus span.fancytree-selected span.fancytree-title, +.fancytree-treefocus span.fancytree-active span.fancytree-title { + color: white; + background-color: #3875D7; // blue +} + +// .fancytree-treefocus span.fancytree-selected span.fancytree-title{ +// color: white; +// background-color: #99DEFD; // blue +// } + +///******************************************************************************* +// * 'table' extension +// */ +//table.fancytree-ext-table { +// border-collapse: collapse; +// tbody { +// tr.fancytree-focused { +// background-color: #99DEFD; +// } +// tr.fancytree-active { +// background-color: royalblue; +// } +// // tr.fancytree-selected { +// // background-color: #99DEFD; +// // } +// } +//} +// +///******************************************************************************* +// * 'columnview' extension +// */ +// +//table.fancytree-ext-columnview tbody tr td { +// border: 1px solid gray; +//} +//table.fancytree-ext-columnview span.fancytree-node.fancytree-expanded { +// background-color: #ccc; +//} +//table.fancytree-ext-columnview span.fancytree-node.fancytree-active { +// background-color: royalblue; +//} diff --git a/plugins/55/indexmenu/scripts/fancytree/skin-typicons/vline-rtl.gif b/plugins/55/indexmenu/scripts/fancytree/skin-typicons/vline-rtl.gif Binary files differnew file mode 100644 index 0000000..0400cb3 --- /dev/null +++ b/plugins/55/indexmenu/scripts/fancytree/skin-typicons/vline-rtl.gif diff --git a/plugins/55/indexmenu/scripts/fancytree/skin-typicons/vline.gif b/plugins/55/indexmenu/scripts/fancytree/skin-typicons/vline.gif Binary files differnew file mode 100644 index 0000000..1b00ae5 --- /dev/null +++ b/plugins/55/indexmenu/scripts/fancytree/skin-typicons/vline.gif diff --git a/plugins/55/indexmenu/scripts/fancytree/skin-vista/icons-rtl.gif b/plugins/55/indexmenu/scripts/fancytree/skin-vista/icons-rtl.gif Binary files differnew file mode 100644 index 0000000..443e1e4 --- /dev/null +++ b/plugins/55/indexmenu/scripts/fancytree/skin-vista/icons-rtl.gif diff --git a/plugins/55/indexmenu/scripts/fancytree/skin-vista/icons.gif b/plugins/55/indexmenu/scripts/fancytree/skin-vista/icons.gif Binary files differnew file mode 100644 index 0000000..0097b1f --- /dev/null +++ b/plugins/55/indexmenu/scripts/fancytree/skin-vista/icons.gif diff --git a/plugins/55/indexmenu/scripts/fancytree/skin-vista/loading.gif b/plugins/55/indexmenu/scripts/fancytree/skin-vista/loading.gif Binary files differnew file mode 100644 index 0000000..ef88497 --- /dev/null +++ b/plugins/55/indexmenu/scripts/fancytree/skin-vista/loading.gif diff --git a/plugins/55/indexmenu/scripts/fancytree/skin-vista/skin-common.less b/plugins/55/indexmenu/scripts/fancytree/skin-vista/skin-common.less new file mode 100644 index 0000000..fc0da50 --- /dev/null +++ b/plugins/55/indexmenu/scripts/fancytree/skin-vista/skin-common.less @@ -0,0 +1,972 @@ +/******************************************************************************* + * Common Styles for Fancytree Skins. + * + * This section is automatically generated from the `skin-common.less` template. + * + * Copyright (c) 2008-2023, Martin Wendt (https://wwWendt.de) + * Released under the MIT license + * https://github.com/mar10/fancytree/wiki/LicenseInfo + * + * @version 2.38.3 + * @date 2023-02-01T20:52:50Z +******************************************************************************/ + +// Variables (defaults, may be overwritten by the including .less files) +@fancy-use-sprites: true; // false: suppress all background images (i.e. icons) +// @fancy-hide-connectors: true; // false: show vertical connector lines + +@fancy-level-indent: 16px; +@fancy-line-height: 16px; // height of a nodes selection bar including borders +@fancy-node-v-spacing: 1px; // gap between two node borders +@fancy-icon-width: 16px; +@fancy-icon-height: 16px; +@fancy-icon-spacing: 3px; // margin between icon/icon or icon/title +@fancy-icon-ofs-top: 0px; // extra vertical offset for expander, checkbox and icon +@fancy-title-ofs-top: 0px; // extra vertical offset for title +@fancy-node-border-width: 1px; +@fancy-node-border-radius: 0px; +@fancy-node-outline-width: 1px; + +// @fancy-line-ofs-top: (@fancy-line-height - @fancy-icon-height) / 2; + +// webpack uses /dist/skin-common.less as root path +// grunt-less uses /dist/skin-Xxx/ui.fancyree.less as root path +// So we define our theme LESS files for webpack compatibility, i.e. +// define the image path n every main LESS file instead of here. +// Prefix may be set to "", "/", "./", or any other value +// Note: this variable must be defined by the main LESS files: +// @fancy-image-prefix: ""; + +// Use 'url(...)' to link to the throbber image, or +// use data-uri(...)' to inline the data in css instead: +/* CHANGE use url, as less does not handel data-uri() correct. DokuWiki can eventually inline it */ + @fancy-loading-url: url("@{fancy-image-prefix}loading.gif"); +//@fancy-loading-url: data-uri("@{fancy-image-prefix}loading.gif"); + +// Set to `true` to use `data-uri(...)` instead of a `url(...)` link: +@fancy-inline-sprites: false; // data-uri() is not handle correct by phpless + +@fancy-font-size: 10pt; +@fancy-font-family: tahoma, arial, helvetica; +@fancy-font-color: black; +@fancy-font-color-dimm: #c0c0c0; +@fancy-font-error-color: red; + +//------------------------------------------------------------------------------ +// Mixins +//------------------------------------------------------------------------------ +.setBgPos(@x, @y, @cond:true) when (@cond) { + background-position: (@x * -@fancy-icon-width) (@y * -@fancy-icon-height); +} +.clearBgImage(@cond:true) when (@cond) { + background-image: none; +} +.setBgImageUrl(@url) when (@fancy-use-sprites) and not (@fancy-inline-sprites) { + background-image: url("@{fancy-image-prefix}@{url}"); +} +.setBgImageUrl(@url) when (@fancy-use-sprites) and (@fancy-inline-sprites) { + background-image: data-uri("@{fancy-image-prefix}@{url}"); +} +.useSprite(@x, @y) when (@fancy-use-sprites) { + .setBgPos(@x, @y); +} +.rounded-corners(@radius) { + -webkit-border-radius: @radius; + -moz-border-radius: @radius; + -ms-border-radius: @radius; + -o-border-radius: @radius; + border-radius: @radius; +} +.spanStyleMixin(@color, @bgcolor, @bordercolor) { + border-color: @bordercolor; + background: @bgcolor; + color: @color; +} +.spanStyleMixin(@color, @bgcolor, @bordercolor, @startColor, @stopColor) { + .spanStyleMixin(@color, @bgcolor, @bordercolor); + // @c-start: argb(@startColor); + // @c-end: argb(@stopColor); + background: -moz-linear-gradient( + top, + @startColor 0%, + @stopColor 100% + ); // FF3.6+ + background: -webkit-gradient( + linear, + left top, + left bottom, + color-stop(0%, @startColor), + color-stop(100%, @stopColor) + ); // Chrome,Safari4+ + background: -webkit-linear-gradient( + top, + @startColor 0%, + @stopColor 100% + ); // Chrome10+,Safari5.1+ + background: -o-linear-gradient( + top, + @startColor 0%, + @stopColor 100% + ); // Opera 11.10+ + background: -ms-linear-gradient( + top, + @startColor 0%, + @stopColor 100% + ); // IE10+ + background: linear-gradient( + to bottom, + @startColor 0%, + @stopColor 100% + ); // W3C + filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='@{startColor}', endColorstr='@{stopColor}',GradientType=0 ); // IE6-9 +} + +/*------------------------------------------------------------------------------ + * Helpers + *----------------------------------------------------------------------------*/ +// Redefine, in case jQuery-UI is not included +// .ui-helper-hidden, +.fancytree-helper-hidden { + display: none; +} +.fancytree-helper-indeterminate-cb { + // tri-state checkbox + color: #777; +} +.fancytree-helper-disabled { + color: @fancy-font-color-dimm; +} + +/* Helper to allow spinning loader icon with glyph-, ligature-, and SVG-icons. */ +/* CHANGE: renamed spin to spin-fancytree */ +.fancytree-helper-spin { + -webkit-animation: spin-fancytree 1000ms infinite linear; + animation: spin-fancytree 1000ms infinite linear; +} +/* CHANGE: commented because it is wrong prefixed by phpless +@-webkit-keyframes spin { + 0% { + -webkit-transform: rotate(0deg); + transform: rotate(0deg); + } + 100% { + -webkit-transform: rotate(359deg); + transform: rotate(359deg); + } +} +@keyframes spin { + 0% { + -webkit-transform: rotate(0deg); + transform: rotate(0deg); + } + 100% { + -webkit-transform: rotate(359deg); + transform: rotate(359deg); + } +} +*/ +/*------------------------------------------------------------------------------ + * Container and UL / LI + *----------------------------------------------------------------------------*/ + +ul.fancytree-container { + font-family: @fancy-font-family; + font-size: @fancy-font-size; + white-space: nowrap; + padding: 3px; + margin: 0; // DT issue 201 + //background-color: white; CHANGE + //border: 1px dotted gray; CHANGE + // overflow: auto; // ext-dnd5: otherwise this is always the scroll parent + // height: 100%; // DT issue 263, 470 + min-height: 0%; // #192 + position: relative; // #235 + ul { + padding: 0 0 0 @fancy-level-indent; + margin: 0; + } + ul > li:before { + // #538 + content: none; + } + li { + list-style-image: none; + list-style-position: outside; + list-style-type: none; + -moz-background-clip: border; + -moz-background-inline-policy: continuous; + -moz-background-origin: padding; + background-attachment: scroll; + background-color: transparent; + .setBgPos(0, 0); + background-repeat: repeat-y; + background-image: none; // no v-lines + + margin: 0; + // padding: 1px 0 0 0; // issue #246 + } + // Suppress lines for last child node + li.fancytree-lastsib { + background-image: none; + } +} + +// Style, when control is disabled +.ui-fancytree-disabled ul.fancytree-container { + opacity: 0.5; + // filter: alpha(opacity=50); // Yields a css warning + background-color: silver; +} + +ul.fancytree-connectors.fancytree-container { + li { + // Use 'data-uri(...)' to embed the image into CSS instead of linking to 'loading.gif': + /* CHANGE: phpless does not handle data-uri() correct */ + //background-image: data-uri("@{fancy-image-prefix}vline.gif"); + background-image: url("@{fancy-image-prefix}vline.gif"); + background-position: 0 0; + } +} + +// Suppress lines for last child node +ul.fancytree-container li.fancytree-lastsib, +// Suppress lines if level is fixed expanded (option minExpandLevel) +ul.fancytree-no-connector > li { + background-image: none; +} + +// Fix jQuery UI 'blind' animation for jQuery UI (#717) +li.fancytree-animating { + position: relative; +} + +/*------------------------------------------------------------------------------ + * Common icon definitions + *----------------------------------------------------------------------------*/ + +span.fancytree-empty, +span.fancytree-vline, +span.fancytree-expander, +span.fancytree-icon, +span.fancytree-checkbox, +// span.fancytree-radio, +span.fancytree-drag-helper-img, +#fancytree-drop-marker { + width: @fancy-icon-width; + height: @fancy-icon-height; + // display: -moz-inline-box; // @ FF 1+2 removed for issue 221 + // -moz-box-align: start; /* issue 221 */ + display: inline-block; // Required to make a span sizeable + vertical-align: top; + background-repeat: no-repeat; + // background-position: left; + .setBgImageUrl("icons.gif"); + .setBgPos(0, 0); +} +span.fancytree-icon, +span.fancytree-checkbox, +span.fancytree-expander, +// span.fancytree-radio, +span.fancytree-custom-icon { + margin-top: @fancy-icon-ofs-top; +} +/* Used by icon option: */ +span.fancytree-custom-icon { + width: @fancy-icon-width; + height: @fancy-icon-height; + display: inline-block; + margin-left: @fancy-icon-spacing; + .setBgPos(0, 0); +} +/* Used by 'icon' node option: */ +img.fancytree-icon { + width: @fancy-icon-width; + height: @fancy-icon-height; + margin-left: @fancy-icon-spacing; + margin-top: @fancy-icon-ofs-top; + vertical-align: top; + border-style: none; +} + +/*------------------------------------------------------------------------------ + * Expander icon + * + * Note: IE6 doesn't correctly evaluate multiples class names, + * so we create combined class names that can be used in the CSS. + * + * Prefix: fancytree-exp- + * 1st character: 'e': expanded, 'c': collapsed, 'n': no children + * 2nd character (optional): 'd': lazy (Delayed) + * 3rd character (optional): 'l': Last sibling + *----------------------------------------------------------------------------*/ + +span.fancytree-expander { + // .useSprite(0, 5); + cursor: pointer; +} +// span.fancytree-expander:hover { +// // .useSprite(1, 5); +// } + +// --- End nodes (use connectors instead of expanders) + +.fancytree-exp-n span.fancytree-expander, +.fancytree-exp-nl span.fancytree-expander { + // .clearBgImage( @fancy-hide-connectors ); + background-image: none; + cursor: default; +} +.fancytree-connectors { + .fancytree-exp-n span.fancytree-expander, + .fancytree-exp-nl span.fancytree-expander { + .setBgImageUrl("icons.gif"); + margin-top: 0; + } + .fancytree-exp-n span.fancytree-expander, // End-node, not last sibling + .fancytree-exp-n span.fancytree-expander:hover { + .useSprite(0, 4); + } + .fancytree-exp-nl span.fancytree-expander, // End-node, last sibling + .fancytree-exp-nl span.fancytree-expander:hover { + .useSprite(1, 4); + } +} + +// --- Collapsed + +.fancytree-exp-c span.fancytree-expander { + // Collapsed, not delayed, not last sibling + .useSprite(0, 5); +} +.fancytree-exp-c span.fancytree-expander:hover { + .useSprite(1, 5); +} +.fancytree-exp-cl span.fancytree-expander { + // Collapsed, not delayed, last sibling + .useSprite(0, 6); +} +.fancytree-exp-cl span.fancytree-expander:hover { + .useSprite(1, 6); +} +.fancytree-exp-cd span.fancytree-expander { + // Collapsed, delayed, not last sibling + .useSprite(4, 5); +} +.fancytree-exp-cd span.fancytree-expander:hover { + .useSprite(5, 5); +} +.fancytree-exp-cdl span.fancytree-expander { + // Collapsed, delayed, last sibling + .useSprite(4, 6); +} +.fancytree-exp-cdl span.fancytree-expander:hover { + .useSprite(5, 6); +} + +// --- Expanded + +.fancytree-exp-e span.fancytree-expander, // Expanded, not delayed, not last sibling +.fancytree-exp-ed span.fancytree-expander { + // Expanded, delayed, not last sibling + .useSprite(2, 5); +} +.fancytree-exp-e span.fancytree-expander:hover, +.fancytree-exp-ed span.fancytree-expander:hover { + .useSprite(3, 5); +} +.fancytree-exp-el span.fancytree-expander, // Expanded, not delayed, last sibling +.fancytree-exp-edl span.fancytree-expander { + // Expanded, delayed, last sibling + .useSprite(2, 6); +} +.fancytree-exp-el span.fancytree-expander:hover, +.fancytree-exp-edl span.fancytree-expander:hover { + .useSprite(3, 6); +} + +/* Fade out expanders, when container is not hovered or active */ +.fancytree-fade-expander { + span.fancytree-expander { + transition: opacity 1.5s; + opacity: 0; + } + &:hover span.fancytree-expander, + &.fancytree-treefocus span.fancytree-expander, + .fancytree-treefocus span.fancytree-expander, + [class*="fancytree-statusnode-"] span.fancytree-expander { + transition: opacity 0.6s; + opacity: 1; + } +} + +//// CHANGE: not used. +///*------------------------------------------------------------------------------ +// * Checkbox icon +// *----------------------------------------------------------------------------*/ +// +//span.fancytree-checkbox { +// margin-left: @fancy-icon-spacing; +// .useSprite(0, 2); +// &:hover { +// .useSprite(1, 2); +// } +// &.fancytree-radio { +// .useSprite(0, 3); +// } +// &.fancytree-radio:hover { +// .useSprite(1, 3); +// } +//} +//.fancytree-partsel span.fancytree-checkbox { +// .useSprite(4, 2); +// &:hover { +// .useSprite(5, 2); +// } +// &.fancytree-radio { +// .useSprite(4, 3); +// } +// &.fancytree-radio:hover { +// .useSprite(5, 3); +// } +//} +//// selected after partsel, so it takes precedence: +//.fancytree-selected span.fancytree-checkbox { +// .useSprite(2, 2); +// &:hover { +// .useSprite(3, 2); +// } +// &.fancytree-radio { +// .useSprite(2, 3); +// } +// &.fancytree-radio:hover { +// .useSprite(3, 3); +// } +//} +//// Unselectable is dimmed, without hover effects +//.fancytree-unselectable { +// span.fancytree-checkbox { +// opacity: 0.4; +// filter: alpha(opacity=40); +// } +// span.fancytree-checkbox:hover { +// .useSprite(0, 2); +// } +// span.fancytree-checkbox.fancytree-radio:hover { +// .useSprite(0, 3); +// } +// &.fancytree-partsel span.fancytree-checkbox:hover { +// .useSprite(4, 2); +// } +// &.fancytree-selected span.fancytree-checkbox:hover { +// .useSprite(2, 2); +// } +// &.fancytree-selected span.fancytree-checkbox.fancytree-radio:hover { +// .useSprite(2, 3); +// } +//} +// +//// Auto-hide checkboxes unless selected or hovered +//.fancytree-container.fancytree-checkbox-auto-hide { +// span.fancytree-checkbox { +// visibility: hidden; +// } +// .fancytree-node:hover span.fancytree-checkbox, +// tr:hover td span.fancytree-checkbox, +// .fancytree-node.fancytree-selected span.fancytree-checkbox, +// tr.fancytree-selected td span.fancytree-checkbox { +// visibility: unset; +// } +// &.fancytree-treefocus { +// .fancytree-node.fancytree-active span.fancytree-checkbox, +// tr.fancytree-active td span.fancytree-checkbox { +// visibility: unset; +// } +// } +//} + +/*------------------------------------------------------------------------------ + * Node type icon + * Note: IE6 doesn't correctly evaluate multiples class names, + * so we create combined class names that can be used in the CSS. + * + * Prefix: fancytree-ico- + * 1st character: 'e': expanded, 'c': collapsed + * 2nd character (optional): 'f': folder + *----------------------------------------------------------------------------*/ + +span.fancytree-icon { + // Default icon + margin-left: @fancy-icon-spacing; + .useSprite(0, 0); +} + +/* Documents */ +.fancytree-ico-c span.fancytree-icon { + // Collapsed folder (empty) + // .useSprite(0, 0); +} +.fancytree-ico-c span.fancytree-icon:hover { + .useSprite(1, 0); +} +.fancytree-has-children.fancytree-ico-c span.fancytree-icon { + // Collapsed folder (not empty) + .useSprite(2, 0); +} +.fancytree-has-children.fancytree-ico-c span.fancytree-icon:hover { + .useSprite(3, 0); +} +.fancytree-ico-e span.fancytree-icon { + // Expanded folder + .useSprite(4, 0); +} +.fancytree-ico-e span.fancytree-icon:hover { + .useSprite(5, 0); +} + +/* Folders */ +.fancytree-ico-cf span.fancytree-icon { + // Collapsed folder (empty) + .useSprite(0, 1); +} +.fancytree-ico-cf span.fancytree-icon:hover { + .useSprite(1, 1); +} +.fancytree-has-children.fancytree-ico-cf span.fancytree-icon { + // Collapsed folder (not empty) + .useSprite(2, 1); +} +.fancytree-has-children.fancytree-ico-cf span.fancytree-icon:hover { + .useSprite(3, 1); +} +.fancytree-ico-ef span.fancytree-icon { + // Expanded folder + .useSprite(4, 1); +} +.fancytree-ico-ef span.fancytree-icon:hover { + .useSprite(5, 1); +} + +// 'Loading' status overrides all others +.fancytree-loading span.fancytree-expander, +.fancytree-loading span.fancytree-expander:hover, +.fancytree-statusnode-loading span.fancytree-icon, +.fancytree-statusnode-loading span.fancytree-icon:hover, +span.fancytree-icon.fancytree-icon-loading { + background-image: @fancy-loading-url; + .useSprite(0, 0); +} + +/* Status node icons */ + +.fancytree-statusnode-error span.fancytree-icon, +.fancytree-statusnode-error span.fancytree-icon:hover { + .useSprite(0, 7); +} + +/*------------------------------------------------------------------------------ + * Node titles and highlighting + *----------------------------------------------------------------------------*/ + +span.fancytree-node { + /* See #117 */ + display: inherit; // #117, resolves to 'display: list-item;' for standard trees + width: 100%; + margin-top: @fancy-node-v-spacing; + min-height: @fancy-line-height; +} +span.fancytree-title { + color: @fancy-font-color; // inherit doesn't work on IE + cursor: pointer; + display: inline-block; // Better alignment, when title contains <br> + vertical-align: top; + min-height: @fancy-line-height; + padding: 0 3px 0 3px; // Otherwise italic font will be outside right bounds + margin: @fancy-title-ofs-top 0 0 @fancy-icon-spacing; + // margin: 0px; + // margin-top: @fancy-line-ofs-top; + // margin-left: @fancy-icon-spacing; + border: @fancy-node-border-width solid transparent; // avoid jumping, when a border is added on hover + .rounded-corners(@fancy-node-border-radius); + // outline: 0; // @ Firefox, prevent dotted border after click + // Set transparent border to prevent jumping when active node gets a border + // (we can do this, because this theme doesn't use vertical lines) + // border: 1px solid white; // Note: 'transparent' would not work in IE6 +} +span.fancytree-node.fancytree-error span.fancytree-title { + color: @fancy-font-error-color; +} + +//// CHANGE: not used. +///*------------------------------------------------------------------------------ +// * Drag'n'drop support +// *----------------------------------------------------------------------------*/ +///* ext-dnd5: */ +//span.fancytree-childcounter { +// color: #fff; +// background: #337ab7; // bootstrap blue +// border: 1px solid gray; +// border-radius: 10px; +// padding: 2px; +// text-align: center; +//} +// +///* ext-dnd: */ +//div.fancytree-drag-helper { +// span.fancytree-childcounter, +// span.fancytree-dnd-modifier { +// display: inline-block; +// color: #fff; +// background: #337ab7; // bootstrap blue +// border: 1px solid gray; +// min-width: 10px; +// // min-height: 16px; +// height: 10px; +// line-height: 1; +// vertical-align: baseline; +// border-radius: 10px; +// padding: 2px; +// text-align: center; +// font-size: 9px; +// } +// span.fancytree-childcounter { +// position: absolute; +// // left: 16px; +// top: -6px; +// right: -6px; +// } +// span.fancytree-dnd-modifier { +// background: #5cb85c; // bootstrap green +// border: none; +// // min-height: 16px; +// // font-size: 12px; +// font-weight: bolder; +// } +// &.fancytree-drop-accept { +// span.fancytree-drag-helper-img { +// .useSprite(2, 7); +// } +// } +// &.fancytree-drop-reject { +// span.fancytree-drag-helper-img { +// .useSprite(1, 7); +// } +// } +//} +// +///*** Drop marker icon *********************************************************/ +//#fancytree-drop-marker { +// width: 2 * @fancy-icon-width; // was 24px, but 32 should be correct +// position: absolute; +// .useSprite(0, 8); +// margin: 0; +// &.fancytree-drop-after, +// &.fancytree-drop-before { +// width: 4 * @fancy-icon-width; // 64px; +// .useSprite(0, 9); +// } +// &.fancytree-drop-copy { +// .useSprite(4, 8); +// } +// &.fancytree-drop-move { +// .useSprite(2, 8); +// } +//} +// +///*** Source node while dragging ***********************************************/ +// +//span.fancytree-drag-source { +// &.fancytree-drag-remove { +// // text-decoration: line-through; +// opacity: 0.15; +// } +//} +// +///*** Target node while dragging cursor is over it *****************************/ +// +//span.fancytree-drop-target { +// &.fancytree-drop-accept { +// // outline: 1px dotted #5cb85c; // bootstrap sucess +// } +//} +//span.fancytree-drop-reject { +// // outline: 1px dotted #d9534f; // boostrap warning +//} + +/*------------------------------------------------------------------------------ + * 'rtl' option + *----------------------------------------------------------------------------*/ + +.fancytree-container.fancytree-rtl { + .fancytree-title { + /*unicode-bidi: bidi-override;*/ /* optional: reverse title letters */ + } + span.fancytree-connector, + span.fancytree-expander, + span.fancytree-icon, + span.fancytree-drag-helper-img { + .setBgImageUrl("icons-rtl.gif"); + } + .fancytree-exp-n span.fancytree-expander, + .fancytree-exp-nl span.fancytree-expander { + background-image: none; + } + &.fancytree-connectors .fancytree-exp-n span.fancytree-expander, + &.fancytree-connectors .fancytree-exp-nl span.fancytree-expander { + .setBgImageUrl("icons-rtl.gif"); + } +} +ul.fancytree-container.fancytree-rtl { + ul { + padding: 0 16px 0 0; + } + &.fancytree-connectors li { + background-position: right 0; + background-image: url("@{fancy-image-prefix}vline-rtl.gif"); + } + // Suppress lines for last child node + li.fancytree-lastsib, + // Suppress lines if level is fixed expanded (option minExpandLevel) + &.fancytree-no-connector > li { + background-image: none; + } +} +#fancytree-drop-marker.fancytree-rtl { + .setBgImageUrl("icons-rtl.gif"); +} + +//// CHANGE: not used. +///*------------------------------------------------------------------------------ +// * 'table' extension +// *----------------------------------------------------------------------------*/ +// +//table.fancytree-ext-table { +// font-family: @fancy-font-family; +// font-size: @fancy-font-size; +// border-collapse: collapse; +// span.fancytree-node { +// display: inline-block; // #117 +// box-sizing: border-box; // #562 +// } +// td.fancytree-status-merged { +// text-align: center; +// // font-weight: bold; +// font-style: italic; +// // line-height: 100px; +// color: @fancy-font-color-dimm; +// } +// tr.fancytree-statusnode-error td.fancytree-status-merged { +// color: @fancy-font-error-color; +// } +// /* ext-ariagrid */ +// &.fancytree-ext-ariagrid.fancytree-cell-mode { +// > tbody > tr.fancytree-active > td { +// background-color: #eee; +// } +// > tbody > tr > td.fancytree-active-cell { +// background-color: #cbe8f6; +// } +// &.fancytree-cell-nav-mode > tbody > tr > td.fancytree-active-cell { +// background-color: #3875d7; +// } +// } +//} +// +///*------------------------------------------------------------------------------ +// * 'columnview' extension +// *----------------------------------------------------------------------------*/ +// +//table.fancytree-ext-columnview { +// // border-collapse: collapse; +// // width: 100%; +// tbody tr td { +// position: relative; +// border: 1px solid gray; +// vertical-align: top; +// overflow: auto; +// > ul { +// padding: 0; +// li { +// list-style-image: none; +// list-style-position: outside; +// list-style-type: none; +// -moz-background-clip: border; +// -moz-background-inline-policy: continuous; +// -moz-background-origin: padding; +// background-attachment: scroll; +// background-color: transparent; +// .setBgPos(0, 0); +// background-repeat: repeat-y; +// background-image: none; /* no v-lines */ +// +// margin: 0; +// // padding: 1px 0 0 0; // issue #246 +// } +// } +// } +// span.fancytree-node { +// position: relative; /* allow positioning of embedded spans */ +// display: inline-block; // #117 +// } +// span.fancytree-node.fancytree-expanded { +// background-color: #e0e0e0; +// } +// span.fancytree-node.fancytree-active { +// background-color: #cbe8f6; +// // background-color: royalblue; +// } +// .fancytree-has-children span.fancytree-cv-right { +// position: absolute; +// right: 3px; +// .useSprite(0, 5); +// &:hover { +// .useSprite(1, 5); +// } +// } +//} +// +///*------------------------------------------------------------------------------ +// * 'filter' extension +// *----------------------------------------------------------------------------*/ +// +//.fancytree-ext-filter-dimm { +// span.fancytree-node span.fancytree-title { +// color: @fancy-font-color-dimm; +// font-weight: lighter; +// } +// tr.fancytree-submatch span.fancytree-title, +// span.fancytree-node.fancytree-submatch span.fancytree-title { +// color: black; +// font-weight: normal; +// } +// tr.fancytree-match span.fancytree-title, +// span.fancytree-node.fancytree-match span.fancytree-title { +// color: black; +// font-weight: bold; +// } +//} +//.fancytree-ext-filter-hide { +// tr.fancytree-hide, +// span.fancytree-node.fancytree-hide { +// display: none; +// } +// tr.fancytree-submatch span.fancytree-title, +// span.fancytree-node.fancytree-submatch span.fancytree-title { +// color: @fancy-font-color-dimm; +// font-weight: lighter; +// } +// tr.fancytree-match span.fancytree-title, +// span.fancytree-node.fancytree-match span.fancytree-title { +// color: black; +// font-weight: normal; +// } +//} +///* Hide expanders if all child nodes are hidden by filter */ +//.fancytree-ext-filter-hide-expanders { +// tr.fancytree-match span.fancytree-expander, +// span.fancytree-node.fancytree-match span.fancytree-expander { +// visibility: hidden; +// } +// tr.fancytree-submatch span.fancytree-expander, +// span.fancytree-node.fancytree-submatch span.fancytree-expander { +// visibility: visible; +// } +//} +// +//.fancytree-ext-childcounter, +//.fancytree-ext-filter { +// // span.fancytree-title mark { +// // font-style: normal; +// // background-color: #ead61c; // yellow +// // border-radius: 3px; +// // } +// span.fancytree-icon, +// span.fancytree-custom-icon { +// position: relative; +// } +// span.fancytree-childcounter { +// color: #fff; +// background: #777; // #337ab7; // bootstrap blue +// border: 1px solid gray; +// position: absolute; +// top: -6px; +// right: -6px; +// min-width: 10px; +// height: 10px; +// line-height: 1; +// vertical-align: baseline; +// border-radius: 10px; +// padding: 2px; +// text-align: center; +// font-size: 9px; +// } +//} +///*------------------------------------------------------------------------------ +// * 'wide' extension +// *----------------------------------------------------------------------------*/ +// +//ul.fancytree-ext-wide { +// position: relative; +// min-width: 100%; +// z-index: 2; +// +// -webkit-box-sizing: border-box; +// -moz-box-sizing: border-box; +// box-sizing: border-box; +// +// span.fancytree-node > span { +// position: relative; +// z-index: 2; +// } +// span.fancytree-node span.fancytree-title { +// position: absolute; // Allow left: 0. Note: prevents smooth dropdown animation +// z-index: 1; // Behind expander and checkbox +// left: 0px; +// min-width: 100%; +// margin-left: 0; +// margin-right: 0; +// +// -webkit-box-sizing: border-box; +// -moz-box-sizing: border-box; +// box-sizing: border-box; +// } +//} +// +///*------------------------------------------------------------------------------ +// * 'fixed' extension +// *----------------------------------------------------------------------------*/ +// +//.fancytree-ext-fixed-wrapper { +// .fancytree-ext-fixed-hidden { +// display: none; +// } +// div.fancytree-ext-fixed-scroll-border-bottom { +// border-bottom: 3px solid rgba(0, 0, 0, 0.75); +// } +// div.fancytree-ext-fixed-scroll-border-right { +// border-right: 3px solid rgba(0, 0, 0, 0.75); +// } +// div.fancytree-ext-fixed-wrapper-tl { +// position: absolute; +// overflow: hidden; +// z-index: 3; +// top: 0px; +// left: 0px; +// } +// div.fancytree-ext-fixed-wrapper-tr { +// position: absolute; +// overflow: hidden; +// z-index: 2; +// top: 0px; +// } +// div.fancytree-ext-fixed-wrapper-bl { +// position: absolute; +// overflow: hidden; +// z-index: 2; +// left: 0px; +// } +// div.fancytree-ext-fixed-wrapper-br { +// position: absolute; +// overflow: scroll; +// z-index: 1; +// } +//} diff --git a/plugins/55/indexmenu/scripts/fancytree/skin-vista/ui.fancytree.css b/plugins/55/indexmenu/scripts/fancytree/skin-vista/ui.fancytree.css new file mode 100644 index 0000000..3920b04 --- /dev/null +++ b/plugins/55/indexmenu/scripts/fancytree/skin-vista/ui.fancytree.css @@ -0,0 +1,763 @@ +/*! + * Fancytree "Vista" skin. + * + * DON'T EDIT THE CSS FILE DIRECTLY, since it is automatically generated from + * the LESS templates. + */ +/* +both: + unselected background: #FCFCFC 'nearly white' + hover bar (unselected, inactive): #F8FCFE..#EFF9FE (border: #D8F0FA) 'very light blue' + active node: #F6FBFD..#D5EFFC (border: #99DEFD) 'light blue' + active node with hover: #F2F9FD..#C4E8FA (border: #B6E6FB) + +Tree view: + active node, tree inactive: #FAFAFB..#E5E5E5 (border: #D9D9D9) 'light gray, selected, but tree not active' + +List view: + selected bar: --> active bar + focus bar: active + border 1px dotted #090402 (inside the blue border) + + table left/right border: #EDEDED 'light gray' + */ +/******************************************************************************* + * Common Styles for Fancytree Skins. + * + * This section is automatically generated from the `skin-common.less` template. + * + * Copyright (c) 2008-2023, Martin Wendt (https://wwWendt.de) + * Released under the MIT license + * https://github.com/mar10/fancytree/wiki/LicenseInfo + * + * @version 2.38.3 + * @date 2023-02-01T20:52:50Z +******************************************************************************/ +/*------------------------------------------------------------------------------ + * Helpers + *----------------------------------------------------------------------------*/ +.fancytree-helper-hidden { + display: none; +} +.fancytree-helper-indeterminate-cb { + color: #777; +} +.fancytree-helper-disabled { + color: #c0c0c0; +} +/* Helper to allow spinning loader icon with glyph-, ligature-, and SVG-icons. */ +.fancytree-helper-spin { + -webkit-animation: spin 1000ms infinite linear; + animation: spin 1000ms infinite linear; +} +@-webkit-keyframes spin { + 0% { + -webkit-transform: rotate(0deg); + transform: rotate(0deg); + } + 100% { + -webkit-transform: rotate(359deg); + transform: rotate(359deg); + } +} +@keyframes spin { + 0% { + -webkit-transform: rotate(0deg); + transform: rotate(0deg); + } + 100% { + -webkit-transform: rotate(359deg); + transform: rotate(359deg); + } +} +/*------------------------------------------------------------------------------ + * Container and UL / LI + *----------------------------------------------------------------------------*/ +ul.fancytree-container { + font-family: tahoma, arial, helvetica; + font-size: 10pt; + white-space: nowrap; + padding: 3px; + margin: 0; + background-color: white; + border: 1px dotted gray; + min-height: 0%; + position: relative; +} +ul.fancytree-container ul { + padding: 0 0 0 16px; + margin: 0; +} +ul.fancytree-container ul > li:before { + content: none; +} +ul.fancytree-container li { + list-style-image: none; + list-style-position: outside; + list-style-type: none; + -moz-background-clip: border; + -moz-background-inline-policy: continuous; + -moz-background-origin: padding; + background-attachment: scroll; + background-color: transparent; + background-position: 0px 0px; + background-repeat: repeat-y; + background-image: none; + margin: 0; +} +ul.fancytree-container li.fancytree-lastsib { + background-image: none; +} +.ui-fancytree-disabled ul.fancytree-container { + opacity: 0.5; + background-color: silver; +} +ul.fancytree-connectors.fancytree-container li { + background-image: url("../skin-vista/vline.gif"); + background-position: 0 0; +} +ul.fancytree-container li.fancytree-lastsib, +ul.fancytree-no-connector > li { + background-image: none; +} +li.fancytree-animating { + position: relative; +} +/*------------------------------------------------------------------------------ + * Common icon definitions + *----------------------------------------------------------------------------*/ +span.fancytree-empty, +span.fancytree-vline, +span.fancytree-expander, +span.fancytree-icon, +span.fancytree-checkbox, +span.fancytree-drag-helper-img, +#fancytree-drop-marker { + width: 16px; + height: 16px; + display: inline-block; + vertical-align: top; + background-repeat: no-repeat; + background-image: url("../skin-vista/icons.gif"); + background-position: 0px 0px; +} +span.fancytree-icon, +span.fancytree-checkbox, +span.fancytree-expander, +span.fancytree-custom-icon { + margin-top: 0px; +} +/* Used by icon option: */ +span.fancytree-custom-icon { + width: 16px; + height: 16px; + display: inline-block; + margin-left: 3px; + background-position: 0px 0px; +} +/* Used by 'icon' node option: */ +img.fancytree-icon { + width: 16px; + height: 16px; + margin-left: 3px; + margin-top: 0px; + vertical-align: top; + border-style: none; +} +/*------------------------------------------------------------------------------ + * Expander icon + * + * Note: IE6 doesn't correctly evaluate multiples class names, + * so we create combined class names that can be used in the CSS. + * + * Prefix: fancytree-exp- + * 1st character: 'e': expanded, 'c': collapsed, 'n': no children + * 2nd character (optional): 'd': lazy (Delayed) + * 3rd character (optional): 'l': Last sibling + *----------------------------------------------------------------------------*/ +span.fancytree-expander { + cursor: pointer; +} +.fancytree-exp-n span.fancytree-expander, +.fancytree-exp-nl span.fancytree-expander { + background-image: none; + cursor: default; +} +.fancytree-connectors .fancytree-exp-n span.fancytree-expander, +.fancytree-connectors .fancytree-exp-nl span.fancytree-expander { + background-image: url("../skin-vista/icons.gif"); + margin-top: 0; +} +.fancytree-connectors .fancytree-exp-n span.fancytree-expander, +.fancytree-connectors .fancytree-exp-n span.fancytree-expander:hover { + background-position: 0px -64px; +} +.fancytree-connectors .fancytree-exp-nl span.fancytree-expander, +.fancytree-connectors .fancytree-exp-nl span.fancytree-expander:hover { + background-position: -16px -64px; +} +.fancytree-exp-c span.fancytree-expander { + background-position: 0px -80px; +} +.fancytree-exp-c span.fancytree-expander:hover { + background-position: -16px -80px; +} +.fancytree-exp-cl span.fancytree-expander { + background-position: 0px -96px; +} +.fancytree-exp-cl span.fancytree-expander:hover { + background-position: -16px -96px; +} +.fancytree-exp-cd span.fancytree-expander { + background-position: -64px -80px; +} +.fancytree-exp-cd span.fancytree-expander:hover { + background-position: -80px -80px; +} +.fancytree-exp-cdl span.fancytree-expander { + background-position: -64px -96px; +} +.fancytree-exp-cdl span.fancytree-expander:hover { + background-position: -80px -96px; +} +.fancytree-exp-e span.fancytree-expander, +.fancytree-exp-ed span.fancytree-expander { + background-position: -32px -80px; +} +.fancytree-exp-e span.fancytree-expander:hover, +.fancytree-exp-ed span.fancytree-expander:hover { + background-position: -48px -80px; +} +.fancytree-exp-el span.fancytree-expander, +.fancytree-exp-edl span.fancytree-expander { + background-position: -32px -96px; +} +.fancytree-exp-el span.fancytree-expander:hover, +.fancytree-exp-edl span.fancytree-expander:hover { + background-position: -48px -96px; +} +/* Fade out expanders, when container is not hovered or active */ +.fancytree-fade-expander span.fancytree-expander { + transition: opacity 1.5s; + opacity: 0; +} +.fancytree-fade-expander:hover span.fancytree-expander, +.fancytree-fade-expander.fancytree-treefocus span.fancytree-expander, +.fancytree-fade-expander .fancytree-treefocus span.fancytree-expander, +.fancytree-fade-expander [class*="fancytree-statusnode-"] span.fancytree-expander { + transition: opacity 0.6s; + opacity: 1; +} +/*------------------------------------------------------------------------------ + * Checkbox icon + *----------------------------------------------------------------------------*/ +span.fancytree-checkbox { + margin-left: 3px; + background-position: 0px -32px; +} +span.fancytree-checkbox:hover { + background-position: -16px -32px; +} +span.fancytree-checkbox.fancytree-radio { + background-position: 0px -48px; +} +span.fancytree-checkbox.fancytree-radio:hover { + background-position: -16px -48px; +} +.fancytree-partsel span.fancytree-checkbox { + background-position: -64px -32px; +} +.fancytree-partsel span.fancytree-checkbox:hover { + background-position: -80px -32px; +} +.fancytree-partsel span.fancytree-checkbox.fancytree-radio { + background-position: -64px -48px; +} +.fancytree-partsel span.fancytree-checkbox.fancytree-radio:hover { + background-position: -80px -48px; +} +.fancytree-selected span.fancytree-checkbox { + background-position: -32px -32px; +} +.fancytree-selected span.fancytree-checkbox:hover { + background-position: -48px -32px; +} +.fancytree-selected span.fancytree-checkbox.fancytree-radio { + background-position: -32px -48px; +} +.fancytree-selected span.fancytree-checkbox.fancytree-radio:hover { + background-position: -48px -48px; +} +.fancytree-unselectable span.fancytree-checkbox { + opacity: 0.4; + filter: alpha(opacity=40); +} +.fancytree-unselectable span.fancytree-checkbox:hover { + background-position: 0px -32px; +} +.fancytree-unselectable span.fancytree-checkbox.fancytree-radio:hover { + background-position: 0px -48px; +} +.fancytree-unselectable.fancytree-partsel span.fancytree-checkbox:hover { + background-position: -64px -32px; +} +.fancytree-unselectable.fancytree-selected span.fancytree-checkbox:hover { + background-position: -32px -32px; +} +.fancytree-unselectable.fancytree-selected span.fancytree-checkbox.fancytree-radio:hover { + background-position: -32px -48px; +} +.fancytree-container.fancytree-checkbox-auto-hide span.fancytree-checkbox { + visibility: hidden; +} +.fancytree-container.fancytree-checkbox-auto-hide .fancytree-node:hover span.fancytree-checkbox, +.fancytree-container.fancytree-checkbox-auto-hide tr:hover td span.fancytree-checkbox, +.fancytree-container.fancytree-checkbox-auto-hide .fancytree-node.fancytree-selected span.fancytree-checkbox, +.fancytree-container.fancytree-checkbox-auto-hide tr.fancytree-selected td span.fancytree-checkbox { + visibility: unset; +} +.fancytree-container.fancytree-checkbox-auto-hide.fancytree-treefocus .fancytree-node.fancytree-active span.fancytree-checkbox, +.fancytree-container.fancytree-checkbox-auto-hide.fancytree-treefocus tr.fancytree-active td span.fancytree-checkbox { + visibility: unset; +} +/*------------------------------------------------------------------------------ + * Node type icon + * Note: IE6 doesn't correctly evaluate multiples class names, + * so we create combined class names that can be used in the CSS. + * + * Prefix: fancytree-ico- + * 1st character: 'e': expanded, 'c': collapsed + * 2nd character (optional): 'f': folder + *----------------------------------------------------------------------------*/ +span.fancytree-icon { + margin-left: 3px; + background-position: 0px 0px; +} +/* Documents */ +.fancytree-ico-c span.fancytree-icon:hover { + background-position: -16px 0px; +} +.fancytree-has-children.fancytree-ico-c span.fancytree-icon { + background-position: -32px 0px; +} +.fancytree-has-children.fancytree-ico-c span.fancytree-icon:hover { + background-position: -48px 0px; +} +.fancytree-ico-e span.fancytree-icon { + background-position: -64px 0px; +} +.fancytree-ico-e span.fancytree-icon:hover { + background-position: -80px 0px; +} +/* Folders */ +.fancytree-ico-cf span.fancytree-icon { + background-position: 0px -16px; +} +.fancytree-ico-cf span.fancytree-icon:hover { + background-position: -16px -16px; +} +.fancytree-has-children.fancytree-ico-cf span.fancytree-icon { + background-position: -32px -16px; +} +.fancytree-has-children.fancytree-ico-cf span.fancytree-icon:hover { + background-position: -48px -16px; +} +.fancytree-ico-ef span.fancytree-icon { + background-position: -64px -16px; +} +.fancytree-ico-ef span.fancytree-icon:hover { + background-position: -80px -16px; +} +.fancytree-loading span.fancytree-expander, +.fancytree-loading span.fancytree-expander:hover, +.fancytree-statusnode-loading span.fancytree-icon, +.fancytree-statusnode-loading span.fancytree-icon:hover, +span.fancytree-icon.fancytree-icon-loading { + background-image: url("../skin-vista/loading.gif"); + background-position: 0px 0px; +} +/* Status node icons */ +.fancytree-statusnode-error span.fancytree-icon, +.fancytree-statusnode-error span.fancytree-icon:hover { + background-position: 0px -112px; +} +/*------------------------------------------------------------------------------ + * Node titles and highlighting + *----------------------------------------------------------------------------*/ +span.fancytree-node { + /* See #117 */ + display: inherit; + width: 100%; + margin-top: 1px; + min-height: 16px; +} +span.fancytree-title { + color: black; + cursor: pointer; + display: inline-block; + vertical-align: top; + min-height: 16px; + padding: 0 3px 0 3px; + margin: 0px 0 0 3px; + border: 1px solid transparent; + -webkit-border-radius: 0px; + -moz-border-radius: 0px; + -ms-border-radius: 0px; + -o-border-radius: 0px; + border-radius: 0px; +} +span.fancytree-node.fancytree-error span.fancytree-title { + color: red; +} +/*------------------------------------------------------------------------------ + * Drag'n'drop support + *----------------------------------------------------------------------------*/ +/* ext-dnd5: */ +span.fancytree-childcounter { + color: #fff; + background: #337ab7; + border: 1px solid gray; + border-radius: 10px; + padding: 2px; + text-align: center; +} +/* ext-dnd: */ +div.fancytree-drag-helper span.fancytree-childcounter, +div.fancytree-drag-helper span.fancytree-dnd-modifier { + display: inline-block; + color: #fff; + background: #337ab7; + border: 1px solid gray; + min-width: 10px; + height: 10px; + line-height: 1; + vertical-align: baseline; + border-radius: 10px; + padding: 2px; + text-align: center; + font-size: 9px; +} +div.fancytree-drag-helper span.fancytree-childcounter { + position: absolute; + top: -6px; + right: -6px; +} +div.fancytree-drag-helper span.fancytree-dnd-modifier { + background: #5cb85c; + border: none; + font-weight: bolder; +} +div.fancytree-drag-helper.fancytree-drop-accept span.fancytree-drag-helper-img { + background-position: -32px -112px; +} +div.fancytree-drag-helper.fancytree-drop-reject span.fancytree-drag-helper-img { + background-position: -16px -112px; +} +/*** Drop marker icon *********************************************************/ +#fancytree-drop-marker { + width: 32px; + position: absolute; + background-position: 0px -128px; + margin: 0; +} +#fancytree-drop-marker.fancytree-drop-after, +#fancytree-drop-marker.fancytree-drop-before { + width: 64px; + background-position: 0px -144px; +} +#fancytree-drop-marker.fancytree-drop-copy { + background-position: -64px -128px; +} +#fancytree-drop-marker.fancytree-drop-move { + background-position: -32px -128px; +} +/*** Source node while dragging ***********************************************/ +span.fancytree-drag-source.fancytree-drag-remove { + opacity: 0.15; +} +/*** Target node while dragging cursor is over it *****************************/ +/*------------------------------------------------------------------------------ + * 'rtl' option + *----------------------------------------------------------------------------*/ +.fancytree-container.fancytree-rtl .fancytree-title { + /*unicode-bidi: bidi-override;*/ + /* optional: reverse title letters */ +} +.fancytree-container.fancytree-rtl span.fancytree-connector, +.fancytree-container.fancytree-rtl span.fancytree-expander, +.fancytree-container.fancytree-rtl span.fancytree-icon, +.fancytree-container.fancytree-rtl span.fancytree-drag-helper-img { + background-image: url("../skin-vista/icons-rtl.gif"); +} +.fancytree-container.fancytree-rtl .fancytree-exp-n span.fancytree-expander, +.fancytree-container.fancytree-rtl .fancytree-exp-nl span.fancytree-expander { + background-image: none; +} +.fancytree-container.fancytree-rtl.fancytree-connectors .fancytree-exp-n span.fancytree-expander, +.fancytree-container.fancytree-rtl.fancytree-connectors .fancytree-exp-nl span.fancytree-expander { + background-image: url("../skin-vista/icons-rtl.gif"); +} +ul.fancytree-container.fancytree-rtl ul { + padding: 0 16px 0 0; +} +ul.fancytree-container.fancytree-rtl.fancytree-connectors li { + background-position: right 0; + background-image: url("../skin-vista/vline-rtl.gif"); +} +ul.fancytree-container.fancytree-rtl li.fancytree-lastsib, +ul.fancytree-container.fancytree-rtl.fancytree-no-connector > li { + background-image: none; +} +#fancytree-drop-marker.fancytree-rtl { + background-image: url("../skin-vista/icons-rtl.gif"); +} +/*------------------------------------------------------------------------------ + * 'table' extension + *----------------------------------------------------------------------------*/ +table.fancytree-ext-table { + font-family: tahoma, arial, helvetica; + font-size: 10pt; + border-collapse: collapse; + /* ext-ariagrid */ +} +table.fancytree-ext-table span.fancytree-node { + display: inline-block; + box-sizing: border-box; +} +table.fancytree-ext-table td.fancytree-status-merged { + text-align: center; + font-style: italic; + color: #c0c0c0; +} +table.fancytree-ext-table tr.fancytree-statusnode-error td.fancytree-status-merged { + color: red; +} +table.fancytree-ext-table.fancytree-ext-ariagrid.fancytree-cell-mode > tbody > tr.fancytree-active > td { + background-color: #eee; +} +table.fancytree-ext-table.fancytree-ext-ariagrid.fancytree-cell-mode > tbody > tr > td.fancytree-active-cell { + background-color: #cbe8f6; +} +table.fancytree-ext-table.fancytree-ext-ariagrid.fancytree-cell-mode.fancytree-cell-nav-mode > tbody > tr > td.fancytree-active-cell { + background-color: #3875d7; +} +/*------------------------------------------------------------------------------ + * 'columnview' extension + *----------------------------------------------------------------------------*/ +table.fancytree-ext-columnview tbody tr td { + position: relative; + border: 1px solid gray; + vertical-align: top; + overflow: auto; +} +table.fancytree-ext-columnview tbody tr td > ul { + padding: 0; +} +table.fancytree-ext-columnview tbody tr td > ul li { + list-style-image: none; + list-style-position: outside; + list-style-type: none; + -moz-background-clip: border; + -moz-background-inline-policy: continuous; + -moz-background-origin: padding; + background-attachment: scroll; + background-color: transparent; + background-position: 0px 0px; + background-repeat: repeat-y; + background-image: none; + /* no v-lines */ + margin: 0; +} +table.fancytree-ext-columnview span.fancytree-node { + position: relative; + /* allow positioning of embedded spans */ + display: inline-block; +} +table.fancytree-ext-columnview span.fancytree-node.fancytree-expanded { + background-color: #e0e0e0; +} +table.fancytree-ext-columnview span.fancytree-node.fancytree-active { + background-color: #cbe8f6; +} +table.fancytree-ext-columnview .fancytree-has-children span.fancytree-cv-right { + position: absolute; + right: 3px; + background-position: 0px -80px; +} +table.fancytree-ext-columnview .fancytree-has-children span.fancytree-cv-right:hover { + background-position: -16px -80px; +} +/*------------------------------------------------------------------------------ + * 'filter' extension + *----------------------------------------------------------------------------*/ +.fancytree-ext-filter-dimm span.fancytree-node span.fancytree-title { + color: #c0c0c0; + font-weight: lighter; +} +.fancytree-ext-filter-dimm tr.fancytree-submatch span.fancytree-title, +.fancytree-ext-filter-dimm span.fancytree-node.fancytree-submatch span.fancytree-title { + color: black; + font-weight: normal; +} +.fancytree-ext-filter-dimm tr.fancytree-match span.fancytree-title, +.fancytree-ext-filter-dimm span.fancytree-node.fancytree-match span.fancytree-title { + color: black; + font-weight: bold; +} +.fancytree-ext-filter-hide tr.fancytree-hide, +.fancytree-ext-filter-hide span.fancytree-node.fancytree-hide { + display: none; +} +.fancytree-ext-filter-hide tr.fancytree-submatch span.fancytree-title, +.fancytree-ext-filter-hide span.fancytree-node.fancytree-submatch span.fancytree-title { + color: #c0c0c0; + font-weight: lighter; +} +.fancytree-ext-filter-hide tr.fancytree-match span.fancytree-title, +.fancytree-ext-filter-hide span.fancytree-node.fancytree-match span.fancytree-title { + color: black; + font-weight: normal; +} +/* Hide expanders if all child nodes are hidden by filter */ +.fancytree-ext-filter-hide-expanders tr.fancytree-match span.fancytree-expander, +.fancytree-ext-filter-hide-expanders span.fancytree-node.fancytree-match span.fancytree-expander { + visibility: hidden; +} +.fancytree-ext-filter-hide-expanders tr.fancytree-submatch span.fancytree-expander, +.fancytree-ext-filter-hide-expanders span.fancytree-node.fancytree-submatch span.fancytree-expander { + visibility: visible; +} +.fancytree-ext-childcounter span.fancytree-icon, +.fancytree-ext-filter span.fancytree-icon, +.fancytree-ext-childcounter span.fancytree-custom-icon, +.fancytree-ext-filter span.fancytree-custom-icon { + position: relative; +} +.fancytree-ext-childcounter span.fancytree-childcounter, +.fancytree-ext-filter span.fancytree-childcounter { + color: #fff; + background: #777; + border: 1px solid gray; + position: absolute; + top: -6px; + right: -6px; + min-width: 10px; + height: 10px; + line-height: 1; + vertical-align: baseline; + border-radius: 10px; + padding: 2px; + text-align: center; + font-size: 9px; +} +/*------------------------------------------------------------------------------ + * 'wide' extension + *----------------------------------------------------------------------------*/ +ul.fancytree-ext-wide { + position: relative; + min-width: 100%; + z-index: 2; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; +} +ul.fancytree-ext-wide span.fancytree-node > span { + position: relative; + z-index: 2; +} +ul.fancytree-ext-wide span.fancytree-node span.fancytree-title { + position: absolute; + z-index: 1; + left: 0px; + min-width: 100%; + margin-left: 0; + margin-right: 0; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; +} +/*------------------------------------------------------------------------------ + * 'fixed' extension + *----------------------------------------------------------------------------*/ +.fancytree-ext-fixed-wrapper .fancytree-ext-fixed-hidden { + display: none; +} +.fancytree-ext-fixed-wrapper div.fancytree-ext-fixed-scroll-border-bottom { + border-bottom: 3px solid rgba(0, 0, 0, 0.75); +} +.fancytree-ext-fixed-wrapper div.fancytree-ext-fixed-scroll-border-right { + border-right: 3px solid rgba(0, 0, 0, 0.75); +} +.fancytree-ext-fixed-wrapper div.fancytree-ext-fixed-wrapper-tl { + position: absolute; + overflow: hidden; + z-index: 3; + top: 0px; + left: 0px; +} +.fancytree-ext-fixed-wrapper div.fancytree-ext-fixed-wrapper-tr { + position: absolute; + overflow: hidden; + z-index: 2; + top: 0px; +} +.fancytree-ext-fixed-wrapper div.fancytree-ext-fixed-wrapper-bl { + position: absolute; + overflow: hidden; + z-index: 2; + left: 0px; +} +.fancytree-ext-fixed-wrapper div.fancytree-ext-fixed-wrapper-br { + position: absolute; + overflow: scroll; + z-index: 1; +} +/******************************************************************************* + * Styles specific to this skin. + * + * This section is automatically generated from the `ui-fancytree.less` template. + ******************************************************************************/ +/******************************************************************************* + * Node titles + */ +span.fancytree-title { + border: 1px solid transparent; +} +span.fancytree-title:hover { + background-color: #F2F7FD; + border-color: #B8D6FB; +} +span.fancytree-focused span.fancytree-title { + background-color: #EFEBDE; + outline: 1px dotted gray; +} +span.fancytree-selected span.fancytree-title { + font-style: italic; +} +span.fancytree-active span.fancytree-title { + border: 1px solid #99DEFD; + background-color: #D8F0FA; +} +/******************************************************************************* + * 'table' extension + */ +table.fancytree-ext-table { + border-collapse: collapse; +} +table.fancytree-ext-table tbody tr.fancytree-focused { + background-color: #99DEFD; +} +table.fancytree-ext-table tbody tr.fancytree-active { + background-color: royalblue; +} +table.fancytree-ext-table tbody tr.fancytree-selected { + background-color: #99FDDE; +} +/******************************************************************************* + * 'columnview' extension + */ +table.fancytree-ext-columnview span.fancytree-node.fancytree-expanded { + background-color: #ccc; +} +table.fancytree-ext-columnview span.fancytree-node.fancytree-active { + background-color: royalblue; +} diff --git a/plugins/55/indexmenu/scripts/fancytree/skin-vista/ui.fancytree.less b/plugins/55/indexmenu/scripts/fancytree/skin-vista/ui.fancytree.less new file mode 100644 index 0000000..5d7ae40 --- /dev/null +++ b/plugins/55/indexmenu/scripts/fancytree/skin-vista/ui.fancytree.less @@ -0,0 +1,117 @@ +/*! + * Fancytree "Vista" skin. + * + * DON'T EDIT THE CSS FILE DIRECTLY, since it is automatically generated from + * the LESS templates. + */ + +/* +both: + unselected background: #FCFCFC 'nearly white' + hover bar (unselected, inactive): #F8FCFE..#EFF9FE (border: #D8F0FA) 'very light blue' + active node: #F6FBFD..#D5EFFC (border: #99DEFD) 'light blue' + active node with hover: #F2F9FD..#C4E8FA (border: #B6E6FB) + +Tree view: + active node, tree inactive: #FAFAFB..#E5E5E5 (border: #D9D9D9) 'light gray, selected, but tree not active' + +List view: + selected bar: --> active bar + focus bar: active + border 1px dotted #090402 (inside the blue border) + + table left/right border: #EDEDED 'light gray' + */ + +// Import common styles +@import "skin-common.less"; + + +/******************************************************************************* + * Styles specific to this skin. + * + * This section is automatically generated from the `ui-fancytree.less` template. + ******************************************************************************/ + + +// Override the variable after the import. +// NOTE: Variables are always resolved as the last definition, even if it is +// after where it is used. +@fancy-use-sprites: true; // false: suppress all background images (i.e. icons) + +@fancy-icon-width: 16px; +@fancy-icon-height: 16px; +@fancy-line-height: 16px; +@fancy-icon-spacing: 3px; + +// We need to define this variable here (not in skin-common.less) to make it +// work with grunt and webpack: +@fancy-image-prefix: "./skin-vista/"; + +// Use 'data-uri(...)' to embed the image into CSS instead of linking to 'loading.gif': +// @fancy-loading-url: data-uri("@{fancy-image-prefix}loading.gif"); +// Set to `true` to use `data-uri(...)` which will embed icons.gif into CSS +// instead of linking to that file: +// @fancy-inline-sprites: true; + +//default 10pt, which is used in a relative manner resulting in 13.3 in dokuwiki-template. +@fancy-font-size: 93%; + +/******************************************************************************* + * Node titles + */ +span.fancytree-title { + border: @fancy-node-border-width solid transparent; // avoid jumping, when a border is added on hover +} +span.fancytree-title:hover { + background-color: #F2F7FD; // light blue + border-color: #B8D6FB; // darker light blue +} +.fancytree-folder span.fancytree-title { + // font-weight: bold; +} +span.fancytree-focused span.fancytree-title { + background-color: #EFEBDE; // gray + outline: 1px dotted gray; +} +span.fancytree-has-children span.fancytree-title { + // font-style: oblique; +} +span.fancytree-expanded span.fancytree-title { +} +span.fancytree-selected span.fancytree-title { + font-style: italic; +} +span.fancytree-active span.fancytree-title { + border: 1px solid #99DEFD; + background-color: #D8F0FA; +} + +/******************************************************************************* + * 'table' extension + */ + +table.fancytree-ext-table { + border-collapse: collapse; + tbody tr.fancytree-focused { + background-color: #99DEFD; + } + tbody tr.fancytree-active { + background-color: royalblue; + } + tbody tr.fancytree-selected { + background-color: #99FDDE; + } +} + +/******************************************************************************* + * 'columnview' extension + */ + +table.fancytree-ext-columnview { + span.fancytree-node.fancytree-expanded { + background-color: #ccc; + } + span.fancytree-node.fancytree-active { + background-color: royalblue; + } +} diff --git a/plugins/55/indexmenu/scripts/fancytree/skin-vista/ui.fancytree.min.css b/plugins/55/indexmenu/scripts/fancytree/skin-vista/ui.fancytree.min.css new file mode 100644 index 0000000..232eb27 --- /dev/null +++ b/plugins/55/indexmenu/scripts/fancytree/skin-vista/ui.fancytree.min.css @@ -0,0 +1,6 @@ +/*! + * Fancytree "Vista" skin. + * + * DON'T EDIT THE CSS FILE DIRECTLY, since it is automatically generated from + * the LESS templates. + */.fancytree-helper-hidden{display:none}.fancytree-helper-indeterminate-cb{color:#777}.fancytree-helper-disabled{color:silver}.fancytree-helper-spin{-webkit-animation:spin 1s infinite linear;animation:spin 1s infinite linear}@-webkit-keyframes spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}ul.fancytree-container{font-family:tahoma,arial,helvetica;font-size:10pt;white-space:nowrap;padding:3px;margin:0;background-color:#fff;border:1px dotted gray;min-height:0;position:relative}ul.fancytree-container ul{padding:0 0 0 16px;margin:0}ul.fancytree-container ul>li:before{content:none}ul.fancytree-container li{list-style-image:none;list-style-position:outside;list-style-type:none;-moz-background-clip:border;-moz-background-inline-policy:continuous;-moz-background-origin:padding;background-attachment:scroll;background-color:transparent;background-position:0 0;background-repeat:repeat-y;background-image:none;margin:0}ul.fancytree-container li.fancytree-lastsib{background-image:none}.ui-fancytree-disabled ul.fancytree-container{opacity:.5;background-color:silver}ul.fancytree-connectors.fancytree-container li{background-image:url("../skin-vista/vline.gif");background-position:0 0}ul.fancytree-container li.fancytree-lastsib,ul.fancytree-no-connector>li{background-image:none}li.fancytree-animating{position:relative}#fancytree-drop-marker,span.fancytree-checkbox,span.fancytree-drag-helper-img,span.fancytree-empty,span.fancytree-expander,span.fancytree-icon,span.fancytree-vline{width:16px;height:16px;display:inline-block;vertical-align:top;background-repeat:no-repeat;background-image:url("../skin-vista/icons.gif");background-position:0 0}span.fancytree-checkbox,span.fancytree-custom-icon,span.fancytree-expander,span.fancytree-icon{margin-top:0}span.fancytree-custom-icon{width:16px;height:16px;display:inline-block;margin-left:3px;background-position:0 0}img.fancytree-icon{width:16px;height:16px;margin-left:3px;margin-top:0;vertical-align:top;border-style:none}span.fancytree-expander{cursor:pointer}.fancytree-exp-n span.fancytree-expander,.fancytree-exp-nl span.fancytree-expander{background-image:none;cursor:default}.fancytree-connectors .fancytree-exp-n span.fancytree-expander,.fancytree-connectors .fancytree-exp-nl span.fancytree-expander{background-image:url("../skin-vista/icons.gif");margin-top:0}.fancytree-connectors .fancytree-exp-n span.fancytree-expander,.fancytree-connectors .fancytree-exp-n span.fancytree-expander:hover{background-position:0 -64px}.fancytree-connectors .fancytree-exp-nl span.fancytree-expander,.fancytree-connectors .fancytree-exp-nl span.fancytree-expander:hover{background-position:-16px -64px}.fancytree-exp-c span.fancytree-expander{background-position:0 -80px}.fancytree-exp-c span.fancytree-expander:hover{background-position:-16px -80px}.fancytree-exp-cl span.fancytree-expander{background-position:0 -96px}.fancytree-exp-cl span.fancytree-expander:hover{background-position:-16px -96px}.fancytree-exp-cd span.fancytree-expander{background-position:-64px -80px}.fancytree-exp-cd span.fancytree-expander:hover{background-position:-80px -80px}.fancytree-exp-cdl span.fancytree-expander{background-position:-64px -96px}.fancytree-exp-cdl span.fancytree-expander:hover{background-position:-80px -96px}.fancytree-exp-e span.fancytree-expander,.fancytree-exp-ed span.fancytree-expander{background-position:-32px -80px}.fancytree-exp-e span.fancytree-expander:hover,.fancytree-exp-ed span.fancytree-expander:hover{background-position:-48px -80px}.fancytree-exp-edl span.fancytree-expander,.fancytree-exp-el span.fancytree-expander{background-position:-32px -96px}.fancytree-exp-edl span.fancytree-expander:hover,.fancytree-exp-el span.fancytree-expander:hover{background-position:-48px -96px}.fancytree-fade-expander span.fancytree-expander{transition:opacity 1.5s;opacity:0}.fancytree-fade-expander .fancytree-treefocus span.fancytree-expander,.fancytree-fade-expander [class*=fancytree-statusnode-] span.fancytree-expander,.fancytree-fade-expander.fancytree-treefocus span.fancytree-expander,.fancytree-fade-expander:hover span.fancytree-expander{transition:opacity .6s;opacity:1}span.fancytree-checkbox{margin-left:3px;background-position:0 -32px}span.fancytree-checkbox:hover{background-position:-16px -32px}span.fancytree-checkbox.fancytree-radio{background-position:0 -48px}span.fancytree-checkbox.fancytree-radio:hover{background-position:-16px -48px}.fancytree-partsel span.fancytree-checkbox{background-position:-64px -32px}.fancytree-partsel span.fancytree-checkbox:hover{background-position:-80px -32px}.fancytree-partsel span.fancytree-checkbox.fancytree-radio{background-position:-64px -48px}.fancytree-partsel span.fancytree-checkbox.fancytree-radio:hover{background-position:-80px -48px}.fancytree-selected span.fancytree-checkbox{background-position:-32px -32px}.fancytree-selected span.fancytree-checkbox:hover{background-position:-48px -32px}.fancytree-selected span.fancytree-checkbox.fancytree-radio{background-position:-32px -48px}.fancytree-selected span.fancytree-checkbox.fancytree-radio:hover{background-position:-48px -48px}.fancytree-unselectable span.fancytree-checkbox{opacity:.4}.fancytree-unselectable span.fancytree-checkbox:hover{background-position:0 -32px}.fancytree-unselectable span.fancytree-checkbox.fancytree-radio:hover{background-position:0 -48px}.fancytree-unselectable.fancytree-partsel span.fancytree-checkbox:hover{background-position:-64px -32px}.fancytree-unselectable.fancytree-selected span.fancytree-checkbox:hover{background-position:-32px -32px}.fancytree-unselectable.fancytree-selected span.fancytree-checkbox.fancytree-radio:hover{background-position:-32px -48px}.fancytree-container.fancytree-checkbox-auto-hide span.fancytree-checkbox{visibility:hidden}.fancytree-container.fancytree-checkbox-auto-hide .fancytree-node.fancytree-selected span.fancytree-checkbox,.fancytree-container.fancytree-checkbox-auto-hide .fancytree-node:hover span.fancytree-checkbox,.fancytree-container.fancytree-checkbox-auto-hide tr.fancytree-selected td span.fancytree-checkbox,.fancytree-container.fancytree-checkbox-auto-hide tr:hover td span.fancytree-checkbox{visibility:unset}.fancytree-container.fancytree-checkbox-auto-hide.fancytree-treefocus .fancytree-node.fancytree-active span.fancytree-checkbox,.fancytree-container.fancytree-checkbox-auto-hide.fancytree-treefocus tr.fancytree-active td span.fancytree-checkbox{visibility:unset}span.fancytree-icon{margin-left:3px;background-position:0 0}.fancytree-ico-c span.fancytree-icon:hover{background-position:-16px 0}.fancytree-has-children.fancytree-ico-c span.fancytree-icon{background-position:-32px 0}.fancytree-has-children.fancytree-ico-c span.fancytree-icon:hover{background-position:-48px 0}.fancytree-ico-e span.fancytree-icon{background-position:-64px 0}.fancytree-ico-e span.fancytree-icon:hover{background-position:-80px 0}.fancytree-ico-cf span.fancytree-icon{background-position:0 -16px}.fancytree-ico-cf span.fancytree-icon:hover{background-position:-16px -16px}.fancytree-has-children.fancytree-ico-cf span.fancytree-icon{background-position:-32px -16px}.fancytree-has-children.fancytree-ico-cf span.fancytree-icon:hover{background-position:-48px -16px}.fancytree-ico-ef span.fancytree-icon{background-position:-64px -16px}.fancytree-ico-ef span.fancytree-icon:hover{background-position:-80px -16px}.fancytree-loading span.fancytree-expander,.fancytree-loading span.fancytree-expander:hover,.fancytree-statusnode-loading span.fancytree-icon,.fancytree-statusnode-loading span.fancytree-icon:hover,span.fancytree-icon.fancytree-icon-loading{background-image:url("../skin-vista/loading.gif");background-position:0 0}.fancytree-statusnode-error span.fancytree-icon,.fancytree-statusnode-error span.fancytree-icon:hover{background-position:0 -112px}span.fancytree-node{display:inherit;width:100%;margin-top:1px;min-height:16px}span.fancytree-title{color:#000;cursor:pointer;display:inline-block;vertical-align:top;min-height:16px;padding:0 3px 0 3px;margin:0 0 0 3px;border:1px solid transparent;-webkit-border-radius:0px;-moz-border-radius:0;-ms-border-radius:0px;-o-border-radius:0;border-radius:0}span.fancytree-node.fancytree-error span.fancytree-title{color:red}span.fancytree-childcounter{color:#fff;background:#337ab7;border:1px solid gray;border-radius:10px;padding:2px;text-align:center}div.fancytree-drag-helper span.fancytree-childcounter,div.fancytree-drag-helper span.fancytree-dnd-modifier{display:inline-block;color:#fff;background:#337ab7;border:1px solid gray;min-width:10px;height:10px;line-height:1;vertical-align:baseline;border-radius:10px;padding:2px;text-align:center;font-size:9px}div.fancytree-drag-helper span.fancytree-childcounter{position:absolute;top:-6px;right:-6px}div.fancytree-drag-helper span.fancytree-dnd-modifier{background:#5cb85c;border:none;font-weight:bolder}div.fancytree-drag-helper.fancytree-drop-accept span.fancytree-drag-helper-img{background-position:-32px -112px}div.fancytree-drag-helper.fancytree-drop-reject span.fancytree-drag-helper-img{background-position:-16px -112px}#fancytree-drop-marker{width:32px;position:absolute;background-position:0 -128px;margin:0}#fancytree-drop-marker.fancytree-drop-after,#fancytree-drop-marker.fancytree-drop-before{width:64px;background-position:0 -144px}#fancytree-drop-marker.fancytree-drop-copy{background-position:-64px -128px}#fancytree-drop-marker.fancytree-drop-move{background-position:-32px -128px}span.fancytree-drag-source.fancytree-drag-remove{opacity:.15}.fancytree-container.fancytree-rtl span.fancytree-connector,.fancytree-container.fancytree-rtl span.fancytree-drag-helper-img,.fancytree-container.fancytree-rtl span.fancytree-expander,.fancytree-container.fancytree-rtl span.fancytree-icon{background-image:url("../skin-vista/icons-rtl.gif")}.fancytree-container.fancytree-rtl .fancytree-exp-n span.fancytree-expander,.fancytree-container.fancytree-rtl .fancytree-exp-nl span.fancytree-expander{background-image:none}.fancytree-container.fancytree-rtl.fancytree-connectors .fancytree-exp-n span.fancytree-expander,.fancytree-container.fancytree-rtl.fancytree-connectors .fancytree-exp-nl span.fancytree-expander{background-image:url("../skin-vista/icons-rtl.gif")}ul.fancytree-container.fancytree-rtl ul{padding:0 16px 0 0}ul.fancytree-container.fancytree-rtl.fancytree-connectors li{background-position:right 0;background-image:url("../skin-vista/vline-rtl.gif")}ul.fancytree-container.fancytree-rtl li.fancytree-lastsib,ul.fancytree-container.fancytree-rtl.fancytree-no-connector>li{background-image:none}#fancytree-drop-marker.fancytree-rtl{background-image:url("../skin-vista/icons-rtl.gif")}table.fancytree-ext-table{font-family:tahoma,arial,helvetica;font-size:10pt;border-collapse:collapse}table.fancytree-ext-table span.fancytree-node{display:inline-block;box-sizing:border-box}table.fancytree-ext-table td.fancytree-status-merged{text-align:center;font-style:italic;color:silver}table.fancytree-ext-table tr.fancytree-statusnode-error td.fancytree-status-merged{color:red}table.fancytree-ext-table.fancytree-ext-ariagrid.fancytree-cell-mode>tbody>tr.fancytree-active>td{background-color:#eee}table.fancytree-ext-table.fancytree-ext-ariagrid.fancytree-cell-mode>tbody>tr>td.fancytree-active-cell{background-color:#cbe8f6}table.fancytree-ext-table.fancytree-ext-ariagrid.fancytree-cell-mode.fancytree-cell-nav-mode>tbody>tr>td.fancytree-active-cell{background-color:#3875d7}table.fancytree-ext-columnview tbody tr td{position:relative;border:1px solid gray;vertical-align:top;overflow:auto}table.fancytree-ext-columnview tbody tr td>ul{padding:0}table.fancytree-ext-columnview tbody tr td>ul li{list-style-image:none;list-style-position:outside;list-style-type:none;-moz-background-clip:border;-moz-background-inline-policy:continuous;-moz-background-origin:padding;background-attachment:scroll;background-color:transparent;background-position:0 0;background-repeat:repeat-y;background-image:none;margin:0}table.fancytree-ext-columnview span.fancytree-node{position:relative;display:inline-block}table.fancytree-ext-columnview span.fancytree-node.fancytree-expanded{background-color:#e0e0e0}table.fancytree-ext-columnview span.fancytree-node.fancytree-active{background-color:#cbe8f6}table.fancytree-ext-columnview .fancytree-has-children span.fancytree-cv-right{position:absolute;right:3px;background-position:0 -80px}table.fancytree-ext-columnview .fancytree-has-children span.fancytree-cv-right:hover{background-position:-16px -80px}.fancytree-ext-filter-dimm span.fancytree-node span.fancytree-title{color:silver;font-weight:lighter}.fancytree-ext-filter-dimm span.fancytree-node.fancytree-submatch span.fancytree-title,.fancytree-ext-filter-dimm tr.fancytree-submatch span.fancytree-title{color:#000;font-weight:400}.fancytree-ext-filter-dimm span.fancytree-node.fancytree-match span.fancytree-title,.fancytree-ext-filter-dimm tr.fancytree-match span.fancytree-title{color:#000;font-weight:700}.fancytree-ext-filter-hide span.fancytree-node.fancytree-hide,.fancytree-ext-filter-hide tr.fancytree-hide{display:none}.fancytree-ext-filter-hide span.fancytree-node.fancytree-submatch span.fancytree-title,.fancytree-ext-filter-hide tr.fancytree-submatch span.fancytree-title{color:silver;font-weight:lighter}.fancytree-ext-filter-hide span.fancytree-node.fancytree-match span.fancytree-title,.fancytree-ext-filter-hide tr.fancytree-match span.fancytree-title{color:#000;font-weight:400}.fancytree-ext-filter-hide-expanders span.fancytree-node.fancytree-match span.fancytree-expander,.fancytree-ext-filter-hide-expanders tr.fancytree-match span.fancytree-expander{visibility:hidden}.fancytree-ext-filter-hide-expanders span.fancytree-node.fancytree-submatch span.fancytree-expander,.fancytree-ext-filter-hide-expanders tr.fancytree-submatch span.fancytree-expander{visibility:visible}.fancytree-ext-childcounter span.fancytree-custom-icon,.fancytree-ext-childcounter span.fancytree-icon,.fancytree-ext-filter span.fancytree-custom-icon,.fancytree-ext-filter span.fancytree-icon{position:relative}.fancytree-ext-childcounter span.fancytree-childcounter,.fancytree-ext-filter span.fancytree-childcounter{color:#fff;background:#777;border:1px solid gray;position:absolute;top:-6px;right:-6px;min-width:10px;height:10px;line-height:1;vertical-align:baseline;border-radius:10px;padding:2px;text-align:center;font-size:9px}ul.fancytree-ext-wide{position:relative;min-width:100%;z-index:2;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}ul.fancytree-ext-wide span.fancytree-node>span{position:relative;z-index:2}ul.fancytree-ext-wide span.fancytree-node span.fancytree-title{position:absolute;z-index:1;left:0;min-width:100%;margin-left:0;margin-right:0;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.fancytree-ext-fixed-wrapper .fancytree-ext-fixed-hidden{display:none}.fancytree-ext-fixed-wrapper div.fancytree-ext-fixed-scroll-border-bottom{border-bottom:3px solid rgba(0,0,0,.75)}.fancytree-ext-fixed-wrapper div.fancytree-ext-fixed-scroll-border-right{border-right:3px solid rgba(0,0,0,.75)}.fancytree-ext-fixed-wrapper div.fancytree-ext-fixed-wrapper-tl{position:absolute;overflow:hidden;z-index:3;top:0;left:0}.fancytree-ext-fixed-wrapper div.fancytree-ext-fixed-wrapper-tr{position:absolute;overflow:hidden;z-index:2;top:0}.fancytree-ext-fixed-wrapper div.fancytree-ext-fixed-wrapper-bl{position:absolute;overflow:hidden;z-index:2;left:0}.fancytree-ext-fixed-wrapper div.fancytree-ext-fixed-wrapper-br{position:absolute;overflow:scroll;z-index:1}span.fancytree-title{border:1px solid transparent}span.fancytree-title:hover{background-color:#f2f7fd;border-color:#b8d6fb}span.fancytree-focused span.fancytree-title{background-color:#efebde;outline:1px dotted gray}span.fancytree-selected span.fancytree-title{font-style:italic}span.fancytree-active span.fancytree-title{border:1px solid #99defd;background-color:#d8f0fa}table.fancytree-ext-table{border-collapse:collapse}table.fancytree-ext-table tbody tr.fancytree-focused{background-color:#99defd}table.fancytree-ext-table tbody tr.fancytree-active{background-color:#4169e1}table.fancytree-ext-table tbody tr.fancytree-selected{background-color:#99fdde}table.fancytree-ext-columnview span.fancytree-node.fancytree-expanded{background-color:#ccc}table.fancytree-ext-columnview span.fancytree-node.fancytree-active{background-color:#4169e1}
\ No newline at end of file diff --git a/plugins/55/indexmenu/scripts/fancytree/skin-vista/vline-rtl.gif b/plugins/55/indexmenu/scripts/fancytree/skin-vista/vline-rtl.gif Binary files differnew file mode 100644 index 0000000..f9b4232 --- /dev/null +++ b/plugins/55/indexmenu/scripts/fancytree/skin-vista/vline-rtl.gif diff --git a/plugins/55/indexmenu/scripts/fancytree/skin-vista/vline.gif b/plugins/55/indexmenu/scripts/fancytree/skin-vista/vline.gif Binary files differnew file mode 100644 index 0000000..f9b4232 --- /dev/null +++ b/plugins/55/indexmenu/scripts/fancytree/skin-vista/vline.gif diff --git a/plugins/55/indexmenu/scripts/fancytree/skin-win7/icons-rtl.gif b/plugins/55/indexmenu/scripts/fancytree/skin-win7/icons-rtl.gif Binary files differnew file mode 100644 index 0000000..443e1e4 --- /dev/null +++ b/plugins/55/indexmenu/scripts/fancytree/skin-win7/icons-rtl.gif diff --git a/plugins/55/indexmenu/scripts/fancytree/skin-win7/icons.gif b/plugins/55/indexmenu/scripts/fancytree/skin-win7/icons.gif Binary files differnew file mode 100644 index 0000000..0097b1f --- /dev/null +++ b/plugins/55/indexmenu/scripts/fancytree/skin-win7/icons.gif diff --git a/plugins/55/indexmenu/scripts/fancytree/skin-win7/loading.gif b/plugins/55/indexmenu/scripts/fancytree/skin-win7/loading.gif Binary files differnew file mode 100644 index 0000000..ef88497 --- /dev/null +++ b/plugins/55/indexmenu/scripts/fancytree/skin-win7/loading.gif diff --git a/plugins/55/indexmenu/scripts/fancytree/skin-win7/skin-common.less b/plugins/55/indexmenu/scripts/fancytree/skin-win7/skin-common.less new file mode 100644 index 0000000..fc0da50 --- /dev/null +++ b/plugins/55/indexmenu/scripts/fancytree/skin-win7/skin-common.less @@ -0,0 +1,972 @@ +/******************************************************************************* + * Common Styles for Fancytree Skins. + * + * This section is automatically generated from the `skin-common.less` template. + * + * Copyright (c) 2008-2023, Martin Wendt (https://wwWendt.de) + * Released under the MIT license + * https://github.com/mar10/fancytree/wiki/LicenseInfo + * + * @version 2.38.3 + * @date 2023-02-01T20:52:50Z +******************************************************************************/ + +// Variables (defaults, may be overwritten by the including .less files) +@fancy-use-sprites: true; // false: suppress all background images (i.e. icons) +// @fancy-hide-connectors: true; // false: show vertical connector lines + +@fancy-level-indent: 16px; +@fancy-line-height: 16px; // height of a nodes selection bar including borders +@fancy-node-v-spacing: 1px; // gap between two node borders +@fancy-icon-width: 16px; +@fancy-icon-height: 16px; +@fancy-icon-spacing: 3px; // margin between icon/icon or icon/title +@fancy-icon-ofs-top: 0px; // extra vertical offset for expander, checkbox and icon +@fancy-title-ofs-top: 0px; // extra vertical offset for title +@fancy-node-border-width: 1px; +@fancy-node-border-radius: 0px; +@fancy-node-outline-width: 1px; + +// @fancy-line-ofs-top: (@fancy-line-height - @fancy-icon-height) / 2; + +// webpack uses /dist/skin-common.less as root path +// grunt-less uses /dist/skin-Xxx/ui.fancyree.less as root path +// So we define our theme LESS files for webpack compatibility, i.e. +// define the image path n every main LESS file instead of here. +// Prefix may be set to "", "/", "./", or any other value +// Note: this variable must be defined by the main LESS files: +// @fancy-image-prefix: ""; + +// Use 'url(...)' to link to the throbber image, or +// use data-uri(...)' to inline the data in css instead: +/* CHANGE use url, as less does not handel data-uri() correct. DokuWiki can eventually inline it */ + @fancy-loading-url: url("@{fancy-image-prefix}loading.gif"); +//@fancy-loading-url: data-uri("@{fancy-image-prefix}loading.gif"); + +// Set to `true` to use `data-uri(...)` instead of a `url(...)` link: +@fancy-inline-sprites: false; // data-uri() is not handle correct by phpless + +@fancy-font-size: 10pt; +@fancy-font-family: tahoma, arial, helvetica; +@fancy-font-color: black; +@fancy-font-color-dimm: #c0c0c0; +@fancy-font-error-color: red; + +//------------------------------------------------------------------------------ +// Mixins +//------------------------------------------------------------------------------ +.setBgPos(@x, @y, @cond:true) when (@cond) { + background-position: (@x * -@fancy-icon-width) (@y * -@fancy-icon-height); +} +.clearBgImage(@cond:true) when (@cond) { + background-image: none; +} +.setBgImageUrl(@url) when (@fancy-use-sprites) and not (@fancy-inline-sprites) { + background-image: url("@{fancy-image-prefix}@{url}"); +} +.setBgImageUrl(@url) when (@fancy-use-sprites) and (@fancy-inline-sprites) { + background-image: data-uri("@{fancy-image-prefix}@{url}"); +} +.useSprite(@x, @y) when (@fancy-use-sprites) { + .setBgPos(@x, @y); +} +.rounded-corners(@radius) { + -webkit-border-radius: @radius; + -moz-border-radius: @radius; + -ms-border-radius: @radius; + -o-border-radius: @radius; + border-radius: @radius; +} +.spanStyleMixin(@color, @bgcolor, @bordercolor) { + border-color: @bordercolor; + background: @bgcolor; + color: @color; +} +.spanStyleMixin(@color, @bgcolor, @bordercolor, @startColor, @stopColor) { + .spanStyleMixin(@color, @bgcolor, @bordercolor); + // @c-start: argb(@startColor); + // @c-end: argb(@stopColor); + background: -moz-linear-gradient( + top, + @startColor 0%, + @stopColor 100% + ); // FF3.6+ + background: -webkit-gradient( + linear, + left top, + left bottom, + color-stop(0%, @startColor), + color-stop(100%, @stopColor) + ); // Chrome,Safari4+ + background: -webkit-linear-gradient( + top, + @startColor 0%, + @stopColor 100% + ); // Chrome10+,Safari5.1+ + background: -o-linear-gradient( + top, + @startColor 0%, + @stopColor 100% + ); // Opera 11.10+ + background: -ms-linear-gradient( + top, + @startColor 0%, + @stopColor 100% + ); // IE10+ + background: linear-gradient( + to bottom, + @startColor 0%, + @stopColor 100% + ); // W3C + filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='@{startColor}', endColorstr='@{stopColor}',GradientType=0 ); // IE6-9 +} + +/*------------------------------------------------------------------------------ + * Helpers + *----------------------------------------------------------------------------*/ +// Redefine, in case jQuery-UI is not included +// .ui-helper-hidden, +.fancytree-helper-hidden { + display: none; +} +.fancytree-helper-indeterminate-cb { + // tri-state checkbox + color: #777; +} +.fancytree-helper-disabled { + color: @fancy-font-color-dimm; +} + +/* Helper to allow spinning loader icon with glyph-, ligature-, and SVG-icons. */ +/* CHANGE: renamed spin to spin-fancytree */ +.fancytree-helper-spin { + -webkit-animation: spin-fancytree 1000ms infinite linear; + animation: spin-fancytree 1000ms infinite linear; +} +/* CHANGE: commented because it is wrong prefixed by phpless +@-webkit-keyframes spin { + 0% { + -webkit-transform: rotate(0deg); + transform: rotate(0deg); + } + 100% { + -webkit-transform: rotate(359deg); + transform: rotate(359deg); + } +} +@keyframes spin { + 0% { + -webkit-transform: rotate(0deg); + transform: rotate(0deg); + } + 100% { + -webkit-transform: rotate(359deg); + transform: rotate(359deg); + } +} +*/ +/*------------------------------------------------------------------------------ + * Container and UL / LI + *----------------------------------------------------------------------------*/ + +ul.fancytree-container { + font-family: @fancy-font-family; + font-size: @fancy-font-size; + white-space: nowrap; + padding: 3px; + margin: 0; // DT issue 201 + //background-color: white; CHANGE + //border: 1px dotted gray; CHANGE + // overflow: auto; // ext-dnd5: otherwise this is always the scroll parent + // height: 100%; // DT issue 263, 470 + min-height: 0%; // #192 + position: relative; // #235 + ul { + padding: 0 0 0 @fancy-level-indent; + margin: 0; + } + ul > li:before { + // #538 + content: none; + } + li { + list-style-image: none; + list-style-position: outside; + list-style-type: none; + -moz-background-clip: border; + -moz-background-inline-policy: continuous; + -moz-background-origin: padding; + background-attachment: scroll; + background-color: transparent; + .setBgPos(0, 0); + background-repeat: repeat-y; + background-image: none; // no v-lines + + margin: 0; + // padding: 1px 0 0 0; // issue #246 + } + // Suppress lines for last child node + li.fancytree-lastsib { + background-image: none; + } +} + +// Style, when control is disabled +.ui-fancytree-disabled ul.fancytree-container { + opacity: 0.5; + // filter: alpha(opacity=50); // Yields a css warning + background-color: silver; +} + +ul.fancytree-connectors.fancytree-container { + li { + // Use 'data-uri(...)' to embed the image into CSS instead of linking to 'loading.gif': + /* CHANGE: phpless does not handle data-uri() correct */ + //background-image: data-uri("@{fancy-image-prefix}vline.gif"); + background-image: url("@{fancy-image-prefix}vline.gif"); + background-position: 0 0; + } +} + +// Suppress lines for last child node +ul.fancytree-container li.fancytree-lastsib, +// Suppress lines if level is fixed expanded (option minExpandLevel) +ul.fancytree-no-connector > li { + background-image: none; +} + +// Fix jQuery UI 'blind' animation for jQuery UI (#717) +li.fancytree-animating { + position: relative; +} + +/*------------------------------------------------------------------------------ + * Common icon definitions + *----------------------------------------------------------------------------*/ + +span.fancytree-empty, +span.fancytree-vline, +span.fancytree-expander, +span.fancytree-icon, +span.fancytree-checkbox, +// span.fancytree-radio, +span.fancytree-drag-helper-img, +#fancytree-drop-marker { + width: @fancy-icon-width; + height: @fancy-icon-height; + // display: -moz-inline-box; // @ FF 1+2 removed for issue 221 + // -moz-box-align: start; /* issue 221 */ + display: inline-block; // Required to make a span sizeable + vertical-align: top; + background-repeat: no-repeat; + // background-position: left; + .setBgImageUrl("icons.gif"); + .setBgPos(0, 0); +} +span.fancytree-icon, +span.fancytree-checkbox, +span.fancytree-expander, +// span.fancytree-radio, +span.fancytree-custom-icon { + margin-top: @fancy-icon-ofs-top; +} +/* Used by icon option: */ +span.fancytree-custom-icon { + width: @fancy-icon-width; + height: @fancy-icon-height; + display: inline-block; + margin-left: @fancy-icon-spacing; + .setBgPos(0, 0); +} +/* Used by 'icon' node option: */ +img.fancytree-icon { + width: @fancy-icon-width; + height: @fancy-icon-height; + margin-left: @fancy-icon-spacing; + margin-top: @fancy-icon-ofs-top; + vertical-align: top; + border-style: none; +} + +/*------------------------------------------------------------------------------ + * Expander icon + * + * Note: IE6 doesn't correctly evaluate multiples class names, + * so we create combined class names that can be used in the CSS. + * + * Prefix: fancytree-exp- + * 1st character: 'e': expanded, 'c': collapsed, 'n': no children + * 2nd character (optional): 'd': lazy (Delayed) + * 3rd character (optional): 'l': Last sibling + *----------------------------------------------------------------------------*/ + +span.fancytree-expander { + // .useSprite(0, 5); + cursor: pointer; +} +// span.fancytree-expander:hover { +// // .useSprite(1, 5); +// } + +// --- End nodes (use connectors instead of expanders) + +.fancytree-exp-n span.fancytree-expander, +.fancytree-exp-nl span.fancytree-expander { + // .clearBgImage( @fancy-hide-connectors ); + background-image: none; + cursor: default; +} +.fancytree-connectors { + .fancytree-exp-n span.fancytree-expander, + .fancytree-exp-nl span.fancytree-expander { + .setBgImageUrl("icons.gif"); + margin-top: 0; + } + .fancytree-exp-n span.fancytree-expander, // End-node, not last sibling + .fancytree-exp-n span.fancytree-expander:hover { + .useSprite(0, 4); + } + .fancytree-exp-nl span.fancytree-expander, // End-node, last sibling + .fancytree-exp-nl span.fancytree-expander:hover { + .useSprite(1, 4); + } +} + +// --- Collapsed + +.fancytree-exp-c span.fancytree-expander { + // Collapsed, not delayed, not last sibling + .useSprite(0, 5); +} +.fancytree-exp-c span.fancytree-expander:hover { + .useSprite(1, 5); +} +.fancytree-exp-cl span.fancytree-expander { + // Collapsed, not delayed, last sibling + .useSprite(0, 6); +} +.fancytree-exp-cl span.fancytree-expander:hover { + .useSprite(1, 6); +} +.fancytree-exp-cd span.fancytree-expander { + // Collapsed, delayed, not last sibling + .useSprite(4, 5); +} +.fancytree-exp-cd span.fancytree-expander:hover { + .useSprite(5, 5); +} +.fancytree-exp-cdl span.fancytree-expander { + // Collapsed, delayed, last sibling + .useSprite(4, 6); +} +.fancytree-exp-cdl span.fancytree-expander:hover { + .useSprite(5, 6); +} + +// --- Expanded + +.fancytree-exp-e span.fancytree-expander, // Expanded, not delayed, not last sibling +.fancytree-exp-ed span.fancytree-expander { + // Expanded, delayed, not last sibling + .useSprite(2, 5); +} +.fancytree-exp-e span.fancytree-expander:hover, +.fancytree-exp-ed span.fancytree-expander:hover { + .useSprite(3, 5); +} +.fancytree-exp-el span.fancytree-expander, // Expanded, not delayed, last sibling +.fancytree-exp-edl span.fancytree-expander { + // Expanded, delayed, last sibling + .useSprite(2, 6); +} +.fancytree-exp-el span.fancytree-expander:hover, +.fancytree-exp-edl span.fancytree-expander:hover { + .useSprite(3, 6); +} + +/* Fade out expanders, when container is not hovered or active */ +.fancytree-fade-expander { + span.fancytree-expander { + transition: opacity 1.5s; + opacity: 0; + } + &:hover span.fancytree-expander, + &.fancytree-treefocus span.fancytree-expander, + .fancytree-treefocus span.fancytree-expander, + [class*="fancytree-statusnode-"] span.fancytree-expander { + transition: opacity 0.6s; + opacity: 1; + } +} + +//// CHANGE: not used. +///*------------------------------------------------------------------------------ +// * Checkbox icon +// *----------------------------------------------------------------------------*/ +// +//span.fancytree-checkbox { +// margin-left: @fancy-icon-spacing; +// .useSprite(0, 2); +// &:hover { +// .useSprite(1, 2); +// } +// &.fancytree-radio { +// .useSprite(0, 3); +// } +// &.fancytree-radio:hover { +// .useSprite(1, 3); +// } +//} +//.fancytree-partsel span.fancytree-checkbox { +// .useSprite(4, 2); +// &:hover { +// .useSprite(5, 2); +// } +// &.fancytree-radio { +// .useSprite(4, 3); +// } +// &.fancytree-radio:hover { +// .useSprite(5, 3); +// } +//} +//// selected after partsel, so it takes precedence: +//.fancytree-selected span.fancytree-checkbox { +// .useSprite(2, 2); +// &:hover { +// .useSprite(3, 2); +// } +// &.fancytree-radio { +// .useSprite(2, 3); +// } +// &.fancytree-radio:hover { +// .useSprite(3, 3); +// } +//} +//// Unselectable is dimmed, without hover effects +//.fancytree-unselectable { +// span.fancytree-checkbox { +// opacity: 0.4; +// filter: alpha(opacity=40); +// } +// span.fancytree-checkbox:hover { +// .useSprite(0, 2); +// } +// span.fancytree-checkbox.fancytree-radio:hover { +// .useSprite(0, 3); +// } +// &.fancytree-partsel span.fancytree-checkbox:hover { +// .useSprite(4, 2); +// } +// &.fancytree-selected span.fancytree-checkbox:hover { +// .useSprite(2, 2); +// } +// &.fancytree-selected span.fancytree-checkbox.fancytree-radio:hover { +// .useSprite(2, 3); +// } +//} +// +//// Auto-hide checkboxes unless selected or hovered +//.fancytree-container.fancytree-checkbox-auto-hide { +// span.fancytree-checkbox { +// visibility: hidden; +// } +// .fancytree-node:hover span.fancytree-checkbox, +// tr:hover td span.fancytree-checkbox, +// .fancytree-node.fancytree-selected span.fancytree-checkbox, +// tr.fancytree-selected td span.fancytree-checkbox { +// visibility: unset; +// } +// &.fancytree-treefocus { +// .fancytree-node.fancytree-active span.fancytree-checkbox, +// tr.fancytree-active td span.fancytree-checkbox { +// visibility: unset; +// } +// } +//} + +/*------------------------------------------------------------------------------ + * Node type icon + * Note: IE6 doesn't correctly evaluate multiples class names, + * so we create combined class names that can be used in the CSS. + * + * Prefix: fancytree-ico- + * 1st character: 'e': expanded, 'c': collapsed + * 2nd character (optional): 'f': folder + *----------------------------------------------------------------------------*/ + +span.fancytree-icon { + // Default icon + margin-left: @fancy-icon-spacing; + .useSprite(0, 0); +} + +/* Documents */ +.fancytree-ico-c span.fancytree-icon { + // Collapsed folder (empty) + // .useSprite(0, 0); +} +.fancytree-ico-c span.fancytree-icon:hover { + .useSprite(1, 0); +} +.fancytree-has-children.fancytree-ico-c span.fancytree-icon { + // Collapsed folder (not empty) + .useSprite(2, 0); +} +.fancytree-has-children.fancytree-ico-c span.fancytree-icon:hover { + .useSprite(3, 0); +} +.fancytree-ico-e span.fancytree-icon { + // Expanded folder + .useSprite(4, 0); +} +.fancytree-ico-e span.fancytree-icon:hover { + .useSprite(5, 0); +} + +/* Folders */ +.fancytree-ico-cf span.fancytree-icon { + // Collapsed folder (empty) + .useSprite(0, 1); +} +.fancytree-ico-cf span.fancytree-icon:hover { + .useSprite(1, 1); +} +.fancytree-has-children.fancytree-ico-cf span.fancytree-icon { + // Collapsed folder (not empty) + .useSprite(2, 1); +} +.fancytree-has-children.fancytree-ico-cf span.fancytree-icon:hover { + .useSprite(3, 1); +} +.fancytree-ico-ef span.fancytree-icon { + // Expanded folder + .useSprite(4, 1); +} +.fancytree-ico-ef span.fancytree-icon:hover { + .useSprite(5, 1); +} + +// 'Loading' status overrides all others +.fancytree-loading span.fancytree-expander, +.fancytree-loading span.fancytree-expander:hover, +.fancytree-statusnode-loading span.fancytree-icon, +.fancytree-statusnode-loading span.fancytree-icon:hover, +span.fancytree-icon.fancytree-icon-loading { + background-image: @fancy-loading-url; + .useSprite(0, 0); +} + +/* Status node icons */ + +.fancytree-statusnode-error span.fancytree-icon, +.fancytree-statusnode-error span.fancytree-icon:hover { + .useSprite(0, 7); +} + +/*------------------------------------------------------------------------------ + * Node titles and highlighting + *----------------------------------------------------------------------------*/ + +span.fancytree-node { + /* See #117 */ + display: inherit; // #117, resolves to 'display: list-item;' for standard trees + width: 100%; + margin-top: @fancy-node-v-spacing; + min-height: @fancy-line-height; +} +span.fancytree-title { + color: @fancy-font-color; // inherit doesn't work on IE + cursor: pointer; + display: inline-block; // Better alignment, when title contains <br> + vertical-align: top; + min-height: @fancy-line-height; + padding: 0 3px 0 3px; // Otherwise italic font will be outside right bounds + margin: @fancy-title-ofs-top 0 0 @fancy-icon-spacing; + // margin: 0px; + // margin-top: @fancy-line-ofs-top; + // margin-left: @fancy-icon-spacing; + border: @fancy-node-border-width solid transparent; // avoid jumping, when a border is added on hover + .rounded-corners(@fancy-node-border-radius); + // outline: 0; // @ Firefox, prevent dotted border after click + // Set transparent border to prevent jumping when active node gets a border + // (we can do this, because this theme doesn't use vertical lines) + // border: 1px solid white; // Note: 'transparent' would not work in IE6 +} +span.fancytree-node.fancytree-error span.fancytree-title { + color: @fancy-font-error-color; +} + +//// CHANGE: not used. +///*------------------------------------------------------------------------------ +// * Drag'n'drop support +// *----------------------------------------------------------------------------*/ +///* ext-dnd5: */ +//span.fancytree-childcounter { +// color: #fff; +// background: #337ab7; // bootstrap blue +// border: 1px solid gray; +// border-radius: 10px; +// padding: 2px; +// text-align: center; +//} +// +///* ext-dnd: */ +//div.fancytree-drag-helper { +// span.fancytree-childcounter, +// span.fancytree-dnd-modifier { +// display: inline-block; +// color: #fff; +// background: #337ab7; // bootstrap blue +// border: 1px solid gray; +// min-width: 10px; +// // min-height: 16px; +// height: 10px; +// line-height: 1; +// vertical-align: baseline; +// border-radius: 10px; +// padding: 2px; +// text-align: center; +// font-size: 9px; +// } +// span.fancytree-childcounter { +// position: absolute; +// // left: 16px; +// top: -6px; +// right: -6px; +// } +// span.fancytree-dnd-modifier { +// background: #5cb85c; // bootstrap green +// border: none; +// // min-height: 16px; +// // font-size: 12px; +// font-weight: bolder; +// } +// &.fancytree-drop-accept { +// span.fancytree-drag-helper-img { +// .useSprite(2, 7); +// } +// } +// &.fancytree-drop-reject { +// span.fancytree-drag-helper-img { +// .useSprite(1, 7); +// } +// } +//} +// +///*** Drop marker icon *********************************************************/ +//#fancytree-drop-marker { +// width: 2 * @fancy-icon-width; // was 24px, but 32 should be correct +// position: absolute; +// .useSprite(0, 8); +// margin: 0; +// &.fancytree-drop-after, +// &.fancytree-drop-before { +// width: 4 * @fancy-icon-width; // 64px; +// .useSprite(0, 9); +// } +// &.fancytree-drop-copy { +// .useSprite(4, 8); +// } +// &.fancytree-drop-move { +// .useSprite(2, 8); +// } +//} +// +///*** Source node while dragging ***********************************************/ +// +//span.fancytree-drag-source { +// &.fancytree-drag-remove { +// // text-decoration: line-through; +// opacity: 0.15; +// } +//} +// +///*** Target node while dragging cursor is over it *****************************/ +// +//span.fancytree-drop-target { +// &.fancytree-drop-accept { +// // outline: 1px dotted #5cb85c; // bootstrap sucess +// } +//} +//span.fancytree-drop-reject { +// // outline: 1px dotted #d9534f; // boostrap warning +//} + +/*------------------------------------------------------------------------------ + * 'rtl' option + *----------------------------------------------------------------------------*/ + +.fancytree-container.fancytree-rtl { + .fancytree-title { + /*unicode-bidi: bidi-override;*/ /* optional: reverse title letters */ + } + span.fancytree-connector, + span.fancytree-expander, + span.fancytree-icon, + span.fancytree-drag-helper-img { + .setBgImageUrl("icons-rtl.gif"); + } + .fancytree-exp-n span.fancytree-expander, + .fancytree-exp-nl span.fancytree-expander { + background-image: none; + } + &.fancytree-connectors .fancytree-exp-n span.fancytree-expander, + &.fancytree-connectors .fancytree-exp-nl span.fancytree-expander { + .setBgImageUrl("icons-rtl.gif"); + } +} +ul.fancytree-container.fancytree-rtl { + ul { + padding: 0 16px 0 0; + } + &.fancytree-connectors li { + background-position: right 0; + background-image: url("@{fancy-image-prefix}vline-rtl.gif"); + } + // Suppress lines for last child node + li.fancytree-lastsib, + // Suppress lines if level is fixed expanded (option minExpandLevel) + &.fancytree-no-connector > li { + background-image: none; + } +} +#fancytree-drop-marker.fancytree-rtl { + .setBgImageUrl("icons-rtl.gif"); +} + +//// CHANGE: not used. +///*------------------------------------------------------------------------------ +// * 'table' extension +// *----------------------------------------------------------------------------*/ +// +//table.fancytree-ext-table { +// font-family: @fancy-font-family; +// font-size: @fancy-font-size; +// border-collapse: collapse; +// span.fancytree-node { +// display: inline-block; // #117 +// box-sizing: border-box; // #562 +// } +// td.fancytree-status-merged { +// text-align: center; +// // font-weight: bold; +// font-style: italic; +// // line-height: 100px; +// color: @fancy-font-color-dimm; +// } +// tr.fancytree-statusnode-error td.fancytree-status-merged { +// color: @fancy-font-error-color; +// } +// /* ext-ariagrid */ +// &.fancytree-ext-ariagrid.fancytree-cell-mode { +// > tbody > tr.fancytree-active > td { +// background-color: #eee; +// } +// > tbody > tr > td.fancytree-active-cell { +// background-color: #cbe8f6; +// } +// &.fancytree-cell-nav-mode > tbody > tr > td.fancytree-active-cell { +// background-color: #3875d7; +// } +// } +//} +// +///*------------------------------------------------------------------------------ +// * 'columnview' extension +// *----------------------------------------------------------------------------*/ +// +//table.fancytree-ext-columnview { +// // border-collapse: collapse; +// // width: 100%; +// tbody tr td { +// position: relative; +// border: 1px solid gray; +// vertical-align: top; +// overflow: auto; +// > ul { +// padding: 0; +// li { +// list-style-image: none; +// list-style-position: outside; +// list-style-type: none; +// -moz-background-clip: border; +// -moz-background-inline-policy: continuous; +// -moz-background-origin: padding; +// background-attachment: scroll; +// background-color: transparent; +// .setBgPos(0, 0); +// background-repeat: repeat-y; +// background-image: none; /* no v-lines */ +// +// margin: 0; +// // padding: 1px 0 0 0; // issue #246 +// } +// } +// } +// span.fancytree-node { +// position: relative; /* allow positioning of embedded spans */ +// display: inline-block; // #117 +// } +// span.fancytree-node.fancytree-expanded { +// background-color: #e0e0e0; +// } +// span.fancytree-node.fancytree-active { +// background-color: #cbe8f6; +// // background-color: royalblue; +// } +// .fancytree-has-children span.fancytree-cv-right { +// position: absolute; +// right: 3px; +// .useSprite(0, 5); +// &:hover { +// .useSprite(1, 5); +// } +// } +//} +// +///*------------------------------------------------------------------------------ +// * 'filter' extension +// *----------------------------------------------------------------------------*/ +// +//.fancytree-ext-filter-dimm { +// span.fancytree-node span.fancytree-title { +// color: @fancy-font-color-dimm; +// font-weight: lighter; +// } +// tr.fancytree-submatch span.fancytree-title, +// span.fancytree-node.fancytree-submatch span.fancytree-title { +// color: black; +// font-weight: normal; +// } +// tr.fancytree-match span.fancytree-title, +// span.fancytree-node.fancytree-match span.fancytree-title { +// color: black; +// font-weight: bold; +// } +//} +//.fancytree-ext-filter-hide { +// tr.fancytree-hide, +// span.fancytree-node.fancytree-hide { +// display: none; +// } +// tr.fancytree-submatch span.fancytree-title, +// span.fancytree-node.fancytree-submatch span.fancytree-title { +// color: @fancy-font-color-dimm; +// font-weight: lighter; +// } +// tr.fancytree-match span.fancytree-title, +// span.fancytree-node.fancytree-match span.fancytree-title { +// color: black; +// font-weight: normal; +// } +//} +///* Hide expanders if all child nodes are hidden by filter */ +//.fancytree-ext-filter-hide-expanders { +// tr.fancytree-match span.fancytree-expander, +// span.fancytree-node.fancytree-match span.fancytree-expander { +// visibility: hidden; +// } +// tr.fancytree-submatch span.fancytree-expander, +// span.fancytree-node.fancytree-submatch span.fancytree-expander { +// visibility: visible; +// } +//} +// +//.fancytree-ext-childcounter, +//.fancytree-ext-filter { +// // span.fancytree-title mark { +// // font-style: normal; +// // background-color: #ead61c; // yellow +// // border-radius: 3px; +// // } +// span.fancytree-icon, +// span.fancytree-custom-icon { +// position: relative; +// } +// span.fancytree-childcounter { +// color: #fff; +// background: #777; // #337ab7; // bootstrap blue +// border: 1px solid gray; +// position: absolute; +// top: -6px; +// right: -6px; +// min-width: 10px; +// height: 10px; +// line-height: 1; +// vertical-align: baseline; +// border-radius: 10px; +// padding: 2px; +// text-align: center; +// font-size: 9px; +// } +//} +///*------------------------------------------------------------------------------ +// * 'wide' extension +// *----------------------------------------------------------------------------*/ +// +//ul.fancytree-ext-wide { +// position: relative; +// min-width: 100%; +// z-index: 2; +// +// -webkit-box-sizing: border-box; +// -moz-box-sizing: border-box; +// box-sizing: border-box; +// +// span.fancytree-node > span { +// position: relative; +// z-index: 2; +// } +// span.fancytree-node span.fancytree-title { +// position: absolute; // Allow left: 0. Note: prevents smooth dropdown animation +// z-index: 1; // Behind expander and checkbox +// left: 0px; +// min-width: 100%; +// margin-left: 0; +// margin-right: 0; +// +// -webkit-box-sizing: border-box; +// -moz-box-sizing: border-box; +// box-sizing: border-box; +// } +//} +// +///*------------------------------------------------------------------------------ +// * 'fixed' extension +// *----------------------------------------------------------------------------*/ +// +//.fancytree-ext-fixed-wrapper { +// .fancytree-ext-fixed-hidden { +// display: none; +// } +// div.fancytree-ext-fixed-scroll-border-bottom { +// border-bottom: 3px solid rgba(0, 0, 0, 0.75); +// } +// div.fancytree-ext-fixed-scroll-border-right { +// border-right: 3px solid rgba(0, 0, 0, 0.75); +// } +// div.fancytree-ext-fixed-wrapper-tl { +// position: absolute; +// overflow: hidden; +// z-index: 3; +// top: 0px; +// left: 0px; +// } +// div.fancytree-ext-fixed-wrapper-tr { +// position: absolute; +// overflow: hidden; +// z-index: 2; +// top: 0px; +// } +// div.fancytree-ext-fixed-wrapper-bl { +// position: absolute; +// overflow: hidden; +// z-index: 2; +// left: 0px; +// } +// div.fancytree-ext-fixed-wrapper-br { +// position: absolute; +// overflow: scroll; +// z-index: 1; +// } +//} diff --git a/plugins/55/indexmenu/scripts/fancytree/skin-win7/ui.fancytree.css b/plugins/55/indexmenu/scripts/fancytree/skin-win7/ui.fancytree.css new file mode 100644 index 0000000..fdd5191 --- /dev/null +++ b/plugins/55/indexmenu/scripts/fancytree/skin-win7/ui.fancytree.css @@ -0,0 +1,822 @@ +/*! + * Fancytree "Win7" skin. + * + * DON'T EDIT THE CSS FILE DIRECTLY, since it is automatically generated from + * the LESS templates. + */ +/******************************************************************************* + * Common Styles for Fancytree Skins. + * + * This section is automatically generated from the `skin-common.less` template. + * + * Copyright (c) 2008-2023, Martin Wendt (https://wwWendt.de) + * Released under the MIT license + * https://github.com/mar10/fancytree/wiki/LicenseInfo + * + * @version 2.38.3 + * @date 2023-02-01T20:52:50Z +******************************************************************************/ +/*------------------------------------------------------------------------------ + * Helpers + *----------------------------------------------------------------------------*/ +.fancytree-helper-hidden { + display: none; +} +.fancytree-helper-indeterminate-cb { + color: #777; +} +.fancytree-helper-disabled { + color: #c0c0c0; +} +/* Helper to allow spinning loader icon with glyph-, ligature-, and SVG-icons. */ +.fancytree-helper-spin { + -webkit-animation: spin 1000ms infinite linear; + animation: spin 1000ms infinite linear; +} +@-webkit-keyframes spin { + 0% { + -webkit-transform: rotate(0deg); + transform: rotate(0deg); + } + 100% { + -webkit-transform: rotate(359deg); + transform: rotate(359deg); + } +} +@keyframes spin { + 0% { + -webkit-transform: rotate(0deg); + transform: rotate(0deg); + } + 100% { + -webkit-transform: rotate(359deg); + transform: rotate(359deg); + } +} +/*------------------------------------------------------------------------------ + * Container and UL / LI + *----------------------------------------------------------------------------*/ +ul.fancytree-container { + font-family: tahoma, arial, helvetica; + font-size: 10pt; + white-space: nowrap; + padding: 3px; + margin: 0; + background-color: white; + border: 1px dotted gray; + min-height: 0%; + position: relative; +} +ul.fancytree-container ul { + padding: 0 0 0 16px; + margin: 0; +} +ul.fancytree-container ul > li:before { + content: none; +} +ul.fancytree-container li { + list-style-image: none; + list-style-position: outside; + list-style-type: none; + -moz-background-clip: border; + -moz-background-inline-policy: continuous; + -moz-background-origin: padding; + background-attachment: scroll; + background-color: transparent; + background-position: 0px 0px; + background-repeat: repeat-y; + background-image: none; + margin: 0; +} +ul.fancytree-container li.fancytree-lastsib { + background-image: none; +} +.ui-fancytree-disabled ul.fancytree-container { + opacity: 0.5; + background-color: silver; +} +ul.fancytree-connectors.fancytree-container li { + background-image: url("../skin-win7/vline.gif"); + background-position: 0 0; +} +ul.fancytree-container li.fancytree-lastsib, +ul.fancytree-no-connector > li { + background-image: none; +} +li.fancytree-animating { + position: relative; +} +/*------------------------------------------------------------------------------ + * Common icon definitions + *----------------------------------------------------------------------------*/ +span.fancytree-empty, +span.fancytree-vline, +span.fancytree-expander, +span.fancytree-icon, +span.fancytree-checkbox, +span.fancytree-drag-helper-img, +#fancytree-drop-marker { + width: 16px; + height: 16px; + display: inline-block; + vertical-align: top; + background-repeat: no-repeat; + background-image: url("../skin-win7/icons.gif"); + background-position: 0px 0px; +} +span.fancytree-icon, +span.fancytree-checkbox, +span.fancytree-expander, +span.fancytree-custom-icon { + margin-top: 2px; +} +/* Used by icon option: */ +span.fancytree-custom-icon { + width: 16px; + height: 16px; + display: inline-block; + margin-left: 3px; + background-position: 0px 0px; +} +/* Used by 'icon' node option: */ +img.fancytree-icon { + width: 16px; + height: 16px; + margin-left: 3px; + margin-top: 2px; + vertical-align: top; + border-style: none; +} +/*------------------------------------------------------------------------------ + * Expander icon + * + * Note: IE6 doesn't correctly evaluate multiples class names, + * so we create combined class names that can be used in the CSS. + * + * Prefix: fancytree-exp- + * 1st character: 'e': expanded, 'c': collapsed, 'n': no children + * 2nd character (optional): 'd': lazy (Delayed) + * 3rd character (optional): 'l': Last sibling + *----------------------------------------------------------------------------*/ +span.fancytree-expander { + cursor: pointer; +} +.fancytree-exp-n span.fancytree-expander, +.fancytree-exp-nl span.fancytree-expander { + background-image: none; + cursor: default; +} +.fancytree-connectors .fancytree-exp-n span.fancytree-expander, +.fancytree-connectors .fancytree-exp-nl span.fancytree-expander { + background-image: url("../skin-win7/icons.gif"); + margin-top: 0; +} +.fancytree-connectors .fancytree-exp-n span.fancytree-expander, +.fancytree-connectors .fancytree-exp-n span.fancytree-expander:hover { + background-position: 0px -64px; +} +.fancytree-connectors .fancytree-exp-nl span.fancytree-expander, +.fancytree-connectors .fancytree-exp-nl span.fancytree-expander:hover { + background-position: -16px -64px; +} +.fancytree-exp-c span.fancytree-expander { + background-position: 0px -80px; +} +.fancytree-exp-c span.fancytree-expander:hover { + background-position: -16px -80px; +} +.fancytree-exp-cl span.fancytree-expander { + background-position: 0px -96px; +} +.fancytree-exp-cl span.fancytree-expander:hover { + background-position: -16px -96px; +} +.fancytree-exp-cd span.fancytree-expander { + background-position: -64px -80px; +} +.fancytree-exp-cd span.fancytree-expander:hover { + background-position: -80px -80px; +} +.fancytree-exp-cdl span.fancytree-expander { + background-position: -64px -96px; +} +.fancytree-exp-cdl span.fancytree-expander:hover { + background-position: -80px -96px; +} +.fancytree-exp-e span.fancytree-expander, +.fancytree-exp-ed span.fancytree-expander { + background-position: -32px -80px; +} +.fancytree-exp-e span.fancytree-expander:hover, +.fancytree-exp-ed span.fancytree-expander:hover { + background-position: -48px -80px; +} +.fancytree-exp-el span.fancytree-expander, +.fancytree-exp-edl span.fancytree-expander { + background-position: -32px -96px; +} +.fancytree-exp-el span.fancytree-expander:hover, +.fancytree-exp-edl span.fancytree-expander:hover { + background-position: -48px -96px; +} +/* Fade out expanders, when container is not hovered or active */ +.fancytree-fade-expander span.fancytree-expander { + transition: opacity 1.5s; + opacity: 0; +} +.fancytree-fade-expander:hover span.fancytree-expander, +.fancytree-fade-expander.fancytree-treefocus span.fancytree-expander, +.fancytree-fade-expander .fancytree-treefocus span.fancytree-expander, +.fancytree-fade-expander [class*="fancytree-statusnode-"] span.fancytree-expander { + transition: opacity 0.6s; + opacity: 1; +} +/*------------------------------------------------------------------------------ + * Checkbox icon + *----------------------------------------------------------------------------*/ +span.fancytree-checkbox { + margin-left: 3px; + background-position: 0px -32px; +} +span.fancytree-checkbox:hover { + background-position: -16px -32px; +} +span.fancytree-checkbox.fancytree-radio { + background-position: 0px -48px; +} +span.fancytree-checkbox.fancytree-radio:hover { + background-position: -16px -48px; +} +.fancytree-partsel span.fancytree-checkbox { + background-position: -64px -32px; +} +.fancytree-partsel span.fancytree-checkbox:hover { + background-position: -80px -32px; +} +.fancytree-partsel span.fancytree-checkbox.fancytree-radio { + background-position: -64px -48px; +} +.fancytree-partsel span.fancytree-checkbox.fancytree-radio:hover { + background-position: -80px -48px; +} +.fancytree-selected span.fancytree-checkbox { + background-position: -32px -32px; +} +.fancytree-selected span.fancytree-checkbox:hover { + background-position: -48px -32px; +} +.fancytree-selected span.fancytree-checkbox.fancytree-radio { + background-position: -32px -48px; +} +.fancytree-selected span.fancytree-checkbox.fancytree-radio:hover { + background-position: -48px -48px; +} +.fancytree-unselectable span.fancytree-checkbox { + opacity: 0.4; + filter: alpha(opacity=40); +} +.fancytree-unselectable span.fancytree-checkbox:hover { + background-position: 0px -32px; +} +.fancytree-unselectable span.fancytree-checkbox.fancytree-radio:hover { + background-position: 0px -48px; +} +.fancytree-unselectable.fancytree-partsel span.fancytree-checkbox:hover { + background-position: -64px -32px; +} +.fancytree-unselectable.fancytree-selected span.fancytree-checkbox:hover { + background-position: -32px -32px; +} +.fancytree-unselectable.fancytree-selected span.fancytree-checkbox.fancytree-radio:hover { + background-position: -32px -48px; +} +.fancytree-container.fancytree-checkbox-auto-hide span.fancytree-checkbox { + visibility: hidden; +} +.fancytree-container.fancytree-checkbox-auto-hide .fancytree-node:hover span.fancytree-checkbox, +.fancytree-container.fancytree-checkbox-auto-hide tr:hover td span.fancytree-checkbox, +.fancytree-container.fancytree-checkbox-auto-hide .fancytree-node.fancytree-selected span.fancytree-checkbox, +.fancytree-container.fancytree-checkbox-auto-hide tr.fancytree-selected td span.fancytree-checkbox { + visibility: unset; +} +.fancytree-container.fancytree-checkbox-auto-hide.fancytree-treefocus .fancytree-node.fancytree-active span.fancytree-checkbox, +.fancytree-container.fancytree-checkbox-auto-hide.fancytree-treefocus tr.fancytree-active td span.fancytree-checkbox { + visibility: unset; +} +/*------------------------------------------------------------------------------ + * Node type icon + * Note: IE6 doesn't correctly evaluate multiples class names, + * so we create combined class names that can be used in the CSS. + * + * Prefix: fancytree-ico- + * 1st character: 'e': expanded, 'c': collapsed + * 2nd character (optional): 'f': folder + *----------------------------------------------------------------------------*/ +span.fancytree-icon { + margin-left: 3px; + background-position: 0px 0px; +} +/* Documents */ +.fancytree-ico-c span.fancytree-icon:hover { + background-position: -16px 0px; +} +.fancytree-has-children.fancytree-ico-c span.fancytree-icon { + background-position: -32px 0px; +} +.fancytree-has-children.fancytree-ico-c span.fancytree-icon:hover { + background-position: -48px 0px; +} +.fancytree-ico-e span.fancytree-icon { + background-position: -64px 0px; +} +.fancytree-ico-e span.fancytree-icon:hover { + background-position: -80px 0px; +} +/* Folders */ +.fancytree-ico-cf span.fancytree-icon { + background-position: 0px -16px; +} +.fancytree-ico-cf span.fancytree-icon:hover { + background-position: -16px -16px; +} +.fancytree-has-children.fancytree-ico-cf span.fancytree-icon { + background-position: -32px -16px; +} +.fancytree-has-children.fancytree-ico-cf span.fancytree-icon:hover { + background-position: -48px -16px; +} +.fancytree-ico-ef span.fancytree-icon { + background-position: -64px -16px; +} +.fancytree-ico-ef span.fancytree-icon:hover { + background-position: -80px -16px; +} +.fancytree-loading span.fancytree-expander, +.fancytree-loading span.fancytree-expander:hover, +.fancytree-statusnode-loading span.fancytree-icon, +.fancytree-statusnode-loading span.fancytree-icon:hover, +span.fancytree-icon.fancytree-icon-loading { + background-image: url("../skin-win7/loading.gif"); + background-position: 0px 0px; +} +/* Status node icons */ +.fancytree-statusnode-error span.fancytree-icon, +.fancytree-statusnode-error span.fancytree-icon:hover { + background-position: 0px -112px; +} +/*------------------------------------------------------------------------------ + * Node titles and highlighting + *----------------------------------------------------------------------------*/ +span.fancytree-node { + /* See #117 */ + display: inherit; + width: 100%; + margin-top: 1px; + min-height: 20px; +} +span.fancytree-title { + color: black; + cursor: pointer; + display: inline-block; + vertical-align: top; + min-height: 20px; + padding: 0 3px 0 3px; + margin: 0px 0 0 3px; + border: 1px solid transparent; + -webkit-border-radius: 3px; + -moz-border-radius: 3px; + -ms-border-radius: 3px; + -o-border-radius: 3px; + border-radius: 3px; +} +span.fancytree-node.fancytree-error span.fancytree-title { + color: red; +} +/*------------------------------------------------------------------------------ + * Drag'n'drop support + *----------------------------------------------------------------------------*/ +/* ext-dnd5: */ +span.fancytree-childcounter { + color: #fff; + background: #337ab7; + border: 1px solid gray; + border-radius: 10px; + padding: 2px; + text-align: center; +} +/* ext-dnd: */ +div.fancytree-drag-helper span.fancytree-childcounter, +div.fancytree-drag-helper span.fancytree-dnd-modifier { + display: inline-block; + color: #fff; + background: #337ab7; + border: 1px solid gray; + min-width: 10px; + height: 10px; + line-height: 1; + vertical-align: baseline; + border-radius: 10px; + padding: 2px; + text-align: center; + font-size: 9px; +} +div.fancytree-drag-helper span.fancytree-childcounter { + position: absolute; + top: -6px; + right: -6px; +} +div.fancytree-drag-helper span.fancytree-dnd-modifier { + background: #5cb85c; + border: none; + font-weight: bolder; +} +div.fancytree-drag-helper.fancytree-drop-accept span.fancytree-drag-helper-img { + background-position: -32px -112px; +} +div.fancytree-drag-helper.fancytree-drop-reject span.fancytree-drag-helper-img { + background-position: -16px -112px; +} +/*** Drop marker icon *********************************************************/ +#fancytree-drop-marker { + width: 32px; + position: absolute; + background-position: 0px -128px; + margin: 0; +} +#fancytree-drop-marker.fancytree-drop-after, +#fancytree-drop-marker.fancytree-drop-before { + width: 64px; + background-position: 0px -144px; +} +#fancytree-drop-marker.fancytree-drop-copy { + background-position: -64px -128px; +} +#fancytree-drop-marker.fancytree-drop-move { + background-position: -32px -128px; +} +/*** Source node while dragging ***********************************************/ +span.fancytree-drag-source.fancytree-drag-remove { + opacity: 0.15; +} +/*** Target node while dragging cursor is over it *****************************/ +/*------------------------------------------------------------------------------ + * 'rtl' option + *----------------------------------------------------------------------------*/ +.fancytree-container.fancytree-rtl .fancytree-title { + /*unicode-bidi: bidi-override;*/ + /* optional: reverse title letters */ +} +.fancytree-container.fancytree-rtl span.fancytree-connector, +.fancytree-container.fancytree-rtl span.fancytree-expander, +.fancytree-container.fancytree-rtl span.fancytree-icon, +.fancytree-container.fancytree-rtl span.fancytree-drag-helper-img { + background-image: url("../skin-win7/icons-rtl.gif"); +} +.fancytree-container.fancytree-rtl .fancytree-exp-n span.fancytree-expander, +.fancytree-container.fancytree-rtl .fancytree-exp-nl span.fancytree-expander { + background-image: none; +} +.fancytree-container.fancytree-rtl.fancytree-connectors .fancytree-exp-n span.fancytree-expander, +.fancytree-container.fancytree-rtl.fancytree-connectors .fancytree-exp-nl span.fancytree-expander { + background-image: url("../skin-win7/icons-rtl.gif"); +} +ul.fancytree-container.fancytree-rtl ul { + padding: 0 16px 0 0; +} +ul.fancytree-container.fancytree-rtl.fancytree-connectors li { + background-position: right 0; + background-image: url("../skin-win7/vline-rtl.gif"); +} +ul.fancytree-container.fancytree-rtl li.fancytree-lastsib, +ul.fancytree-container.fancytree-rtl.fancytree-no-connector > li { + background-image: none; +} +#fancytree-drop-marker.fancytree-rtl { + background-image: url("../skin-win7/icons-rtl.gif"); +} +/*------------------------------------------------------------------------------ + * 'table' extension + *----------------------------------------------------------------------------*/ +table.fancytree-ext-table { + font-family: tahoma, arial, helvetica; + font-size: 10pt; + border-collapse: collapse; + /* ext-ariagrid */ +} +table.fancytree-ext-table span.fancytree-node { + display: inline-block; + box-sizing: border-box; +} +table.fancytree-ext-table td.fancytree-status-merged { + text-align: center; + font-style: italic; + color: #c0c0c0; +} +table.fancytree-ext-table tr.fancytree-statusnode-error td.fancytree-status-merged { + color: red; +} +table.fancytree-ext-table.fancytree-ext-ariagrid.fancytree-cell-mode > tbody > tr.fancytree-active > td { + background-color: #eee; +} +table.fancytree-ext-table.fancytree-ext-ariagrid.fancytree-cell-mode > tbody > tr > td.fancytree-active-cell { + background-color: #cbe8f6; +} +table.fancytree-ext-table.fancytree-ext-ariagrid.fancytree-cell-mode.fancytree-cell-nav-mode > tbody > tr > td.fancytree-active-cell { + background-color: #3875d7; +} +/*------------------------------------------------------------------------------ + * 'columnview' extension + *----------------------------------------------------------------------------*/ +table.fancytree-ext-columnview tbody tr td { + position: relative; + border: 1px solid gray; + vertical-align: top; + overflow: auto; +} +table.fancytree-ext-columnview tbody tr td > ul { + padding: 0; +} +table.fancytree-ext-columnview tbody tr td > ul li { + list-style-image: none; + list-style-position: outside; + list-style-type: none; + -moz-background-clip: border; + -moz-background-inline-policy: continuous; + -moz-background-origin: padding; + background-attachment: scroll; + background-color: transparent; + background-position: 0px 0px; + background-repeat: repeat-y; + background-image: none; + /* no v-lines */ + margin: 0; +} +table.fancytree-ext-columnview span.fancytree-node { + position: relative; + /* allow positioning of embedded spans */ + display: inline-block; +} +table.fancytree-ext-columnview span.fancytree-node.fancytree-expanded { + background-color: #e0e0e0; +} +table.fancytree-ext-columnview span.fancytree-node.fancytree-active { + background-color: #cbe8f6; +} +table.fancytree-ext-columnview .fancytree-has-children span.fancytree-cv-right { + position: absolute; + right: 3px; + background-position: 0px -80px; +} +table.fancytree-ext-columnview .fancytree-has-children span.fancytree-cv-right:hover { + background-position: -16px -80px; +} +/*------------------------------------------------------------------------------ + * 'filter' extension + *----------------------------------------------------------------------------*/ +.fancytree-ext-filter-dimm span.fancytree-node span.fancytree-title { + color: #c0c0c0; + font-weight: lighter; +} +.fancytree-ext-filter-dimm tr.fancytree-submatch span.fancytree-title, +.fancytree-ext-filter-dimm span.fancytree-node.fancytree-submatch span.fancytree-title { + color: black; + font-weight: normal; +} +.fancytree-ext-filter-dimm tr.fancytree-match span.fancytree-title, +.fancytree-ext-filter-dimm span.fancytree-node.fancytree-match span.fancytree-title { + color: black; + font-weight: bold; +} +.fancytree-ext-filter-hide tr.fancytree-hide, +.fancytree-ext-filter-hide span.fancytree-node.fancytree-hide { + display: none; +} +.fancytree-ext-filter-hide tr.fancytree-submatch span.fancytree-title, +.fancytree-ext-filter-hide span.fancytree-node.fancytree-submatch span.fancytree-title { + color: #c0c0c0; + font-weight: lighter; +} +.fancytree-ext-filter-hide tr.fancytree-match span.fancytree-title, +.fancytree-ext-filter-hide span.fancytree-node.fancytree-match span.fancytree-title { + color: black; + font-weight: normal; +} +/* Hide expanders if all child nodes are hidden by filter */ +.fancytree-ext-filter-hide-expanders tr.fancytree-match span.fancytree-expander, +.fancytree-ext-filter-hide-expanders span.fancytree-node.fancytree-match span.fancytree-expander { + visibility: hidden; +} +.fancytree-ext-filter-hide-expanders tr.fancytree-submatch span.fancytree-expander, +.fancytree-ext-filter-hide-expanders span.fancytree-node.fancytree-submatch span.fancytree-expander { + visibility: visible; +} +.fancytree-ext-childcounter span.fancytree-icon, +.fancytree-ext-filter span.fancytree-icon, +.fancytree-ext-childcounter span.fancytree-custom-icon, +.fancytree-ext-filter span.fancytree-custom-icon { + position: relative; +} +.fancytree-ext-childcounter span.fancytree-childcounter, +.fancytree-ext-filter span.fancytree-childcounter { + color: #fff; + background: #777; + border: 1px solid gray; + position: absolute; + top: -6px; + right: -6px; + min-width: 10px; + height: 10px; + line-height: 1; + vertical-align: baseline; + border-radius: 10px; + padding: 2px; + text-align: center; + font-size: 9px; +} +/*------------------------------------------------------------------------------ + * 'wide' extension + *----------------------------------------------------------------------------*/ +ul.fancytree-ext-wide { + position: relative; + min-width: 100%; + z-index: 2; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; +} +ul.fancytree-ext-wide span.fancytree-node > span { + position: relative; + z-index: 2; +} +ul.fancytree-ext-wide span.fancytree-node span.fancytree-title { + position: absolute; + z-index: 1; + left: 0px; + min-width: 100%; + margin-left: 0; + margin-right: 0; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; +} +/*------------------------------------------------------------------------------ + * 'fixed' extension + *----------------------------------------------------------------------------*/ +.fancytree-ext-fixed-wrapper .fancytree-ext-fixed-hidden { + display: none; +} +.fancytree-ext-fixed-wrapper div.fancytree-ext-fixed-scroll-border-bottom { + border-bottom: 3px solid rgba(0, 0, 0, 0.75); +} +.fancytree-ext-fixed-wrapper div.fancytree-ext-fixed-scroll-border-right { + border-right: 3px solid rgba(0, 0, 0, 0.75); +} +.fancytree-ext-fixed-wrapper div.fancytree-ext-fixed-wrapper-tl { + position: absolute; + overflow: hidden; + z-index: 3; + top: 0px; + left: 0px; +} +.fancytree-ext-fixed-wrapper div.fancytree-ext-fixed-wrapper-tr { + position: absolute; + overflow: hidden; + z-index: 2; + top: 0px; +} +.fancytree-ext-fixed-wrapper div.fancytree-ext-fixed-wrapper-bl { + position: absolute; + overflow: hidden; + z-index: 2; + left: 0px; +} +.fancytree-ext-fixed-wrapper div.fancytree-ext-fixed-wrapper-br { + position: absolute; + overflow: scroll; + z-index: 1; +} +/******************************************************************************* + * Styles specific to this skin. + * + * This section is automatically generated from the `ui-fancytree.less` template. + ******************************************************************************/ +/******************************************************************************* + * Node titles + */ +span.fancytree-active .fancytree-title, +span.fancytree-selected .fancytree-title { + border-color: #d9d9d9; + background: #e5e5e5; + color: inherit; + background: -moz-linear-gradient(top, #fafafb 0%, #e5e5e5 100%); + background: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #fafafb), color-stop(100%, #e5e5e5)); + background: -webkit-linear-gradient(top, #fafafb 0%, #e5e5e5 100%); + background: -o-linear-gradient(top, #fafafb 0%, #e5e5e5 100%); + background: -ms-linear-gradient(top, #fafafb 0%, #e5e5e5 100%); + background: linear-gradient(to bottom, #fafafb 0%, #e5e5e5 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fafafb', endColorstr='#e5e5e5', GradientType=0); +} +span.fancytree-selected .fancytree-title { + font-style: italic; +} +.fancytree-treefocus span.fancytree-active .fancytree-title, +.fancytree-treefocus span.fancytree-selected .fancytree-title { + border-color: #99defd; + background: #f6fbfd; + color: inherit; + background: -moz-linear-gradient(top, #f6fbfd 0%, #d5effc 100%); + background: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #f6fbfd), color-stop(100%, #d5effc)); + background: -webkit-linear-gradient(top, #f6fbfd 0%, #d5effc 100%); + background: -o-linear-gradient(top, #f6fbfd 0%, #d5effc 100%); + background: -ms-linear-gradient(top, #f6fbfd 0%, #d5effc 100%); + background: linear-gradient(to bottom, #f6fbfd 0%, #d5effc 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#f6fbfd', endColorstr='#d5effc', GradientType=0); +} +.fancytree-treefocus span.fancytree-focused span.fancytree-title { + border: 1px solid #719acb; +} +span.fancytree-title:hover { + border-color: #d8f0fa; + background: #f8fcfe; + color: inherit; + background: -moz-linear-gradient(top, #f8fcfe 0%, #eff9fe 100%); + background: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #f8fcfe), color-stop(100%, #eff9fe)); + background: -webkit-linear-gradient(top, #f8fcfe 0%, #eff9fe 100%); + background: -o-linear-gradient(top, #f8fcfe 0%, #eff9fe 100%); + background: -ms-linear-gradient(top, #f8fcfe 0%, #eff9fe 100%); + background: linear-gradient(to bottom, #f8fcfe 0%, #eff9fe 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#f8fcfe', endColorstr='#eff9fe', GradientType=0); +} +span.fancytree-active .fancytree-title:hover, +span.fancytree-selected .fancytree-title:hover { + border-color: #719acb; + background: #f2f9fd; + color: inherit; + background: -moz-linear-gradient(top, #f2f9fd 0%, #c4e8fa 100%); + background: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #f2f9fd), color-stop(100%, #c4e8fa)); + background: -webkit-linear-gradient(top, #f2f9fd 0%, #c4e8fa 100%); + background: -o-linear-gradient(top, #f2f9fd 0%, #c4e8fa 100%); + background: -ms-linear-gradient(top, #f2f9fd 0%, #c4e8fa 100%); + background: linear-gradient(to bottom, #f2f9fd 0%, #c4e8fa 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#f2f9fd', endColorstr='#c4e8fa', GradientType=0); +} +/******************************************************************************* + * 'table' extension + */ +table.fancytree-ext-table tbody tr td { + border: 1px solid #ededed; +} +table.fancytree-ext-table tbody tr:hover { + border-color: inherit; + background: #f8fcfe; + color: inherit; + background: -moz-linear-gradient(top, #f8fcfe 0%, #eff9fe 100%); + background: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #f8fcfe), color-stop(100%, #eff9fe)); + background: -webkit-linear-gradient(top, #f8fcfe 0%, #eff9fe 100%); + background: -o-linear-gradient(top, #f8fcfe 0%, #eff9fe 100%); + background: -ms-linear-gradient(top, #f8fcfe 0%, #eff9fe 100%); + background: linear-gradient(to bottom, #f8fcfe 0%, #eff9fe 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#f8fcfe', endColorstr='#eff9fe', GradientType=0); + outline: 1px solid #d8f0fa; +} +table.fancytree-ext-table tbody tr.fancytree-focused { + outline: 1px dotted #090402; +} +table.fancytree-ext-table tbody span.fancytree-focused span.fancytree-title { + outline: solid dotted black; +} +table.fancytree-ext-table tbody span.fancytree-title:hover { + border: 1px solid transparent; + background: inherit; + background: transparent; + background: none; + filter: none; +} +table.fancytree-ext-table tbody tr.fancytree-active:hover, +table.fancytree-ext-table tbody tr.fancytree-selected:hover { + border-color: inherit; + background: #f2f9fd; + color: inherit; + background: -moz-linear-gradient(top, #f2f9fd 0%, #c4e8fa 100%); + background: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #f2f9fd), color-stop(100%, #c4e8fa)); + background: -webkit-linear-gradient(top, #f2f9fd 0%, #c4e8fa 100%); + background: -o-linear-gradient(top, #f2f9fd 0%, #c4e8fa 100%); + background: -ms-linear-gradient(top, #f2f9fd 0%, #c4e8fa 100%); + background: linear-gradient(to bottom, #f2f9fd 0%, #c4e8fa 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#f2f9fd', endColorstr='#c4e8fa', GradientType=0); + outline: 1px solid #B6E6FB; +} +table.fancytree-ext-table tbody tr.fancytree-active, +table.fancytree-ext-table tbody tr.fancytree-selected { + border-color: inherit; + background: #f6fbfd; + color: inherit; + background: -moz-linear-gradient(top, #f6fbfd 0%, #d5effc 100%); + background: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #f6fbfd), color-stop(100%, #d5effc)); + background: -webkit-linear-gradient(top, #f6fbfd 0%, #d5effc 100%); + background: -o-linear-gradient(top, #f6fbfd 0%, #d5effc 100%); + background: -ms-linear-gradient(top, #f6fbfd 0%, #d5effc 100%); + background: linear-gradient(to bottom, #f6fbfd 0%, #d5effc 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#f6fbfd', endColorstr='#d5effc', GradientType=0); + outline: 1px solid #99DEFD; +} diff --git a/plugins/55/indexmenu/scripts/fancytree/skin-win7/ui.fancytree.less b/plugins/55/indexmenu/scripts/fancytree/skin-win7/ui.fancytree.less new file mode 100644 index 0000000..f075c49 --- /dev/null +++ b/plugins/55/indexmenu/scripts/fancytree/skin-win7/ui.fancytree.less @@ -0,0 +1,157 @@ +/*! + * Fancytree "Win7" skin. + * + * DON'T EDIT THE CSS FILE DIRECTLY, since it is automatically generated from + * the LESS templates. + */ + +// Fancytree Win7 styles + +// both: +// unselected background: #FCFCFC 'nearly white', no border +// +// hover bar (unselected, inactive): #fcfdfe..#EFF9FE (border: #b8d6fb) 'very light blue' +// background: #f8fcfe; // +// background: -moz-linear-gradient(top, #f8fcfe 0%, #eff9fe 100%); + +// active node: #F6FBFD..#D5EFFC (border: #719acb) 'light blue' +// background: #f6fbfd; +// background: -moz-linear-gradient(top, #f6fbfd 0%, #d5effc 100%); + +// active node with hover: #F2F9FD..#C4E8FA (border: #B6E6FB) +// background: #f2f9fd; +// background: -moz-linear-gradient(top, #f2f9fd 0%, #c4e8fa 100%); + +// Tree view: +// active node, tree inactive: #FAFAFB..#E5E5E5 (border: #D9D9D9) 'light gray, selected, but tree not active' +// background: #fafafb; +// background: -moz-linear-gradient(top, #fafafb 0%, #e5e5e5 100%); + +// List view: +// selected bar: --> active bar +// focus bar: active + border 1px dotted #090402 (inside the blue border) + +// table left/right border: #EDEDED 'light gray' + +// Import common styles +@import "skin-common.less"; + + +/******************************************************************************* + * Styles specific to this skin. + * + * This section is automatically generated from the `ui-fancytree.less` template. + ******************************************************************************/ + +// Override the variable after the import. +// NOTE: Variables are always resolved as the last definition, even if it is +// after where it is used. +@fancy-use-sprites: true; // false: suppress all background images (i.e. icons) + +@fancy-line-height: 20px; // height of a nodes selection bar including borders +@fancy-node-v-spacing: 1px; // gap between two node borders +@fancy-icon-width: 16px; +@fancy-icon-height: 16px; +@fancy-icon-spacing: 3px; // margin between icon/icon or icon/title +@fancy-icon-ofs-top: 2px; // extra vertical offset for expander, checkbox and icon +@fancy-title-ofs-top: 0px; // extra vertical offset for title +@fancy-node-border-width: 1px; +@fancy-node-border-radius: 3px; +@fancy-node-outline-width: 1px; + +// We need to define this variable here (not in skin-common.less) to make it +// work with grunt and webpack: +@fancy-image-prefix: "./skin-win7/"; + +// Use 'data-uri(...)' to embed the image into CSS instead of linking to 'loading.gif': +// @fancy-loading-url: data-uri("@{fancy-image-prefix}loading.gif"); +// Set to `true` to use `data-uri(...)` which will embed icons.gif into CSS +// instead of linking to that file: +// @fancy-inline-sprites: true; + +//default 10pt, which is used in a relative manner resulting in 13.3 in dokuwiki-template. +@fancy-font-size: 93%; + +ul.fancytree-container { + +} + +/******************************************************************************* + * Node titles + */ +span.fancytree-title { +} +// active nodes inside an UN-focused tree are gray instead of blue +span.fancytree-active .fancytree-title, +span.fancytree-selected .fancytree-title { + .spanStyleMixin(inherit, #e5e5e5, #d9d9d9, #fafafb, #e5e5e5); +} +span.fancytree-selected .fancytree-title { + font-style: italic; +} +// Markers inside an active tree +.fancytree-treefocus { + span.fancytree-active .fancytree-title, + span.fancytree-selected .fancytree-title { + .spanStyleMixin(inherit, #f6fbfd, #99defd, #f6fbfd, #d5effc); + } + span.fancytree-focused span.fancytree-title { + border: @fancy-node-border-width solid #719acb; + } +} +// Hover is always colored (even if tree is inactive) +span.fancytree-title:hover { + .spanStyleMixin(inherit, #f8fcfe, #d8f0fa, #f8fcfe, #eff9fe); +} +span.fancytree-active .fancytree-title:hover, +span.fancytree-selected .fancytree-title:hover { + .spanStyleMixin(inherit, #f2f9fd, #719acb, #f2f9fd, #c4e8fa); +} + +/******************************************************************************* + * 'table' extension + */ + +table.fancytree-ext-table tbody { + tr td { + border: 1px solid #ededed; + } + tr:hover { + .spanStyleMixin(inherit, #f8fcfe, inherit, #f8fcfe, #eff9fe); + outline: 1px solid #d8f0fa; + } + // tr:hover td { + // outline: 1px solid #D8F0FA; + // } + tr.fancytree-focused { + // background-color: #99DEFD; + outline: 1px dotted #090402; + } + span.fancytree-focused span.fancytree-title { + outline: solid dotted black; + } + + // Title gets a white background, when hovered. Undo standard node formatting + span.fancytree-title:hover { + border: 1px solid transparent; + background: inherit; + background: transparent; + background: none; + filter: none; + } + + tr.fancytree-active:hover, + tr.fancytree-selected:hover { + .spanStyleMixin(inherit, #f2f9fd, inherit, #f2f9fd, #c4e8fa); + outline: 1px solid #B6E6FB; + } + tr.fancytree-active, + tr.fancytree-selected { + .spanStyleMixin(inherit, #f6fbfd, inherit, #f6fbfd, #d5effc); + outline: 1px solid #99DEFD; + } + // tr.fancytree-selected .fancytree-title { + // font-style: italic; + // } + +} diff --git a/plugins/55/indexmenu/scripts/fancytree/skin-win7/ui.fancytree.min.css b/plugins/55/indexmenu/scripts/fancytree/skin-win7/ui.fancytree.min.css new file mode 100644 index 0000000..bcbe5eb --- /dev/null +++ b/plugins/55/indexmenu/scripts/fancytree/skin-win7/ui.fancytree.min.css @@ -0,0 +1,6 @@ +/*! + * Fancytree "Win7" skin. + * + * DON'T EDIT THE CSS FILE DIRECTLY, since it is automatically generated from + * the LESS templates. + */.fancytree-helper-hidden{display:none}.fancytree-helper-indeterminate-cb{color:#777}.fancytree-helper-disabled{color:silver}.fancytree-helper-spin{-webkit-animation:spin 1s infinite linear;animation:spin 1s infinite linear}@-webkit-keyframes spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}ul.fancytree-container{font-family:tahoma,arial,helvetica;font-size:10pt;white-space:nowrap;padding:3px;margin:0;background-color:#fff;border:1px dotted gray;min-height:0;position:relative}ul.fancytree-container ul{padding:0 0 0 16px;margin:0}ul.fancytree-container ul>li:before{content:none}ul.fancytree-container li{list-style-image:none;list-style-position:outside;list-style-type:none;-moz-background-clip:border;-moz-background-inline-policy:continuous;-moz-background-origin:padding;background-attachment:scroll;background-color:transparent;background-position:0 0;background-repeat:repeat-y;background-image:none;margin:0}ul.fancytree-container li.fancytree-lastsib{background-image:none}.ui-fancytree-disabled ul.fancytree-container{opacity:.5;background-color:silver}ul.fancytree-connectors.fancytree-container li{background-image:url("../skin-win7/vline.gif");background-position:0 0}ul.fancytree-container li.fancytree-lastsib,ul.fancytree-no-connector>li{background-image:none}li.fancytree-animating{position:relative}#fancytree-drop-marker,span.fancytree-checkbox,span.fancytree-drag-helper-img,span.fancytree-empty,span.fancytree-expander,span.fancytree-icon,span.fancytree-vline{width:16px;height:16px;display:inline-block;vertical-align:top;background-repeat:no-repeat;background-image:url("../skin-win7/icons.gif");background-position:0 0}span.fancytree-checkbox,span.fancytree-custom-icon,span.fancytree-expander,span.fancytree-icon{margin-top:2px}span.fancytree-custom-icon{width:16px;height:16px;display:inline-block;margin-left:3px;background-position:0 0}img.fancytree-icon{width:16px;height:16px;margin-left:3px;margin-top:2px;vertical-align:top;border-style:none}span.fancytree-expander{cursor:pointer}.fancytree-exp-n span.fancytree-expander,.fancytree-exp-nl span.fancytree-expander{background-image:none;cursor:default}.fancytree-connectors .fancytree-exp-n span.fancytree-expander,.fancytree-connectors .fancytree-exp-nl span.fancytree-expander{background-image:url("../skin-win7/icons.gif");margin-top:0}.fancytree-connectors .fancytree-exp-n span.fancytree-expander,.fancytree-connectors .fancytree-exp-n span.fancytree-expander:hover{background-position:0 -64px}.fancytree-connectors .fancytree-exp-nl span.fancytree-expander,.fancytree-connectors .fancytree-exp-nl span.fancytree-expander:hover{background-position:-16px -64px}.fancytree-exp-c span.fancytree-expander{background-position:0 -80px}.fancytree-exp-c span.fancytree-expander:hover{background-position:-16px -80px}.fancytree-exp-cl span.fancytree-expander{background-position:0 -96px}.fancytree-exp-cl span.fancytree-expander:hover{background-position:-16px -96px}.fancytree-exp-cd span.fancytree-expander{background-position:-64px -80px}.fancytree-exp-cd span.fancytree-expander:hover{background-position:-80px -80px}.fancytree-exp-cdl span.fancytree-expander{background-position:-64px -96px}.fancytree-exp-cdl span.fancytree-expander:hover{background-position:-80px -96px}.fancytree-exp-e span.fancytree-expander,.fancytree-exp-ed span.fancytree-expander{background-position:-32px -80px}.fancytree-exp-e span.fancytree-expander:hover,.fancytree-exp-ed span.fancytree-expander:hover{background-position:-48px -80px}.fancytree-exp-edl span.fancytree-expander,.fancytree-exp-el span.fancytree-expander{background-position:-32px -96px}.fancytree-exp-edl span.fancytree-expander:hover,.fancytree-exp-el span.fancytree-expander:hover{background-position:-48px -96px}.fancytree-fade-expander span.fancytree-expander{transition:opacity 1.5s;opacity:0}.fancytree-fade-expander .fancytree-treefocus span.fancytree-expander,.fancytree-fade-expander [class*=fancytree-statusnode-] span.fancytree-expander,.fancytree-fade-expander.fancytree-treefocus span.fancytree-expander,.fancytree-fade-expander:hover span.fancytree-expander{transition:opacity .6s;opacity:1}span.fancytree-checkbox{margin-left:3px;background-position:0 -32px}span.fancytree-checkbox:hover{background-position:-16px -32px}span.fancytree-checkbox.fancytree-radio{background-position:0 -48px}span.fancytree-checkbox.fancytree-radio:hover{background-position:-16px -48px}.fancytree-partsel span.fancytree-checkbox{background-position:-64px -32px}.fancytree-partsel span.fancytree-checkbox:hover{background-position:-80px -32px}.fancytree-partsel span.fancytree-checkbox.fancytree-radio{background-position:-64px -48px}.fancytree-partsel span.fancytree-checkbox.fancytree-radio:hover{background-position:-80px -48px}.fancytree-selected span.fancytree-checkbox{background-position:-32px -32px}.fancytree-selected span.fancytree-checkbox:hover{background-position:-48px -32px}.fancytree-selected span.fancytree-checkbox.fancytree-radio{background-position:-32px -48px}.fancytree-selected span.fancytree-checkbox.fancytree-radio:hover{background-position:-48px -48px}.fancytree-unselectable span.fancytree-checkbox{opacity:.4}.fancytree-unselectable span.fancytree-checkbox:hover{background-position:0 -32px}.fancytree-unselectable span.fancytree-checkbox.fancytree-radio:hover{background-position:0 -48px}.fancytree-unselectable.fancytree-partsel span.fancytree-checkbox:hover{background-position:-64px -32px}.fancytree-unselectable.fancytree-selected span.fancytree-checkbox:hover{background-position:-32px -32px}.fancytree-unselectable.fancytree-selected span.fancytree-checkbox.fancytree-radio:hover{background-position:-32px -48px}.fancytree-container.fancytree-checkbox-auto-hide span.fancytree-checkbox{visibility:hidden}.fancytree-container.fancytree-checkbox-auto-hide .fancytree-node.fancytree-selected span.fancytree-checkbox,.fancytree-container.fancytree-checkbox-auto-hide .fancytree-node:hover span.fancytree-checkbox,.fancytree-container.fancytree-checkbox-auto-hide tr.fancytree-selected td span.fancytree-checkbox,.fancytree-container.fancytree-checkbox-auto-hide tr:hover td span.fancytree-checkbox{visibility:unset}.fancytree-container.fancytree-checkbox-auto-hide.fancytree-treefocus .fancytree-node.fancytree-active span.fancytree-checkbox,.fancytree-container.fancytree-checkbox-auto-hide.fancytree-treefocus tr.fancytree-active td span.fancytree-checkbox{visibility:unset}span.fancytree-icon{margin-left:3px;background-position:0 0}.fancytree-ico-c span.fancytree-icon:hover{background-position:-16px 0}.fancytree-has-children.fancytree-ico-c span.fancytree-icon{background-position:-32px 0}.fancytree-has-children.fancytree-ico-c span.fancytree-icon:hover{background-position:-48px 0}.fancytree-ico-e span.fancytree-icon{background-position:-64px 0}.fancytree-ico-e span.fancytree-icon:hover{background-position:-80px 0}.fancytree-ico-cf span.fancytree-icon{background-position:0 -16px}.fancytree-ico-cf span.fancytree-icon:hover{background-position:-16px -16px}.fancytree-has-children.fancytree-ico-cf span.fancytree-icon{background-position:-32px -16px}.fancytree-has-children.fancytree-ico-cf span.fancytree-icon:hover{background-position:-48px -16px}.fancytree-ico-ef span.fancytree-icon{background-position:-64px -16px}.fancytree-ico-ef span.fancytree-icon:hover{background-position:-80px -16px}.fancytree-loading span.fancytree-expander,.fancytree-loading span.fancytree-expander:hover,.fancytree-statusnode-loading span.fancytree-icon,.fancytree-statusnode-loading span.fancytree-icon:hover,span.fancytree-icon.fancytree-icon-loading{background-image:url("../skin-win7/loading.gif");background-position:0 0}.fancytree-statusnode-error span.fancytree-icon,.fancytree-statusnode-error span.fancytree-icon:hover{background-position:0 -112px}span.fancytree-node{display:inherit;width:100%;margin-top:1px;min-height:20px}span.fancytree-title{color:#000;cursor:pointer;display:inline-block;vertical-align:top;min-height:20px;padding:0 3px 0 3px;margin:0 0 0 3px;border:1px solid transparent;-webkit-border-radius:3px;-moz-border-radius:3px;-ms-border-radius:3px;-o-border-radius:3px;border-radius:3px}span.fancytree-node.fancytree-error span.fancytree-title{color:red}span.fancytree-childcounter{color:#fff;background:#337ab7;border:1px solid gray;border-radius:10px;padding:2px;text-align:center}div.fancytree-drag-helper span.fancytree-childcounter,div.fancytree-drag-helper span.fancytree-dnd-modifier{display:inline-block;color:#fff;background:#337ab7;border:1px solid gray;min-width:10px;height:10px;line-height:1;vertical-align:baseline;border-radius:10px;padding:2px;text-align:center;font-size:9px}div.fancytree-drag-helper span.fancytree-childcounter{position:absolute;top:-6px;right:-6px}div.fancytree-drag-helper span.fancytree-dnd-modifier{background:#5cb85c;border:none;font-weight:bolder}div.fancytree-drag-helper.fancytree-drop-accept span.fancytree-drag-helper-img{background-position:-32px -112px}div.fancytree-drag-helper.fancytree-drop-reject span.fancytree-drag-helper-img{background-position:-16px -112px}#fancytree-drop-marker{width:32px;position:absolute;background-position:0 -128px;margin:0}#fancytree-drop-marker.fancytree-drop-after,#fancytree-drop-marker.fancytree-drop-before{width:64px;background-position:0 -144px}#fancytree-drop-marker.fancytree-drop-copy{background-position:-64px -128px}#fancytree-drop-marker.fancytree-drop-move{background-position:-32px -128px}span.fancytree-drag-source.fancytree-drag-remove{opacity:.15}.fancytree-container.fancytree-rtl span.fancytree-connector,.fancytree-container.fancytree-rtl span.fancytree-drag-helper-img,.fancytree-container.fancytree-rtl span.fancytree-expander,.fancytree-container.fancytree-rtl span.fancytree-icon{background-image:url("../skin-win7/icons-rtl.gif")}.fancytree-container.fancytree-rtl .fancytree-exp-n span.fancytree-expander,.fancytree-container.fancytree-rtl .fancytree-exp-nl span.fancytree-expander{background-image:none}.fancytree-container.fancytree-rtl.fancytree-connectors .fancytree-exp-n span.fancytree-expander,.fancytree-container.fancytree-rtl.fancytree-connectors .fancytree-exp-nl span.fancytree-expander{background-image:url("../skin-win7/icons-rtl.gif")}ul.fancytree-container.fancytree-rtl ul{padding:0 16px 0 0}ul.fancytree-container.fancytree-rtl.fancytree-connectors li{background-position:right 0;background-image:url("../skin-win7/vline-rtl.gif")}ul.fancytree-container.fancytree-rtl li.fancytree-lastsib,ul.fancytree-container.fancytree-rtl.fancytree-no-connector>li{background-image:none}#fancytree-drop-marker.fancytree-rtl{background-image:url("../skin-win7/icons-rtl.gif")}table.fancytree-ext-table{font-family:tahoma,arial,helvetica;font-size:10pt;border-collapse:collapse}table.fancytree-ext-table span.fancytree-node{display:inline-block;box-sizing:border-box}table.fancytree-ext-table td.fancytree-status-merged{text-align:center;font-style:italic;color:silver}table.fancytree-ext-table tr.fancytree-statusnode-error td.fancytree-status-merged{color:red}table.fancytree-ext-table.fancytree-ext-ariagrid.fancytree-cell-mode>tbody>tr.fancytree-active>td{background-color:#eee}table.fancytree-ext-table.fancytree-ext-ariagrid.fancytree-cell-mode>tbody>tr>td.fancytree-active-cell{background-color:#cbe8f6}table.fancytree-ext-table.fancytree-ext-ariagrid.fancytree-cell-mode.fancytree-cell-nav-mode>tbody>tr>td.fancytree-active-cell{background-color:#3875d7}table.fancytree-ext-columnview tbody tr td{position:relative;border:1px solid gray;vertical-align:top;overflow:auto}table.fancytree-ext-columnview tbody tr td>ul{padding:0}table.fancytree-ext-columnview tbody tr td>ul li{list-style-image:none;list-style-position:outside;list-style-type:none;-moz-background-clip:border;-moz-background-inline-policy:continuous;-moz-background-origin:padding;background-attachment:scroll;background-color:transparent;background-position:0 0;background-repeat:repeat-y;background-image:none;margin:0}table.fancytree-ext-columnview span.fancytree-node{position:relative;display:inline-block}table.fancytree-ext-columnview span.fancytree-node.fancytree-expanded{background-color:#e0e0e0}table.fancytree-ext-columnview span.fancytree-node.fancytree-active{background-color:#cbe8f6}table.fancytree-ext-columnview .fancytree-has-children span.fancytree-cv-right{position:absolute;right:3px;background-position:0 -80px}table.fancytree-ext-columnview .fancytree-has-children span.fancytree-cv-right:hover{background-position:-16px -80px}.fancytree-ext-filter-dimm span.fancytree-node span.fancytree-title{color:silver;font-weight:lighter}.fancytree-ext-filter-dimm span.fancytree-node.fancytree-submatch span.fancytree-title,.fancytree-ext-filter-dimm tr.fancytree-submatch span.fancytree-title{color:#000;font-weight:400}.fancytree-ext-filter-dimm span.fancytree-node.fancytree-match span.fancytree-title,.fancytree-ext-filter-dimm tr.fancytree-match span.fancytree-title{color:#000;font-weight:700}.fancytree-ext-filter-hide span.fancytree-node.fancytree-hide,.fancytree-ext-filter-hide tr.fancytree-hide{display:none}.fancytree-ext-filter-hide span.fancytree-node.fancytree-submatch span.fancytree-title,.fancytree-ext-filter-hide tr.fancytree-submatch span.fancytree-title{color:silver;font-weight:lighter}.fancytree-ext-filter-hide span.fancytree-node.fancytree-match span.fancytree-title,.fancytree-ext-filter-hide tr.fancytree-match span.fancytree-title{color:#000;font-weight:400}.fancytree-ext-filter-hide-expanders span.fancytree-node.fancytree-match span.fancytree-expander,.fancytree-ext-filter-hide-expanders tr.fancytree-match span.fancytree-expander{visibility:hidden}.fancytree-ext-filter-hide-expanders span.fancytree-node.fancytree-submatch span.fancytree-expander,.fancytree-ext-filter-hide-expanders tr.fancytree-submatch span.fancytree-expander{visibility:visible}.fancytree-ext-childcounter span.fancytree-custom-icon,.fancytree-ext-childcounter span.fancytree-icon,.fancytree-ext-filter span.fancytree-custom-icon,.fancytree-ext-filter span.fancytree-icon{position:relative}.fancytree-ext-childcounter span.fancytree-childcounter,.fancytree-ext-filter span.fancytree-childcounter{color:#fff;background:#777;border:1px solid gray;position:absolute;top:-6px;right:-6px;min-width:10px;height:10px;line-height:1;vertical-align:baseline;border-radius:10px;padding:2px;text-align:center;font-size:9px}ul.fancytree-ext-wide{position:relative;min-width:100%;z-index:2;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}ul.fancytree-ext-wide span.fancytree-node>span{position:relative;z-index:2}ul.fancytree-ext-wide span.fancytree-node span.fancytree-title{position:absolute;z-index:1;left:0;min-width:100%;margin-left:0;margin-right:0;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.fancytree-ext-fixed-wrapper .fancytree-ext-fixed-hidden{display:none}.fancytree-ext-fixed-wrapper div.fancytree-ext-fixed-scroll-border-bottom{border-bottom:3px solid rgba(0,0,0,.75)}.fancytree-ext-fixed-wrapper div.fancytree-ext-fixed-scroll-border-right{border-right:3px solid rgba(0,0,0,.75)}.fancytree-ext-fixed-wrapper div.fancytree-ext-fixed-wrapper-tl{position:absolute;overflow:hidden;z-index:3;top:0;left:0}.fancytree-ext-fixed-wrapper div.fancytree-ext-fixed-wrapper-tr{position:absolute;overflow:hidden;z-index:2;top:0}.fancytree-ext-fixed-wrapper div.fancytree-ext-fixed-wrapper-bl{position:absolute;overflow:hidden;z-index:2;left:0}.fancytree-ext-fixed-wrapper div.fancytree-ext-fixed-wrapper-br{position:absolute;overflow:scroll;z-index:1}span.fancytree-active .fancytree-title,span.fancytree-selected .fancytree-title{border-color:#d9d9d9;background:#e5e5e5;color:inherit;background:-moz-linear-gradient(top,#fafafb 0,#e5e5e5 100%);background:-webkit-gradient(linear,left top,left bottom,color-stop(0,#fafafb),color-stop(100%,#e5e5e5));background:-webkit-linear-gradient(top,#fafafb 0,#e5e5e5 100%);background:-o-linear-gradient(top,#fafafb 0,#e5e5e5 100%);background:-ms-linear-gradient(top,#fafafb 0,#e5e5e5 100%);background:linear-gradient(to bottom,#fafafb 0,#e5e5e5 100%)}span.fancytree-selected .fancytree-title{font-style:italic}.fancytree-treefocus span.fancytree-active .fancytree-title,.fancytree-treefocus span.fancytree-selected .fancytree-title{border-color:#99defd;background:#f6fbfd;color:inherit;background:-moz-linear-gradient(top,#f6fbfd 0,#d5effc 100%);background:-webkit-gradient(linear,left top,left bottom,color-stop(0,#f6fbfd),color-stop(100%,#d5effc));background:-webkit-linear-gradient(top,#f6fbfd 0,#d5effc 100%);background:-o-linear-gradient(top,#f6fbfd 0,#d5effc 100%);background:-ms-linear-gradient(top,#f6fbfd 0,#d5effc 100%);background:linear-gradient(to bottom,#f6fbfd 0,#d5effc 100%)}.fancytree-treefocus span.fancytree-focused span.fancytree-title{border:1px solid #719acb}span.fancytree-title:hover{border-color:#d8f0fa;background:#f8fcfe;color:inherit;background:-moz-linear-gradient(top,#f8fcfe 0,#eff9fe 100%);background:-webkit-gradient(linear,left top,left bottom,color-stop(0,#f8fcfe),color-stop(100%,#eff9fe));background:-webkit-linear-gradient(top,#f8fcfe 0,#eff9fe 100%);background:-o-linear-gradient(top,#f8fcfe 0,#eff9fe 100%);background:-ms-linear-gradient(top,#f8fcfe 0,#eff9fe 100%);background:linear-gradient(to bottom,#f8fcfe 0,#eff9fe 100%)}span.fancytree-active .fancytree-title:hover,span.fancytree-selected .fancytree-title:hover{border-color:#719acb;background:#f2f9fd;color:inherit;background:-moz-linear-gradient(top,#f2f9fd 0,#c4e8fa 100%);background:-webkit-gradient(linear,left top,left bottom,color-stop(0,#f2f9fd),color-stop(100%,#c4e8fa));background:-webkit-linear-gradient(top,#f2f9fd 0,#c4e8fa 100%);background:-o-linear-gradient(top,#f2f9fd 0,#c4e8fa 100%);background:-ms-linear-gradient(top,#f2f9fd 0,#c4e8fa 100%);background:linear-gradient(to bottom,#f2f9fd 0,#c4e8fa 100%)}table.fancytree-ext-table tbody tr td{border:1px solid #ededed}table.fancytree-ext-table tbody tr:hover{border-color:inherit;background:#f8fcfe;color:inherit;background:-moz-linear-gradient(top,#f8fcfe 0,#eff9fe 100%);background:-webkit-gradient(linear,left top,left bottom,color-stop(0,#f8fcfe),color-stop(100%,#eff9fe));background:-webkit-linear-gradient(top,#f8fcfe 0,#eff9fe 100%);background:-o-linear-gradient(top,#f8fcfe 0,#eff9fe 100%);background:-ms-linear-gradient(top,#f8fcfe 0,#eff9fe 100%);background:linear-gradient(to bottom,#f8fcfe 0,#eff9fe 100%);outline:1px solid #d8f0fa}table.fancytree-ext-table tbody tr.fancytree-focused{outline:1px dotted #090402}table.fancytree-ext-table tbody span.fancytree-focused span.fancytree-title{outline:solid dotted black}table.fancytree-ext-table tbody span.fancytree-title:hover{border:1px solid transparent;background:inherit;background:0 0;background:0 0;filter:none}table.fancytree-ext-table tbody tr.fancytree-active:hover,table.fancytree-ext-table tbody tr.fancytree-selected:hover{border-color:inherit;background:#f2f9fd;color:inherit;background:-moz-linear-gradient(top,#f2f9fd 0,#c4e8fa 100%);background:-webkit-gradient(linear,left top,left bottom,color-stop(0,#f2f9fd),color-stop(100%,#c4e8fa));background:-webkit-linear-gradient(top,#f2f9fd 0,#c4e8fa 100%);background:-o-linear-gradient(top,#f2f9fd 0,#c4e8fa 100%);background:-ms-linear-gradient(top,#f2f9fd 0,#c4e8fa 100%);background:linear-gradient(to bottom,#f2f9fd 0,#c4e8fa 100%);outline:1px solid #B6E6FB}table.fancytree-ext-table tbody tr.fancytree-active,table.fancytree-ext-table tbody tr.fancytree-selected{border-color:inherit;background:#f6fbfd;color:inherit;background:-moz-linear-gradient(top,#f6fbfd 0,#d5effc 100%);background:-webkit-gradient(linear,left top,left bottom,color-stop(0,#f6fbfd),color-stop(100%,#d5effc));background:-webkit-linear-gradient(top,#f6fbfd 0,#d5effc 100%);background:-o-linear-gradient(top,#f6fbfd 0,#d5effc 100%);background:-ms-linear-gradient(top,#f6fbfd 0,#d5effc 100%);background:linear-gradient(to bottom,#f6fbfd 0,#d5effc 100%);outline:1px solid #99DEFD}
\ No newline at end of file diff --git a/plugins/55/indexmenu/scripts/fancytree/skin-win7/vline-rtl.gif b/plugins/55/indexmenu/scripts/fancytree/skin-win7/vline-rtl.gif Binary files differnew file mode 100644 index 0000000..f9b4232 --- /dev/null +++ b/plugins/55/indexmenu/scripts/fancytree/skin-win7/vline-rtl.gif diff --git a/plugins/55/indexmenu/scripts/fancytree/skin-win7/vline.gif b/plugins/55/indexmenu/scripts/fancytree/skin-win7/vline.gif Binary files differnew file mode 100644 index 0000000..f9b4232 --- /dev/null +++ b/plugins/55/indexmenu/scripts/fancytree/skin-win7/vline.gif diff --git a/plugins/55/indexmenu/scripts/fancytree/skin-win8-n/icons-rtl.gif b/plugins/55/indexmenu/scripts/fancytree/skin-win8-n/icons-rtl.gif Binary files differnew file mode 100644 index 0000000..443e1e4 --- /dev/null +++ b/plugins/55/indexmenu/scripts/fancytree/skin-win8-n/icons-rtl.gif diff --git a/plugins/55/indexmenu/scripts/fancytree/skin-win8-n/icons.gif b/plugins/55/indexmenu/scripts/fancytree/skin-win8-n/icons.gif Binary files differnew file mode 100644 index 0000000..0097b1f --- /dev/null +++ b/plugins/55/indexmenu/scripts/fancytree/skin-win8-n/icons.gif diff --git a/plugins/55/indexmenu/scripts/fancytree/skin-win8-n/loading.gif b/plugins/55/indexmenu/scripts/fancytree/skin-win8-n/loading.gif Binary files differnew file mode 100644 index 0000000..ef88497 --- /dev/null +++ b/plugins/55/indexmenu/scripts/fancytree/skin-win8-n/loading.gif diff --git a/plugins/55/indexmenu/scripts/fancytree/skin-win8-n/ui.fancytree.css b/plugins/55/indexmenu/scripts/fancytree/skin-win8-n/ui.fancytree.css new file mode 100644 index 0000000..73113d6 --- /dev/null +++ b/plugins/55/indexmenu/scripts/fancytree/skin-win8-n/ui.fancytree.css @@ -0,0 +1,767 @@ +/*! + * Fancytree "win8" skin (highlighting the node span instead of title-only). + * + * DON'T EDIT THE CSS FILE DIRECTLY, since it is automatically generated from + * the LESS templates. + */ +/******************************************************************************* + * Common Styles for Fancytree Skins. + * + * This section is automatically generated from the `skin-common.less` template. + * + * Copyright (c) 2008-2023, Martin Wendt (https://wwWendt.de) + * Released under the MIT license + * https://github.com/mar10/fancytree/wiki/LicenseInfo + * + * @version 2.38.3 + * @date 2023-02-01T20:52:50Z +******************************************************************************/ +/*------------------------------------------------------------------------------ + * Helpers + *----------------------------------------------------------------------------*/ +.fancytree-helper-hidden { + display: none; +} +.fancytree-helper-indeterminate-cb { + color: #777; +} +.fancytree-helper-disabled { + color: #c0c0c0; +} +/* Helper to allow spinning loader icon with glyph-, ligature-, and SVG-icons. */ +.fancytree-helper-spin { + -webkit-animation: spin 1000ms infinite linear; + animation: spin 1000ms infinite linear; +} +@-webkit-keyframes spin { + 0% { + -webkit-transform: rotate(0deg); + transform: rotate(0deg); + } + 100% { + -webkit-transform: rotate(359deg); + transform: rotate(359deg); + } +} +@keyframes spin { + 0% { + -webkit-transform: rotate(0deg); + transform: rotate(0deg); + } + 100% { + -webkit-transform: rotate(359deg); + transform: rotate(359deg); + } +} +/*------------------------------------------------------------------------------ + * Container and UL / LI + *----------------------------------------------------------------------------*/ +ul.fancytree-container { + font-family: tahoma, arial, helvetica; + font-size: 10pt; + white-space: nowrap; + padding: 3px; + margin: 0; + background-color: white; + border: 1px dotted gray; + min-height: 0%; + position: relative; +} +ul.fancytree-container ul { + padding: 0 0 0 16px; + margin: 0; +} +ul.fancytree-container ul > li:before { + content: none; +} +ul.fancytree-container li { + list-style-image: none; + list-style-position: outside; + list-style-type: none; + -moz-background-clip: border; + -moz-background-inline-policy: continuous; + -moz-background-origin: padding; + background-attachment: scroll; + background-color: transparent; + background-position: 0px 0px; + background-repeat: repeat-y; + background-image: none; + margin: 0; +} +ul.fancytree-container li.fancytree-lastsib { + background-image: none; +} +.ui-fancytree-disabled ul.fancytree-container { + opacity: 0.5; + background-color: silver; +} +ul.fancytree-connectors.fancytree-container li { + background-image: url("../skin-win8-n/vline.gif"); + background-position: 0 0; +} +ul.fancytree-container li.fancytree-lastsib, +ul.fancytree-no-connector > li { + background-image: none; +} +li.fancytree-animating { + position: relative; +} +/*------------------------------------------------------------------------------ + * Common icon definitions + *----------------------------------------------------------------------------*/ +span.fancytree-empty, +span.fancytree-vline, +span.fancytree-expander, +span.fancytree-icon, +span.fancytree-checkbox, +span.fancytree-drag-helper-img, +#fancytree-drop-marker { + width: 16px; + height: 16px; + display: inline-block; + vertical-align: top; + background-repeat: no-repeat; + background-image: url("../skin-win8-n/icons.gif"); + background-position: 0px 0px; +} +span.fancytree-icon, +span.fancytree-checkbox, +span.fancytree-expander, +span.fancytree-custom-icon { + margin-top: 0px; +} +/* Used by icon option: */ +span.fancytree-custom-icon { + width: 16px; + height: 16px; + display: inline-block; + margin-left: 3px; + background-position: 0px 0px; +} +/* Used by 'icon' node option: */ +img.fancytree-icon { + width: 16px; + height: 16px; + margin-left: 3px; + margin-top: 0px; + vertical-align: top; + border-style: none; +} +/*------------------------------------------------------------------------------ + * Expander icon + * + * Note: IE6 doesn't correctly evaluate multiples class names, + * so we create combined class names that can be used in the CSS. + * + * Prefix: fancytree-exp- + * 1st character: 'e': expanded, 'c': collapsed, 'n': no children + * 2nd character (optional): 'd': lazy (Delayed) + * 3rd character (optional): 'l': Last sibling + *----------------------------------------------------------------------------*/ +span.fancytree-expander { + cursor: pointer; +} +.fancytree-exp-n span.fancytree-expander, +.fancytree-exp-nl span.fancytree-expander { + background-image: none; + cursor: default; +} +.fancytree-connectors .fancytree-exp-n span.fancytree-expander, +.fancytree-connectors .fancytree-exp-nl span.fancytree-expander { + background-image: url("../skin-win8-n/icons.gif"); + margin-top: 0; +} +.fancytree-connectors .fancytree-exp-n span.fancytree-expander, +.fancytree-connectors .fancytree-exp-n span.fancytree-expander:hover { + background-position: 0px -64px; +} +.fancytree-connectors .fancytree-exp-nl span.fancytree-expander, +.fancytree-connectors .fancytree-exp-nl span.fancytree-expander:hover { + background-position: -16px -64px; +} +.fancytree-exp-c span.fancytree-expander { + background-position: 0px -80px; +} +.fancytree-exp-c span.fancytree-expander:hover { + background-position: -16px -80px; +} +.fancytree-exp-cl span.fancytree-expander { + background-position: 0px -96px; +} +.fancytree-exp-cl span.fancytree-expander:hover { + background-position: -16px -96px; +} +.fancytree-exp-cd span.fancytree-expander { + background-position: -64px -80px; +} +.fancytree-exp-cd span.fancytree-expander:hover { + background-position: -80px -80px; +} +.fancytree-exp-cdl span.fancytree-expander { + background-position: -64px -96px; +} +.fancytree-exp-cdl span.fancytree-expander:hover { + background-position: -80px -96px; +} +.fancytree-exp-e span.fancytree-expander, +.fancytree-exp-ed span.fancytree-expander { + background-position: -32px -80px; +} +.fancytree-exp-e span.fancytree-expander:hover, +.fancytree-exp-ed span.fancytree-expander:hover { + background-position: -48px -80px; +} +.fancytree-exp-el span.fancytree-expander, +.fancytree-exp-edl span.fancytree-expander { + background-position: -32px -96px; +} +.fancytree-exp-el span.fancytree-expander:hover, +.fancytree-exp-edl span.fancytree-expander:hover { + background-position: -48px -96px; +} +/* Fade out expanders, when container is not hovered or active */ +.fancytree-fade-expander span.fancytree-expander { + transition: opacity 1.5s; + opacity: 0; +} +.fancytree-fade-expander:hover span.fancytree-expander, +.fancytree-fade-expander.fancytree-treefocus span.fancytree-expander, +.fancytree-fade-expander .fancytree-treefocus span.fancytree-expander, +.fancytree-fade-expander [class*="fancytree-statusnode-"] span.fancytree-expander { + transition: opacity 0.6s; + opacity: 1; +} +/*------------------------------------------------------------------------------ + * Checkbox icon + *----------------------------------------------------------------------------*/ +span.fancytree-checkbox { + margin-left: 3px; + background-position: 0px -32px; +} +span.fancytree-checkbox:hover { + background-position: -16px -32px; +} +span.fancytree-checkbox.fancytree-radio { + background-position: 0px -48px; +} +span.fancytree-checkbox.fancytree-radio:hover { + background-position: -16px -48px; +} +.fancytree-partsel span.fancytree-checkbox { + background-position: -64px -32px; +} +.fancytree-partsel span.fancytree-checkbox:hover { + background-position: -80px -32px; +} +.fancytree-partsel span.fancytree-checkbox.fancytree-radio { + background-position: -64px -48px; +} +.fancytree-partsel span.fancytree-checkbox.fancytree-radio:hover { + background-position: -80px -48px; +} +.fancytree-selected span.fancytree-checkbox { + background-position: -32px -32px; +} +.fancytree-selected span.fancytree-checkbox:hover { + background-position: -48px -32px; +} +.fancytree-selected span.fancytree-checkbox.fancytree-radio { + background-position: -32px -48px; +} +.fancytree-selected span.fancytree-checkbox.fancytree-radio:hover { + background-position: -48px -48px; +} +.fancytree-unselectable span.fancytree-checkbox { + opacity: 0.4; + filter: alpha(opacity=40); +} +.fancytree-unselectable span.fancytree-checkbox:hover { + background-position: 0px -32px; +} +.fancytree-unselectable span.fancytree-checkbox.fancytree-radio:hover { + background-position: 0px -48px; +} +.fancytree-unselectable.fancytree-partsel span.fancytree-checkbox:hover { + background-position: -64px -32px; +} +.fancytree-unselectable.fancytree-selected span.fancytree-checkbox:hover { + background-position: -32px -32px; +} +.fancytree-unselectable.fancytree-selected span.fancytree-checkbox.fancytree-radio:hover { + background-position: -32px -48px; +} +.fancytree-container.fancytree-checkbox-auto-hide span.fancytree-checkbox { + visibility: hidden; +} +.fancytree-container.fancytree-checkbox-auto-hide .fancytree-node:hover span.fancytree-checkbox, +.fancytree-container.fancytree-checkbox-auto-hide tr:hover td span.fancytree-checkbox, +.fancytree-container.fancytree-checkbox-auto-hide .fancytree-node.fancytree-selected span.fancytree-checkbox, +.fancytree-container.fancytree-checkbox-auto-hide tr.fancytree-selected td span.fancytree-checkbox { + visibility: unset; +} +.fancytree-container.fancytree-checkbox-auto-hide.fancytree-treefocus .fancytree-node.fancytree-active span.fancytree-checkbox, +.fancytree-container.fancytree-checkbox-auto-hide.fancytree-treefocus tr.fancytree-active td span.fancytree-checkbox { + visibility: unset; +} +/*------------------------------------------------------------------------------ + * Node type icon + * Note: IE6 doesn't correctly evaluate multiples class names, + * so we create combined class names that can be used in the CSS. + * + * Prefix: fancytree-ico- + * 1st character: 'e': expanded, 'c': collapsed + * 2nd character (optional): 'f': folder + *----------------------------------------------------------------------------*/ +span.fancytree-icon { + margin-left: 3px; + background-position: 0px 0px; +} +/* Documents */ +.fancytree-ico-c span.fancytree-icon:hover { + background-position: -16px 0px; +} +.fancytree-has-children.fancytree-ico-c span.fancytree-icon { + background-position: -32px 0px; +} +.fancytree-has-children.fancytree-ico-c span.fancytree-icon:hover { + background-position: -48px 0px; +} +.fancytree-ico-e span.fancytree-icon { + background-position: -64px 0px; +} +.fancytree-ico-e span.fancytree-icon:hover { + background-position: -80px 0px; +} +/* Folders */ +.fancytree-ico-cf span.fancytree-icon { + background-position: 0px -16px; +} +.fancytree-ico-cf span.fancytree-icon:hover { + background-position: -16px -16px; +} +.fancytree-has-children.fancytree-ico-cf span.fancytree-icon { + background-position: -32px -16px; +} +.fancytree-has-children.fancytree-ico-cf span.fancytree-icon:hover { + background-position: -48px -16px; +} +.fancytree-ico-ef span.fancytree-icon { + background-position: -64px -16px; +} +.fancytree-ico-ef span.fancytree-icon:hover { + background-position: -80px -16px; +} +.fancytree-loading span.fancytree-expander, +.fancytree-loading span.fancytree-expander:hover, +.fancytree-statusnode-loading span.fancytree-icon, +.fancytree-statusnode-loading span.fancytree-icon:hover, +span.fancytree-icon.fancytree-icon-loading { + background-image: url("../skin-win8-n/loading.gif"); + background-position: 0px 0px; +} +/* Status node icons */ +.fancytree-statusnode-error span.fancytree-icon, +.fancytree-statusnode-error span.fancytree-icon:hover { + background-position: 0px -112px; +} +/*------------------------------------------------------------------------------ + * Node titles and highlighting + *----------------------------------------------------------------------------*/ +span.fancytree-node { + /* See #117 */ + display: inherit; + width: 100%; + margin-top: 1px; + min-height: 16px; +} +span.fancytree-title { + color: black; + cursor: pointer; + display: inline-block; + vertical-align: top; + min-height: 16px; + padding: 0 3px 0 3px; + margin: 0px 0 0 3px; + border: 1px solid transparent; + -webkit-border-radius: 0px; + -moz-border-radius: 0px; + -ms-border-radius: 0px; + -o-border-radius: 0px; + border-radius: 0px; +} +span.fancytree-node.fancytree-error span.fancytree-title { + color: red; +} +/*------------------------------------------------------------------------------ + * Drag'n'drop support + *----------------------------------------------------------------------------*/ +/* ext-dnd5: */ +span.fancytree-childcounter { + color: #fff; + background: #337ab7; + border: 1px solid gray; + border-radius: 10px; + padding: 2px; + text-align: center; +} +/* ext-dnd: */ +div.fancytree-drag-helper span.fancytree-childcounter, +div.fancytree-drag-helper span.fancytree-dnd-modifier { + display: inline-block; + color: #fff; + background: #337ab7; + border: 1px solid gray; + min-width: 10px; + height: 10px; + line-height: 1; + vertical-align: baseline; + border-radius: 10px; + padding: 2px; + text-align: center; + font-size: 9px; +} +div.fancytree-drag-helper span.fancytree-childcounter { + position: absolute; + top: -6px; + right: -6px; +} +div.fancytree-drag-helper span.fancytree-dnd-modifier { + background: #5cb85c; + border: none; + font-weight: bolder; +} +div.fancytree-drag-helper.fancytree-drop-accept span.fancytree-drag-helper-img { + background-position: -32px -112px; +} +div.fancytree-drag-helper.fancytree-drop-reject span.fancytree-drag-helper-img { + background-position: -16px -112px; +} +/*** Drop marker icon *********************************************************/ +#fancytree-drop-marker { + width: 32px; + position: absolute; + background-position: 0px -128px; + margin: 0; +} +#fancytree-drop-marker.fancytree-drop-after, +#fancytree-drop-marker.fancytree-drop-before { + width: 64px; + background-position: 0px -144px; +} +#fancytree-drop-marker.fancytree-drop-copy { + background-position: -64px -128px; +} +#fancytree-drop-marker.fancytree-drop-move { + background-position: -32px -128px; +} +/*** Source node while dragging ***********************************************/ +span.fancytree-drag-source.fancytree-drag-remove { + opacity: 0.15; +} +/*** Target node while dragging cursor is over it *****************************/ +/*------------------------------------------------------------------------------ + * 'rtl' option + *----------------------------------------------------------------------------*/ +.fancytree-container.fancytree-rtl .fancytree-title { + /*unicode-bidi: bidi-override;*/ + /* optional: reverse title letters */ +} +.fancytree-container.fancytree-rtl span.fancytree-connector, +.fancytree-container.fancytree-rtl span.fancytree-expander, +.fancytree-container.fancytree-rtl span.fancytree-icon, +.fancytree-container.fancytree-rtl span.fancytree-drag-helper-img { + background-image: url("../skin-win8-n/icons-rtl.gif"); +} +.fancytree-container.fancytree-rtl .fancytree-exp-n span.fancytree-expander, +.fancytree-container.fancytree-rtl .fancytree-exp-nl span.fancytree-expander { + background-image: none; +} +.fancytree-container.fancytree-rtl.fancytree-connectors .fancytree-exp-n span.fancytree-expander, +.fancytree-container.fancytree-rtl.fancytree-connectors .fancytree-exp-nl span.fancytree-expander { + background-image: url("../skin-win8-n/icons-rtl.gif"); +} +ul.fancytree-container.fancytree-rtl ul { + padding: 0 16px 0 0; +} +ul.fancytree-container.fancytree-rtl.fancytree-connectors li { + background-position: right 0; + background-image: url("../skin-win8-n/vline-rtl.gif"); +} +ul.fancytree-container.fancytree-rtl li.fancytree-lastsib, +ul.fancytree-container.fancytree-rtl.fancytree-no-connector > li { + background-image: none; +} +#fancytree-drop-marker.fancytree-rtl { + background-image: url("../skin-win8-n/icons-rtl.gif"); +} +/*------------------------------------------------------------------------------ + * 'table' extension + *----------------------------------------------------------------------------*/ +table.fancytree-ext-table { + font-family: tahoma, arial, helvetica; + font-size: 10pt; + border-collapse: collapse; + /* ext-ariagrid */ +} +table.fancytree-ext-table span.fancytree-node { + display: inline-block; + box-sizing: border-box; +} +table.fancytree-ext-table td.fancytree-status-merged { + text-align: center; + font-style: italic; + color: #c0c0c0; +} +table.fancytree-ext-table tr.fancytree-statusnode-error td.fancytree-status-merged { + color: red; +} +table.fancytree-ext-table.fancytree-ext-ariagrid.fancytree-cell-mode > tbody > tr.fancytree-active > td { + background-color: #eee; +} +table.fancytree-ext-table.fancytree-ext-ariagrid.fancytree-cell-mode > tbody > tr > td.fancytree-active-cell { + background-color: #cbe8f6; +} +table.fancytree-ext-table.fancytree-ext-ariagrid.fancytree-cell-mode.fancytree-cell-nav-mode > tbody > tr > td.fancytree-active-cell { + background-color: #3875d7; +} +/*------------------------------------------------------------------------------ + * 'columnview' extension + *----------------------------------------------------------------------------*/ +table.fancytree-ext-columnview tbody tr td { + position: relative; + border: 1px solid gray; + vertical-align: top; + overflow: auto; +} +table.fancytree-ext-columnview tbody tr td > ul { + padding: 0; +} +table.fancytree-ext-columnview tbody tr td > ul li { + list-style-image: none; + list-style-position: outside; + list-style-type: none; + -moz-background-clip: border; + -moz-background-inline-policy: continuous; + -moz-background-origin: padding; + background-attachment: scroll; + background-color: transparent; + background-position: 0px 0px; + background-repeat: repeat-y; + background-image: none; + /* no v-lines */ + margin: 0; +} +table.fancytree-ext-columnview span.fancytree-node { + position: relative; + /* allow positioning of embedded spans */ + display: inline-block; +} +table.fancytree-ext-columnview span.fancytree-node.fancytree-expanded { + background-color: #e0e0e0; +} +table.fancytree-ext-columnview span.fancytree-node.fancytree-active { + background-color: #cbe8f6; +} +table.fancytree-ext-columnview .fancytree-has-children span.fancytree-cv-right { + position: absolute; + right: 3px; + background-position: 0px -80px; +} +table.fancytree-ext-columnview .fancytree-has-children span.fancytree-cv-right:hover { + background-position: -16px -80px; +} +/*------------------------------------------------------------------------------ + * 'filter' extension + *----------------------------------------------------------------------------*/ +.fancytree-ext-filter-dimm span.fancytree-node span.fancytree-title { + color: #c0c0c0; + font-weight: lighter; +} +.fancytree-ext-filter-dimm tr.fancytree-submatch span.fancytree-title, +.fancytree-ext-filter-dimm span.fancytree-node.fancytree-submatch span.fancytree-title { + color: black; + font-weight: normal; +} +.fancytree-ext-filter-dimm tr.fancytree-match span.fancytree-title, +.fancytree-ext-filter-dimm span.fancytree-node.fancytree-match span.fancytree-title { + color: black; + font-weight: bold; +} +.fancytree-ext-filter-hide tr.fancytree-hide, +.fancytree-ext-filter-hide span.fancytree-node.fancytree-hide { + display: none; +} +.fancytree-ext-filter-hide tr.fancytree-submatch span.fancytree-title, +.fancytree-ext-filter-hide span.fancytree-node.fancytree-submatch span.fancytree-title { + color: #c0c0c0; + font-weight: lighter; +} +.fancytree-ext-filter-hide tr.fancytree-match span.fancytree-title, +.fancytree-ext-filter-hide span.fancytree-node.fancytree-match span.fancytree-title { + color: black; + font-weight: normal; +} +/* Hide expanders if all child nodes are hidden by filter */ +.fancytree-ext-filter-hide-expanders tr.fancytree-match span.fancytree-expander, +.fancytree-ext-filter-hide-expanders span.fancytree-node.fancytree-match span.fancytree-expander { + visibility: hidden; +} +.fancytree-ext-filter-hide-expanders tr.fancytree-submatch span.fancytree-expander, +.fancytree-ext-filter-hide-expanders span.fancytree-node.fancytree-submatch span.fancytree-expander { + visibility: visible; +} +.fancytree-ext-childcounter span.fancytree-icon, +.fancytree-ext-filter span.fancytree-icon, +.fancytree-ext-childcounter span.fancytree-custom-icon, +.fancytree-ext-filter span.fancytree-custom-icon { + position: relative; +} +.fancytree-ext-childcounter span.fancytree-childcounter, +.fancytree-ext-filter span.fancytree-childcounter { + color: #fff; + background: #777; + border: 1px solid gray; + position: absolute; + top: -6px; + right: -6px; + min-width: 10px; + height: 10px; + line-height: 1; + vertical-align: baseline; + border-radius: 10px; + padding: 2px; + text-align: center; + font-size: 9px; +} +/*------------------------------------------------------------------------------ + * 'wide' extension + *----------------------------------------------------------------------------*/ +ul.fancytree-ext-wide { + position: relative; + min-width: 100%; + z-index: 2; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; +} +ul.fancytree-ext-wide span.fancytree-node > span { + position: relative; + z-index: 2; +} +ul.fancytree-ext-wide span.fancytree-node span.fancytree-title { + position: absolute; + z-index: 1; + left: 0px; + min-width: 100%; + margin-left: 0; + margin-right: 0; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; +} +/*------------------------------------------------------------------------------ + * 'fixed' extension + *----------------------------------------------------------------------------*/ +.fancytree-ext-fixed-wrapper .fancytree-ext-fixed-hidden { + display: none; +} +.fancytree-ext-fixed-wrapper div.fancytree-ext-fixed-scroll-border-bottom { + border-bottom: 3px solid rgba(0, 0, 0, 0.75); +} +.fancytree-ext-fixed-wrapper div.fancytree-ext-fixed-scroll-border-right { + border-right: 3px solid rgba(0, 0, 0, 0.75); +} +.fancytree-ext-fixed-wrapper div.fancytree-ext-fixed-wrapper-tl { + position: absolute; + overflow: hidden; + z-index: 3; + top: 0px; + left: 0px; +} +.fancytree-ext-fixed-wrapper div.fancytree-ext-fixed-wrapper-tr { + position: absolute; + overflow: hidden; + z-index: 2; + top: 0px; +} +.fancytree-ext-fixed-wrapper div.fancytree-ext-fixed-wrapper-bl { + position: absolute; + overflow: hidden; + z-index: 2; + left: 0px; +} +.fancytree-ext-fixed-wrapper div.fancytree-ext-fixed-wrapper-br { + position: absolute; + overflow: scroll; + z-index: 1; +} +/******************************************************************************* + * Styles specific to this skin. + * + * This section is automatically generated from the `ui-fancytree.less` template. + ******************************************************************************/ +/******************************************************************************* + * Node titles + */ +.fancytree-plain span.fancytree-node { + border: 1px solid transparent; +} +.fancytree-plain span.fancytree-node:hover { + background-color: #E5F3FB; + border-color: #70C0E7; +} +.fancytree-plain.fancytree-container.fancytree-treefocus span.fancytree-node.fancytree-focused { + border-color: #3399FF; +} +.fancytree-plain span.fancytree-node.fancytree-active, +.fancytree-plain span.fancytree-node.fancytree-selected { + background-color: #F7F7F7; + border-color: #DEDEDE; +} +.fancytree-plain.fancytree-container.fancytree-treefocus span.fancytree-node.fancytree-active, +.fancytree-plain.fancytree-container.fancytree-treefocus span.fancytree-node.fancytree-selected, +.fancytree-plain span.fancytree-node.fancytree-active:hover, +.fancytree-plain span.fancytree-node.fancytree-selected:hover { + background-color: #CBE8F6; + border-color: #26A0DA; +} +.fancytree-plain .fancytree-node.fancytree-selected { + font-style: italic; +} +/******************************************************************************* + * 'table' extension + */ +table.fancytree-ext-table tbody tr td { + border: 1px solid #EDEDED; +} +table.fancytree-ext-table tbody span.fancytree-node, +table.fancytree-ext-table tbody span.fancytree-node:hover { + border: none; + background: none; +} +table.fancytree-ext-table tbody tr:hover { + background-color: #E5F3FB; + outline: 1px solid #70C0E7; +} +table.fancytree-ext-table tbody tr.fancytree-focused span.fancytree-title { + outline: 1px dotted black; +} +table.fancytree-ext-table tbody tr.fancytree-active:hover, +table.fancytree-ext-table tbody tr.fancytree-selected:hover { + background-color: #CBE8F6; + outline: 1px solid #26A0DA; +} +table.fancytree-ext-table tbody tr.fancytree-active { + background-color: #F7F7F7; + outline: 1px solid #DEDEDE; +} +table.fancytree-ext-table tbody tr.fancytree-selected { + background-color: #F7F7F7; +} +table.fancytree-ext-table.fancytree-treefocus tbody tr.fancytree-active { + background-color: #CBE8F6; + outline: 1px solid #26A0DA; +} +table.fancytree-ext-table.fancytree-treefocus tbody tr.fancytree-selected { + background-color: #CBE8F6; +} diff --git a/plugins/55/indexmenu/scripts/fancytree/skin-win8-n/ui.fancytree.less b/plugins/55/indexmenu/scripts/fancytree/skin-win8-n/ui.fancytree.less new file mode 100644 index 0000000..633827e --- /dev/null +++ b/plugins/55/indexmenu/scripts/fancytree/skin-win8-n/ui.fancytree.less @@ -0,0 +1,145 @@ +/*! + * Fancytree "win8" skin (highlighting the node span instead of title-only). + * + * DON'T EDIT THE CSS FILE DIRECTLY, since it is automatically generated from + * the LESS templates. + */ + +// Import common styles +@import "../skin-common.less"; + + +/******************************************************************************* + * Styles specific to this skin. + * + * This section is automatically generated from the `ui-fancytree.less` template. + ******************************************************************************/ + +// Borders have NO radius and NO gradients are used! + +// both: +// unselected background: white +// hover bar (unselected, inactive): #E5F3FB (border: #70C0E7) 'very light blue' +// active node: #CBE8F6 (border: #26A0DA) 'light blue' +// active node with hover: wie active node + +// Tree view: +// active node, tree inactive: #F7F7F7 (border: #DEDEDE) 'light gray, selected, but tree not active' + +// List view: +// selected bar: --> active bar +// focus bar: transparent(white) + border 1px solid #3399FF () + +// table left/right border: #EDEDED 'light gray' + +// Override the variable after the import. +// NOTE: Variables are always resolved as the last definition, even if it is +// after where it is used. +@fancy-use-sprites: true; // false: suppress all background images (i.e. icons) +// Set to `true` to inline icon sprite into CSS: +// @fancy-inline-sprites: true; +@fancy-icon-width: 16px; +@fancy-icon-height: 16px; +@fancy-line-height: 16px; +@fancy-icon-spacing: 3px; + +// We need to define this variable here (not in skin-common.less) to make it +// work with grunt and webpack: +@fancy-image-prefix: "./skin-win8-n/"; +// Use 'data-uri(...)' to embed the image into CSS instead of linking to 'loading.gif': +// @fancy-loading-url: data-uri("@{fancy-image-prefix}loading.gif"); +// Set to `true` to use `data-uri(...)` which will embed icons.gif into CSS +// instead of linking to that file: +// @fancy-inline-sprites: true; + + +/******************************************************************************* + * Node titles + */ +.fancytree-plain { + span.fancytree-node { + border: @fancy-node-border-width solid transparent; // avoid jumping, when a border is added on hover + } + span.fancytree-node:hover { + background-color: #E5F3FB; + border-color: #70C0E7; + } + &.fancytree-container.fancytree-treefocus span.fancytree-node.fancytree-focused { + border-color: #3399FF; + // outline: 1px solid #3399FF; + } + span.fancytree-node.fancytree-active, + span.fancytree-node.fancytree-selected { // active/selcted nodes inside inactive tree + background-color: #F7F7F7; + border-color: #DEDEDE; + } + &.fancytree-container.fancytree-treefocus span.fancytree-node.fancytree-active, + &.fancytree-container.fancytree-treefocus span.fancytree-node.fancytree-selected, + span.fancytree-node.fancytree-active:hover, + span.fancytree-node.fancytree-selected:hover { + background-color: #CBE8F6; + border-color: #26A0DA; + } + .fancytree-node.fancytree-selected { + font-style: italic; + } +} + +/******************************************************************************* + * 'table' extension + */ +table.fancytree-ext-table tbody { + tr td { + border: 1px solid #EDEDED; + } + span.fancytree-node, + span.fancytree-node:hover { // undo standard tree css + border: none; + background: none; + } + // Title gets a white background, when hovered. Undo standard node formatting + // span.fancytree-title:hover { + // border: none; //1px solid transparent; + // background: inherit; + // background: transparent; + // background: none; + // filter: none; + // } + tr:hover { + background-color: #E5F3FB; + outline: 1px solid #70C0E7; + } + // tr:hover td { + // outline: 1px solid #D8F0FA; + // } + // tr.fancytree-focused { + // border-color: #3399FF; + // outline: 1px dotted black; + // } + tr.fancytree-focused span.fancytree-title { + outline: 1px dotted black; + } + + tr.fancytree-active:hover, + tr.fancytree-selected:hover { + background-color: #CBE8F6; + outline: 1px solid #26A0DA; + } + tr.fancytree-active { // dimmed, if inside inactive tree + background-color: #F7F7F7; + outline: 1px solid #DEDEDE; + } + tr.fancytree-selected { // dimmed, if inside inactive tree + background-color: #F7F7F7; + } +} + +table.fancytree-ext-table.fancytree-treefocus tbody { + tr.fancytree-active { + background-color: #CBE8F6; + outline: 1px solid #26A0DA; + } + tr.fancytree-selected { + background-color: #CBE8F6; + } +} diff --git a/plugins/55/indexmenu/scripts/fancytree/skin-win8-n/ui.fancytree.min.css b/plugins/55/indexmenu/scripts/fancytree/skin-win8-n/ui.fancytree.min.css new file mode 100644 index 0000000..8dfa9fd --- /dev/null +++ b/plugins/55/indexmenu/scripts/fancytree/skin-win8-n/ui.fancytree.min.css @@ -0,0 +1,6 @@ +/*! + * Fancytree "win8" skin (highlighting the node span instead of title-only). + * + * DON'T EDIT THE CSS FILE DIRECTLY, since it is automatically generated from + * the LESS templates. + */.fancytree-helper-hidden{display:none}.fancytree-helper-indeterminate-cb{color:#777}.fancytree-helper-disabled{color:silver}.fancytree-helper-spin{-webkit-animation:spin 1s infinite linear;animation:spin 1s infinite linear}@-webkit-keyframes spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}ul.fancytree-container{font-family:tahoma,arial,helvetica;font-size:10pt;white-space:nowrap;padding:3px;margin:0;background-color:#fff;border:1px dotted gray;min-height:0;position:relative}ul.fancytree-container ul{padding:0 0 0 16px;margin:0}ul.fancytree-container ul>li:before{content:none}ul.fancytree-container li{list-style-image:none;list-style-position:outside;list-style-type:none;-moz-background-clip:border;-moz-background-inline-policy:continuous;-moz-background-origin:padding;background-attachment:scroll;background-color:transparent;background-position:0 0;background-repeat:repeat-y;background-image:none;margin:0}ul.fancytree-container li.fancytree-lastsib{background-image:none}.ui-fancytree-disabled ul.fancytree-container{opacity:.5;background-color:silver}ul.fancytree-connectors.fancytree-container li{background-image:url("../skin-win8-n/vline.gif");background-position:0 0}ul.fancytree-container li.fancytree-lastsib,ul.fancytree-no-connector>li{background-image:none}li.fancytree-animating{position:relative}#fancytree-drop-marker,span.fancytree-checkbox,span.fancytree-drag-helper-img,span.fancytree-empty,span.fancytree-expander,span.fancytree-icon,span.fancytree-vline{width:16px;height:16px;display:inline-block;vertical-align:top;background-repeat:no-repeat;background-image:url("../skin-win8-n/icons.gif");background-position:0 0}span.fancytree-checkbox,span.fancytree-custom-icon,span.fancytree-expander,span.fancytree-icon{margin-top:0}span.fancytree-custom-icon{width:16px;height:16px;display:inline-block;margin-left:3px;background-position:0 0}img.fancytree-icon{width:16px;height:16px;margin-left:3px;margin-top:0;vertical-align:top;border-style:none}span.fancytree-expander{cursor:pointer}.fancytree-exp-n span.fancytree-expander,.fancytree-exp-nl span.fancytree-expander{background-image:none;cursor:default}.fancytree-connectors .fancytree-exp-n span.fancytree-expander,.fancytree-connectors .fancytree-exp-nl span.fancytree-expander{background-image:url("../skin-win8-n/icons.gif");margin-top:0}.fancytree-connectors .fancytree-exp-n span.fancytree-expander,.fancytree-connectors .fancytree-exp-n span.fancytree-expander:hover{background-position:0 -64px}.fancytree-connectors .fancytree-exp-nl span.fancytree-expander,.fancytree-connectors .fancytree-exp-nl span.fancytree-expander:hover{background-position:-16px -64px}.fancytree-exp-c span.fancytree-expander{background-position:0 -80px}.fancytree-exp-c span.fancytree-expander:hover{background-position:-16px -80px}.fancytree-exp-cl span.fancytree-expander{background-position:0 -96px}.fancytree-exp-cl span.fancytree-expander:hover{background-position:-16px -96px}.fancytree-exp-cd span.fancytree-expander{background-position:-64px -80px}.fancytree-exp-cd span.fancytree-expander:hover{background-position:-80px -80px}.fancytree-exp-cdl span.fancytree-expander{background-position:-64px -96px}.fancytree-exp-cdl span.fancytree-expander:hover{background-position:-80px -96px}.fancytree-exp-e span.fancytree-expander,.fancytree-exp-ed span.fancytree-expander{background-position:-32px -80px}.fancytree-exp-e span.fancytree-expander:hover,.fancytree-exp-ed span.fancytree-expander:hover{background-position:-48px -80px}.fancytree-exp-edl span.fancytree-expander,.fancytree-exp-el span.fancytree-expander{background-position:-32px -96px}.fancytree-exp-edl span.fancytree-expander:hover,.fancytree-exp-el span.fancytree-expander:hover{background-position:-48px -96px}.fancytree-fade-expander span.fancytree-expander{transition:opacity 1.5s;opacity:0}.fancytree-fade-expander .fancytree-treefocus span.fancytree-expander,.fancytree-fade-expander [class*=fancytree-statusnode-] span.fancytree-expander,.fancytree-fade-expander.fancytree-treefocus span.fancytree-expander,.fancytree-fade-expander:hover span.fancytree-expander{transition:opacity .6s;opacity:1}span.fancytree-checkbox{margin-left:3px;background-position:0 -32px}span.fancytree-checkbox:hover{background-position:-16px -32px}span.fancytree-checkbox.fancytree-radio{background-position:0 -48px}span.fancytree-checkbox.fancytree-radio:hover{background-position:-16px -48px}.fancytree-partsel span.fancytree-checkbox{background-position:-64px -32px}.fancytree-partsel span.fancytree-checkbox:hover{background-position:-80px -32px}.fancytree-partsel span.fancytree-checkbox.fancytree-radio{background-position:-64px -48px}.fancytree-partsel span.fancytree-checkbox.fancytree-radio:hover{background-position:-80px -48px}.fancytree-selected span.fancytree-checkbox{background-position:-32px -32px}.fancytree-selected span.fancytree-checkbox:hover{background-position:-48px -32px}.fancytree-selected span.fancytree-checkbox.fancytree-radio{background-position:-32px -48px}.fancytree-selected span.fancytree-checkbox.fancytree-radio:hover{background-position:-48px -48px}.fancytree-unselectable span.fancytree-checkbox{opacity:.4}.fancytree-unselectable span.fancytree-checkbox:hover{background-position:0 -32px}.fancytree-unselectable span.fancytree-checkbox.fancytree-radio:hover{background-position:0 -48px}.fancytree-unselectable.fancytree-partsel span.fancytree-checkbox:hover{background-position:-64px -32px}.fancytree-unselectable.fancytree-selected span.fancytree-checkbox:hover{background-position:-32px -32px}.fancytree-unselectable.fancytree-selected span.fancytree-checkbox.fancytree-radio:hover{background-position:-32px -48px}.fancytree-container.fancytree-checkbox-auto-hide span.fancytree-checkbox{visibility:hidden}.fancytree-container.fancytree-checkbox-auto-hide .fancytree-node.fancytree-selected span.fancytree-checkbox,.fancytree-container.fancytree-checkbox-auto-hide .fancytree-node:hover span.fancytree-checkbox,.fancytree-container.fancytree-checkbox-auto-hide tr.fancytree-selected td span.fancytree-checkbox,.fancytree-container.fancytree-checkbox-auto-hide tr:hover td span.fancytree-checkbox{visibility:unset}.fancytree-container.fancytree-checkbox-auto-hide.fancytree-treefocus .fancytree-node.fancytree-active span.fancytree-checkbox,.fancytree-container.fancytree-checkbox-auto-hide.fancytree-treefocus tr.fancytree-active td span.fancytree-checkbox{visibility:unset}span.fancytree-icon{margin-left:3px;background-position:0 0}.fancytree-ico-c span.fancytree-icon:hover{background-position:-16px 0}.fancytree-has-children.fancytree-ico-c span.fancytree-icon{background-position:-32px 0}.fancytree-has-children.fancytree-ico-c span.fancytree-icon:hover{background-position:-48px 0}.fancytree-ico-e span.fancytree-icon{background-position:-64px 0}.fancytree-ico-e span.fancytree-icon:hover{background-position:-80px 0}.fancytree-ico-cf span.fancytree-icon{background-position:0 -16px}.fancytree-ico-cf span.fancytree-icon:hover{background-position:-16px -16px}.fancytree-has-children.fancytree-ico-cf span.fancytree-icon{background-position:-32px -16px}.fancytree-has-children.fancytree-ico-cf span.fancytree-icon:hover{background-position:-48px -16px}.fancytree-ico-ef span.fancytree-icon{background-position:-64px -16px}.fancytree-ico-ef span.fancytree-icon:hover{background-position:-80px -16px}.fancytree-loading span.fancytree-expander,.fancytree-loading span.fancytree-expander:hover,.fancytree-statusnode-loading span.fancytree-icon,.fancytree-statusnode-loading span.fancytree-icon:hover,span.fancytree-icon.fancytree-icon-loading{background-image:url("../skin-win8-n/loading.gif");background-position:0 0}.fancytree-statusnode-error span.fancytree-icon,.fancytree-statusnode-error span.fancytree-icon:hover{background-position:0 -112px}span.fancytree-node{display:inherit;width:100%;margin-top:1px;min-height:16px}span.fancytree-title{color:#000;cursor:pointer;display:inline-block;vertical-align:top;min-height:16px;padding:0 3px 0 3px;margin:0 0 0 3px;border:1px solid transparent;-webkit-border-radius:0px;-moz-border-radius:0;-ms-border-radius:0px;-o-border-radius:0;border-radius:0}span.fancytree-node.fancytree-error span.fancytree-title{color:red}span.fancytree-childcounter{color:#fff;background:#337ab7;border:1px solid gray;border-radius:10px;padding:2px;text-align:center}div.fancytree-drag-helper span.fancytree-childcounter,div.fancytree-drag-helper span.fancytree-dnd-modifier{display:inline-block;color:#fff;background:#337ab7;border:1px solid gray;min-width:10px;height:10px;line-height:1;vertical-align:baseline;border-radius:10px;padding:2px;text-align:center;font-size:9px}div.fancytree-drag-helper span.fancytree-childcounter{position:absolute;top:-6px;right:-6px}div.fancytree-drag-helper span.fancytree-dnd-modifier{background:#5cb85c;border:none;font-weight:bolder}div.fancytree-drag-helper.fancytree-drop-accept span.fancytree-drag-helper-img{background-position:-32px -112px}div.fancytree-drag-helper.fancytree-drop-reject span.fancytree-drag-helper-img{background-position:-16px -112px}#fancytree-drop-marker{width:32px;position:absolute;background-position:0 -128px;margin:0}#fancytree-drop-marker.fancytree-drop-after,#fancytree-drop-marker.fancytree-drop-before{width:64px;background-position:0 -144px}#fancytree-drop-marker.fancytree-drop-copy{background-position:-64px -128px}#fancytree-drop-marker.fancytree-drop-move{background-position:-32px -128px}span.fancytree-drag-source.fancytree-drag-remove{opacity:.15}.fancytree-container.fancytree-rtl span.fancytree-connector,.fancytree-container.fancytree-rtl span.fancytree-drag-helper-img,.fancytree-container.fancytree-rtl span.fancytree-expander,.fancytree-container.fancytree-rtl span.fancytree-icon{background-image:url("../skin-win8-n/icons-rtl.gif")}.fancytree-container.fancytree-rtl .fancytree-exp-n span.fancytree-expander,.fancytree-container.fancytree-rtl .fancytree-exp-nl span.fancytree-expander{background-image:none}.fancytree-container.fancytree-rtl.fancytree-connectors .fancytree-exp-n span.fancytree-expander,.fancytree-container.fancytree-rtl.fancytree-connectors .fancytree-exp-nl span.fancytree-expander{background-image:url("../skin-win8-n/icons-rtl.gif")}ul.fancytree-container.fancytree-rtl ul{padding:0 16px 0 0}ul.fancytree-container.fancytree-rtl.fancytree-connectors li{background-position:right 0;background-image:url("../skin-win8-n/vline-rtl.gif")}ul.fancytree-container.fancytree-rtl li.fancytree-lastsib,ul.fancytree-container.fancytree-rtl.fancytree-no-connector>li{background-image:none}#fancytree-drop-marker.fancytree-rtl{background-image:url("../skin-win8-n/icons-rtl.gif")}table.fancytree-ext-table{font-family:tahoma,arial,helvetica;font-size:10pt;border-collapse:collapse}table.fancytree-ext-table span.fancytree-node{display:inline-block;box-sizing:border-box}table.fancytree-ext-table td.fancytree-status-merged{text-align:center;font-style:italic;color:silver}table.fancytree-ext-table tr.fancytree-statusnode-error td.fancytree-status-merged{color:red}table.fancytree-ext-table.fancytree-ext-ariagrid.fancytree-cell-mode>tbody>tr.fancytree-active>td{background-color:#eee}table.fancytree-ext-table.fancytree-ext-ariagrid.fancytree-cell-mode>tbody>tr>td.fancytree-active-cell{background-color:#cbe8f6}table.fancytree-ext-table.fancytree-ext-ariagrid.fancytree-cell-mode.fancytree-cell-nav-mode>tbody>tr>td.fancytree-active-cell{background-color:#3875d7}table.fancytree-ext-columnview tbody tr td{position:relative;border:1px solid gray;vertical-align:top;overflow:auto}table.fancytree-ext-columnview tbody tr td>ul{padding:0}table.fancytree-ext-columnview tbody tr td>ul li{list-style-image:none;list-style-position:outside;list-style-type:none;-moz-background-clip:border;-moz-background-inline-policy:continuous;-moz-background-origin:padding;background-attachment:scroll;background-color:transparent;background-position:0 0;background-repeat:repeat-y;background-image:none;margin:0}table.fancytree-ext-columnview span.fancytree-node{position:relative;display:inline-block}table.fancytree-ext-columnview span.fancytree-node.fancytree-expanded{background-color:#e0e0e0}table.fancytree-ext-columnview span.fancytree-node.fancytree-active{background-color:#cbe8f6}table.fancytree-ext-columnview .fancytree-has-children span.fancytree-cv-right{position:absolute;right:3px;background-position:0 -80px}table.fancytree-ext-columnview .fancytree-has-children span.fancytree-cv-right:hover{background-position:-16px -80px}.fancytree-ext-filter-dimm span.fancytree-node span.fancytree-title{color:silver;font-weight:lighter}.fancytree-ext-filter-dimm span.fancytree-node.fancytree-submatch span.fancytree-title,.fancytree-ext-filter-dimm tr.fancytree-submatch span.fancytree-title{color:#000;font-weight:400}.fancytree-ext-filter-dimm span.fancytree-node.fancytree-match span.fancytree-title,.fancytree-ext-filter-dimm tr.fancytree-match span.fancytree-title{color:#000;font-weight:700}.fancytree-ext-filter-hide span.fancytree-node.fancytree-hide,.fancytree-ext-filter-hide tr.fancytree-hide{display:none}.fancytree-ext-filter-hide span.fancytree-node.fancytree-submatch span.fancytree-title,.fancytree-ext-filter-hide tr.fancytree-submatch span.fancytree-title{color:silver;font-weight:lighter}.fancytree-ext-filter-hide span.fancytree-node.fancytree-match span.fancytree-title,.fancytree-ext-filter-hide tr.fancytree-match span.fancytree-title{color:#000;font-weight:400}.fancytree-ext-filter-hide-expanders span.fancytree-node.fancytree-match span.fancytree-expander,.fancytree-ext-filter-hide-expanders tr.fancytree-match span.fancytree-expander{visibility:hidden}.fancytree-ext-filter-hide-expanders span.fancytree-node.fancytree-submatch span.fancytree-expander,.fancytree-ext-filter-hide-expanders tr.fancytree-submatch span.fancytree-expander{visibility:visible}.fancytree-ext-childcounter span.fancytree-custom-icon,.fancytree-ext-childcounter span.fancytree-icon,.fancytree-ext-filter span.fancytree-custom-icon,.fancytree-ext-filter span.fancytree-icon{position:relative}.fancytree-ext-childcounter span.fancytree-childcounter,.fancytree-ext-filter span.fancytree-childcounter{color:#fff;background:#777;border:1px solid gray;position:absolute;top:-6px;right:-6px;min-width:10px;height:10px;line-height:1;vertical-align:baseline;border-radius:10px;padding:2px;text-align:center;font-size:9px}ul.fancytree-ext-wide{position:relative;min-width:100%;z-index:2;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}ul.fancytree-ext-wide span.fancytree-node>span{position:relative;z-index:2}ul.fancytree-ext-wide span.fancytree-node span.fancytree-title{position:absolute;z-index:1;left:0;min-width:100%;margin-left:0;margin-right:0;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.fancytree-ext-fixed-wrapper .fancytree-ext-fixed-hidden{display:none}.fancytree-ext-fixed-wrapper div.fancytree-ext-fixed-scroll-border-bottom{border-bottom:3px solid rgba(0,0,0,.75)}.fancytree-ext-fixed-wrapper div.fancytree-ext-fixed-scroll-border-right{border-right:3px solid rgba(0,0,0,.75)}.fancytree-ext-fixed-wrapper div.fancytree-ext-fixed-wrapper-tl{position:absolute;overflow:hidden;z-index:3;top:0;left:0}.fancytree-ext-fixed-wrapper div.fancytree-ext-fixed-wrapper-tr{position:absolute;overflow:hidden;z-index:2;top:0}.fancytree-ext-fixed-wrapper div.fancytree-ext-fixed-wrapper-bl{position:absolute;overflow:hidden;z-index:2;left:0}.fancytree-ext-fixed-wrapper div.fancytree-ext-fixed-wrapper-br{position:absolute;overflow:scroll;z-index:1}.fancytree-plain span.fancytree-node{border:1px solid transparent}.fancytree-plain span.fancytree-node:hover{background-color:#e5f3fb;border-color:#70c0e7}.fancytree-plain.fancytree-container.fancytree-treefocus span.fancytree-node.fancytree-focused{border-color:#39f}.fancytree-plain span.fancytree-node.fancytree-active,.fancytree-plain span.fancytree-node.fancytree-selected{background-color:#f7f7f7;border-color:#dedede}.fancytree-plain span.fancytree-node.fancytree-active:hover,.fancytree-plain span.fancytree-node.fancytree-selected:hover,.fancytree-plain.fancytree-container.fancytree-treefocus span.fancytree-node.fancytree-active,.fancytree-plain.fancytree-container.fancytree-treefocus span.fancytree-node.fancytree-selected{background-color:#cbe8f6;border-color:#26a0da}.fancytree-plain .fancytree-node.fancytree-selected{font-style:italic}table.fancytree-ext-table tbody tr td{border:1px solid #ededed}table.fancytree-ext-table tbody span.fancytree-node,table.fancytree-ext-table tbody span.fancytree-node:hover{border:none;background:0 0}table.fancytree-ext-table tbody tr:hover{background-color:#e5f3fb;outline:1px solid #70C0E7}table.fancytree-ext-table tbody tr.fancytree-focused span.fancytree-title{outline:1px dotted black}table.fancytree-ext-table tbody tr.fancytree-active:hover,table.fancytree-ext-table tbody tr.fancytree-selected:hover{background-color:#cbe8f6;outline:1px solid #26A0DA}table.fancytree-ext-table tbody tr.fancytree-active{background-color:#f7f7f7;outline:1px solid #DEDEDE}table.fancytree-ext-table tbody tr.fancytree-selected{background-color:#f7f7f7}table.fancytree-ext-table.fancytree-treefocus tbody tr.fancytree-active{background-color:#cbe8f6;outline:1px solid #26A0DA}table.fancytree-ext-table.fancytree-treefocus tbody tr.fancytree-selected{background-color:#cbe8f6}
\ No newline at end of file diff --git a/plugins/55/indexmenu/scripts/fancytree/skin-win8-n/vline-rtl.gif b/plugins/55/indexmenu/scripts/fancytree/skin-win8-n/vline-rtl.gif Binary files differnew file mode 100644 index 0000000..f9b4232 --- /dev/null +++ b/plugins/55/indexmenu/scripts/fancytree/skin-win8-n/vline-rtl.gif diff --git a/plugins/55/indexmenu/scripts/fancytree/skin-win8-n/vline.gif b/plugins/55/indexmenu/scripts/fancytree/skin-win8-n/vline.gif Binary files differnew file mode 100644 index 0000000..f9b4232 --- /dev/null +++ b/plugins/55/indexmenu/scripts/fancytree/skin-win8-n/vline.gif diff --git a/plugins/55/indexmenu/scripts/fancytree/skin-win8-xxl/icons-rtl.gif b/plugins/55/indexmenu/scripts/fancytree/skin-win8-xxl/icons-rtl.gif Binary files differnew file mode 100644 index 0000000..0ce1c5b --- /dev/null +++ b/plugins/55/indexmenu/scripts/fancytree/skin-win8-xxl/icons-rtl.gif diff --git a/plugins/55/indexmenu/scripts/fancytree/skin-win8-xxl/icons.gif b/plugins/55/indexmenu/scripts/fancytree/skin-win8-xxl/icons.gif Binary files differnew file mode 100644 index 0000000..f3abe16 --- /dev/null +++ b/plugins/55/indexmenu/scripts/fancytree/skin-win8-xxl/icons.gif diff --git a/plugins/55/indexmenu/scripts/fancytree/skin-win8-xxl/loading.gif b/plugins/55/indexmenu/scripts/fancytree/skin-win8-xxl/loading.gif Binary files differnew file mode 100644 index 0000000..8031e44 --- /dev/null +++ b/plugins/55/indexmenu/scripts/fancytree/skin-win8-xxl/loading.gif diff --git a/plugins/55/indexmenu/scripts/fancytree/skin-win8-xxl/ui.fancytree.css b/plugins/55/indexmenu/scripts/fancytree/skin-win8-xxl/ui.fancytree.css new file mode 100644 index 0000000..e4aff21 --- /dev/null +++ b/plugins/55/indexmenu/scripts/fancytree/skin-win8-xxl/ui.fancytree.css @@ -0,0 +1,775 @@ +/*! + * Fancytree "Win8" 32x32 skin. + * + * DON'T EDIT THE CSS FILE DIRECTLY, since it is automatically generated from + * the LESS templates. + */ +/******************************************************************************* + * Common Styles for Fancytree Skins. + * + * This section is automatically generated from the `skin-common.less` template. + * + * Copyright (c) 2008-2023, Martin Wendt (https://wwWendt.de) + * Released under the MIT license + * https://github.com/mar10/fancytree/wiki/LicenseInfo + * + * @version 2.38.3 + * @date 2023-02-01T20:52:50Z +******************************************************************************/ +/*------------------------------------------------------------------------------ + * Helpers + *----------------------------------------------------------------------------*/ +.fancytree-helper-hidden { + display: none; +} +.fancytree-helper-indeterminate-cb { + color: #777; +} +.fancytree-helper-disabled { + color: #c0c0c0; +} +/* Helper to allow spinning loader icon with glyph-, ligature-, and SVG-icons. */ +.fancytree-helper-spin { + -webkit-animation: spin 1000ms infinite linear; + animation: spin 1000ms infinite linear; +} +@-webkit-keyframes spin { + 0% { + -webkit-transform: rotate(0deg); + transform: rotate(0deg); + } + 100% { + -webkit-transform: rotate(359deg); + transform: rotate(359deg); + } +} +@keyframes spin { + 0% { + -webkit-transform: rotate(0deg); + transform: rotate(0deg); + } + 100% { + -webkit-transform: rotate(359deg); + transform: rotate(359deg); + } +} +/*------------------------------------------------------------------------------ + * Container and UL / LI + *----------------------------------------------------------------------------*/ +ul.fancytree-container { + font-family: tahoma, arial, helvetica; + font-size: 10pt; + white-space: nowrap; + padding: 3px; + margin: 0; + background-color: white; + border: 1px dotted gray; + min-height: 0%; + position: relative; +} +ul.fancytree-container ul { + padding: 0 0 0 32px; + margin: 0; +} +ul.fancytree-container ul > li:before { + content: none; +} +ul.fancytree-container li { + list-style-image: none; + list-style-position: outside; + list-style-type: none; + -moz-background-clip: border; + -moz-background-inline-policy: continuous; + -moz-background-origin: padding; + background-attachment: scroll; + background-color: transparent; + background-position: 0px 0px; + background-repeat: repeat-y; + background-image: none; + margin: 0; +} +ul.fancytree-container li.fancytree-lastsib { + background-image: none; +} +.ui-fancytree-disabled ul.fancytree-container { + opacity: 0.5; + background-color: silver; +} +ul.fancytree-connectors.fancytree-container li { + background-image: url("../skin-win8-xxl/vline.gif"); + background-position: 0 0; +} +ul.fancytree-container li.fancytree-lastsib, +ul.fancytree-no-connector > li { + background-image: none; +} +li.fancytree-animating { + position: relative; +} +/*------------------------------------------------------------------------------ + * Common icon definitions + *----------------------------------------------------------------------------*/ +span.fancytree-empty, +span.fancytree-vline, +span.fancytree-expander, +span.fancytree-icon, +span.fancytree-checkbox, +span.fancytree-drag-helper-img, +#fancytree-drop-marker { + width: 32px; + height: 32px; + display: inline-block; + vertical-align: top; + background-repeat: no-repeat; + background-image: url("../skin-win8-xxl/icons.gif"); + background-position: 0px 0px; +} +span.fancytree-icon, +span.fancytree-checkbox, +span.fancytree-expander, +span.fancytree-custom-icon { + margin-top: 0px; +} +/* Used by icon option: */ +span.fancytree-custom-icon { + width: 32px; + height: 32px; + display: inline-block; + margin-left: 6px; + background-position: 0px 0px; +} +/* Used by 'icon' node option: */ +img.fancytree-icon { + width: 32px; + height: 32px; + margin-left: 6px; + margin-top: 0px; + vertical-align: top; + border-style: none; +} +/*------------------------------------------------------------------------------ + * Expander icon + * + * Note: IE6 doesn't correctly evaluate multiples class names, + * so we create combined class names that can be used in the CSS. + * + * Prefix: fancytree-exp- + * 1st character: 'e': expanded, 'c': collapsed, 'n': no children + * 2nd character (optional): 'd': lazy (Delayed) + * 3rd character (optional): 'l': Last sibling + *----------------------------------------------------------------------------*/ +span.fancytree-expander { + cursor: pointer; +} +.fancytree-exp-n span.fancytree-expander, +.fancytree-exp-nl span.fancytree-expander { + background-image: none; + cursor: default; +} +.fancytree-connectors .fancytree-exp-n span.fancytree-expander, +.fancytree-connectors .fancytree-exp-nl span.fancytree-expander { + background-image: url("../skin-win8-xxl/icons.gif"); + margin-top: 0; +} +.fancytree-connectors .fancytree-exp-n span.fancytree-expander, +.fancytree-connectors .fancytree-exp-n span.fancytree-expander:hover { + background-position: 0px -128px; +} +.fancytree-connectors .fancytree-exp-nl span.fancytree-expander, +.fancytree-connectors .fancytree-exp-nl span.fancytree-expander:hover { + background-position: -32px -128px; +} +.fancytree-exp-c span.fancytree-expander { + background-position: 0px -160px; +} +.fancytree-exp-c span.fancytree-expander:hover { + background-position: -32px -160px; +} +.fancytree-exp-cl span.fancytree-expander { + background-position: 0px -192px; +} +.fancytree-exp-cl span.fancytree-expander:hover { + background-position: -32px -192px; +} +.fancytree-exp-cd span.fancytree-expander { + background-position: -128px -160px; +} +.fancytree-exp-cd span.fancytree-expander:hover { + background-position: -160px -160px; +} +.fancytree-exp-cdl span.fancytree-expander { + background-position: -128px -192px; +} +.fancytree-exp-cdl span.fancytree-expander:hover { + background-position: -160px -192px; +} +.fancytree-exp-e span.fancytree-expander, +.fancytree-exp-ed span.fancytree-expander { + background-position: -64px -160px; +} +.fancytree-exp-e span.fancytree-expander:hover, +.fancytree-exp-ed span.fancytree-expander:hover { + background-position: -96px -160px; +} +.fancytree-exp-el span.fancytree-expander, +.fancytree-exp-edl span.fancytree-expander { + background-position: -64px -192px; +} +.fancytree-exp-el span.fancytree-expander:hover, +.fancytree-exp-edl span.fancytree-expander:hover { + background-position: -96px -192px; +} +/* Fade out expanders, when container is not hovered or active */ +.fancytree-fade-expander span.fancytree-expander { + transition: opacity 1.5s; + opacity: 0; +} +.fancytree-fade-expander:hover span.fancytree-expander, +.fancytree-fade-expander.fancytree-treefocus span.fancytree-expander, +.fancytree-fade-expander .fancytree-treefocus span.fancytree-expander, +.fancytree-fade-expander [class*="fancytree-statusnode-"] span.fancytree-expander { + transition: opacity 0.6s; + opacity: 1; +} +/*------------------------------------------------------------------------------ + * Checkbox icon + *----------------------------------------------------------------------------*/ +span.fancytree-checkbox { + margin-left: 6px; + background-position: 0px -64px; +} +span.fancytree-checkbox:hover { + background-position: -32px -64px; +} +span.fancytree-checkbox.fancytree-radio { + background-position: 0px -96px; +} +span.fancytree-checkbox.fancytree-radio:hover { + background-position: -32px -96px; +} +.fancytree-partsel span.fancytree-checkbox { + background-position: -128px -64px; +} +.fancytree-partsel span.fancytree-checkbox:hover { + background-position: -160px -64px; +} +.fancytree-partsel span.fancytree-checkbox.fancytree-radio { + background-position: -128px -96px; +} +.fancytree-partsel span.fancytree-checkbox.fancytree-radio:hover { + background-position: -160px -96px; +} +.fancytree-selected span.fancytree-checkbox { + background-position: -64px -64px; +} +.fancytree-selected span.fancytree-checkbox:hover { + background-position: -96px -64px; +} +.fancytree-selected span.fancytree-checkbox.fancytree-radio { + background-position: -64px -96px; +} +.fancytree-selected span.fancytree-checkbox.fancytree-radio:hover { + background-position: -96px -96px; +} +.fancytree-unselectable span.fancytree-checkbox { + opacity: 0.4; + filter: alpha(opacity=40); +} +.fancytree-unselectable span.fancytree-checkbox:hover { + background-position: 0px -64px; +} +.fancytree-unselectable span.fancytree-checkbox.fancytree-radio:hover { + background-position: 0px -96px; +} +.fancytree-unselectable.fancytree-partsel span.fancytree-checkbox:hover { + background-position: -128px -64px; +} +.fancytree-unselectable.fancytree-selected span.fancytree-checkbox:hover { + background-position: -64px -64px; +} +.fancytree-unselectable.fancytree-selected span.fancytree-checkbox.fancytree-radio:hover { + background-position: -64px -96px; +} +.fancytree-container.fancytree-checkbox-auto-hide span.fancytree-checkbox { + visibility: hidden; +} +.fancytree-container.fancytree-checkbox-auto-hide .fancytree-node:hover span.fancytree-checkbox, +.fancytree-container.fancytree-checkbox-auto-hide tr:hover td span.fancytree-checkbox, +.fancytree-container.fancytree-checkbox-auto-hide .fancytree-node.fancytree-selected span.fancytree-checkbox, +.fancytree-container.fancytree-checkbox-auto-hide tr.fancytree-selected td span.fancytree-checkbox { + visibility: unset; +} +.fancytree-container.fancytree-checkbox-auto-hide.fancytree-treefocus .fancytree-node.fancytree-active span.fancytree-checkbox, +.fancytree-container.fancytree-checkbox-auto-hide.fancytree-treefocus tr.fancytree-active td span.fancytree-checkbox { + visibility: unset; +} +/*------------------------------------------------------------------------------ + * Node type icon + * Note: IE6 doesn't correctly evaluate multiples class names, + * so we create combined class names that can be used in the CSS. + * + * Prefix: fancytree-ico- + * 1st character: 'e': expanded, 'c': collapsed + * 2nd character (optional): 'f': folder + *----------------------------------------------------------------------------*/ +span.fancytree-icon { + margin-left: 6px; + background-position: 0px 0px; +} +/* Documents */ +.fancytree-ico-c span.fancytree-icon:hover { + background-position: -32px 0px; +} +.fancytree-has-children.fancytree-ico-c span.fancytree-icon { + background-position: -64px 0px; +} +.fancytree-has-children.fancytree-ico-c span.fancytree-icon:hover { + background-position: -96px 0px; +} +.fancytree-ico-e span.fancytree-icon { + background-position: -128px 0px; +} +.fancytree-ico-e span.fancytree-icon:hover { + background-position: -160px 0px; +} +/* Folders */ +.fancytree-ico-cf span.fancytree-icon { + background-position: 0px -32px; +} +.fancytree-ico-cf span.fancytree-icon:hover { + background-position: -32px -32px; +} +.fancytree-has-children.fancytree-ico-cf span.fancytree-icon { + background-position: -64px -32px; +} +.fancytree-has-children.fancytree-ico-cf span.fancytree-icon:hover { + background-position: -96px -32px; +} +.fancytree-ico-ef span.fancytree-icon { + background-position: -128px -32px; +} +.fancytree-ico-ef span.fancytree-icon:hover { + background-position: -160px -32px; +} +.fancytree-loading span.fancytree-expander, +.fancytree-loading span.fancytree-expander:hover, +.fancytree-statusnode-loading span.fancytree-icon, +.fancytree-statusnode-loading span.fancytree-icon:hover, +span.fancytree-icon.fancytree-icon-loading { + background-image: url("../skin-win8-xxl/loading.gif"); + background-position: 0px 0px; +} +/* Status node icons */ +.fancytree-statusnode-error span.fancytree-icon, +.fancytree-statusnode-error span.fancytree-icon:hover { + background-position: 0px -224px; +} +/*------------------------------------------------------------------------------ + * Node titles and highlighting + *----------------------------------------------------------------------------*/ +span.fancytree-node { + /* See #117 */ + display: inherit; + width: 100%; + margin-top: 1px; + min-height: 32px; +} +span.fancytree-title { + color: black; + cursor: pointer; + display: inline-block; + vertical-align: top; + min-height: 32px; + padding: 0 3px 0 3px; + margin: 0px 0 0 6px; + border: 1px solid transparent; + -webkit-border-radius: 0px; + -moz-border-radius: 0px; + -ms-border-radius: 0px; + -o-border-radius: 0px; + border-radius: 0px; +} +span.fancytree-node.fancytree-error span.fancytree-title { + color: red; +} +/*------------------------------------------------------------------------------ + * Drag'n'drop support + *----------------------------------------------------------------------------*/ +/* ext-dnd5: */ +span.fancytree-childcounter { + color: #fff; + background: #337ab7; + border: 1px solid gray; + border-radius: 10px; + padding: 2px; + text-align: center; +} +/* ext-dnd: */ +div.fancytree-drag-helper span.fancytree-childcounter, +div.fancytree-drag-helper span.fancytree-dnd-modifier { + display: inline-block; + color: #fff; + background: #337ab7; + border: 1px solid gray; + min-width: 10px; + height: 10px; + line-height: 1; + vertical-align: baseline; + border-radius: 10px; + padding: 2px; + text-align: center; + font-size: 9px; +} +div.fancytree-drag-helper span.fancytree-childcounter { + position: absolute; + top: -6px; + right: -6px; +} +div.fancytree-drag-helper span.fancytree-dnd-modifier { + background: #5cb85c; + border: none; + font-weight: bolder; +} +div.fancytree-drag-helper.fancytree-drop-accept span.fancytree-drag-helper-img { + background-position: -64px -224px; +} +div.fancytree-drag-helper.fancytree-drop-reject span.fancytree-drag-helper-img { + background-position: -32px -224px; +} +/*** Drop marker icon *********************************************************/ +#fancytree-drop-marker { + width: 64px; + position: absolute; + background-position: 0px -256px; + margin: 0; +} +#fancytree-drop-marker.fancytree-drop-after, +#fancytree-drop-marker.fancytree-drop-before { + width: 128px; + background-position: 0px -288px; +} +#fancytree-drop-marker.fancytree-drop-copy { + background-position: -128px -256px; +} +#fancytree-drop-marker.fancytree-drop-move { + background-position: -64px -256px; +} +/*** Source node while dragging ***********************************************/ +span.fancytree-drag-source.fancytree-drag-remove { + opacity: 0.15; +} +/*** Target node while dragging cursor is over it *****************************/ +/*------------------------------------------------------------------------------ + * 'rtl' option + *----------------------------------------------------------------------------*/ +.fancytree-container.fancytree-rtl .fancytree-title { + /*unicode-bidi: bidi-override;*/ + /* optional: reverse title letters */ +} +.fancytree-container.fancytree-rtl span.fancytree-connector, +.fancytree-container.fancytree-rtl span.fancytree-expander, +.fancytree-container.fancytree-rtl span.fancytree-icon, +.fancytree-container.fancytree-rtl span.fancytree-drag-helper-img { + background-image: url("../skin-win8-xxl/icons-rtl.gif"); +} +.fancytree-container.fancytree-rtl .fancytree-exp-n span.fancytree-expander, +.fancytree-container.fancytree-rtl .fancytree-exp-nl span.fancytree-expander { + background-image: none; +} +.fancytree-container.fancytree-rtl.fancytree-connectors .fancytree-exp-n span.fancytree-expander, +.fancytree-container.fancytree-rtl.fancytree-connectors .fancytree-exp-nl span.fancytree-expander { + background-image: url("../skin-win8-xxl/icons-rtl.gif"); +} +ul.fancytree-container.fancytree-rtl ul { + padding: 0 16px 0 0; +} +ul.fancytree-container.fancytree-rtl.fancytree-connectors li { + background-position: right 0; + background-image: url("../skin-win8-xxl/vline-rtl.gif"); +} +ul.fancytree-container.fancytree-rtl li.fancytree-lastsib, +ul.fancytree-container.fancytree-rtl.fancytree-no-connector > li { + background-image: none; +} +#fancytree-drop-marker.fancytree-rtl { + background-image: url("../skin-win8-xxl/icons-rtl.gif"); +} +/*------------------------------------------------------------------------------ + * 'table' extension + *----------------------------------------------------------------------------*/ +table.fancytree-ext-table { + font-family: tahoma, arial, helvetica; + font-size: 10pt; + border-collapse: collapse; + /* ext-ariagrid */ +} +table.fancytree-ext-table span.fancytree-node { + display: inline-block; + box-sizing: border-box; +} +table.fancytree-ext-table td.fancytree-status-merged { + text-align: center; + font-style: italic; + color: #c0c0c0; +} +table.fancytree-ext-table tr.fancytree-statusnode-error td.fancytree-status-merged { + color: red; +} +table.fancytree-ext-table.fancytree-ext-ariagrid.fancytree-cell-mode > tbody > tr.fancytree-active > td { + background-color: #eee; +} +table.fancytree-ext-table.fancytree-ext-ariagrid.fancytree-cell-mode > tbody > tr > td.fancytree-active-cell { + background-color: #cbe8f6; +} +table.fancytree-ext-table.fancytree-ext-ariagrid.fancytree-cell-mode.fancytree-cell-nav-mode > tbody > tr > td.fancytree-active-cell { + background-color: #3875d7; +} +/*------------------------------------------------------------------------------ + * 'columnview' extension + *----------------------------------------------------------------------------*/ +table.fancytree-ext-columnview tbody tr td { + position: relative; + border: 1px solid gray; + vertical-align: top; + overflow: auto; +} +table.fancytree-ext-columnview tbody tr td > ul { + padding: 0; +} +table.fancytree-ext-columnview tbody tr td > ul li { + list-style-image: none; + list-style-position: outside; + list-style-type: none; + -moz-background-clip: border; + -moz-background-inline-policy: continuous; + -moz-background-origin: padding; + background-attachment: scroll; + background-color: transparent; + background-position: 0px 0px; + background-repeat: repeat-y; + background-image: none; + /* no v-lines */ + margin: 0; +} +table.fancytree-ext-columnview span.fancytree-node { + position: relative; + /* allow positioning of embedded spans */ + display: inline-block; +} +table.fancytree-ext-columnview span.fancytree-node.fancytree-expanded { + background-color: #e0e0e0; +} +table.fancytree-ext-columnview span.fancytree-node.fancytree-active { + background-color: #cbe8f6; +} +table.fancytree-ext-columnview .fancytree-has-children span.fancytree-cv-right { + position: absolute; + right: 3px; + background-position: 0px -160px; +} +table.fancytree-ext-columnview .fancytree-has-children span.fancytree-cv-right:hover { + background-position: -32px -160px; +} +/*------------------------------------------------------------------------------ + * 'filter' extension + *----------------------------------------------------------------------------*/ +.fancytree-ext-filter-dimm span.fancytree-node span.fancytree-title { + color: #c0c0c0; + font-weight: lighter; +} +.fancytree-ext-filter-dimm tr.fancytree-submatch span.fancytree-title, +.fancytree-ext-filter-dimm span.fancytree-node.fancytree-submatch span.fancytree-title { + color: black; + font-weight: normal; +} +.fancytree-ext-filter-dimm tr.fancytree-match span.fancytree-title, +.fancytree-ext-filter-dimm span.fancytree-node.fancytree-match span.fancytree-title { + color: black; + font-weight: bold; +} +.fancytree-ext-filter-hide tr.fancytree-hide, +.fancytree-ext-filter-hide span.fancytree-node.fancytree-hide { + display: none; +} +.fancytree-ext-filter-hide tr.fancytree-submatch span.fancytree-title, +.fancytree-ext-filter-hide span.fancytree-node.fancytree-submatch span.fancytree-title { + color: #c0c0c0; + font-weight: lighter; +} +.fancytree-ext-filter-hide tr.fancytree-match span.fancytree-title, +.fancytree-ext-filter-hide span.fancytree-node.fancytree-match span.fancytree-title { + color: black; + font-weight: normal; +} +/* Hide expanders if all child nodes are hidden by filter */ +.fancytree-ext-filter-hide-expanders tr.fancytree-match span.fancytree-expander, +.fancytree-ext-filter-hide-expanders span.fancytree-node.fancytree-match span.fancytree-expander { + visibility: hidden; +} +.fancytree-ext-filter-hide-expanders tr.fancytree-submatch span.fancytree-expander, +.fancytree-ext-filter-hide-expanders span.fancytree-node.fancytree-submatch span.fancytree-expander { + visibility: visible; +} +.fancytree-ext-childcounter span.fancytree-icon, +.fancytree-ext-filter span.fancytree-icon, +.fancytree-ext-childcounter span.fancytree-custom-icon, +.fancytree-ext-filter span.fancytree-custom-icon { + position: relative; +} +.fancytree-ext-childcounter span.fancytree-childcounter, +.fancytree-ext-filter span.fancytree-childcounter { + color: #fff; + background: #777; + border: 1px solid gray; + position: absolute; + top: -6px; + right: -6px; + min-width: 10px; + height: 10px; + line-height: 1; + vertical-align: baseline; + border-radius: 10px; + padding: 2px; + text-align: center; + font-size: 9px; +} +/*------------------------------------------------------------------------------ + * 'wide' extension + *----------------------------------------------------------------------------*/ +ul.fancytree-ext-wide { + position: relative; + min-width: 100%; + z-index: 2; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; +} +ul.fancytree-ext-wide span.fancytree-node > span { + position: relative; + z-index: 2; +} +ul.fancytree-ext-wide span.fancytree-node span.fancytree-title { + position: absolute; + z-index: 1; + left: 0px; + min-width: 100%; + margin-left: 0; + margin-right: 0; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; +} +/*------------------------------------------------------------------------------ + * 'fixed' extension + *----------------------------------------------------------------------------*/ +.fancytree-ext-fixed-wrapper .fancytree-ext-fixed-hidden { + display: none; +} +.fancytree-ext-fixed-wrapper div.fancytree-ext-fixed-scroll-border-bottom { + border-bottom: 3px solid rgba(0, 0, 0, 0.75); +} +.fancytree-ext-fixed-wrapper div.fancytree-ext-fixed-scroll-border-right { + border-right: 3px solid rgba(0, 0, 0, 0.75); +} +.fancytree-ext-fixed-wrapper div.fancytree-ext-fixed-wrapper-tl { + position: absolute; + overflow: hidden; + z-index: 3; + top: 0px; + left: 0px; +} +.fancytree-ext-fixed-wrapper div.fancytree-ext-fixed-wrapper-tr { + position: absolute; + overflow: hidden; + z-index: 2; + top: 0px; +} +.fancytree-ext-fixed-wrapper div.fancytree-ext-fixed-wrapper-bl { + position: absolute; + overflow: hidden; + z-index: 2; + left: 0px; +} +.fancytree-ext-fixed-wrapper div.fancytree-ext-fixed-wrapper-br { + position: absolute; + overflow: scroll; + z-index: 1; +} +/*! + * Fancytree "Win8" skin. + * + * DON'T EDIT THE CSS FILE DIRECTLY, since it is automatically generated from + * the LESS templates. + */ +/******************************************************************************* + * Styles specific to this skin. + * + * This section is automatically generated from the `ui-fancytree.less` template. + ******************************************************************************/ +/******************************************************************************* + * Node titles + */ +.fancytree-plain span.fancytree-title { + border: 1px solid transparent; +} +.fancytree-plain.fancytree-container.fancytree-treefocus span.fancytree-focused span.fancytree-title { + border-color: #3399ff; +} +.fancytree-plain span.fancytree-active span.fancytree-title, +.fancytree-plain span.fancytree-selected span.fancytree-title { + background-color: #f7f7f7; + border-color: #dedede; +} +.fancytree-plain span.fancytree-node span.fancytree-selected span.fancytree-title { + font-style: italic; +} +.fancytree-plain span.fancytree-node:hover span.fancytree-title { + background-color: #eff9fe; + border-color: #70c0e7; +} +.fancytree-plain.fancytree-container.fancytree-treefocus span.fancytree-active span.fancytree-title, +.fancytree-plain.fancytree-container.fancytree-treefocus span.fancytree-selected span.fancytree-title { + background-color: #cbe8f6; + border-color: #26a0da; +} +/******************************************************************************* + * 'table' extension + */ +table.fancytree-ext-table tbody tr td { + border: 1px solid #EDEDED; +} +table.fancytree-ext-table tbody span.fancytree-node, +table.fancytree-ext-table tbody span.fancytree-node:hover { + border: none; + background: none; +} +table.fancytree-ext-table tbody tr:hover { + background-color: #E5F3FB; + outline: 1px solid #70C0E7; +} +table.fancytree-ext-table tbody tr.fancytree-focused span.fancytree-title { + outline: 1px dotted black; +} +table.fancytree-ext-table tbody tr.fancytree-active:hover, +table.fancytree-ext-table tbody tr.fancytree-selected:hover { + background-color: #CBE8F6; + outline: 1px solid #26A0DA; +} +table.fancytree-ext-table tbody tr.fancytree-active { + background-color: #F7F7F7; + outline: 1px solid #DEDEDE; +} +table.fancytree-ext-table tbody tr.fancytree-selected { + background-color: #F7F7F7; +} +table.fancytree-ext-table.fancytree-treefocus tbody tr.fancytree-active { + background-color: #CBE8F6; + outline: 1px solid #26A0DA; +} +table.fancytree-ext-table.fancytree-treefocus tbody tr.fancytree-selected { + background-color: #CBE8F6; +} +ul.fancytree-container { + font-size: 20pt; + padding: 6px; +} diff --git a/plugins/55/indexmenu/scripts/fancytree/skin-win8-xxl/ui.fancytree.less b/plugins/55/indexmenu/scripts/fancytree/skin-win8-xxl/ui.fancytree.less new file mode 100644 index 0000000..2241d97 --- /dev/null +++ b/plugins/55/indexmenu/scripts/fancytree/skin-win8-xxl/ui.fancytree.less @@ -0,0 +1,40 @@ +/*! + * Fancytree "Win8" 32x32 skin. + * + * DON'T EDIT THE CSS FILE DIRECTLY, since it is automatically generated from + * the LESS templates. + */ + +// Import common styles +@import "../skin-common.less"; + +// Import standard win8 +@import "../skin-win8/ui.fancytree.less"; + + +// Override the variable after the import. +// NOTE: Variables are always resolved as the last definition, even if it is +// after where it is used. +@fancy-use-sprites: true; // false: suppress all background images (i.e. icons) + +@fancy-level-indent: 32px; +@fancy-line-height: 32px; // height of a nodes selection bar including borders +@fancy-node-v-spacing: 1px; // gap between two node borders +@fancy-icon-width: 32px; +@fancy-icon-height: 32px; +@fancy-icon-spacing: 6px; // margin between icon/icon or icon/title +@fancy-icon-ofs-top: 0px; // extra vertical offset for expander, checkbox and icon +@fancy-title-ofs-top: 0px; // extra vertical offset for title +@fancy-node-border-width: 1px; +@fancy-node-border-radius: 0px; +@fancy-node-outline-width: 1px; + +// We need to define this variable here (not in skin-common.less) to make it +// work with grunt and webpack: +@fancy-image-prefix: "./skin-win8-xxl/"; + +ul.fancytree-container { +// font-family: tahoma, arial, helvetica; + font-size: 20pt; + padding: 6px; +} diff --git a/plugins/55/indexmenu/scripts/fancytree/skin-win8-xxl/ui.fancytree.min.css b/plugins/55/indexmenu/scripts/fancytree/skin-win8-xxl/ui.fancytree.min.css new file mode 100644 index 0000000..9c7e9ca --- /dev/null +++ b/plugins/55/indexmenu/scripts/fancytree/skin-win8-xxl/ui.fancytree.min.css @@ -0,0 +1,11 @@ +/*! + * Fancytree "Win8" 32x32 skin. + * + * DON'T EDIT THE CSS FILE DIRECTLY, since it is automatically generated from + * the LESS templates. + */.fancytree-helper-hidden{display:none}.fancytree-helper-indeterminate-cb{color:#777}.fancytree-helper-disabled{color:silver}.fancytree-helper-spin{-webkit-animation:spin 1s infinite linear;animation:spin 1s infinite linear}@-webkit-keyframes spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}ul.fancytree-container{font-family:tahoma,arial,helvetica;font-size:10pt;white-space:nowrap;padding:3px;margin:0;background-color:#fff;border:1px dotted gray;min-height:0;position:relative}ul.fancytree-container ul{padding:0 0 0 32px;margin:0}ul.fancytree-container ul>li:before{content:none}ul.fancytree-container li{list-style-image:none;list-style-position:outside;list-style-type:none;-moz-background-clip:border;-moz-background-inline-policy:continuous;-moz-background-origin:padding;background-attachment:scroll;background-color:transparent;background-position:0 0;background-repeat:repeat-y;background-image:none;margin:0}ul.fancytree-container li.fancytree-lastsib{background-image:none}.ui-fancytree-disabled ul.fancytree-container{opacity:.5;background-color:silver}ul.fancytree-connectors.fancytree-container li{background-image:url("../skin-win8-xxl/vline.gif");background-position:0 0}ul.fancytree-container li.fancytree-lastsib,ul.fancytree-no-connector>li{background-image:none}li.fancytree-animating{position:relative}#fancytree-drop-marker,span.fancytree-checkbox,span.fancytree-drag-helper-img,span.fancytree-empty,span.fancytree-expander,span.fancytree-icon,span.fancytree-vline{width:32px;height:32px;display:inline-block;vertical-align:top;background-repeat:no-repeat;background-image:url("../skin-win8-xxl/icons.gif");background-position:0 0}span.fancytree-checkbox,span.fancytree-custom-icon,span.fancytree-expander,span.fancytree-icon{margin-top:0}span.fancytree-custom-icon{width:32px;height:32px;display:inline-block;margin-left:6px;background-position:0 0}img.fancytree-icon{width:32px;height:32px;margin-left:6px;margin-top:0;vertical-align:top;border-style:none}span.fancytree-expander{cursor:pointer}.fancytree-exp-n span.fancytree-expander,.fancytree-exp-nl span.fancytree-expander{background-image:none;cursor:default}.fancytree-connectors .fancytree-exp-n span.fancytree-expander,.fancytree-connectors .fancytree-exp-nl span.fancytree-expander{background-image:url("../skin-win8-xxl/icons.gif");margin-top:0}.fancytree-connectors .fancytree-exp-n span.fancytree-expander,.fancytree-connectors .fancytree-exp-n span.fancytree-expander:hover{background-position:0 -128px}.fancytree-connectors .fancytree-exp-nl span.fancytree-expander,.fancytree-connectors .fancytree-exp-nl span.fancytree-expander:hover{background-position:-32px -128px}.fancytree-exp-c span.fancytree-expander{background-position:0 -160px}.fancytree-exp-c span.fancytree-expander:hover{background-position:-32px -160px}.fancytree-exp-cl span.fancytree-expander{background-position:0 -192px}.fancytree-exp-cl span.fancytree-expander:hover{background-position:-32px -192px}.fancytree-exp-cd span.fancytree-expander{background-position:-128px -160px}.fancytree-exp-cd span.fancytree-expander:hover{background-position:-160px -160px}.fancytree-exp-cdl span.fancytree-expander{background-position:-128px -192px}.fancytree-exp-cdl span.fancytree-expander:hover{background-position:-160px -192px}.fancytree-exp-e span.fancytree-expander,.fancytree-exp-ed span.fancytree-expander{background-position:-64px -160px}.fancytree-exp-e span.fancytree-expander:hover,.fancytree-exp-ed span.fancytree-expander:hover{background-position:-96px -160px}.fancytree-exp-edl span.fancytree-expander,.fancytree-exp-el span.fancytree-expander{background-position:-64px -192px}.fancytree-exp-edl span.fancytree-expander:hover,.fancytree-exp-el span.fancytree-expander:hover{background-position:-96px -192px}.fancytree-fade-expander span.fancytree-expander{transition:opacity 1.5s;opacity:0}.fancytree-fade-expander .fancytree-treefocus span.fancytree-expander,.fancytree-fade-expander [class*=fancytree-statusnode-] span.fancytree-expander,.fancytree-fade-expander.fancytree-treefocus span.fancytree-expander,.fancytree-fade-expander:hover span.fancytree-expander{transition:opacity .6s;opacity:1}span.fancytree-checkbox{margin-left:6px;background-position:0 -64px}span.fancytree-checkbox:hover{background-position:-32px -64px}span.fancytree-checkbox.fancytree-radio{background-position:0 -96px}span.fancytree-checkbox.fancytree-radio:hover{background-position:-32px -96px}.fancytree-partsel span.fancytree-checkbox{background-position:-128px -64px}.fancytree-partsel span.fancytree-checkbox:hover{background-position:-160px -64px}.fancytree-partsel span.fancytree-checkbox.fancytree-radio{background-position:-128px -96px}.fancytree-partsel span.fancytree-checkbox.fancytree-radio:hover{background-position:-160px -96px}.fancytree-selected span.fancytree-checkbox{background-position:-64px -64px}.fancytree-selected span.fancytree-checkbox:hover{background-position:-96px -64px}.fancytree-selected span.fancytree-checkbox.fancytree-radio{background-position:-64px -96px}.fancytree-selected span.fancytree-checkbox.fancytree-radio:hover{background-position:-96px -96px}.fancytree-unselectable span.fancytree-checkbox{opacity:.4}.fancytree-unselectable span.fancytree-checkbox:hover{background-position:0 -64px}.fancytree-unselectable span.fancytree-checkbox.fancytree-radio:hover{background-position:0 -96px}.fancytree-unselectable.fancytree-partsel span.fancytree-checkbox:hover{background-position:-128px -64px}.fancytree-unselectable.fancytree-selected span.fancytree-checkbox:hover{background-position:-64px -64px}.fancytree-unselectable.fancytree-selected span.fancytree-checkbox.fancytree-radio:hover{background-position:-64px -96px}.fancytree-container.fancytree-checkbox-auto-hide span.fancytree-checkbox{visibility:hidden}.fancytree-container.fancytree-checkbox-auto-hide .fancytree-node.fancytree-selected span.fancytree-checkbox,.fancytree-container.fancytree-checkbox-auto-hide .fancytree-node:hover span.fancytree-checkbox,.fancytree-container.fancytree-checkbox-auto-hide tr.fancytree-selected td span.fancytree-checkbox,.fancytree-container.fancytree-checkbox-auto-hide tr:hover td span.fancytree-checkbox{visibility:unset}.fancytree-container.fancytree-checkbox-auto-hide.fancytree-treefocus .fancytree-node.fancytree-active span.fancytree-checkbox,.fancytree-container.fancytree-checkbox-auto-hide.fancytree-treefocus tr.fancytree-active td span.fancytree-checkbox{visibility:unset}span.fancytree-icon{margin-left:6px;background-position:0 0}.fancytree-ico-c span.fancytree-icon:hover{background-position:-32px 0}.fancytree-has-children.fancytree-ico-c span.fancytree-icon{background-position:-64px 0}.fancytree-has-children.fancytree-ico-c span.fancytree-icon:hover{background-position:-96px 0}.fancytree-ico-e span.fancytree-icon{background-position:-128px 0}.fancytree-ico-e span.fancytree-icon:hover{background-position:-160px 0}.fancytree-ico-cf span.fancytree-icon{background-position:0 -32px}.fancytree-ico-cf span.fancytree-icon:hover{background-position:-32px -32px}.fancytree-has-children.fancytree-ico-cf span.fancytree-icon{background-position:-64px -32px}.fancytree-has-children.fancytree-ico-cf span.fancytree-icon:hover{background-position:-96px -32px}.fancytree-ico-ef span.fancytree-icon{background-position:-128px -32px}.fancytree-ico-ef span.fancytree-icon:hover{background-position:-160px -32px}.fancytree-loading span.fancytree-expander,.fancytree-loading span.fancytree-expander:hover,.fancytree-statusnode-loading span.fancytree-icon,.fancytree-statusnode-loading span.fancytree-icon:hover,span.fancytree-icon.fancytree-icon-loading{background-image:url("../skin-win8-xxl/loading.gif");background-position:0 0}.fancytree-statusnode-error span.fancytree-icon,.fancytree-statusnode-error span.fancytree-icon:hover{background-position:0 -224px}span.fancytree-node{display:inherit;width:100%;margin-top:1px;min-height:32px}span.fancytree-title{color:#000;cursor:pointer;display:inline-block;vertical-align:top;min-height:32px;padding:0 3px 0 3px;margin:0 0 0 6px;border:1px solid transparent;-webkit-border-radius:0px;-moz-border-radius:0;-ms-border-radius:0px;-o-border-radius:0;border-radius:0}span.fancytree-node.fancytree-error span.fancytree-title{color:red}span.fancytree-childcounter{color:#fff;background:#337ab7;border:1px solid gray;border-radius:10px;padding:2px;text-align:center}div.fancytree-drag-helper span.fancytree-childcounter,div.fancytree-drag-helper span.fancytree-dnd-modifier{display:inline-block;color:#fff;background:#337ab7;border:1px solid gray;min-width:10px;height:10px;line-height:1;vertical-align:baseline;border-radius:10px;padding:2px;text-align:center;font-size:9px}div.fancytree-drag-helper span.fancytree-childcounter{position:absolute;top:-6px;right:-6px}div.fancytree-drag-helper span.fancytree-dnd-modifier{background:#5cb85c;border:none;font-weight:bolder}div.fancytree-drag-helper.fancytree-drop-accept span.fancytree-drag-helper-img{background-position:-64px -224px}div.fancytree-drag-helper.fancytree-drop-reject span.fancytree-drag-helper-img{background-position:-32px -224px}#fancytree-drop-marker{width:64px;position:absolute;background-position:0 -256px;margin:0}#fancytree-drop-marker.fancytree-drop-after,#fancytree-drop-marker.fancytree-drop-before{width:128px;background-position:0 -288px}#fancytree-drop-marker.fancytree-drop-copy{background-position:-128px -256px}#fancytree-drop-marker.fancytree-drop-move{background-position:-64px -256px}span.fancytree-drag-source.fancytree-drag-remove{opacity:.15}.fancytree-container.fancytree-rtl span.fancytree-connector,.fancytree-container.fancytree-rtl span.fancytree-drag-helper-img,.fancytree-container.fancytree-rtl span.fancytree-expander,.fancytree-container.fancytree-rtl span.fancytree-icon{background-image:url("../skin-win8-xxl/icons-rtl.gif")}.fancytree-container.fancytree-rtl .fancytree-exp-n span.fancytree-expander,.fancytree-container.fancytree-rtl .fancytree-exp-nl span.fancytree-expander{background-image:none}.fancytree-container.fancytree-rtl.fancytree-connectors .fancytree-exp-n span.fancytree-expander,.fancytree-container.fancytree-rtl.fancytree-connectors .fancytree-exp-nl span.fancytree-expander{background-image:url("../skin-win8-xxl/icons-rtl.gif")}ul.fancytree-container.fancytree-rtl ul{padding:0 16px 0 0}ul.fancytree-container.fancytree-rtl.fancytree-connectors li{background-position:right 0;background-image:url("../skin-win8-xxl/vline-rtl.gif")}ul.fancytree-container.fancytree-rtl li.fancytree-lastsib,ul.fancytree-container.fancytree-rtl.fancytree-no-connector>li{background-image:none}#fancytree-drop-marker.fancytree-rtl{background-image:url("../skin-win8-xxl/icons-rtl.gif")}table.fancytree-ext-table{font-family:tahoma,arial,helvetica;font-size:10pt;border-collapse:collapse}table.fancytree-ext-table span.fancytree-node{display:inline-block;box-sizing:border-box}table.fancytree-ext-table td.fancytree-status-merged{text-align:center;font-style:italic;color:silver}table.fancytree-ext-table tr.fancytree-statusnode-error td.fancytree-status-merged{color:red}table.fancytree-ext-table.fancytree-ext-ariagrid.fancytree-cell-mode>tbody>tr.fancytree-active>td{background-color:#eee}table.fancytree-ext-table.fancytree-ext-ariagrid.fancytree-cell-mode>tbody>tr>td.fancytree-active-cell{background-color:#cbe8f6}table.fancytree-ext-table.fancytree-ext-ariagrid.fancytree-cell-mode.fancytree-cell-nav-mode>tbody>tr>td.fancytree-active-cell{background-color:#3875d7}table.fancytree-ext-columnview tbody tr td{position:relative;border:1px solid gray;vertical-align:top;overflow:auto}table.fancytree-ext-columnview tbody tr td>ul{padding:0}table.fancytree-ext-columnview tbody tr td>ul li{list-style-image:none;list-style-position:outside;list-style-type:none;-moz-background-clip:border;-moz-background-inline-policy:continuous;-moz-background-origin:padding;background-attachment:scroll;background-color:transparent;background-position:0 0;background-repeat:repeat-y;background-image:none;margin:0}table.fancytree-ext-columnview span.fancytree-node{position:relative;display:inline-block}table.fancytree-ext-columnview span.fancytree-node.fancytree-expanded{background-color:#e0e0e0}table.fancytree-ext-columnview span.fancytree-node.fancytree-active{background-color:#cbe8f6}table.fancytree-ext-columnview .fancytree-has-children span.fancytree-cv-right{position:absolute;right:3px;background-position:0 -160px}table.fancytree-ext-columnview .fancytree-has-children span.fancytree-cv-right:hover{background-position:-32px -160px}.fancytree-ext-filter-dimm span.fancytree-node span.fancytree-title{color:silver;font-weight:lighter}.fancytree-ext-filter-dimm span.fancytree-node.fancytree-submatch span.fancytree-title,.fancytree-ext-filter-dimm tr.fancytree-submatch span.fancytree-title{color:#000;font-weight:400}.fancytree-ext-filter-dimm span.fancytree-node.fancytree-match span.fancytree-title,.fancytree-ext-filter-dimm tr.fancytree-match span.fancytree-title{color:#000;font-weight:700}.fancytree-ext-filter-hide span.fancytree-node.fancytree-hide,.fancytree-ext-filter-hide tr.fancytree-hide{display:none}.fancytree-ext-filter-hide span.fancytree-node.fancytree-submatch span.fancytree-title,.fancytree-ext-filter-hide tr.fancytree-submatch span.fancytree-title{color:silver;font-weight:lighter}.fancytree-ext-filter-hide span.fancytree-node.fancytree-match span.fancytree-title,.fancytree-ext-filter-hide tr.fancytree-match span.fancytree-title{color:#000;font-weight:400}.fancytree-ext-filter-hide-expanders span.fancytree-node.fancytree-match span.fancytree-expander,.fancytree-ext-filter-hide-expanders tr.fancytree-match span.fancytree-expander{visibility:hidden}.fancytree-ext-filter-hide-expanders span.fancytree-node.fancytree-submatch span.fancytree-expander,.fancytree-ext-filter-hide-expanders tr.fancytree-submatch span.fancytree-expander{visibility:visible}.fancytree-ext-childcounter span.fancytree-custom-icon,.fancytree-ext-childcounter span.fancytree-icon,.fancytree-ext-filter span.fancytree-custom-icon,.fancytree-ext-filter span.fancytree-icon{position:relative}.fancytree-ext-childcounter span.fancytree-childcounter,.fancytree-ext-filter span.fancytree-childcounter{color:#fff;background:#777;border:1px solid gray;position:absolute;top:-6px;right:-6px;min-width:10px;height:10px;line-height:1;vertical-align:baseline;border-radius:10px;padding:2px;text-align:center;font-size:9px}ul.fancytree-ext-wide{position:relative;min-width:100%;z-index:2;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}ul.fancytree-ext-wide span.fancytree-node>span{position:relative;z-index:2}ul.fancytree-ext-wide span.fancytree-node span.fancytree-title{position:absolute;z-index:1;left:0;min-width:100%;margin-left:0;margin-right:0;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.fancytree-ext-fixed-wrapper .fancytree-ext-fixed-hidden{display:none}.fancytree-ext-fixed-wrapper div.fancytree-ext-fixed-scroll-border-bottom{border-bottom:3px solid rgba(0,0,0,.75)}.fancytree-ext-fixed-wrapper div.fancytree-ext-fixed-scroll-border-right{border-right:3px solid rgba(0,0,0,.75)}.fancytree-ext-fixed-wrapper div.fancytree-ext-fixed-wrapper-tl{position:absolute;overflow:hidden;z-index:3;top:0;left:0}.fancytree-ext-fixed-wrapper div.fancytree-ext-fixed-wrapper-tr{position:absolute;overflow:hidden;z-index:2;top:0}.fancytree-ext-fixed-wrapper div.fancytree-ext-fixed-wrapper-bl{position:absolute;overflow:hidden;z-index:2;left:0}.fancytree-ext-fixed-wrapper div.fancytree-ext-fixed-wrapper-br{position:absolute;overflow:scroll;z-index:1}/*! + * Fancytree "Win8" skin. + * + * DON'T EDIT THE CSS FILE DIRECTLY, since it is automatically generated from + * the LESS templates. + */.fancytree-plain span.fancytree-title{border:1px solid transparent}.fancytree-plain.fancytree-container.fancytree-treefocus span.fancytree-focused span.fancytree-title{border-color:#39f}.fancytree-plain span.fancytree-active span.fancytree-title,.fancytree-plain span.fancytree-selected span.fancytree-title{background-color:#f7f7f7;border-color:#dedede}.fancytree-plain span.fancytree-node span.fancytree-selected span.fancytree-title{font-style:italic}.fancytree-plain span.fancytree-node:hover span.fancytree-title{background-color:#eff9fe;border-color:#70c0e7}.fancytree-plain.fancytree-container.fancytree-treefocus span.fancytree-active span.fancytree-title,.fancytree-plain.fancytree-container.fancytree-treefocus span.fancytree-selected span.fancytree-title{background-color:#cbe8f6;border-color:#26a0da}table.fancytree-ext-table tbody tr td{border:1px solid #ededed}table.fancytree-ext-table tbody span.fancytree-node,table.fancytree-ext-table tbody span.fancytree-node:hover{border:none;background:0 0}table.fancytree-ext-table tbody tr:hover{background-color:#e5f3fb;outline:1px solid #70C0E7}table.fancytree-ext-table tbody tr.fancytree-focused span.fancytree-title{outline:1px dotted black}table.fancytree-ext-table tbody tr.fancytree-active:hover,table.fancytree-ext-table tbody tr.fancytree-selected:hover{background-color:#cbe8f6;outline:1px solid #26A0DA}table.fancytree-ext-table tbody tr.fancytree-active{background-color:#f7f7f7;outline:1px solid #DEDEDE}table.fancytree-ext-table tbody tr.fancytree-selected{background-color:#f7f7f7}table.fancytree-ext-table.fancytree-treefocus tbody tr.fancytree-active{background-color:#cbe8f6;outline:1px solid #26A0DA}table.fancytree-ext-table.fancytree-treefocus tbody tr.fancytree-selected{background-color:#cbe8f6}ul.fancytree-container{font-size:20pt;padding:6px}
\ No newline at end of file diff --git a/plugins/55/indexmenu/scripts/fancytree/skin-win8-xxl/vline-rtl.gif b/plugins/55/indexmenu/scripts/fancytree/skin-win8-xxl/vline-rtl.gif Binary files differnew file mode 100644 index 0000000..8b5a279 --- /dev/null +++ b/plugins/55/indexmenu/scripts/fancytree/skin-win8-xxl/vline-rtl.gif diff --git a/plugins/55/indexmenu/scripts/fancytree/skin-win8-xxl/vline.gif b/plugins/55/indexmenu/scripts/fancytree/skin-win8-xxl/vline.gif Binary files differnew file mode 100644 index 0000000..214e4dd --- /dev/null +++ b/plugins/55/indexmenu/scripts/fancytree/skin-win8-xxl/vline.gif diff --git a/plugins/55/indexmenu/scripts/fancytree/skin-win8/icons-rtl.gif b/plugins/55/indexmenu/scripts/fancytree/skin-win8/icons-rtl.gif Binary files differnew file mode 100644 index 0000000..443e1e4 --- /dev/null +++ b/plugins/55/indexmenu/scripts/fancytree/skin-win8/icons-rtl.gif diff --git a/plugins/55/indexmenu/scripts/fancytree/skin-win8/icons.gif b/plugins/55/indexmenu/scripts/fancytree/skin-win8/icons.gif Binary files differnew file mode 100644 index 0000000..0097b1f --- /dev/null +++ b/plugins/55/indexmenu/scripts/fancytree/skin-win8/icons.gif diff --git a/plugins/55/indexmenu/scripts/fancytree/skin-win8/loading.gif b/plugins/55/indexmenu/scripts/fancytree/skin-win8/loading.gif Binary files differnew file mode 100644 index 0000000..ef88497 --- /dev/null +++ b/plugins/55/indexmenu/scripts/fancytree/skin-win8/loading.gif diff --git a/plugins/55/indexmenu/scripts/fancytree/skin-win8/skin-common.less b/plugins/55/indexmenu/scripts/fancytree/skin-win8/skin-common.less new file mode 100644 index 0000000..fc0da50 --- /dev/null +++ b/plugins/55/indexmenu/scripts/fancytree/skin-win8/skin-common.less @@ -0,0 +1,972 @@ +/******************************************************************************* + * Common Styles for Fancytree Skins. + * + * This section is automatically generated from the `skin-common.less` template. + * + * Copyright (c) 2008-2023, Martin Wendt (https://wwWendt.de) + * Released under the MIT license + * https://github.com/mar10/fancytree/wiki/LicenseInfo + * + * @version 2.38.3 + * @date 2023-02-01T20:52:50Z +******************************************************************************/ + +// Variables (defaults, may be overwritten by the including .less files) +@fancy-use-sprites: true; // false: suppress all background images (i.e. icons) +// @fancy-hide-connectors: true; // false: show vertical connector lines + +@fancy-level-indent: 16px; +@fancy-line-height: 16px; // height of a nodes selection bar including borders +@fancy-node-v-spacing: 1px; // gap between two node borders +@fancy-icon-width: 16px; +@fancy-icon-height: 16px; +@fancy-icon-spacing: 3px; // margin between icon/icon or icon/title +@fancy-icon-ofs-top: 0px; // extra vertical offset for expander, checkbox and icon +@fancy-title-ofs-top: 0px; // extra vertical offset for title +@fancy-node-border-width: 1px; +@fancy-node-border-radius: 0px; +@fancy-node-outline-width: 1px; + +// @fancy-line-ofs-top: (@fancy-line-height - @fancy-icon-height) / 2; + +// webpack uses /dist/skin-common.less as root path +// grunt-less uses /dist/skin-Xxx/ui.fancyree.less as root path +// So we define our theme LESS files for webpack compatibility, i.e. +// define the image path n every main LESS file instead of here. +// Prefix may be set to "", "/", "./", or any other value +// Note: this variable must be defined by the main LESS files: +// @fancy-image-prefix: ""; + +// Use 'url(...)' to link to the throbber image, or +// use data-uri(...)' to inline the data in css instead: +/* CHANGE use url, as less does not handel data-uri() correct. DokuWiki can eventually inline it */ + @fancy-loading-url: url("@{fancy-image-prefix}loading.gif"); +//@fancy-loading-url: data-uri("@{fancy-image-prefix}loading.gif"); + +// Set to `true` to use `data-uri(...)` instead of a `url(...)` link: +@fancy-inline-sprites: false; // data-uri() is not handle correct by phpless + +@fancy-font-size: 10pt; +@fancy-font-family: tahoma, arial, helvetica; +@fancy-font-color: black; +@fancy-font-color-dimm: #c0c0c0; +@fancy-font-error-color: red; + +//------------------------------------------------------------------------------ +// Mixins +//------------------------------------------------------------------------------ +.setBgPos(@x, @y, @cond:true) when (@cond) { + background-position: (@x * -@fancy-icon-width) (@y * -@fancy-icon-height); +} +.clearBgImage(@cond:true) when (@cond) { + background-image: none; +} +.setBgImageUrl(@url) when (@fancy-use-sprites) and not (@fancy-inline-sprites) { + background-image: url("@{fancy-image-prefix}@{url}"); +} +.setBgImageUrl(@url) when (@fancy-use-sprites) and (@fancy-inline-sprites) { + background-image: data-uri("@{fancy-image-prefix}@{url}"); +} +.useSprite(@x, @y) when (@fancy-use-sprites) { + .setBgPos(@x, @y); +} +.rounded-corners(@radius) { + -webkit-border-radius: @radius; + -moz-border-radius: @radius; + -ms-border-radius: @radius; + -o-border-radius: @radius; + border-radius: @radius; +} +.spanStyleMixin(@color, @bgcolor, @bordercolor) { + border-color: @bordercolor; + background: @bgcolor; + color: @color; +} +.spanStyleMixin(@color, @bgcolor, @bordercolor, @startColor, @stopColor) { + .spanStyleMixin(@color, @bgcolor, @bordercolor); + // @c-start: argb(@startColor); + // @c-end: argb(@stopColor); + background: -moz-linear-gradient( + top, + @startColor 0%, + @stopColor 100% + ); // FF3.6+ + background: -webkit-gradient( + linear, + left top, + left bottom, + color-stop(0%, @startColor), + color-stop(100%, @stopColor) + ); // Chrome,Safari4+ + background: -webkit-linear-gradient( + top, + @startColor 0%, + @stopColor 100% + ); // Chrome10+,Safari5.1+ + background: -o-linear-gradient( + top, + @startColor 0%, + @stopColor 100% + ); // Opera 11.10+ + background: -ms-linear-gradient( + top, + @startColor 0%, + @stopColor 100% + ); // IE10+ + background: linear-gradient( + to bottom, + @startColor 0%, + @stopColor 100% + ); // W3C + filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='@{startColor}', endColorstr='@{stopColor}',GradientType=0 ); // IE6-9 +} + +/*------------------------------------------------------------------------------ + * Helpers + *----------------------------------------------------------------------------*/ +// Redefine, in case jQuery-UI is not included +// .ui-helper-hidden, +.fancytree-helper-hidden { + display: none; +} +.fancytree-helper-indeterminate-cb { + // tri-state checkbox + color: #777; +} +.fancytree-helper-disabled { + color: @fancy-font-color-dimm; +} + +/* Helper to allow spinning loader icon with glyph-, ligature-, and SVG-icons. */ +/* CHANGE: renamed spin to spin-fancytree */ +.fancytree-helper-spin { + -webkit-animation: spin-fancytree 1000ms infinite linear; + animation: spin-fancytree 1000ms infinite linear; +} +/* CHANGE: commented because it is wrong prefixed by phpless +@-webkit-keyframes spin { + 0% { + -webkit-transform: rotate(0deg); + transform: rotate(0deg); + } + 100% { + -webkit-transform: rotate(359deg); + transform: rotate(359deg); + } +} +@keyframes spin { + 0% { + -webkit-transform: rotate(0deg); + transform: rotate(0deg); + } + 100% { + -webkit-transform: rotate(359deg); + transform: rotate(359deg); + } +} +*/ +/*------------------------------------------------------------------------------ + * Container and UL / LI + *----------------------------------------------------------------------------*/ + +ul.fancytree-container { + font-family: @fancy-font-family; + font-size: @fancy-font-size; + white-space: nowrap; + padding: 3px; + margin: 0; // DT issue 201 + //background-color: white; CHANGE + //border: 1px dotted gray; CHANGE + // overflow: auto; // ext-dnd5: otherwise this is always the scroll parent + // height: 100%; // DT issue 263, 470 + min-height: 0%; // #192 + position: relative; // #235 + ul { + padding: 0 0 0 @fancy-level-indent; + margin: 0; + } + ul > li:before { + // #538 + content: none; + } + li { + list-style-image: none; + list-style-position: outside; + list-style-type: none; + -moz-background-clip: border; + -moz-background-inline-policy: continuous; + -moz-background-origin: padding; + background-attachment: scroll; + background-color: transparent; + .setBgPos(0, 0); + background-repeat: repeat-y; + background-image: none; // no v-lines + + margin: 0; + // padding: 1px 0 0 0; // issue #246 + } + // Suppress lines for last child node + li.fancytree-lastsib { + background-image: none; + } +} + +// Style, when control is disabled +.ui-fancytree-disabled ul.fancytree-container { + opacity: 0.5; + // filter: alpha(opacity=50); // Yields a css warning + background-color: silver; +} + +ul.fancytree-connectors.fancytree-container { + li { + // Use 'data-uri(...)' to embed the image into CSS instead of linking to 'loading.gif': + /* CHANGE: phpless does not handle data-uri() correct */ + //background-image: data-uri("@{fancy-image-prefix}vline.gif"); + background-image: url("@{fancy-image-prefix}vline.gif"); + background-position: 0 0; + } +} + +// Suppress lines for last child node +ul.fancytree-container li.fancytree-lastsib, +// Suppress lines if level is fixed expanded (option minExpandLevel) +ul.fancytree-no-connector > li { + background-image: none; +} + +// Fix jQuery UI 'blind' animation for jQuery UI (#717) +li.fancytree-animating { + position: relative; +} + +/*------------------------------------------------------------------------------ + * Common icon definitions + *----------------------------------------------------------------------------*/ + +span.fancytree-empty, +span.fancytree-vline, +span.fancytree-expander, +span.fancytree-icon, +span.fancytree-checkbox, +// span.fancytree-radio, +span.fancytree-drag-helper-img, +#fancytree-drop-marker { + width: @fancy-icon-width; + height: @fancy-icon-height; + // display: -moz-inline-box; // @ FF 1+2 removed for issue 221 + // -moz-box-align: start; /* issue 221 */ + display: inline-block; // Required to make a span sizeable + vertical-align: top; + background-repeat: no-repeat; + // background-position: left; + .setBgImageUrl("icons.gif"); + .setBgPos(0, 0); +} +span.fancytree-icon, +span.fancytree-checkbox, +span.fancytree-expander, +// span.fancytree-radio, +span.fancytree-custom-icon { + margin-top: @fancy-icon-ofs-top; +} +/* Used by icon option: */ +span.fancytree-custom-icon { + width: @fancy-icon-width; + height: @fancy-icon-height; + display: inline-block; + margin-left: @fancy-icon-spacing; + .setBgPos(0, 0); +} +/* Used by 'icon' node option: */ +img.fancytree-icon { + width: @fancy-icon-width; + height: @fancy-icon-height; + margin-left: @fancy-icon-spacing; + margin-top: @fancy-icon-ofs-top; + vertical-align: top; + border-style: none; +} + +/*------------------------------------------------------------------------------ + * Expander icon + * + * Note: IE6 doesn't correctly evaluate multiples class names, + * so we create combined class names that can be used in the CSS. + * + * Prefix: fancytree-exp- + * 1st character: 'e': expanded, 'c': collapsed, 'n': no children + * 2nd character (optional): 'd': lazy (Delayed) + * 3rd character (optional): 'l': Last sibling + *----------------------------------------------------------------------------*/ + +span.fancytree-expander { + // .useSprite(0, 5); + cursor: pointer; +} +// span.fancytree-expander:hover { +// // .useSprite(1, 5); +// } + +// --- End nodes (use connectors instead of expanders) + +.fancytree-exp-n span.fancytree-expander, +.fancytree-exp-nl span.fancytree-expander { + // .clearBgImage( @fancy-hide-connectors ); + background-image: none; + cursor: default; +} +.fancytree-connectors { + .fancytree-exp-n span.fancytree-expander, + .fancytree-exp-nl span.fancytree-expander { + .setBgImageUrl("icons.gif"); + margin-top: 0; + } + .fancytree-exp-n span.fancytree-expander, // End-node, not last sibling + .fancytree-exp-n span.fancytree-expander:hover { + .useSprite(0, 4); + } + .fancytree-exp-nl span.fancytree-expander, // End-node, last sibling + .fancytree-exp-nl span.fancytree-expander:hover { + .useSprite(1, 4); + } +} + +// --- Collapsed + +.fancytree-exp-c span.fancytree-expander { + // Collapsed, not delayed, not last sibling + .useSprite(0, 5); +} +.fancytree-exp-c span.fancytree-expander:hover { + .useSprite(1, 5); +} +.fancytree-exp-cl span.fancytree-expander { + // Collapsed, not delayed, last sibling + .useSprite(0, 6); +} +.fancytree-exp-cl span.fancytree-expander:hover { + .useSprite(1, 6); +} +.fancytree-exp-cd span.fancytree-expander { + // Collapsed, delayed, not last sibling + .useSprite(4, 5); +} +.fancytree-exp-cd span.fancytree-expander:hover { + .useSprite(5, 5); +} +.fancytree-exp-cdl span.fancytree-expander { + // Collapsed, delayed, last sibling + .useSprite(4, 6); +} +.fancytree-exp-cdl span.fancytree-expander:hover { + .useSprite(5, 6); +} + +// --- Expanded + +.fancytree-exp-e span.fancytree-expander, // Expanded, not delayed, not last sibling +.fancytree-exp-ed span.fancytree-expander { + // Expanded, delayed, not last sibling + .useSprite(2, 5); +} +.fancytree-exp-e span.fancytree-expander:hover, +.fancytree-exp-ed span.fancytree-expander:hover { + .useSprite(3, 5); +} +.fancytree-exp-el span.fancytree-expander, // Expanded, not delayed, last sibling +.fancytree-exp-edl span.fancytree-expander { + // Expanded, delayed, last sibling + .useSprite(2, 6); +} +.fancytree-exp-el span.fancytree-expander:hover, +.fancytree-exp-edl span.fancytree-expander:hover { + .useSprite(3, 6); +} + +/* Fade out expanders, when container is not hovered or active */ +.fancytree-fade-expander { + span.fancytree-expander { + transition: opacity 1.5s; + opacity: 0; + } + &:hover span.fancytree-expander, + &.fancytree-treefocus span.fancytree-expander, + .fancytree-treefocus span.fancytree-expander, + [class*="fancytree-statusnode-"] span.fancytree-expander { + transition: opacity 0.6s; + opacity: 1; + } +} + +//// CHANGE: not used. +///*------------------------------------------------------------------------------ +// * Checkbox icon +// *----------------------------------------------------------------------------*/ +// +//span.fancytree-checkbox { +// margin-left: @fancy-icon-spacing; +// .useSprite(0, 2); +// &:hover { +// .useSprite(1, 2); +// } +// &.fancytree-radio { +// .useSprite(0, 3); +// } +// &.fancytree-radio:hover { +// .useSprite(1, 3); +// } +//} +//.fancytree-partsel span.fancytree-checkbox { +// .useSprite(4, 2); +// &:hover { +// .useSprite(5, 2); +// } +// &.fancytree-radio { +// .useSprite(4, 3); +// } +// &.fancytree-radio:hover { +// .useSprite(5, 3); +// } +//} +//// selected after partsel, so it takes precedence: +//.fancytree-selected span.fancytree-checkbox { +// .useSprite(2, 2); +// &:hover { +// .useSprite(3, 2); +// } +// &.fancytree-radio { +// .useSprite(2, 3); +// } +// &.fancytree-radio:hover { +// .useSprite(3, 3); +// } +//} +//// Unselectable is dimmed, without hover effects +//.fancytree-unselectable { +// span.fancytree-checkbox { +// opacity: 0.4; +// filter: alpha(opacity=40); +// } +// span.fancytree-checkbox:hover { +// .useSprite(0, 2); +// } +// span.fancytree-checkbox.fancytree-radio:hover { +// .useSprite(0, 3); +// } +// &.fancytree-partsel span.fancytree-checkbox:hover { +// .useSprite(4, 2); +// } +// &.fancytree-selected span.fancytree-checkbox:hover { +// .useSprite(2, 2); +// } +// &.fancytree-selected span.fancytree-checkbox.fancytree-radio:hover { +// .useSprite(2, 3); +// } +//} +// +//// Auto-hide checkboxes unless selected or hovered +//.fancytree-container.fancytree-checkbox-auto-hide { +// span.fancytree-checkbox { +// visibility: hidden; +// } +// .fancytree-node:hover span.fancytree-checkbox, +// tr:hover td span.fancytree-checkbox, +// .fancytree-node.fancytree-selected span.fancytree-checkbox, +// tr.fancytree-selected td span.fancytree-checkbox { +// visibility: unset; +// } +// &.fancytree-treefocus { +// .fancytree-node.fancytree-active span.fancytree-checkbox, +// tr.fancytree-active td span.fancytree-checkbox { +// visibility: unset; +// } +// } +//} + +/*------------------------------------------------------------------------------ + * Node type icon + * Note: IE6 doesn't correctly evaluate multiples class names, + * so we create combined class names that can be used in the CSS. + * + * Prefix: fancytree-ico- + * 1st character: 'e': expanded, 'c': collapsed + * 2nd character (optional): 'f': folder + *----------------------------------------------------------------------------*/ + +span.fancytree-icon { + // Default icon + margin-left: @fancy-icon-spacing; + .useSprite(0, 0); +} + +/* Documents */ +.fancytree-ico-c span.fancytree-icon { + // Collapsed folder (empty) + // .useSprite(0, 0); +} +.fancytree-ico-c span.fancytree-icon:hover { + .useSprite(1, 0); +} +.fancytree-has-children.fancytree-ico-c span.fancytree-icon { + // Collapsed folder (not empty) + .useSprite(2, 0); +} +.fancytree-has-children.fancytree-ico-c span.fancytree-icon:hover { + .useSprite(3, 0); +} +.fancytree-ico-e span.fancytree-icon { + // Expanded folder + .useSprite(4, 0); +} +.fancytree-ico-e span.fancytree-icon:hover { + .useSprite(5, 0); +} + +/* Folders */ +.fancytree-ico-cf span.fancytree-icon { + // Collapsed folder (empty) + .useSprite(0, 1); +} +.fancytree-ico-cf span.fancytree-icon:hover { + .useSprite(1, 1); +} +.fancytree-has-children.fancytree-ico-cf span.fancytree-icon { + // Collapsed folder (not empty) + .useSprite(2, 1); +} +.fancytree-has-children.fancytree-ico-cf span.fancytree-icon:hover { + .useSprite(3, 1); +} +.fancytree-ico-ef span.fancytree-icon { + // Expanded folder + .useSprite(4, 1); +} +.fancytree-ico-ef span.fancytree-icon:hover { + .useSprite(5, 1); +} + +// 'Loading' status overrides all others +.fancytree-loading span.fancytree-expander, +.fancytree-loading span.fancytree-expander:hover, +.fancytree-statusnode-loading span.fancytree-icon, +.fancytree-statusnode-loading span.fancytree-icon:hover, +span.fancytree-icon.fancytree-icon-loading { + background-image: @fancy-loading-url; + .useSprite(0, 0); +} + +/* Status node icons */ + +.fancytree-statusnode-error span.fancytree-icon, +.fancytree-statusnode-error span.fancytree-icon:hover { + .useSprite(0, 7); +} + +/*------------------------------------------------------------------------------ + * Node titles and highlighting + *----------------------------------------------------------------------------*/ + +span.fancytree-node { + /* See #117 */ + display: inherit; // #117, resolves to 'display: list-item;' for standard trees + width: 100%; + margin-top: @fancy-node-v-spacing; + min-height: @fancy-line-height; +} +span.fancytree-title { + color: @fancy-font-color; // inherit doesn't work on IE + cursor: pointer; + display: inline-block; // Better alignment, when title contains <br> + vertical-align: top; + min-height: @fancy-line-height; + padding: 0 3px 0 3px; // Otherwise italic font will be outside right bounds + margin: @fancy-title-ofs-top 0 0 @fancy-icon-spacing; + // margin: 0px; + // margin-top: @fancy-line-ofs-top; + // margin-left: @fancy-icon-spacing; + border: @fancy-node-border-width solid transparent; // avoid jumping, when a border is added on hover + .rounded-corners(@fancy-node-border-radius); + // outline: 0; // @ Firefox, prevent dotted border after click + // Set transparent border to prevent jumping when active node gets a border + // (we can do this, because this theme doesn't use vertical lines) + // border: 1px solid white; // Note: 'transparent' would not work in IE6 +} +span.fancytree-node.fancytree-error span.fancytree-title { + color: @fancy-font-error-color; +} + +//// CHANGE: not used. +///*------------------------------------------------------------------------------ +// * Drag'n'drop support +// *----------------------------------------------------------------------------*/ +///* ext-dnd5: */ +//span.fancytree-childcounter { +// color: #fff; +// background: #337ab7; // bootstrap blue +// border: 1px solid gray; +// border-radius: 10px; +// padding: 2px; +// text-align: center; +//} +// +///* ext-dnd: */ +//div.fancytree-drag-helper { +// span.fancytree-childcounter, +// span.fancytree-dnd-modifier { +// display: inline-block; +// color: #fff; +// background: #337ab7; // bootstrap blue +// border: 1px solid gray; +// min-width: 10px; +// // min-height: 16px; +// height: 10px; +// line-height: 1; +// vertical-align: baseline; +// border-radius: 10px; +// padding: 2px; +// text-align: center; +// font-size: 9px; +// } +// span.fancytree-childcounter { +// position: absolute; +// // left: 16px; +// top: -6px; +// right: -6px; +// } +// span.fancytree-dnd-modifier { +// background: #5cb85c; // bootstrap green +// border: none; +// // min-height: 16px; +// // font-size: 12px; +// font-weight: bolder; +// } +// &.fancytree-drop-accept { +// span.fancytree-drag-helper-img { +// .useSprite(2, 7); +// } +// } +// &.fancytree-drop-reject { +// span.fancytree-drag-helper-img { +// .useSprite(1, 7); +// } +// } +//} +// +///*** Drop marker icon *********************************************************/ +//#fancytree-drop-marker { +// width: 2 * @fancy-icon-width; // was 24px, but 32 should be correct +// position: absolute; +// .useSprite(0, 8); +// margin: 0; +// &.fancytree-drop-after, +// &.fancytree-drop-before { +// width: 4 * @fancy-icon-width; // 64px; +// .useSprite(0, 9); +// } +// &.fancytree-drop-copy { +// .useSprite(4, 8); +// } +// &.fancytree-drop-move { +// .useSprite(2, 8); +// } +//} +// +///*** Source node while dragging ***********************************************/ +// +//span.fancytree-drag-source { +// &.fancytree-drag-remove { +// // text-decoration: line-through; +// opacity: 0.15; +// } +//} +// +///*** Target node while dragging cursor is over it *****************************/ +// +//span.fancytree-drop-target { +// &.fancytree-drop-accept { +// // outline: 1px dotted #5cb85c; // bootstrap sucess +// } +//} +//span.fancytree-drop-reject { +// // outline: 1px dotted #d9534f; // boostrap warning +//} + +/*------------------------------------------------------------------------------ + * 'rtl' option + *----------------------------------------------------------------------------*/ + +.fancytree-container.fancytree-rtl { + .fancytree-title { + /*unicode-bidi: bidi-override;*/ /* optional: reverse title letters */ + } + span.fancytree-connector, + span.fancytree-expander, + span.fancytree-icon, + span.fancytree-drag-helper-img { + .setBgImageUrl("icons-rtl.gif"); + } + .fancytree-exp-n span.fancytree-expander, + .fancytree-exp-nl span.fancytree-expander { + background-image: none; + } + &.fancytree-connectors .fancytree-exp-n span.fancytree-expander, + &.fancytree-connectors .fancytree-exp-nl span.fancytree-expander { + .setBgImageUrl("icons-rtl.gif"); + } +} +ul.fancytree-container.fancytree-rtl { + ul { + padding: 0 16px 0 0; + } + &.fancytree-connectors li { + background-position: right 0; + background-image: url("@{fancy-image-prefix}vline-rtl.gif"); + } + // Suppress lines for last child node + li.fancytree-lastsib, + // Suppress lines if level is fixed expanded (option minExpandLevel) + &.fancytree-no-connector > li { + background-image: none; + } +} +#fancytree-drop-marker.fancytree-rtl { + .setBgImageUrl("icons-rtl.gif"); +} + +//// CHANGE: not used. +///*------------------------------------------------------------------------------ +// * 'table' extension +// *----------------------------------------------------------------------------*/ +// +//table.fancytree-ext-table { +// font-family: @fancy-font-family; +// font-size: @fancy-font-size; +// border-collapse: collapse; +// span.fancytree-node { +// display: inline-block; // #117 +// box-sizing: border-box; // #562 +// } +// td.fancytree-status-merged { +// text-align: center; +// // font-weight: bold; +// font-style: italic; +// // line-height: 100px; +// color: @fancy-font-color-dimm; +// } +// tr.fancytree-statusnode-error td.fancytree-status-merged { +// color: @fancy-font-error-color; +// } +// /* ext-ariagrid */ +// &.fancytree-ext-ariagrid.fancytree-cell-mode { +// > tbody > tr.fancytree-active > td { +// background-color: #eee; +// } +// > tbody > tr > td.fancytree-active-cell { +// background-color: #cbe8f6; +// } +// &.fancytree-cell-nav-mode > tbody > tr > td.fancytree-active-cell { +// background-color: #3875d7; +// } +// } +//} +// +///*------------------------------------------------------------------------------ +// * 'columnview' extension +// *----------------------------------------------------------------------------*/ +// +//table.fancytree-ext-columnview { +// // border-collapse: collapse; +// // width: 100%; +// tbody tr td { +// position: relative; +// border: 1px solid gray; +// vertical-align: top; +// overflow: auto; +// > ul { +// padding: 0; +// li { +// list-style-image: none; +// list-style-position: outside; +// list-style-type: none; +// -moz-background-clip: border; +// -moz-background-inline-policy: continuous; +// -moz-background-origin: padding; +// background-attachment: scroll; +// background-color: transparent; +// .setBgPos(0, 0); +// background-repeat: repeat-y; +// background-image: none; /* no v-lines */ +// +// margin: 0; +// // padding: 1px 0 0 0; // issue #246 +// } +// } +// } +// span.fancytree-node { +// position: relative; /* allow positioning of embedded spans */ +// display: inline-block; // #117 +// } +// span.fancytree-node.fancytree-expanded { +// background-color: #e0e0e0; +// } +// span.fancytree-node.fancytree-active { +// background-color: #cbe8f6; +// // background-color: royalblue; +// } +// .fancytree-has-children span.fancytree-cv-right { +// position: absolute; +// right: 3px; +// .useSprite(0, 5); +// &:hover { +// .useSprite(1, 5); +// } +// } +//} +// +///*------------------------------------------------------------------------------ +// * 'filter' extension +// *----------------------------------------------------------------------------*/ +// +//.fancytree-ext-filter-dimm { +// span.fancytree-node span.fancytree-title { +// color: @fancy-font-color-dimm; +// font-weight: lighter; +// } +// tr.fancytree-submatch span.fancytree-title, +// span.fancytree-node.fancytree-submatch span.fancytree-title { +// color: black; +// font-weight: normal; +// } +// tr.fancytree-match span.fancytree-title, +// span.fancytree-node.fancytree-match span.fancytree-title { +// color: black; +// font-weight: bold; +// } +//} +//.fancytree-ext-filter-hide { +// tr.fancytree-hide, +// span.fancytree-node.fancytree-hide { +// display: none; +// } +// tr.fancytree-submatch span.fancytree-title, +// span.fancytree-node.fancytree-submatch span.fancytree-title { +// color: @fancy-font-color-dimm; +// font-weight: lighter; +// } +// tr.fancytree-match span.fancytree-title, +// span.fancytree-node.fancytree-match span.fancytree-title { +// color: black; +// font-weight: normal; +// } +//} +///* Hide expanders if all child nodes are hidden by filter */ +//.fancytree-ext-filter-hide-expanders { +// tr.fancytree-match span.fancytree-expander, +// span.fancytree-node.fancytree-match span.fancytree-expander { +// visibility: hidden; +// } +// tr.fancytree-submatch span.fancytree-expander, +// span.fancytree-node.fancytree-submatch span.fancytree-expander { +// visibility: visible; +// } +//} +// +//.fancytree-ext-childcounter, +//.fancytree-ext-filter { +// // span.fancytree-title mark { +// // font-style: normal; +// // background-color: #ead61c; // yellow +// // border-radius: 3px; +// // } +// span.fancytree-icon, +// span.fancytree-custom-icon { +// position: relative; +// } +// span.fancytree-childcounter { +// color: #fff; +// background: #777; // #337ab7; // bootstrap blue +// border: 1px solid gray; +// position: absolute; +// top: -6px; +// right: -6px; +// min-width: 10px; +// height: 10px; +// line-height: 1; +// vertical-align: baseline; +// border-radius: 10px; +// padding: 2px; +// text-align: center; +// font-size: 9px; +// } +//} +///*------------------------------------------------------------------------------ +// * 'wide' extension +// *----------------------------------------------------------------------------*/ +// +//ul.fancytree-ext-wide { +// position: relative; +// min-width: 100%; +// z-index: 2; +// +// -webkit-box-sizing: border-box; +// -moz-box-sizing: border-box; +// box-sizing: border-box; +// +// span.fancytree-node > span { +// position: relative; +// z-index: 2; +// } +// span.fancytree-node span.fancytree-title { +// position: absolute; // Allow left: 0. Note: prevents smooth dropdown animation +// z-index: 1; // Behind expander and checkbox +// left: 0px; +// min-width: 100%; +// margin-left: 0; +// margin-right: 0; +// +// -webkit-box-sizing: border-box; +// -moz-box-sizing: border-box; +// box-sizing: border-box; +// } +//} +// +///*------------------------------------------------------------------------------ +// * 'fixed' extension +// *----------------------------------------------------------------------------*/ +// +//.fancytree-ext-fixed-wrapper { +// .fancytree-ext-fixed-hidden { +// display: none; +// } +// div.fancytree-ext-fixed-scroll-border-bottom { +// border-bottom: 3px solid rgba(0, 0, 0, 0.75); +// } +// div.fancytree-ext-fixed-scroll-border-right { +// border-right: 3px solid rgba(0, 0, 0, 0.75); +// } +// div.fancytree-ext-fixed-wrapper-tl { +// position: absolute; +// overflow: hidden; +// z-index: 3; +// top: 0px; +// left: 0px; +// } +// div.fancytree-ext-fixed-wrapper-tr { +// position: absolute; +// overflow: hidden; +// z-index: 2; +// top: 0px; +// } +// div.fancytree-ext-fixed-wrapper-bl { +// position: absolute; +// overflow: hidden; +// z-index: 2; +// left: 0px; +// } +// div.fancytree-ext-fixed-wrapper-br { +// position: absolute; +// overflow: scroll; +// z-index: 1; +// } +//} diff --git a/plugins/55/indexmenu/scripts/fancytree/skin-win8/ui.fancytree.css b/plugins/55/indexmenu/scripts/fancytree/skin-win8/ui.fancytree.css new file mode 100644 index 0000000..8a0ba4b --- /dev/null +++ b/plugins/55/indexmenu/scripts/fancytree/skin-win8/ui.fancytree.css @@ -0,0 +1,765 @@ +/*! + * Fancytree "Win8" skin. + * + * DON'T EDIT THE CSS FILE DIRECTLY, since it is automatically generated from + * the LESS templates. + */ +/******************************************************************************* + * Common Styles for Fancytree Skins. + * + * This section is automatically generated from the `skin-common.less` template. + * + * Copyright (c) 2008-2023, Martin Wendt (https://wwWendt.de) + * Released under the MIT license + * https://github.com/mar10/fancytree/wiki/LicenseInfo + * + * @version 2.38.3 + * @date 2023-02-01T20:52:50Z +******************************************************************************/ +/*------------------------------------------------------------------------------ + * Helpers + *----------------------------------------------------------------------------*/ +.fancytree-helper-hidden { + display: none; +} +.fancytree-helper-indeterminate-cb { + color: #777; +} +.fancytree-helper-disabled { + color: #c0c0c0; +} +/* Helper to allow spinning loader icon with glyph-, ligature-, and SVG-icons. */ +.fancytree-helper-spin { + -webkit-animation: spin 1000ms infinite linear; + animation: spin 1000ms infinite linear; +} +@-webkit-keyframes spin { + 0% { + -webkit-transform: rotate(0deg); + transform: rotate(0deg); + } + 100% { + -webkit-transform: rotate(359deg); + transform: rotate(359deg); + } +} +@keyframes spin { + 0% { + -webkit-transform: rotate(0deg); + transform: rotate(0deg); + } + 100% { + -webkit-transform: rotate(359deg); + transform: rotate(359deg); + } +} +/*------------------------------------------------------------------------------ + * Container and UL / LI + *----------------------------------------------------------------------------*/ +ul.fancytree-container { + font-family: tahoma, arial, helvetica; + font-size: 10pt; + white-space: nowrap; + padding: 3px; + margin: 0; + background-color: white; + border: 1px dotted gray; + min-height: 0%; + position: relative; +} +ul.fancytree-container ul { + padding: 0 0 0 16px; + margin: 0; +} +ul.fancytree-container ul > li:before { + content: none; +} +ul.fancytree-container li { + list-style-image: none; + list-style-position: outside; + list-style-type: none; + -moz-background-clip: border; + -moz-background-inline-policy: continuous; + -moz-background-origin: padding; + background-attachment: scroll; + background-color: transparent; + background-position: 0px 0px; + background-repeat: repeat-y; + background-image: none; + margin: 0; +} +ul.fancytree-container li.fancytree-lastsib { + background-image: none; +} +.ui-fancytree-disabled ul.fancytree-container { + opacity: 0.5; + background-color: silver; +} +ul.fancytree-connectors.fancytree-container li { + background-image: url("../skin-win8/vline.gif"); + background-position: 0 0; +} +ul.fancytree-container li.fancytree-lastsib, +ul.fancytree-no-connector > li { + background-image: none; +} +li.fancytree-animating { + position: relative; +} +/*------------------------------------------------------------------------------ + * Common icon definitions + *----------------------------------------------------------------------------*/ +span.fancytree-empty, +span.fancytree-vline, +span.fancytree-expander, +span.fancytree-icon, +span.fancytree-checkbox, +span.fancytree-drag-helper-img, +#fancytree-drop-marker { + width: 16px; + height: 16px; + display: inline-block; + vertical-align: top; + background-repeat: no-repeat; + background-image: url("../skin-win8/icons.gif"); + background-position: 0px 0px; +} +span.fancytree-icon, +span.fancytree-checkbox, +span.fancytree-expander, +span.fancytree-custom-icon { + margin-top: 2px; +} +/* Used by icon option: */ +span.fancytree-custom-icon { + width: 16px; + height: 16px; + display: inline-block; + margin-left: 3px; + background-position: 0px 0px; +} +/* Used by 'icon' node option: */ +img.fancytree-icon { + width: 16px; + height: 16px; + margin-left: 3px; + margin-top: 2px; + vertical-align: top; + border-style: none; +} +/*------------------------------------------------------------------------------ + * Expander icon + * + * Note: IE6 doesn't correctly evaluate multiples class names, + * so we create combined class names that can be used in the CSS. + * + * Prefix: fancytree-exp- + * 1st character: 'e': expanded, 'c': collapsed, 'n': no children + * 2nd character (optional): 'd': lazy (Delayed) + * 3rd character (optional): 'l': Last sibling + *----------------------------------------------------------------------------*/ +span.fancytree-expander { + cursor: pointer; +} +.fancytree-exp-n span.fancytree-expander, +.fancytree-exp-nl span.fancytree-expander { + background-image: none; + cursor: default; +} +.fancytree-connectors .fancytree-exp-n span.fancytree-expander, +.fancytree-connectors .fancytree-exp-nl span.fancytree-expander { + background-image: url("../skin-win8/icons.gif"); + margin-top: 0; +} +.fancytree-connectors .fancytree-exp-n span.fancytree-expander, +.fancytree-connectors .fancytree-exp-n span.fancytree-expander:hover { + background-position: 0px -64px; +} +.fancytree-connectors .fancytree-exp-nl span.fancytree-expander, +.fancytree-connectors .fancytree-exp-nl span.fancytree-expander:hover { + background-position: -16px -64px; +} +.fancytree-exp-c span.fancytree-expander { + background-position: 0px -80px; +} +.fancytree-exp-c span.fancytree-expander:hover { + background-position: -16px -80px; +} +.fancytree-exp-cl span.fancytree-expander { + background-position: 0px -96px; +} +.fancytree-exp-cl span.fancytree-expander:hover { + background-position: -16px -96px; +} +.fancytree-exp-cd span.fancytree-expander { + background-position: -64px -80px; +} +.fancytree-exp-cd span.fancytree-expander:hover { + background-position: -80px -80px; +} +.fancytree-exp-cdl span.fancytree-expander { + background-position: -64px -96px; +} +.fancytree-exp-cdl span.fancytree-expander:hover { + background-position: -80px -96px; +} +.fancytree-exp-e span.fancytree-expander, +.fancytree-exp-ed span.fancytree-expander { + background-position: -32px -80px; +} +.fancytree-exp-e span.fancytree-expander:hover, +.fancytree-exp-ed span.fancytree-expander:hover { + background-position: -48px -80px; +} +.fancytree-exp-el span.fancytree-expander, +.fancytree-exp-edl span.fancytree-expander { + background-position: -32px -96px; +} +.fancytree-exp-el span.fancytree-expander:hover, +.fancytree-exp-edl span.fancytree-expander:hover { + background-position: -48px -96px; +} +/* Fade out expanders, when container is not hovered or active */ +.fancytree-fade-expander span.fancytree-expander { + transition: opacity 1.5s; + opacity: 0; +} +.fancytree-fade-expander:hover span.fancytree-expander, +.fancytree-fade-expander.fancytree-treefocus span.fancytree-expander, +.fancytree-fade-expander .fancytree-treefocus span.fancytree-expander, +.fancytree-fade-expander [class*="fancytree-statusnode-"] span.fancytree-expander { + transition: opacity 0.6s; + opacity: 1; +} +/*------------------------------------------------------------------------------ + * Checkbox icon + *----------------------------------------------------------------------------*/ +span.fancytree-checkbox { + margin-left: 3px; + background-position: 0px -32px; +} +span.fancytree-checkbox:hover { + background-position: -16px -32px; +} +span.fancytree-checkbox.fancytree-radio { + background-position: 0px -48px; +} +span.fancytree-checkbox.fancytree-radio:hover { + background-position: -16px -48px; +} +.fancytree-partsel span.fancytree-checkbox { + background-position: -64px -32px; +} +.fancytree-partsel span.fancytree-checkbox:hover { + background-position: -80px -32px; +} +.fancytree-partsel span.fancytree-checkbox.fancytree-radio { + background-position: -64px -48px; +} +.fancytree-partsel span.fancytree-checkbox.fancytree-radio:hover { + background-position: -80px -48px; +} +.fancytree-selected span.fancytree-checkbox { + background-position: -32px -32px; +} +.fancytree-selected span.fancytree-checkbox:hover { + background-position: -48px -32px; +} +.fancytree-selected span.fancytree-checkbox.fancytree-radio { + background-position: -32px -48px; +} +.fancytree-selected span.fancytree-checkbox.fancytree-radio:hover { + background-position: -48px -48px; +} +.fancytree-unselectable span.fancytree-checkbox { + opacity: 0.4; + filter: alpha(opacity=40); +} +.fancytree-unselectable span.fancytree-checkbox:hover { + background-position: 0px -32px; +} +.fancytree-unselectable span.fancytree-checkbox.fancytree-radio:hover { + background-position: 0px -48px; +} +.fancytree-unselectable.fancytree-partsel span.fancytree-checkbox:hover { + background-position: -64px -32px; +} +.fancytree-unselectable.fancytree-selected span.fancytree-checkbox:hover { + background-position: -32px -32px; +} +.fancytree-unselectable.fancytree-selected span.fancytree-checkbox.fancytree-radio:hover { + background-position: -32px -48px; +} +.fancytree-container.fancytree-checkbox-auto-hide span.fancytree-checkbox { + visibility: hidden; +} +.fancytree-container.fancytree-checkbox-auto-hide .fancytree-node:hover span.fancytree-checkbox, +.fancytree-container.fancytree-checkbox-auto-hide tr:hover td span.fancytree-checkbox, +.fancytree-container.fancytree-checkbox-auto-hide .fancytree-node.fancytree-selected span.fancytree-checkbox, +.fancytree-container.fancytree-checkbox-auto-hide tr.fancytree-selected td span.fancytree-checkbox { + visibility: unset; +} +.fancytree-container.fancytree-checkbox-auto-hide.fancytree-treefocus .fancytree-node.fancytree-active span.fancytree-checkbox, +.fancytree-container.fancytree-checkbox-auto-hide.fancytree-treefocus tr.fancytree-active td span.fancytree-checkbox { + visibility: unset; +} +/*------------------------------------------------------------------------------ + * Node type icon + * Note: IE6 doesn't correctly evaluate multiples class names, + * so we create combined class names that can be used in the CSS. + * + * Prefix: fancytree-ico- + * 1st character: 'e': expanded, 'c': collapsed + * 2nd character (optional): 'f': folder + *----------------------------------------------------------------------------*/ +span.fancytree-icon { + margin-left: 3px; + background-position: 0px 0px; +} +/* Documents */ +.fancytree-ico-c span.fancytree-icon:hover { + background-position: -16px 0px; +} +.fancytree-has-children.fancytree-ico-c span.fancytree-icon { + background-position: -32px 0px; +} +.fancytree-has-children.fancytree-ico-c span.fancytree-icon:hover { + background-position: -48px 0px; +} +.fancytree-ico-e span.fancytree-icon { + background-position: -64px 0px; +} +.fancytree-ico-e span.fancytree-icon:hover { + background-position: -80px 0px; +} +/* Folders */ +.fancytree-ico-cf span.fancytree-icon { + background-position: 0px -16px; +} +.fancytree-ico-cf span.fancytree-icon:hover { + background-position: -16px -16px; +} +.fancytree-has-children.fancytree-ico-cf span.fancytree-icon { + background-position: -32px -16px; +} +.fancytree-has-children.fancytree-ico-cf span.fancytree-icon:hover { + background-position: -48px -16px; +} +.fancytree-ico-ef span.fancytree-icon { + background-position: -64px -16px; +} +.fancytree-ico-ef span.fancytree-icon:hover { + background-position: -80px -16px; +} +.fancytree-loading span.fancytree-expander, +.fancytree-loading span.fancytree-expander:hover, +.fancytree-statusnode-loading span.fancytree-icon, +.fancytree-statusnode-loading span.fancytree-icon:hover, +span.fancytree-icon.fancytree-icon-loading { + background-image: url("../skin-win8/loading.gif"); + background-position: 0px 0px; +} +/* Status node icons */ +.fancytree-statusnode-error span.fancytree-icon, +.fancytree-statusnode-error span.fancytree-icon:hover { + background-position: 0px -112px; +} +/*------------------------------------------------------------------------------ + * Node titles and highlighting + *----------------------------------------------------------------------------*/ +span.fancytree-node { + /* See #117 */ + display: inherit; + width: 100%; + margin-top: 0px; + min-height: 20px; +} +span.fancytree-title { + color: black; + cursor: pointer; + display: inline-block; + vertical-align: top; + min-height: 20px; + padding: 0 3px 0 3px; + margin: 0px 0 0 3px; + border: 1px solid transparent; + -webkit-border-radius: 0px; + -moz-border-radius: 0px; + -ms-border-radius: 0px; + -o-border-radius: 0px; + border-radius: 0px; +} +span.fancytree-node.fancytree-error span.fancytree-title { + color: red; +} +/*------------------------------------------------------------------------------ + * Drag'n'drop support + *----------------------------------------------------------------------------*/ +/* ext-dnd5: */ +span.fancytree-childcounter { + color: #fff; + background: #337ab7; + border: 1px solid gray; + border-radius: 10px; + padding: 2px; + text-align: center; +} +/* ext-dnd: */ +div.fancytree-drag-helper span.fancytree-childcounter, +div.fancytree-drag-helper span.fancytree-dnd-modifier { + display: inline-block; + color: #fff; + background: #337ab7; + border: 1px solid gray; + min-width: 10px; + height: 10px; + line-height: 1; + vertical-align: baseline; + border-radius: 10px; + padding: 2px; + text-align: center; + font-size: 9px; +} +div.fancytree-drag-helper span.fancytree-childcounter { + position: absolute; + top: -6px; + right: -6px; +} +div.fancytree-drag-helper span.fancytree-dnd-modifier { + background: #5cb85c; + border: none; + font-weight: bolder; +} +div.fancytree-drag-helper.fancytree-drop-accept span.fancytree-drag-helper-img { + background-position: -32px -112px; +} +div.fancytree-drag-helper.fancytree-drop-reject span.fancytree-drag-helper-img { + background-position: -16px -112px; +} +/*** Drop marker icon *********************************************************/ +#fancytree-drop-marker { + width: 32px; + position: absolute; + background-position: 0px -128px; + margin: 0; +} +#fancytree-drop-marker.fancytree-drop-after, +#fancytree-drop-marker.fancytree-drop-before { + width: 64px; + background-position: 0px -144px; +} +#fancytree-drop-marker.fancytree-drop-copy { + background-position: -64px -128px; +} +#fancytree-drop-marker.fancytree-drop-move { + background-position: -32px -128px; +} +/*** Source node while dragging ***********************************************/ +span.fancytree-drag-source.fancytree-drag-remove { + opacity: 0.15; +} +/*** Target node while dragging cursor is over it *****************************/ +/*------------------------------------------------------------------------------ + * 'rtl' option + *----------------------------------------------------------------------------*/ +.fancytree-container.fancytree-rtl .fancytree-title { + /*unicode-bidi: bidi-override;*/ + /* optional: reverse title letters */ +} +.fancytree-container.fancytree-rtl span.fancytree-connector, +.fancytree-container.fancytree-rtl span.fancytree-expander, +.fancytree-container.fancytree-rtl span.fancytree-icon, +.fancytree-container.fancytree-rtl span.fancytree-drag-helper-img { + background-image: url("../skin-win8/icons-rtl.gif"); +} +.fancytree-container.fancytree-rtl .fancytree-exp-n span.fancytree-expander, +.fancytree-container.fancytree-rtl .fancytree-exp-nl span.fancytree-expander { + background-image: none; +} +.fancytree-container.fancytree-rtl.fancytree-connectors .fancytree-exp-n span.fancytree-expander, +.fancytree-container.fancytree-rtl.fancytree-connectors .fancytree-exp-nl span.fancytree-expander { + background-image: url("../skin-win8/icons-rtl.gif"); +} +ul.fancytree-container.fancytree-rtl ul { + padding: 0 16px 0 0; +} +ul.fancytree-container.fancytree-rtl.fancytree-connectors li { + background-position: right 0; + background-image: url("../skin-win8/vline-rtl.gif"); +} +ul.fancytree-container.fancytree-rtl li.fancytree-lastsib, +ul.fancytree-container.fancytree-rtl.fancytree-no-connector > li { + background-image: none; +} +#fancytree-drop-marker.fancytree-rtl { + background-image: url("../skin-win8/icons-rtl.gif"); +} +/*------------------------------------------------------------------------------ + * 'table' extension + *----------------------------------------------------------------------------*/ +table.fancytree-ext-table { + font-family: tahoma, arial, helvetica; + font-size: 10pt; + border-collapse: collapse; + /* ext-ariagrid */ +} +table.fancytree-ext-table span.fancytree-node { + display: inline-block; + box-sizing: border-box; +} +table.fancytree-ext-table td.fancytree-status-merged { + text-align: center; + font-style: italic; + color: #c0c0c0; +} +table.fancytree-ext-table tr.fancytree-statusnode-error td.fancytree-status-merged { + color: red; +} +table.fancytree-ext-table.fancytree-ext-ariagrid.fancytree-cell-mode > tbody > tr.fancytree-active > td { + background-color: #eee; +} +table.fancytree-ext-table.fancytree-ext-ariagrid.fancytree-cell-mode > tbody > tr > td.fancytree-active-cell { + background-color: #cbe8f6; +} +table.fancytree-ext-table.fancytree-ext-ariagrid.fancytree-cell-mode.fancytree-cell-nav-mode > tbody > tr > td.fancytree-active-cell { + background-color: #3875d7; +} +/*------------------------------------------------------------------------------ + * 'columnview' extension + *----------------------------------------------------------------------------*/ +table.fancytree-ext-columnview tbody tr td { + position: relative; + border: 1px solid gray; + vertical-align: top; + overflow: auto; +} +table.fancytree-ext-columnview tbody tr td > ul { + padding: 0; +} +table.fancytree-ext-columnview tbody tr td > ul li { + list-style-image: none; + list-style-position: outside; + list-style-type: none; + -moz-background-clip: border; + -moz-background-inline-policy: continuous; + -moz-background-origin: padding; + background-attachment: scroll; + background-color: transparent; + background-position: 0px 0px; + background-repeat: repeat-y; + background-image: none; + /* no v-lines */ + margin: 0; +} +table.fancytree-ext-columnview span.fancytree-node { + position: relative; + /* allow positioning of embedded spans */ + display: inline-block; +} +table.fancytree-ext-columnview span.fancytree-node.fancytree-expanded { + background-color: #e0e0e0; +} +table.fancytree-ext-columnview span.fancytree-node.fancytree-active { + background-color: #cbe8f6; +} +table.fancytree-ext-columnview .fancytree-has-children span.fancytree-cv-right { + position: absolute; + right: 3px; + background-position: 0px -80px; +} +table.fancytree-ext-columnview .fancytree-has-children span.fancytree-cv-right:hover { + background-position: -16px -80px; +} +/*------------------------------------------------------------------------------ + * 'filter' extension + *----------------------------------------------------------------------------*/ +.fancytree-ext-filter-dimm span.fancytree-node span.fancytree-title { + color: #c0c0c0; + font-weight: lighter; +} +.fancytree-ext-filter-dimm tr.fancytree-submatch span.fancytree-title, +.fancytree-ext-filter-dimm span.fancytree-node.fancytree-submatch span.fancytree-title { + color: black; + font-weight: normal; +} +.fancytree-ext-filter-dimm tr.fancytree-match span.fancytree-title, +.fancytree-ext-filter-dimm span.fancytree-node.fancytree-match span.fancytree-title { + color: black; + font-weight: bold; +} +.fancytree-ext-filter-hide tr.fancytree-hide, +.fancytree-ext-filter-hide span.fancytree-node.fancytree-hide { + display: none; +} +.fancytree-ext-filter-hide tr.fancytree-submatch span.fancytree-title, +.fancytree-ext-filter-hide span.fancytree-node.fancytree-submatch span.fancytree-title { + color: #c0c0c0; + font-weight: lighter; +} +.fancytree-ext-filter-hide tr.fancytree-match span.fancytree-title, +.fancytree-ext-filter-hide span.fancytree-node.fancytree-match span.fancytree-title { + color: black; + font-weight: normal; +} +/* Hide expanders if all child nodes are hidden by filter */ +.fancytree-ext-filter-hide-expanders tr.fancytree-match span.fancytree-expander, +.fancytree-ext-filter-hide-expanders span.fancytree-node.fancytree-match span.fancytree-expander { + visibility: hidden; +} +.fancytree-ext-filter-hide-expanders tr.fancytree-submatch span.fancytree-expander, +.fancytree-ext-filter-hide-expanders span.fancytree-node.fancytree-submatch span.fancytree-expander { + visibility: visible; +} +.fancytree-ext-childcounter span.fancytree-icon, +.fancytree-ext-filter span.fancytree-icon, +.fancytree-ext-childcounter span.fancytree-custom-icon, +.fancytree-ext-filter span.fancytree-custom-icon { + position: relative; +} +.fancytree-ext-childcounter span.fancytree-childcounter, +.fancytree-ext-filter span.fancytree-childcounter { + color: #fff; + background: #777; + border: 1px solid gray; + position: absolute; + top: -6px; + right: -6px; + min-width: 10px; + height: 10px; + line-height: 1; + vertical-align: baseline; + border-radius: 10px; + padding: 2px; + text-align: center; + font-size: 9px; +} +/*------------------------------------------------------------------------------ + * 'wide' extension + *----------------------------------------------------------------------------*/ +ul.fancytree-ext-wide { + position: relative; + min-width: 100%; + z-index: 2; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; +} +ul.fancytree-ext-wide span.fancytree-node > span { + position: relative; + z-index: 2; +} +ul.fancytree-ext-wide span.fancytree-node span.fancytree-title { + position: absolute; + z-index: 1; + left: 0px; + min-width: 100%; + margin-left: 0; + margin-right: 0; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; +} +/*------------------------------------------------------------------------------ + * 'fixed' extension + *----------------------------------------------------------------------------*/ +.fancytree-ext-fixed-wrapper .fancytree-ext-fixed-hidden { + display: none; +} +.fancytree-ext-fixed-wrapper div.fancytree-ext-fixed-scroll-border-bottom { + border-bottom: 3px solid rgba(0, 0, 0, 0.75); +} +.fancytree-ext-fixed-wrapper div.fancytree-ext-fixed-scroll-border-right { + border-right: 3px solid rgba(0, 0, 0, 0.75); +} +.fancytree-ext-fixed-wrapper div.fancytree-ext-fixed-wrapper-tl { + position: absolute; + overflow: hidden; + z-index: 3; + top: 0px; + left: 0px; +} +.fancytree-ext-fixed-wrapper div.fancytree-ext-fixed-wrapper-tr { + position: absolute; + overflow: hidden; + z-index: 2; + top: 0px; +} +.fancytree-ext-fixed-wrapper div.fancytree-ext-fixed-wrapper-bl { + position: absolute; + overflow: hidden; + z-index: 2; + left: 0px; +} +.fancytree-ext-fixed-wrapper div.fancytree-ext-fixed-wrapper-br { + position: absolute; + overflow: scroll; + z-index: 1; +} +/******************************************************************************* + * Styles specific to this skin. + * + * This section is automatically generated from the `ui-fancytree.less` template. + ******************************************************************************/ +/******************************************************************************* + * Node titles + */ +.fancytree-plain span.fancytree-title { + border: 1px solid transparent; +} +.fancytree-plain.fancytree-container.fancytree-treefocus span.fancytree-focused span.fancytree-title { + border-color: #3399ff; +} +.fancytree-plain span.fancytree-active span.fancytree-title, +.fancytree-plain span.fancytree-selected span.fancytree-title { + background-color: #f7f7f7; + border-color: #dedede; +} +.fancytree-plain span.fancytree-node span.fancytree-selected span.fancytree-title { + font-style: italic; +} +.fancytree-plain span.fancytree-node:hover span.fancytree-title { + background-color: #eff9fe; + border-color: #70c0e7; +} +.fancytree-plain.fancytree-container.fancytree-treefocus span.fancytree-active span.fancytree-title, +.fancytree-plain.fancytree-container.fancytree-treefocus span.fancytree-selected span.fancytree-title { + background-color: #cbe8f6; + border-color: #26a0da; +} +/******************************************************************************* + * 'table' extension + */ +table.fancytree-ext-table tbody tr td { + border: 1px solid #EDEDED; +} +table.fancytree-ext-table tbody span.fancytree-node, +table.fancytree-ext-table tbody span.fancytree-node:hover { + border: none; + background: none; +} +table.fancytree-ext-table tbody tr:hover { + background-color: #E5F3FB; + outline: 1px solid #70C0E7; +} +table.fancytree-ext-table tbody tr.fancytree-focused span.fancytree-title { + outline: 1px dotted black; +} +table.fancytree-ext-table tbody tr.fancytree-active:hover, +table.fancytree-ext-table tbody tr.fancytree-selected:hover { + background-color: #CBE8F6; + outline: 1px solid #26A0DA; +} +table.fancytree-ext-table tbody tr.fancytree-active { + background-color: #F7F7F7; + outline: 1px solid #DEDEDE; +} +table.fancytree-ext-table tbody tr.fancytree-selected { + background-color: #F7F7F7; +} +table.fancytree-ext-table.fancytree-treefocus tbody tr.fancytree-active { + background-color: #CBE8F6; + outline: 1px solid #26A0DA; +} +table.fancytree-ext-table.fancytree-treefocus tbody tr.fancytree-selected { + background-color: #CBE8F6; +} diff --git a/plugins/55/indexmenu/scripts/fancytree/skin-win8/ui.fancytree.less b/plugins/55/indexmenu/scripts/fancytree/skin-win8/ui.fancytree.less new file mode 100644 index 0000000..fdd3cf0 --- /dev/null +++ b/plugins/55/indexmenu/scripts/fancytree/skin-win8/ui.fancytree.less @@ -0,0 +1,158 @@ +/*! + * Fancytree "Win8" skin. + * + * DON'T EDIT THE CSS FILE DIRECTLY, since it is automatically generated from + * the LESS templates. + */ + +// Import common styles +@import "skin-common.less"; + + +/******************************************************************************* + * Styles specific to this skin. + * + * This section is automatically generated from the `ui-fancytree.less` template. + ******************************************************************************/ + +// Borders have NO radius and NO gradients are used! + +// both: +// unselected background: white +// hover bar (unselected, inactive): #E5F3FB (border: #70C0E7) 'very light blue' +// active node: #CBE8F6 (border: #26A0DA) 'light blue' +// active node with hover: wie active node + +// Tree view: +// active node, tree inactive: #F7F7F7 (border: #DEDEDE) 'light gray, selected, but tree not active' + +// List view: +// selected bar: --> active bar +// focus bar: transparent(white) + border 1px solid #3399FF () + +// table left/right border: #EDEDED 'light gray' + +// Override the variable after the import. +// NOTE: Variables are always resolved as the last definition, even if it is +// after where it is used. +@fancy-use-sprites: true; // false: suppress all background images (i.e. icons) + +@fancy-line-height: 20px; // height of a nodes selection bar including borders +@fancy-node-v-spacing: 0px; // gap between two node borders +@fancy-icon-width: 16px; +@fancy-icon-height: 16px; +@fancy-icon-spacing: 3px; // margin between icon/icon or icon/title +@fancy-icon-ofs-top: 2px; // extra vertical offset for expander, checkbox and icon +@fancy-title-ofs-top: 0px; // extra vertical offset for title +@fancy-node-border-width: 1px; +@fancy-node-border-radius: 0px; +@fancy-node-outline-width: 1px; + + +// @fancy-icon-width: 16px; +// @fancy-icon-height: 16px; +// @fancy-line-height: 16px; +// @fancy-icon-spacing: 3px; + +// We need to define this variable here (not in skin-common.less) to make it +// work with grunt and webpack: +@fancy-image-prefix: "./skin-win8/"; + +// Use 'data-uri(...)' to embed the image into CSS instead of linking to 'loading.gif': +// @fancy-loading-url: data-uri("@{fancy-image-prefix}loading.gif"); +// Set to `true` to use `data-uri(...)` which will embed icons.gif into CSS +// instead of linking to that file: +// @fancy-inline-sprites: true; + +//default 10pt, which is used in a relative manner resulting in 13.3 in dokuwiki-template. +@fancy-font-size: 93%; + +/******************************************************************************* + * Node titles + */ +.fancytree-plain { + span.fancytree-title { + border: @fancy-node-border-width solid transparent; // avoid jumping, when a border is added on hover + } + &.fancytree-container.fancytree-treefocus span.fancytree-focused span.fancytree-title { + border-color: #3399ff; + } + span.fancytree-active span.fancytree-title, + span.fancytree-selected span.fancytree-title { // active/selcted nodes inside inactive tree + background-color: #f7f7f7; + border-color: #dedede; + } + span.fancytree-node span.fancytree-selected span.fancytree-title { + font-style: italic; + } + span.fancytree-node:hover span.fancytree-title { + background-color: #eff9fe; // hover is always colored, even if tree is unfocused + border-color: #70c0e7; + } + &.fancytree-container.fancytree-treefocus { + span.fancytree-active span.fancytree-title, + span.fancytree-selected span.fancytree-title { + background-color: #cbe8f6; + border-color: #26a0da; + } + } +} + +/******************************************************************************* + * 'table' extension + */ +table.fancytree-ext-table tbody { + tr td { + border: 1px solid #EDEDED; + } + span.fancytree-node, + span.fancytree-node:hover { // undo standard tree css + border: none; + background: none; + } + // Title gets a white background, when hovered. Undo standard node formatting + // span.fancytree-title:hover { + // border: none; //1px solid transparent; + // background: inherit; + // background: transparent; + // background: none; + // filter: none; + // } + tr:hover { + background-color: #E5F3FB; + outline: 1px solid #70C0E7; + } + // tr:hover td { + // outline: 1px solid #D8F0FA; + // } + // tr.fancytree-focused { + // border-color: #3399FF; + // outline: 1px dotted black; + // } + tr.fancytree-focused span.fancytree-title { + outline: 1px dotted black; + } + + tr.fancytree-active:hover, + tr.fancytree-selected:hover { + background-color: #CBE8F6; + outline: 1px solid #26A0DA; + } + tr.fancytree-active { // dimmed, if inside inactive tree + background-color: #F7F7F7; + outline: 1px solid #DEDEDE; + } + tr.fancytree-selected { // dimmed, if inside inactive tree + background-color: #F7F7F7; + } +} + +table.fancytree-ext-table.fancytree-treefocus tbody { + tr.fancytree-active { + background-color: #CBE8F6; + outline: 1px solid #26A0DA; + } + tr.fancytree-selected { + background-color: #CBE8F6; + } +} diff --git a/plugins/55/indexmenu/scripts/fancytree/skin-win8/ui.fancytree.min.css b/plugins/55/indexmenu/scripts/fancytree/skin-win8/ui.fancytree.min.css new file mode 100644 index 0000000..a701af5 --- /dev/null +++ b/plugins/55/indexmenu/scripts/fancytree/skin-win8/ui.fancytree.min.css @@ -0,0 +1,6 @@ +/*! + * Fancytree "Win8" skin. + * + * DON'T EDIT THE CSS FILE DIRECTLY, since it is automatically generated from + * the LESS templates. + */.fancytree-helper-hidden{display:none}.fancytree-helper-indeterminate-cb{color:#777}.fancytree-helper-disabled{color:silver}.fancytree-helper-spin{-webkit-animation:spin 1s infinite linear;animation:spin 1s infinite linear}@-webkit-keyframes spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}ul.fancytree-container{font-family:tahoma,arial,helvetica;font-size:10pt;white-space:nowrap;padding:3px;margin:0;background-color:#fff;border:1px dotted gray;min-height:0;position:relative}ul.fancytree-container ul{padding:0 0 0 16px;margin:0}ul.fancytree-container ul>li:before{content:none}ul.fancytree-container li{list-style-image:none;list-style-position:outside;list-style-type:none;-moz-background-clip:border;-moz-background-inline-policy:continuous;-moz-background-origin:padding;background-attachment:scroll;background-color:transparent;background-position:0 0;background-repeat:repeat-y;background-image:none;margin:0}ul.fancytree-container li.fancytree-lastsib{background-image:none}.ui-fancytree-disabled ul.fancytree-container{opacity:.5;background-color:silver}ul.fancytree-connectors.fancytree-container li{background-image:url("../skin-win8/vline.gif");background-position:0 0}ul.fancytree-container li.fancytree-lastsib,ul.fancytree-no-connector>li{background-image:none}li.fancytree-animating{position:relative}#fancytree-drop-marker,span.fancytree-checkbox,span.fancytree-drag-helper-img,span.fancytree-empty,span.fancytree-expander,span.fancytree-icon,span.fancytree-vline{width:16px;height:16px;display:inline-block;vertical-align:top;background-repeat:no-repeat;background-image:url("../skin-win8/icons.gif");background-position:0 0}span.fancytree-checkbox,span.fancytree-custom-icon,span.fancytree-expander,span.fancytree-icon{margin-top:2px}span.fancytree-custom-icon{width:16px;height:16px;display:inline-block;margin-left:3px;background-position:0 0}img.fancytree-icon{width:16px;height:16px;margin-left:3px;margin-top:2px;vertical-align:top;border-style:none}span.fancytree-expander{cursor:pointer}.fancytree-exp-n span.fancytree-expander,.fancytree-exp-nl span.fancytree-expander{background-image:none;cursor:default}.fancytree-connectors .fancytree-exp-n span.fancytree-expander,.fancytree-connectors .fancytree-exp-nl span.fancytree-expander{background-image:url("../skin-win8/icons.gif");margin-top:0}.fancytree-connectors .fancytree-exp-n span.fancytree-expander,.fancytree-connectors .fancytree-exp-n span.fancytree-expander:hover{background-position:0 -64px}.fancytree-connectors .fancytree-exp-nl span.fancytree-expander,.fancytree-connectors .fancytree-exp-nl span.fancytree-expander:hover{background-position:-16px -64px}.fancytree-exp-c span.fancytree-expander{background-position:0 -80px}.fancytree-exp-c span.fancytree-expander:hover{background-position:-16px -80px}.fancytree-exp-cl span.fancytree-expander{background-position:0 -96px}.fancytree-exp-cl span.fancytree-expander:hover{background-position:-16px -96px}.fancytree-exp-cd span.fancytree-expander{background-position:-64px -80px}.fancytree-exp-cd span.fancytree-expander:hover{background-position:-80px -80px}.fancytree-exp-cdl span.fancytree-expander{background-position:-64px -96px}.fancytree-exp-cdl span.fancytree-expander:hover{background-position:-80px -96px}.fancytree-exp-e span.fancytree-expander,.fancytree-exp-ed span.fancytree-expander{background-position:-32px -80px}.fancytree-exp-e span.fancytree-expander:hover,.fancytree-exp-ed span.fancytree-expander:hover{background-position:-48px -80px}.fancytree-exp-edl span.fancytree-expander,.fancytree-exp-el span.fancytree-expander{background-position:-32px -96px}.fancytree-exp-edl span.fancytree-expander:hover,.fancytree-exp-el span.fancytree-expander:hover{background-position:-48px -96px}.fancytree-fade-expander span.fancytree-expander{transition:opacity 1.5s;opacity:0}.fancytree-fade-expander .fancytree-treefocus span.fancytree-expander,.fancytree-fade-expander [class*=fancytree-statusnode-] span.fancytree-expander,.fancytree-fade-expander.fancytree-treefocus span.fancytree-expander,.fancytree-fade-expander:hover span.fancytree-expander{transition:opacity .6s;opacity:1}span.fancytree-checkbox{margin-left:3px;background-position:0 -32px}span.fancytree-checkbox:hover{background-position:-16px -32px}span.fancytree-checkbox.fancytree-radio{background-position:0 -48px}span.fancytree-checkbox.fancytree-radio:hover{background-position:-16px -48px}.fancytree-partsel span.fancytree-checkbox{background-position:-64px -32px}.fancytree-partsel span.fancytree-checkbox:hover{background-position:-80px -32px}.fancytree-partsel span.fancytree-checkbox.fancytree-radio{background-position:-64px -48px}.fancytree-partsel span.fancytree-checkbox.fancytree-radio:hover{background-position:-80px -48px}.fancytree-selected span.fancytree-checkbox{background-position:-32px -32px}.fancytree-selected span.fancytree-checkbox:hover{background-position:-48px -32px}.fancytree-selected span.fancytree-checkbox.fancytree-radio{background-position:-32px -48px}.fancytree-selected span.fancytree-checkbox.fancytree-radio:hover{background-position:-48px -48px}.fancytree-unselectable span.fancytree-checkbox{opacity:.4}.fancytree-unselectable span.fancytree-checkbox:hover{background-position:0 -32px}.fancytree-unselectable span.fancytree-checkbox.fancytree-radio:hover{background-position:0 -48px}.fancytree-unselectable.fancytree-partsel span.fancytree-checkbox:hover{background-position:-64px -32px}.fancytree-unselectable.fancytree-selected span.fancytree-checkbox:hover{background-position:-32px -32px}.fancytree-unselectable.fancytree-selected span.fancytree-checkbox.fancytree-radio:hover{background-position:-32px -48px}.fancytree-container.fancytree-checkbox-auto-hide span.fancytree-checkbox{visibility:hidden}.fancytree-container.fancytree-checkbox-auto-hide .fancytree-node.fancytree-selected span.fancytree-checkbox,.fancytree-container.fancytree-checkbox-auto-hide .fancytree-node:hover span.fancytree-checkbox,.fancytree-container.fancytree-checkbox-auto-hide tr.fancytree-selected td span.fancytree-checkbox,.fancytree-container.fancytree-checkbox-auto-hide tr:hover td span.fancytree-checkbox{visibility:unset}.fancytree-container.fancytree-checkbox-auto-hide.fancytree-treefocus .fancytree-node.fancytree-active span.fancytree-checkbox,.fancytree-container.fancytree-checkbox-auto-hide.fancytree-treefocus tr.fancytree-active td span.fancytree-checkbox{visibility:unset}span.fancytree-icon{margin-left:3px;background-position:0 0}.fancytree-ico-c span.fancytree-icon:hover{background-position:-16px 0}.fancytree-has-children.fancytree-ico-c span.fancytree-icon{background-position:-32px 0}.fancytree-has-children.fancytree-ico-c span.fancytree-icon:hover{background-position:-48px 0}.fancytree-ico-e span.fancytree-icon{background-position:-64px 0}.fancytree-ico-e span.fancytree-icon:hover{background-position:-80px 0}.fancytree-ico-cf span.fancytree-icon{background-position:0 -16px}.fancytree-ico-cf span.fancytree-icon:hover{background-position:-16px -16px}.fancytree-has-children.fancytree-ico-cf span.fancytree-icon{background-position:-32px -16px}.fancytree-has-children.fancytree-ico-cf span.fancytree-icon:hover{background-position:-48px -16px}.fancytree-ico-ef span.fancytree-icon{background-position:-64px -16px}.fancytree-ico-ef span.fancytree-icon:hover{background-position:-80px -16px}.fancytree-loading span.fancytree-expander,.fancytree-loading span.fancytree-expander:hover,.fancytree-statusnode-loading span.fancytree-icon,.fancytree-statusnode-loading span.fancytree-icon:hover,span.fancytree-icon.fancytree-icon-loading{background-image:url("../skin-win8/loading.gif");background-position:0 0}.fancytree-statusnode-error span.fancytree-icon,.fancytree-statusnode-error span.fancytree-icon:hover{background-position:0 -112px}span.fancytree-node{display:inherit;width:100%;margin-top:0;min-height:20px}span.fancytree-title{color:#000;cursor:pointer;display:inline-block;vertical-align:top;min-height:20px;padding:0 3px 0 3px;margin:0 0 0 3px;border:1px solid transparent;-webkit-border-radius:0px;-moz-border-radius:0;-ms-border-radius:0px;-o-border-radius:0;border-radius:0}span.fancytree-node.fancytree-error span.fancytree-title{color:red}span.fancytree-childcounter{color:#fff;background:#337ab7;border:1px solid gray;border-radius:10px;padding:2px;text-align:center}div.fancytree-drag-helper span.fancytree-childcounter,div.fancytree-drag-helper span.fancytree-dnd-modifier{display:inline-block;color:#fff;background:#337ab7;border:1px solid gray;min-width:10px;height:10px;line-height:1;vertical-align:baseline;border-radius:10px;padding:2px;text-align:center;font-size:9px}div.fancytree-drag-helper span.fancytree-childcounter{position:absolute;top:-6px;right:-6px}div.fancytree-drag-helper span.fancytree-dnd-modifier{background:#5cb85c;border:none;font-weight:bolder}div.fancytree-drag-helper.fancytree-drop-accept span.fancytree-drag-helper-img{background-position:-32px -112px}div.fancytree-drag-helper.fancytree-drop-reject span.fancytree-drag-helper-img{background-position:-16px -112px}#fancytree-drop-marker{width:32px;position:absolute;background-position:0 -128px;margin:0}#fancytree-drop-marker.fancytree-drop-after,#fancytree-drop-marker.fancytree-drop-before{width:64px;background-position:0 -144px}#fancytree-drop-marker.fancytree-drop-copy{background-position:-64px -128px}#fancytree-drop-marker.fancytree-drop-move{background-position:-32px -128px}span.fancytree-drag-source.fancytree-drag-remove{opacity:.15}.fancytree-container.fancytree-rtl span.fancytree-connector,.fancytree-container.fancytree-rtl span.fancytree-drag-helper-img,.fancytree-container.fancytree-rtl span.fancytree-expander,.fancytree-container.fancytree-rtl span.fancytree-icon{background-image:url("../skin-win8/icons-rtl.gif")}.fancytree-container.fancytree-rtl .fancytree-exp-n span.fancytree-expander,.fancytree-container.fancytree-rtl .fancytree-exp-nl span.fancytree-expander{background-image:none}.fancytree-container.fancytree-rtl.fancytree-connectors .fancytree-exp-n span.fancytree-expander,.fancytree-container.fancytree-rtl.fancytree-connectors .fancytree-exp-nl span.fancytree-expander{background-image:url("../skin-win8/icons-rtl.gif")}ul.fancytree-container.fancytree-rtl ul{padding:0 16px 0 0}ul.fancytree-container.fancytree-rtl.fancytree-connectors li{background-position:right 0;background-image:url("../skin-win8/vline-rtl.gif")}ul.fancytree-container.fancytree-rtl li.fancytree-lastsib,ul.fancytree-container.fancytree-rtl.fancytree-no-connector>li{background-image:none}#fancytree-drop-marker.fancytree-rtl{background-image:url("../skin-win8/icons-rtl.gif")}table.fancytree-ext-table{font-family:tahoma,arial,helvetica;font-size:10pt;border-collapse:collapse}table.fancytree-ext-table span.fancytree-node{display:inline-block;box-sizing:border-box}table.fancytree-ext-table td.fancytree-status-merged{text-align:center;font-style:italic;color:silver}table.fancytree-ext-table tr.fancytree-statusnode-error td.fancytree-status-merged{color:red}table.fancytree-ext-table.fancytree-ext-ariagrid.fancytree-cell-mode>tbody>tr.fancytree-active>td{background-color:#eee}table.fancytree-ext-table.fancytree-ext-ariagrid.fancytree-cell-mode>tbody>tr>td.fancytree-active-cell{background-color:#cbe8f6}table.fancytree-ext-table.fancytree-ext-ariagrid.fancytree-cell-mode.fancytree-cell-nav-mode>tbody>tr>td.fancytree-active-cell{background-color:#3875d7}table.fancytree-ext-columnview tbody tr td{position:relative;border:1px solid gray;vertical-align:top;overflow:auto}table.fancytree-ext-columnview tbody tr td>ul{padding:0}table.fancytree-ext-columnview tbody tr td>ul li{list-style-image:none;list-style-position:outside;list-style-type:none;-moz-background-clip:border;-moz-background-inline-policy:continuous;-moz-background-origin:padding;background-attachment:scroll;background-color:transparent;background-position:0 0;background-repeat:repeat-y;background-image:none;margin:0}table.fancytree-ext-columnview span.fancytree-node{position:relative;display:inline-block}table.fancytree-ext-columnview span.fancytree-node.fancytree-expanded{background-color:#e0e0e0}table.fancytree-ext-columnview span.fancytree-node.fancytree-active{background-color:#cbe8f6}table.fancytree-ext-columnview .fancytree-has-children span.fancytree-cv-right{position:absolute;right:3px;background-position:0 -80px}table.fancytree-ext-columnview .fancytree-has-children span.fancytree-cv-right:hover{background-position:-16px -80px}.fancytree-ext-filter-dimm span.fancytree-node span.fancytree-title{color:silver;font-weight:lighter}.fancytree-ext-filter-dimm span.fancytree-node.fancytree-submatch span.fancytree-title,.fancytree-ext-filter-dimm tr.fancytree-submatch span.fancytree-title{color:#000;font-weight:400}.fancytree-ext-filter-dimm span.fancytree-node.fancytree-match span.fancytree-title,.fancytree-ext-filter-dimm tr.fancytree-match span.fancytree-title{color:#000;font-weight:700}.fancytree-ext-filter-hide span.fancytree-node.fancytree-hide,.fancytree-ext-filter-hide tr.fancytree-hide{display:none}.fancytree-ext-filter-hide span.fancytree-node.fancytree-submatch span.fancytree-title,.fancytree-ext-filter-hide tr.fancytree-submatch span.fancytree-title{color:silver;font-weight:lighter}.fancytree-ext-filter-hide span.fancytree-node.fancytree-match span.fancytree-title,.fancytree-ext-filter-hide tr.fancytree-match span.fancytree-title{color:#000;font-weight:400}.fancytree-ext-filter-hide-expanders span.fancytree-node.fancytree-match span.fancytree-expander,.fancytree-ext-filter-hide-expanders tr.fancytree-match span.fancytree-expander{visibility:hidden}.fancytree-ext-filter-hide-expanders span.fancytree-node.fancytree-submatch span.fancytree-expander,.fancytree-ext-filter-hide-expanders tr.fancytree-submatch span.fancytree-expander{visibility:visible}.fancytree-ext-childcounter span.fancytree-custom-icon,.fancytree-ext-childcounter span.fancytree-icon,.fancytree-ext-filter span.fancytree-custom-icon,.fancytree-ext-filter span.fancytree-icon{position:relative}.fancytree-ext-childcounter span.fancytree-childcounter,.fancytree-ext-filter span.fancytree-childcounter{color:#fff;background:#777;border:1px solid gray;position:absolute;top:-6px;right:-6px;min-width:10px;height:10px;line-height:1;vertical-align:baseline;border-radius:10px;padding:2px;text-align:center;font-size:9px}ul.fancytree-ext-wide{position:relative;min-width:100%;z-index:2;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}ul.fancytree-ext-wide span.fancytree-node>span{position:relative;z-index:2}ul.fancytree-ext-wide span.fancytree-node span.fancytree-title{position:absolute;z-index:1;left:0;min-width:100%;margin-left:0;margin-right:0;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.fancytree-ext-fixed-wrapper .fancytree-ext-fixed-hidden{display:none}.fancytree-ext-fixed-wrapper div.fancytree-ext-fixed-scroll-border-bottom{border-bottom:3px solid rgba(0,0,0,.75)}.fancytree-ext-fixed-wrapper div.fancytree-ext-fixed-scroll-border-right{border-right:3px solid rgba(0,0,0,.75)}.fancytree-ext-fixed-wrapper div.fancytree-ext-fixed-wrapper-tl{position:absolute;overflow:hidden;z-index:3;top:0;left:0}.fancytree-ext-fixed-wrapper div.fancytree-ext-fixed-wrapper-tr{position:absolute;overflow:hidden;z-index:2;top:0}.fancytree-ext-fixed-wrapper div.fancytree-ext-fixed-wrapper-bl{position:absolute;overflow:hidden;z-index:2;left:0}.fancytree-ext-fixed-wrapper div.fancytree-ext-fixed-wrapper-br{position:absolute;overflow:scroll;z-index:1}.fancytree-plain span.fancytree-title{border:1px solid transparent}.fancytree-plain.fancytree-container.fancytree-treefocus span.fancytree-focused span.fancytree-title{border-color:#39f}.fancytree-plain span.fancytree-active span.fancytree-title,.fancytree-plain span.fancytree-selected span.fancytree-title{background-color:#f7f7f7;border-color:#dedede}.fancytree-plain span.fancytree-node span.fancytree-selected span.fancytree-title{font-style:italic}.fancytree-plain span.fancytree-node:hover span.fancytree-title{background-color:#eff9fe;border-color:#70c0e7}.fancytree-plain.fancytree-container.fancytree-treefocus span.fancytree-active span.fancytree-title,.fancytree-plain.fancytree-container.fancytree-treefocus span.fancytree-selected span.fancytree-title{background-color:#cbe8f6;border-color:#26a0da}table.fancytree-ext-table tbody tr td{border:1px solid #ededed}table.fancytree-ext-table tbody span.fancytree-node,table.fancytree-ext-table tbody span.fancytree-node:hover{border:none;background:0 0}table.fancytree-ext-table tbody tr:hover{background-color:#e5f3fb;outline:1px solid #70C0E7}table.fancytree-ext-table tbody tr.fancytree-focused span.fancytree-title{outline:1px dotted black}table.fancytree-ext-table tbody tr.fancytree-active:hover,table.fancytree-ext-table tbody tr.fancytree-selected:hover{background-color:#cbe8f6;outline:1px solid #26A0DA}table.fancytree-ext-table tbody tr.fancytree-active{background-color:#f7f7f7;outline:1px solid #DEDEDE}table.fancytree-ext-table tbody tr.fancytree-selected{background-color:#f7f7f7}table.fancytree-ext-table.fancytree-treefocus tbody tr.fancytree-active{background-color:#cbe8f6;outline:1px solid #26A0DA}table.fancytree-ext-table.fancytree-treefocus tbody tr.fancytree-selected{background-color:#cbe8f6}
\ No newline at end of file diff --git a/plugins/55/indexmenu/scripts/fancytree/skin-win8/vline-rtl.gif b/plugins/55/indexmenu/scripts/fancytree/skin-win8/vline-rtl.gif Binary files differnew file mode 100644 index 0000000..f9b4232 --- /dev/null +++ b/plugins/55/indexmenu/scripts/fancytree/skin-win8/vline-rtl.gif diff --git a/plugins/55/indexmenu/scripts/fancytree/skin-win8/vline.gif b/plugins/55/indexmenu/scripts/fancytree/skin-win8/vline.gif Binary files differnew file mode 100644 index 0000000..f9b4232 --- /dev/null +++ b/plugins/55/indexmenu/scripts/fancytree/skin-win8/vline.gif diff --git a/plugins/55/indexmenu/scripts/fancytree/skin-xp/icons-rtl.gif b/plugins/55/indexmenu/scripts/fancytree/skin-xp/icons-rtl.gif Binary files differnew file mode 100644 index 0000000..a3f2c8a --- /dev/null +++ b/plugins/55/indexmenu/scripts/fancytree/skin-xp/icons-rtl.gif diff --git a/plugins/55/indexmenu/scripts/fancytree/skin-xp/icons-rtl__old__blue laxy expanders.gif b/plugins/55/indexmenu/scripts/fancytree/skin-xp/icons-rtl__old__blue laxy expanders.gif Binary files differnew file mode 100644 index 0000000..d59b0f5 --- /dev/null +++ b/plugins/55/indexmenu/scripts/fancytree/skin-xp/icons-rtl__old__blue laxy expanders.gif diff --git a/plugins/55/indexmenu/scripts/fancytree/skin-xp/icons.gif b/plugins/55/indexmenu/scripts/fancytree/skin-xp/icons.gif Binary files differnew file mode 100644 index 0000000..0d0635c --- /dev/null +++ b/plugins/55/indexmenu/scripts/fancytree/skin-xp/icons.gif diff --git a/plugins/55/indexmenu/scripts/fancytree/skin-xp/icons__old__blue lazy expanders.gif b/plugins/55/indexmenu/scripts/fancytree/skin-xp/icons__old__blue lazy expanders.gif Binary files differnew file mode 100644 index 0000000..a58eb93 --- /dev/null +++ b/plugins/55/indexmenu/scripts/fancytree/skin-xp/icons__old__blue lazy expanders.gif diff --git a/plugins/55/indexmenu/scripts/fancytree/skin-xp/loading.gif b/plugins/55/indexmenu/scripts/fancytree/skin-xp/loading.gif Binary files differnew file mode 100644 index 0000000..251df05 --- /dev/null +++ b/plugins/55/indexmenu/scripts/fancytree/skin-xp/loading.gif diff --git a/plugins/55/indexmenu/scripts/fancytree/skin-xp/skin-common.less b/plugins/55/indexmenu/scripts/fancytree/skin-xp/skin-common.less new file mode 100644 index 0000000..fc0da50 --- /dev/null +++ b/plugins/55/indexmenu/scripts/fancytree/skin-xp/skin-common.less @@ -0,0 +1,972 @@ +/******************************************************************************* + * Common Styles for Fancytree Skins. + * + * This section is automatically generated from the `skin-common.less` template. + * + * Copyright (c) 2008-2023, Martin Wendt (https://wwWendt.de) + * Released under the MIT license + * https://github.com/mar10/fancytree/wiki/LicenseInfo + * + * @version 2.38.3 + * @date 2023-02-01T20:52:50Z +******************************************************************************/ + +// Variables (defaults, may be overwritten by the including .less files) +@fancy-use-sprites: true; // false: suppress all background images (i.e. icons) +// @fancy-hide-connectors: true; // false: show vertical connector lines + +@fancy-level-indent: 16px; +@fancy-line-height: 16px; // height of a nodes selection bar including borders +@fancy-node-v-spacing: 1px; // gap between two node borders +@fancy-icon-width: 16px; +@fancy-icon-height: 16px; +@fancy-icon-spacing: 3px; // margin between icon/icon or icon/title +@fancy-icon-ofs-top: 0px; // extra vertical offset for expander, checkbox and icon +@fancy-title-ofs-top: 0px; // extra vertical offset for title +@fancy-node-border-width: 1px; +@fancy-node-border-radius: 0px; +@fancy-node-outline-width: 1px; + +// @fancy-line-ofs-top: (@fancy-line-height - @fancy-icon-height) / 2; + +// webpack uses /dist/skin-common.less as root path +// grunt-less uses /dist/skin-Xxx/ui.fancyree.less as root path +// So we define our theme LESS files for webpack compatibility, i.e. +// define the image path n every main LESS file instead of here. +// Prefix may be set to "", "/", "./", or any other value +// Note: this variable must be defined by the main LESS files: +// @fancy-image-prefix: ""; + +// Use 'url(...)' to link to the throbber image, or +// use data-uri(...)' to inline the data in css instead: +/* CHANGE use url, as less does not handel data-uri() correct. DokuWiki can eventually inline it */ + @fancy-loading-url: url("@{fancy-image-prefix}loading.gif"); +//@fancy-loading-url: data-uri("@{fancy-image-prefix}loading.gif"); + +// Set to `true` to use `data-uri(...)` instead of a `url(...)` link: +@fancy-inline-sprites: false; // data-uri() is not handle correct by phpless + +@fancy-font-size: 10pt; +@fancy-font-family: tahoma, arial, helvetica; +@fancy-font-color: black; +@fancy-font-color-dimm: #c0c0c0; +@fancy-font-error-color: red; + +//------------------------------------------------------------------------------ +// Mixins +//------------------------------------------------------------------------------ +.setBgPos(@x, @y, @cond:true) when (@cond) { + background-position: (@x * -@fancy-icon-width) (@y * -@fancy-icon-height); +} +.clearBgImage(@cond:true) when (@cond) { + background-image: none; +} +.setBgImageUrl(@url) when (@fancy-use-sprites) and not (@fancy-inline-sprites) { + background-image: url("@{fancy-image-prefix}@{url}"); +} +.setBgImageUrl(@url) when (@fancy-use-sprites) and (@fancy-inline-sprites) { + background-image: data-uri("@{fancy-image-prefix}@{url}"); +} +.useSprite(@x, @y) when (@fancy-use-sprites) { + .setBgPos(@x, @y); +} +.rounded-corners(@radius) { + -webkit-border-radius: @radius; + -moz-border-radius: @radius; + -ms-border-radius: @radius; + -o-border-radius: @radius; + border-radius: @radius; +} +.spanStyleMixin(@color, @bgcolor, @bordercolor) { + border-color: @bordercolor; + background: @bgcolor; + color: @color; +} +.spanStyleMixin(@color, @bgcolor, @bordercolor, @startColor, @stopColor) { + .spanStyleMixin(@color, @bgcolor, @bordercolor); + // @c-start: argb(@startColor); + // @c-end: argb(@stopColor); + background: -moz-linear-gradient( + top, + @startColor 0%, + @stopColor 100% + ); // FF3.6+ + background: -webkit-gradient( + linear, + left top, + left bottom, + color-stop(0%, @startColor), + color-stop(100%, @stopColor) + ); // Chrome,Safari4+ + background: -webkit-linear-gradient( + top, + @startColor 0%, + @stopColor 100% + ); // Chrome10+,Safari5.1+ + background: -o-linear-gradient( + top, + @startColor 0%, + @stopColor 100% + ); // Opera 11.10+ + background: -ms-linear-gradient( + top, + @startColor 0%, + @stopColor 100% + ); // IE10+ + background: linear-gradient( + to bottom, + @startColor 0%, + @stopColor 100% + ); // W3C + filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='@{startColor}', endColorstr='@{stopColor}',GradientType=0 ); // IE6-9 +} + +/*------------------------------------------------------------------------------ + * Helpers + *----------------------------------------------------------------------------*/ +// Redefine, in case jQuery-UI is not included +// .ui-helper-hidden, +.fancytree-helper-hidden { + display: none; +} +.fancytree-helper-indeterminate-cb { + // tri-state checkbox + color: #777; +} +.fancytree-helper-disabled { + color: @fancy-font-color-dimm; +} + +/* Helper to allow spinning loader icon with glyph-, ligature-, and SVG-icons. */ +/* CHANGE: renamed spin to spin-fancytree */ +.fancytree-helper-spin { + -webkit-animation: spin-fancytree 1000ms infinite linear; + animation: spin-fancytree 1000ms infinite linear; +} +/* CHANGE: commented because it is wrong prefixed by phpless +@-webkit-keyframes spin { + 0% { + -webkit-transform: rotate(0deg); + transform: rotate(0deg); + } + 100% { + -webkit-transform: rotate(359deg); + transform: rotate(359deg); + } +} +@keyframes spin { + 0% { + -webkit-transform: rotate(0deg); + transform: rotate(0deg); + } + 100% { + -webkit-transform: rotate(359deg); + transform: rotate(359deg); + } +} +*/ +/*------------------------------------------------------------------------------ + * Container and UL / LI + *----------------------------------------------------------------------------*/ + +ul.fancytree-container { + font-family: @fancy-font-family; + font-size: @fancy-font-size; + white-space: nowrap; + padding: 3px; + margin: 0; // DT issue 201 + //background-color: white; CHANGE + //border: 1px dotted gray; CHANGE + // overflow: auto; // ext-dnd5: otherwise this is always the scroll parent + // height: 100%; // DT issue 263, 470 + min-height: 0%; // #192 + position: relative; // #235 + ul { + padding: 0 0 0 @fancy-level-indent; + margin: 0; + } + ul > li:before { + // #538 + content: none; + } + li { + list-style-image: none; + list-style-position: outside; + list-style-type: none; + -moz-background-clip: border; + -moz-background-inline-policy: continuous; + -moz-background-origin: padding; + background-attachment: scroll; + background-color: transparent; + .setBgPos(0, 0); + background-repeat: repeat-y; + background-image: none; // no v-lines + + margin: 0; + // padding: 1px 0 0 0; // issue #246 + } + // Suppress lines for last child node + li.fancytree-lastsib { + background-image: none; + } +} + +// Style, when control is disabled +.ui-fancytree-disabled ul.fancytree-container { + opacity: 0.5; + // filter: alpha(opacity=50); // Yields a css warning + background-color: silver; +} + +ul.fancytree-connectors.fancytree-container { + li { + // Use 'data-uri(...)' to embed the image into CSS instead of linking to 'loading.gif': + /* CHANGE: phpless does not handle data-uri() correct */ + //background-image: data-uri("@{fancy-image-prefix}vline.gif"); + background-image: url("@{fancy-image-prefix}vline.gif"); + background-position: 0 0; + } +} + +// Suppress lines for last child node +ul.fancytree-container li.fancytree-lastsib, +// Suppress lines if level is fixed expanded (option minExpandLevel) +ul.fancytree-no-connector > li { + background-image: none; +} + +// Fix jQuery UI 'blind' animation for jQuery UI (#717) +li.fancytree-animating { + position: relative; +} + +/*------------------------------------------------------------------------------ + * Common icon definitions + *----------------------------------------------------------------------------*/ + +span.fancytree-empty, +span.fancytree-vline, +span.fancytree-expander, +span.fancytree-icon, +span.fancytree-checkbox, +// span.fancytree-radio, +span.fancytree-drag-helper-img, +#fancytree-drop-marker { + width: @fancy-icon-width; + height: @fancy-icon-height; + // display: -moz-inline-box; // @ FF 1+2 removed for issue 221 + // -moz-box-align: start; /* issue 221 */ + display: inline-block; // Required to make a span sizeable + vertical-align: top; + background-repeat: no-repeat; + // background-position: left; + .setBgImageUrl("icons.gif"); + .setBgPos(0, 0); +} +span.fancytree-icon, +span.fancytree-checkbox, +span.fancytree-expander, +// span.fancytree-radio, +span.fancytree-custom-icon { + margin-top: @fancy-icon-ofs-top; +} +/* Used by icon option: */ +span.fancytree-custom-icon { + width: @fancy-icon-width; + height: @fancy-icon-height; + display: inline-block; + margin-left: @fancy-icon-spacing; + .setBgPos(0, 0); +} +/* Used by 'icon' node option: */ +img.fancytree-icon { + width: @fancy-icon-width; + height: @fancy-icon-height; + margin-left: @fancy-icon-spacing; + margin-top: @fancy-icon-ofs-top; + vertical-align: top; + border-style: none; +} + +/*------------------------------------------------------------------------------ + * Expander icon + * + * Note: IE6 doesn't correctly evaluate multiples class names, + * so we create combined class names that can be used in the CSS. + * + * Prefix: fancytree-exp- + * 1st character: 'e': expanded, 'c': collapsed, 'n': no children + * 2nd character (optional): 'd': lazy (Delayed) + * 3rd character (optional): 'l': Last sibling + *----------------------------------------------------------------------------*/ + +span.fancytree-expander { + // .useSprite(0, 5); + cursor: pointer; +} +// span.fancytree-expander:hover { +// // .useSprite(1, 5); +// } + +// --- End nodes (use connectors instead of expanders) + +.fancytree-exp-n span.fancytree-expander, +.fancytree-exp-nl span.fancytree-expander { + // .clearBgImage( @fancy-hide-connectors ); + background-image: none; + cursor: default; +} +.fancytree-connectors { + .fancytree-exp-n span.fancytree-expander, + .fancytree-exp-nl span.fancytree-expander { + .setBgImageUrl("icons.gif"); + margin-top: 0; + } + .fancytree-exp-n span.fancytree-expander, // End-node, not last sibling + .fancytree-exp-n span.fancytree-expander:hover { + .useSprite(0, 4); + } + .fancytree-exp-nl span.fancytree-expander, // End-node, last sibling + .fancytree-exp-nl span.fancytree-expander:hover { + .useSprite(1, 4); + } +} + +// --- Collapsed + +.fancytree-exp-c span.fancytree-expander { + // Collapsed, not delayed, not last sibling + .useSprite(0, 5); +} +.fancytree-exp-c span.fancytree-expander:hover { + .useSprite(1, 5); +} +.fancytree-exp-cl span.fancytree-expander { + // Collapsed, not delayed, last sibling + .useSprite(0, 6); +} +.fancytree-exp-cl span.fancytree-expander:hover { + .useSprite(1, 6); +} +.fancytree-exp-cd span.fancytree-expander { + // Collapsed, delayed, not last sibling + .useSprite(4, 5); +} +.fancytree-exp-cd span.fancytree-expander:hover { + .useSprite(5, 5); +} +.fancytree-exp-cdl span.fancytree-expander { + // Collapsed, delayed, last sibling + .useSprite(4, 6); +} +.fancytree-exp-cdl span.fancytree-expander:hover { + .useSprite(5, 6); +} + +// --- Expanded + +.fancytree-exp-e span.fancytree-expander, // Expanded, not delayed, not last sibling +.fancytree-exp-ed span.fancytree-expander { + // Expanded, delayed, not last sibling + .useSprite(2, 5); +} +.fancytree-exp-e span.fancytree-expander:hover, +.fancytree-exp-ed span.fancytree-expander:hover { + .useSprite(3, 5); +} +.fancytree-exp-el span.fancytree-expander, // Expanded, not delayed, last sibling +.fancytree-exp-edl span.fancytree-expander { + // Expanded, delayed, last sibling + .useSprite(2, 6); +} +.fancytree-exp-el span.fancytree-expander:hover, +.fancytree-exp-edl span.fancytree-expander:hover { + .useSprite(3, 6); +} + +/* Fade out expanders, when container is not hovered or active */ +.fancytree-fade-expander { + span.fancytree-expander { + transition: opacity 1.5s; + opacity: 0; + } + &:hover span.fancytree-expander, + &.fancytree-treefocus span.fancytree-expander, + .fancytree-treefocus span.fancytree-expander, + [class*="fancytree-statusnode-"] span.fancytree-expander { + transition: opacity 0.6s; + opacity: 1; + } +} + +//// CHANGE: not used. +///*------------------------------------------------------------------------------ +// * Checkbox icon +// *----------------------------------------------------------------------------*/ +// +//span.fancytree-checkbox { +// margin-left: @fancy-icon-spacing; +// .useSprite(0, 2); +// &:hover { +// .useSprite(1, 2); +// } +// &.fancytree-radio { +// .useSprite(0, 3); +// } +// &.fancytree-radio:hover { +// .useSprite(1, 3); +// } +//} +//.fancytree-partsel span.fancytree-checkbox { +// .useSprite(4, 2); +// &:hover { +// .useSprite(5, 2); +// } +// &.fancytree-radio { +// .useSprite(4, 3); +// } +// &.fancytree-radio:hover { +// .useSprite(5, 3); +// } +//} +//// selected after partsel, so it takes precedence: +//.fancytree-selected span.fancytree-checkbox { +// .useSprite(2, 2); +// &:hover { +// .useSprite(3, 2); +// } +// &.fancytree-radio { +// .useSprite(2, 3); +// } +// &.fancytree-radio:hover { +// .useSprite(3, 3); +// } +//} +//// Unselectable is dimmed, without hover effects +//.fancytree-unselectable { +// span.fancytree-checkbox { +// opacity: 0.4; +// filter: alpha(opacity=40); +// } +// span.fancytree-checkbox:hover { +// .useSprite(0, 2); +// } +// span.fancytree-checkbox.fancytree-radio:hover { +// .useSprite(0, 3); +// } +// &.fancytree-partsel span.fancytree-checkbox:hover { +// .useSprite(4, 2); +// } +// &.fancytree-selected span.fancytree-checkbox:hover { +// .useSprite(2, 2); +// } +// &.fancytree-selected span.fancytree-checkbox.fancytree-radio:hover { +// .useSprite(2, 3); +// } +//} +// +//// Auto-hide checkboxes unless selected or hovered +//.fancytree-container.fancytree-checkbox-auto-hide { +// span.fancytree-checkbox { +// visibility: hidden; +// } +// .fancytree-node:hover span.fancytree-checkbox, +// tr:hover td span.fancytree-checkbox, +// .fancytree-node.fancytree-selected span.fancytree-checkbox, +// tr.fancytree-selected td span.fancytree-checkbox { +// visibility: unset; +// } +// &.fancytree-treefocus { +// .fancytree-node.fancytree-active span.fancytree-checkbox, +// tr.fancytree-active td span.fancytree-checkbox { +// visibility: unset; +// } +// } +//} + +/*------------------------------------------------------------------------------ + * Node type icon + * Note: IE6 doesn't correctly evaluate multiples class names, + * so we create combined class names that can be used in the CSS. + * + * Prefix: fancytree-ico- + * 1st character: 'e': expanded, 'c': collapsed + * 2nd character (optional): 'f': folder + *----------------------------------------------------------------------------*/ + +span.fancytree-icon { + // Default icon + margin-left: @fancy-icon-spacing; + .useSprite(0, 0); +} + +/* Documents */ +.fancytree-ico-c span.fancytree-icon { + // Collapsed folder (empty) + // .useSprite(0, 0); +} +.fancytree-ico-c span.fancytree-icon:hover { + .useSprite(1, 0); +} +.fancytree-has-children.fancytree-ico-c span.fancytree-icon { + // Collapsed folder (not empty) + .useSprite(2, 0); +} +.fancytree-has-children.fancytree-ico-c span.fancytree-icon:hover { + .useSprite(3, 0); +} +.fancytree-ico-e span.fancytree-icon { + // Expanded folder + .useSprite(4, 0); +} +.fancytree-ico-e span.fancytree-icon:hover { + .useSprite(5, 0); +} + +/* Folders */ +.fancytree-ico-cf span.fancytree-icon { + // Collapsed folder (empty) + .useSprite(0, 1); +} +.fancytree-ico-cf span.fancytree-icon:hover { + .useSprite(1, 1); +} +.fancytree-has-children.fancytree-ico-cf span.fancytree-icon { + // Collapsed folder (not empty) + .useSprite(2, 1); +} +.fancytree-has-children.fancytree-ico-cf span.fancytree-icon:hover { + .useSprite(3, 1); +} +.fancytree-ico-ef span.fancytree-icon { + // Expanded folder + .useSprite(4, 1); +} +.fancytree-ico-ef span.fancytree-icon:hover { + .useSprite(5, 1); +} + +// 'Loading' status overrides all others +.fancytree-loading span.fancytree-expander, +.fancytree-loading span.fancytree-expander:hover, +.fancytree-statusnode-loading span.fancytree-icon, +.fancytree-statusnode-loading span.fancytree-icon:hover, +span.fancytree-icon.fancytree-icon-loading { + background-image: @fancy-loading-url; + .useSprite(0, 0); +} + +/* Status node icons */ + +.fancytree-statusnode-error span.fancytree-icon, +.fancytree-statusnode-error span.fancytree-icon:hover { + .useSprite(0, 7); +} + +/*------------------------------------------------------------------------------ + * Node titles and highlighting + *----------------------------------------------------------------------------*/ + +span.fancytree-node { + /* See #117 */ + display: inherit; // #117, resolves to 'display: list-item;' for standard trees + width: 100%; + margin-top: @fancy-node-v-spacing; + min-height: @fancy-line-height; +} +span.fancytree-title { + color: @fancy-font-color; // inherit doesn't work on IE + cursor: pointer; + display: inline-block; // Better alignment, when title contains <br> + vertical-align: top; + min-height: @fancy-line-height; + padding: 0 3px 0 3px; // Otherwise italic font will be outside right bounds + margin: @fancy-title-ofs-top 0 0 @fancy-icon-spacing; + // margin: 0px; + // margin-top: @fancy-line-ofs-top; + // margin-left: @fancy-icon-spacing; + border: @fancy-node-border-width solid transparent; // avoid jumping, when a border is added on hover + .rounded-corners(@fancy-node-border-radius); + // outline: 0; // @ Firefox, prevent dotted border after click + // Set transparent border to prevent jumping when active node gets a border + // (we can do this, because this theme doesn't use vertical lines) + // border: 1px solid white; // Note: 'transparent' would not work in IE6 +} +span.fancytree-node.fancytree-error span.fancytree-title { + color: @fancy-font-error-color; +} + +//// CHANGE: not used. +///*------------------------------------------------------------------------------ +// * Drag'n'drop support +// *----------------------------------------------------------------------------*/ +///* ext-dnd5: */ +//span.fancytree-childcounter { +// color: #fff; +// background: #337ab7; // bootstrap blue +// border: 1px solid gray; +// border-radius: 10px; +// padding: 2px; +// text-align: center; +//} +// +///* ext-dnd: */ +//div.fancytree-drag-helper { +// span.fancytree-childcounter, +// span.fancytree-dnd-modifier { +// display: inline-block; +// color: #fff; +// background: #337ab7; // bootstrap blue +// border: 1px solid gray; +// min-width: 10px; +// // min-height: 16px; +// height: 10px; +// line-height: 1; +// vertical-align: baseline; +// border-radius: 10px; +// padding: 2px; +// text-align: center; +// font-size: 9px; +// } +// span.fancytree-childcounter { +// position: absolute; +// // left: 16px; +// top: -6px; +// right: -6px; +// } +// span.fancytree-dnd-modifier { +// background: #5cb85c; // bootstrap green +// border: none; +// // min-height: 16px; +// // font-size: 12px; +// font-weight: bolder; +// } +// &.fancytree-drop-accept { +// span.fancytree-drag-helper-img { +// .useSprite(2, 7); +// } +// } +// &.fancytree-drop-reject { +// span.fancytree-drag-helper-img { +// .useSprite(1, 7); +// } +// } +//} +// +///*** Drop marker icon *********************************************************/ +//#fancytree-drop-marker { +// width: 2 * @fancy-icon-width; // was 24px, but 32 should be correct +// position: absolute; +// .useSprite(0, 8); +// margin: 0; +// &.fancytree-drop-after, +// &.fancytree-drop-before { +// width: 4 * @fancy-icon-width; // 64px; +// .useSprite(0, 9); +// } +// &.fancytree-drop-copy { +// .useSprite(4, 8); +// } +// &.fancytree-drop-move { +// .useSprite(2, 8); +// } +//} +// +///*** Source node while dragging ***********************************************/ +// +//span.fancytree-drag-source { +// &.fancytree-drag-remove { +// // text-decoration: line-through; +// opacity: 0.15; +// } +//} +// +///*** Target node while dragging cursor is over it *****************************/ +// +//span.fancytree-drop-target { +// &.fancytree-drop-accept { +// // outline: 1px dotted #5cb85c; // bootstrap sucess +// } +//} +//span.fancytree-drop-reject { +// // outline: 1px dotted #d9534f; // boostrap warning +//} + +/*------------------------------------------------------------------------------ + * 'rtl' option + *----------------------------------------------------------------------------*/ + +.fancytree-container.fancytree-rtl { + .fancytree-title { + /*unicode-bidi: bidi-override;*/ /* optional: reverse title letters */ + } + span.fancytree-connector, + span.fancytree-expander, + span.fancytree-icon, + span.fancytree-drag-helper-img { + .setBgImageUrl("icons-rtl.gif"); + } + .fancytree-exp-n span.fancytree-expander, + .fancytree-exp-nl span.fancytree-expander { + background-image: none; + } + &.fancytree-connectors .fancytree-exp-n span.fancytree-expander, + &.fancytree-connectors .fancytree-exp-nl span.fancytree-expander { + .setBgImageUrl("icons-rtl.gif"); + } +} +ul.fancytree-container.fancytree-rtl { + ul { + padding: 0 16px 0 0; + } + &.fancytree-connectors li { + background-position: right 0; + background-image: url("@{fancy-image-prefix}vline-rtl.gif"); + } + // Suppress lines for last child node + li.fancytree-lastsib, + // Suppress lines if level is fixed expanded (option minExpandLevel) + &.fancytree-no-connector > li { + background-image: none; + } +} +#fancytree-drop-marker.fancytree-rtl { + .setBgImageUrl("icons-rtl.gif"); +} + +//// CHANGE: not used. +///*------------------------------------------------------------------------------ +// * 'table' extension +// *----------------------------------------------------------------------------*/ +// +//table.fancytree-ext-table { +// font-family: @fancy-font-family; +// font-size: @fancy-font-size; +// border-collapse: collapse; +// span.fancytree-node { +// display: inline-block; // #117 +// box-sizing: border-box; // #562 +// } +// td.fancytree-status-merged { +// text-align: center; +// // font-weight: bold; +// font-style: italic; +// // line-height: 100px; +// color: @fancy-font-color-dimm; +// } +// tr.fancytree-statusnode-error td.fancytree-status-merged { +// color: @fancy-font-error-color; +// } +// /* ext-ariagrid */ +// &.fancytree-ext-ariagrid.fancytree-cell-mode { +// > tbody > tr.fancytree-active > td { +// background-color: #eee; +// } +// > tbody > tr > td.fancytree-active-cell { +// background-color: #cbe8f6; +// } +// &.fancytree-cell-nav-mode > tbody > tr > td.fancytree-active-cell { +// background-color: #3875d7; +// } +// } +//} +// +///*------------------------------------------------------------------------------ +// * 'columnview' extension +// *----------------------------------------------------------------------------*/ +// +//table.fancytree-ext-columnview { +// // border-collapse: collapse; +// // width: 100%; +// tbody tr td { +// position: relative; +// border: 1px solid gray; +// vertical-align: top; +// overflow: auto; +// > ul { +// padding: 0; +// li { +// list-style-image: none; +// list-style-position: outside; +// list-style-type: none; +// -moz-background-clip: border; +// -moz-background-inline-policy: continuous; +// -moz-background-origin: padding; +// background-attachment: scroll; +// background-color: transparent; +// .setBgPos(0, 0); +// background-repeat: repeat-y; +// background-image: none; /* no v-lines */ +// +// margin: 0; +// // padding: 1px 0 0 0; // issue #246 +// } +// } +// } +// span.fancytree-node { +// position: relative; /* allow positioning of embedded spans */ +// display: inline-block; // #117 +// } +// span.fancytree-node.fancytree-expanded { +// background-color: #e0e0e0; +// } +// span.fancytree-node.fancytree-active { +// background-color: #cbe8f6; +// // background-color: royalblue; +// } +// .fancytree-has-children span.fancytree-cv-right { +// position: absolute; +// right: 3px; +// .useSprite(0, 5); +// &:hover { +// .useSprite(1, 5); +// } +// } +//} +// +///*------------------------------------------------------------------------------ +// * 'filter' extension +// *----------------------------------------------------------------------------*/ +// +//.fancytree-ext-filter-dimm { +// span.fancytree-node span.fancytree-title { +// color: @fancy-font-color-dimm; +// font-weight: lighter; +// } +// tr.fancytree-submatch span.fancytree-title, +// span.fancytree-node.fancytree-submatch span.fancytree-title { +// color: black; +// font-weight: normal; +// } +// tr.fancytree-match span.fancytree-title, +// span.fancytree-node.fancytree-match span.fancytree-title { +// color: black; +// font-weight: bold; +// } +//} +//.fancytree-ext-filter-hide { +// tr.fancytree-hide, +// span.fancytree-node.fancytree-hide { +// display: none; +// } +// tr.fancytree-submatch span.fancytree-title, +// span.fancytree-node.fancytree-submatch span.fancytree-title { +// color: @fancy-font-color-dimm; +// font-weight: lighter; +// } +// tr.fancytree-match span.fancytree-title, +// span.fancytree-node.fancytree-match span.fancytree-title { +// color: black; +// font-weight: normal; +// } +//} +///* Hide expanders if all child nodes are hidden by filter */ +//.fancytree-ext-filter-hide-expanders { +// tr.fancytree-match span.fancytree-expander, +// span.fancytree-node.fancytree-match span.fancytree-expander { +// visibility: hidden; +// } +// tr.fancytree-submatch span.fancytree-expander, +// span.fancytree-node.fancytree-submatch span.fancytree-expander { +// visibility: visible; +// } +//} +// +//.fancytree-ext-childcounter, +//.fancytree-ext-filter { +// // span.fancytree-title mark { +// // font-style: normal; +// // background-color: #ead61c; // yellow +// // border-radius: 3px; +// // } +// span.fancytree-icon, +// span.fancytree-custom-icon { +// position: relative; +// } +// span.fancytree-childcounter { +// color: #fff; +// background: #777; // #337ab7; // bootstrap blue +// border: 1px solid gray; +// position: absolute; +// top: -6px; +// right: -6px; +// min-width: 10px; +// height: 10px; +// line-height: 1; +// vertical-align: baseline; +// border-radius: 10px; +// padding: 2px; +// text-align: center; +// font-size: 9px; +// } +//} +///*------------------------------------------------------------------------------ +// * 'wide' extension +// *----------------------------------------------------------------------------*/ +// +//ul.fancytree-ext-wide { +// position: relative; +// min-width: 100%; +// z-index: 2; +// +// -webkit-box-sizing: border-box; +// -moz-box-sizing: border-box; +// box-sizing: border-box; +// +// span.fancytree-node > span { +// position: relative; +// z-index: 2; +// } +// span.fancytree-node span.fancytree-title { +// position: absolute; // Allow left: 0. Note: prevents smooth dropdown animation +// z-index: 1; // Behind expander and checkbox +// left: 0px; +// min-width: 100%; +// margin-left: 0; +// margin-right: 0; +// +// -webkit-box-sizing: border-box; +// -moz-box-sizing: border-box; +// box-sizing: border-box; +// } +//} +// +///*------------------------------------------------------------------------------ +// * 'fixed' extension +// *----------------------------------------------------------------------------*/ +// +//.fancytree-ext-fixed-wrapper { +// .fancytree-ext-fixed-hidden { +// display: none; +// } +// div.fancytree-ext-fixed-scroll-border-bottom { +// border-bottom: 3px solid rgba(0, 0, 0, 0.75); +// } +// div.fancytree-ext-fixed-scroll-border-right { +// border-right: 3px solid rgba(0, 0, 0, 0.75); +// } +// div.fancytree-ext-fixed-wrapper-tl { +// position: absolute; +// overflow: hidden; +// z-index: 3; +// top: 0px; +// left: 0px; +// } +// div.fancytree-ext-fixed-wrapper-tr { +// position: absolute; +// overflow: hidden; +// z-index: 2; +// top: 0px; +// } +// div.fancytree-ext-fixed-wrapper-bl { +// position: absolute; +// overflow: hidden; +// z-index: 2; +// left: 0px; +// } +// div.fancytree-ext-fixed-wrapper-br { +// position: absolute; +// overflow: scroll; +// z-index: 1; +// } +//} diff --git a/plugins/55/indexmenu/scripts/fancytree/skin-xp/ui.fancytree.css b/plugins/55/indexmenu/scripts/fancytree/skin-xp/ui.fancytree.css new file mode 100644 index 0000000..855c0ff --- /dev/null +++ b/plugins/55/indexmenu/scripts/fancytree/skin-xp/ui.fancytree.css @@ -0,0 +1,779 @@ +/*! + * Fancytree "XP" skin. + * + * DON'T EDIT THE CSS FILE DIRECTLY, since it is automatically generated from + * the LESS templates. + */ +/******************************************************************************* + * Common Styles for Fancytree Skins. + * + * This section is automatically generated from the `skin-common.less` template. + * + * Copyright (c) 2008-2023, Martin Wendt (https://wwWendt.de) + * Released under the MIT license + * https://github.com/mar10/fancytree/wiki/LicenseInfo + * + * @version 2.38.3 + * @date 2023-02-01T20:52:50Z +******************************************************************************/ +/*------------------------------------------------------------------------------ + * Helpers + *----------------------------------------------------------------------------*/ +.fancytree-helper-hidden { + display: none; +} +.fancytree-helper-indeterminate-cb { + color: #777; +} +.fancytree-helper-disabled { + color: #c0c0c0; +} +/* Helper to allow spinning loader icon with glyph-, ligature-, and SVG-icons. */ +.fancytree-helper-spin { + -webkit-animation: spin 1000ms infinite linear; + animation: spin 1000ms infinite linear; +} +@-webkit-keyframes spin { + 0% { + -webkit-transform: rotate(0deg); + transform: rotate(0deg); + } + 100% { + -webkit-transform: rotate(359deg); + transform: rotate(359deg); + } +} +@keyframes spin { + 0% { + -webkit-transform: rotate(0deg); + transform: rotate(0deg); + } + 100% { + -webkit-transform: rotate(359deg); + transform: rotate(359deg); + } +} +/*------------------------------------------------------------------------------ + * Container and UL / LI + *----------------------------------------------------------------------------*/ +ul.fancytree-container { + font-family: tahoma, arial, helvetica; + font-size: 10pt; + white-space: nowrap; + padding: 3px; + margin: 0; + background-color: white; + border: 1px dotted gray; + min-height: 0%; + position: relative; +} +ul.fancytree-container ul { + padding: 0 0 0 16px; + margin: 0; +} +ul.fancytree-container ul > li:before { + content: none; +} +ul.fancytree-container li { + list-style-image: none; + list-style-position: outside; + list-style-type: none; + -moz-background-clip: border; + -moz-background-inline-policy: continuous; + -moz-background-origin: padding; + background-attachment: scroll; + background-color: transparent; + background-position: 0px 0px; + background-repeat: repeat-y; + background-image: none; + margin: 0; +} +ul.fancytree-container li.fancytree-lastsib { + background-image: none; +} +.ui-fancytree-disabled ul.fancytree-container { + opacity: 0.5; + background-color: silver; +} +ul.fancytree-connectors.fancytree-container li { + background-image: url("../skin-xp/vline.gif"); + background-position: 0 0; +} +ul.fancytree-container li.fancytree-lastsib, +ul.fancytree-no-connector > li { + background-image: none; +} +li.fancytree-animating { + position: relative; +} +/*------------------------------------------------------------------------------ + * Common icon definitions + *----------------------------------------------------------------------------*/ +span.fancytree-empty, +span.fancytree-vline, +span.fancytree-expander, +span.fancytree-icon, +span.fancytree-checkbox, +span.fancytree-drag-helper-img, +#fancytree-drop-marker { + width: 16px; + height: 16px; + display: inline-block; + vertical-align: top; + background-repeat: no-repeat; + background-image: url("../skin-xp/icons.gif"); + background-position: 0px 0px; +} +span.fancytree-icon, +span.fancytree-checkbox, +span.fancytree-expander, +span.fancytree-custom-icon { + margin-top: 0px; +} +/* Used by icon option: */ +span.fancytree-custom-icon { + width: 16px; + height: 16px; + display: inline-block; + margin-left: 3px; + background-position: 0px 0px; +} +/* Used by 'icon' node option: */ +img.fancytree-icon { + width: 16px; + height: 16px; + margin-left: 3px; + margin-top: 0px; + vertical-align: top; + border-style: none; +} +/*------------------------------------------------------------------------------ + * Expander icon + * + * Note: IE6 doesn't correctly evaluate multiples class names, + * so we create combined class names that can be used in the CSS. + * + * Prefix: fancytree-exp- + * 1st character: 'e': expanded, 'c': collapsed, 'n': no children + * 2nd character (optional): 'd': lazy (Delayed) + * 3rd character (optional): 'l': Last sibling + *----------------------------------------------------------------------------*/ +span.fancytree-expander { + cursor: pointer; +} +.fancytree-exp-n span.fancytree-expander, +.fancytree-exp-nl span.fancytree-expander { + background-image: none; + cursor: default; +} +.fancytree-connectors .fancytree-exp-n span.fancytree-expander, +.fancytree-connectors .fancytree-exp-nl span.fancytree-expander { + background-image: url("../skin-xp/icons.gif"); + margin-top: 0; +} +.fancytree-connectors .fancytree-exp-n span.fancytree-expander, +.fancytree-connectors .fancytree-exp-n span.fancytree-expander:hover { + background-position: 0px -64px; +} +.fancytree-connectors .fancytree-exp-nl span.fancytree-expander, +.fancytree-connectors .fancytree-exp-nl span.fancytree-expander:hover { + background-position: -16px -64px; +} +.fancytree-exp-c span.fancytree-expander { + background-position: 0px -80px; +} +.fancytree-exp-c span.fancytree-expander:hover { + background-position: -16px -80px; +} +.fancytree-exp-cl span.fancytree-expander { + background-position: 0px -96px; +} +.fancytree-exp-cl span.fancytree-expander:hover { + background-position: -16px -96px; +} +.fancytree-exp-cd span.fancytree-expander { + background-position: -64px -80px; +} +.fancytree-exp-cd span.fancytree-expander:hover { + background-position: -80px -80px; +} +.fancytree-exp-cdl span.fancytree-expander { + background-position: -64px -96px; +} +.fancytree-exp-cdl span.fancytree-expander:hover { + background-position: -80px -96px; +} +.fancytree-exp-e span.fancytree-expander, +.fancytree-exp-ed span.fancytree-expander { + background-position: -32px -80px; +} +.fancytree-exp-e span.fancytree-expander:hover, +.fancytree-exp-ed span.fancytree-expander:hover { + background-position: -48px -80px; +} +.fancytree-exp-el span.fancytree-expander, +.fancytree-exp-edl span.fancytree-expander { + background-position: -32px -96px; +} +.fancytree-exp-el span.fancytree-expander:hover, +.fancytree-exp-edl span.fancytree-expander:hover { + background-position: -48px -96px; +} +/* Fade out expanders, when container is not hovered or active */ +.fancytree-fade-expander span.fancytree-expander { + transition: opacity 1.5s; + opacity: 0; +} +.fancytree-fade-expander:hover span.fancytree-expander, +.fancytree-fade-expander.fancytree-treefocus span.fancytree-expander, +.fancytree-fade-expander .fancytree-treefocus span.fancytree-expander, +.fancytree-fade-expander [class*="fancytree-statusnode-"] span.fancytree-expander { + transition: opacity 0.6s; + opacity: 1; +} +/*------------------------------------------------------------------------------ + * Checkbox icon + *----------------------------------------------------------------------------*/ +span.fancytree-checkbox { + margin-left: 3px; + background-position: 0px -32px; +} +span.fancytree-checkbox:hover { + background-position: -16px -32px; +} +span.fancytree-checkbox.fancytree-radio { + background-position: 0px -48px; +} +span.fancytree-checkbox.fancytree-radio:hover { + background-position: -16px -48px; +} +.fancytree-partsel span.fancytree-checkbox { + background-position: -64px -32px; +} +.fancytree-partsel span.fancytree-checkbox:hover { + background-position: -80px -32px; +} +.fancytree-partsel span.fancytree-checkbox.fancytree-radio { + background-position: -64px -48px; +} +.fancytree-partsel span.fancytree-checkbox.fancytree-radio:hover { + background-position: -80px -48px; +} +.fancytree-selected span.fancytree-checkbox { + background-position: -32px -32px; +} +.fancytree-selected span.fancytree-checkbox:hover { + background-position: -48px -32px; +} +.fancytree-selected span.fancytree-checkbox.fancytree-radio { + background-position: -32px -48px; +} +.fancytree-selected span.fancytree-checkbox.fancytree-radio:hover { + background-position: -48px -48px; +} +.fancytree-unselectable span.fancytree-checkbox { + opacity: 0.4; + filter: alpha(opacity=40); +} +.fancytree-unselectable span.fancytree-checkbox:hover { + background-position: 0px -32px; +} +.fancytree-unselectable span.fancytree-checkbox.fancytree-radio:hover { + background-position: 0px -48px; +} +.fancytree-unselectable.fancytree-partsel span.fancytree-checkbox:hover { + background-position: -64px -32px; +} +.fancytree-unselectable.fancytree-selected span.fancytree-checkbox:hover { + background-position: -32px -32px; +} +.fancytree-unselectable.fancytree-selected span.fancytree-checkbox.fancytree-radio:hover { + background-position: -32px -48px; +} +.fancytree-container.fancytree-checkbox-auto-hide span.fancytree-checkbox { + visibility: hidden; +} +.fancytree-container.fancytree-checkbox-auto-hide .fancytree-node:hover span.fancytree-checkbox, +.fancytree-container.fancytree-checkbox-auto-hide tr:hover td span.fancytree-checkbox, +.fancytree-container.fancytree-checkbox-auto-hide .fancytree-node.fancytree-selected span.fancytree-checkbox, +.fancytree-container.fancytree-checkbox-auto-hide tr.fancytree-selected td span.fancytree-checkbox { + visibility: unset; +} +.fancytree-container.fancytree-checkbox-auto-hide.fancytree-treefocus .fancytree-node.fancytree-active span.fancytree-checkbox, +.fancytree-container.fancytree-checkbox-auto-hide.fancytree-treefocus tr.fancytree-active td span.fancytree-checkbox { + visibility: unset; +} +/*------------------------------------------------------------------------------ + * Node type icon + * Note: IE6 doesn't correctly evaluate multiples class names, + * so we create combined class names that can be used in the CSS. + * + * Prefix: fancytree-ico- + * 1st character: 'e': expanded, 'c': collapsed + * 2nd character (optional): 'f': folder + *----------------------------------------------------------------------------*/ +span.fancytree-icon { + margin-left: 3px; + background-position: 0px 0px; +} +/* Documents */ +.fancytree-ico-c span.fancytree-icon:hover { + background-position: -16px 0px; +} +.fancytree-has-children.fancytree-ico-c span.fancytree-icon { + background-position: -32px 0px; +} +.fancytree-has-children.fancytree-ico-c span.fancytree-icon:hover { + background-position: -48px 0px; +} +.fancytree-ico-e span.fancytree-icon { + background-position: -64px 0px; +} +.fancytree-ico-e span.fancytree-icon:hover { + background-position: -80px 0px; +} +/* Folders */ +.fancytree-ico-cf span.fancytree-icon { + background-position: 0px -16px; +} +.fancytree-ico-cf span.fancytree-icon:hover { + background-position: -16px -16px; +} +.fancytree-has-children.fancytree-ico-cf span.fancytree-icon { + background-position: -32px -16px; +} +.fancytree-has-children.fancytree-ico-cf span.fancytree-icon:hover { + background-position: -48px -16px; +} +.fancytree-ico-ef span.fancytree-icon { + background-position: -64px -16px; +} +.fancytree-ico-ef span.fancytree-icon:hover { + background-position: -80px -16px; +} +.fancytree-loading span.fancytree-expander, +.fancytree-loading span.fancytree-expander:hover, +.fancytree-statusnode-loading span.fancytree-icon, +.fancytree-statusnode-loading span.fancytree-icon:hover, +span.fancytree-icon.fancytree-icon-loading { + background-image: url("../skin-xp/loading.gif"); + background-position: 0px 0px; +} +/* Status node icons */ +.fancytree-statusnode-error span.fancytree-icon, +.fancytree-statusnode-error span.fancytree-icon:hover { + background-position: 0px -112px; +} +/*------------------------------------------------------------------------------ + * Node titles and highlighting + *----------------------------------------------------------------------------*/ +span.fancytree-node { + /* See #117 */ + display: inherit; + width: 100%; + margin-top: 1px; + min-height: 16px; +} +span.fancytree-title { + color: black; + cursor: pointer; + display: inline-block; + vertical-align: top; + min-height: 16px; + padding: 0 3px 0 3px; + margin: 0px 0 0 3px; + border: 0 solid transparent; + -webkit-border-radius: 0px; + -moz-border-radius: 0px; + -ms-border-radius: 0px; + -o-border-radius: 0px; + border-radius: 0px; +} +span.fancytree-node.fancytree-error span.fancytree-title { + color: red; +} +/*------------------------------------------------------------------------------ + * Drag'n'drop support + *----------------------------------------------------------------------------*/ +/* ext-dnd5: */ +span.fancytree-childcounter { + color: #fff; + background: #337ab7; + border: 1px solid gray; + border-radius: 10px; + padding: 2px; + text-align: center; +} +/* ext-dnd: */ +div.fancytree-drag-helper span.fancytree-childcounter, +div.fancytree-drag-helper span.fancytree-dnd-modifier { + display: inline-block; + color: #fff; + background: #337ab7; + border: 1px solid gray; + min-width: 10px; + height: 10px; + line-height: 1; + vertical-align: baseline; + border-radius: 10px; + padding: 2px; + text-align: center; + font-size: 9px; +} +div.fancytree-drag-helper span.fancytree-childcounter { + position: absolute; + top: -6px; + right: -6px; +} +div.fancytree-drag-helper span.fancytree-dnd-modifier { + background: #5cb85c; + border: none; + font-weight: bolder; +} +div.fancytree-drag-helper.fancytree-drop-accept span.fancytree-drag-helper-img { + background-position: -32px -112px; +} +div.fancytree-drag-helper.fancytree-drop-reject span.fancytree-drag-helper-img { + background-position: -16px -112px; +} +/*** Drop marker icon *********************************************************/ +#fancytree-drop-marker { + width: 32px; + position: absolute; + background-position: 0px -128px; + margin: 0; +} +#fancytree-drop-marker.fancytree-drop-after, +#fancytree-drop-marker.fancytree-drop-before { + width: 64px; + background-position: 0px -144px; +} +#fancytree-drop-marker.fancytree-drop-copy { + background-position: -64px -128px; +} +#fancytree-drop-marker.fancytree-drop-move { + background-position: -32px -128px; +} +/*** Source node while dragging ***********************************************/ +span.fancytree-drag-source.fancytree-drag-remove { + opacity: 0.15; +} +/*** Target node while dragging cursor is over it *****************************/ +/*------------------------------------------------------------------------------ + * 'rtl' option + *----------------------------------------------------------------------------*/ +.fancytree-container.fancytree-rtl .fancytree-title { + /*unicode-bidi: bidi-override;*/ + /* optional: reverse title letters */ +} +.fancytree-container.fancytree-rtl span.fancytree-connector, +.fancytree-container.fancytree-rtl span.fancytree-expander, +.fancytree-container.fancytree-rtl span.fancytree-icon, +.fancytree-container.fancytree-rtl span.fancytree-drag-helper-img { + background-image: url("../skin-xp/icons-rtl.gif"); +} +.fancytree-container.fancytree-rtl .fancytree-exp-n span.fancytree-expander, +.fancytree-container.fancytree-rtl .fancytree-exp-nl span.fancytree-expander { + background-image: none; +} +.fancytree-container.fancytree-rtl.fancytree-connectors .fancytree-exp-n span.fancytree-expander, +.fancytree-container.fancytree-rtl.fancytree-connectors .fancytree-exp-nl span.fancytree-expander { + background-image: url("../skin-xp/icons-rtl.gif"); +} +ul.fancytree-container.fancytree-rtl ul { + padding: 0 16px 0 0; +} +ul.fancytree-container.fancytree-rtl.fancytree-connectors li { + background-position: right 0; + background-image: url("../skin-xp/vline-rtl.gif"); +} +ul.fancytree-container.fancytree-rtl li.fancytree-lastsib, +ul.fancytree-container.fancytree-rtl.fancytree-no-connector > li { + background-image: none; +} +#fancytree-drop-marker.fancytree-rtl { + background-image: url("../skin-xp/icons-rtl.gif"); +} +/*------------------------------------------------------------------------------ + * 'table' extension + *----------------------------------------------------------------------------*/ +table.fancytree-ext-table { + font-family: tahoma, arial, helvetica; + font-size: 10pt; + border-collapse: collapse; + /* ext-ariagrid */ +} +table.fancytree-ext-table span.fancytree-node { + display: inline-block; + box-sizing: border-box; +} +table.fancytree-ext-table td.fancytree-status-merged { + text-align: center; + font-style: italic; + color: #c0c0c0; +} +table.fancytree-ext-table tr.fancytree-statusnode-error td.fancytree-status-merged { + color: red; +} +table.fancytree-ext-table.fancytree-ext-ariagrid.fancytree-cell-mode > tbody > tr.fancytree-active > td { + background-color: #eee; +} +table.fancytree-ext-table.fancytree-ext-ariagrid.fancytree-cell-mode > tbody > tr > td.fancytree-active-cell { + background-color: #cbe8f6; +} +table.fancytree-ext-table.fancytree-ext-ariagrid.fancytree-cell-mode.fancytree-cell-nav-mode > tbody > tr > td.fancytree-active-cell { + background-color: #3875d7; +} +/*------------------------------------------------------------------------------ + * 'columnview' extension + *----------------------------------------------------------------------------*/ +table.fancytree-ext-columnview tbody tr td { + position: relative; + border: 1px solid gray; + vertical-align: top; + overflow: auto; +} +table.fancytree-ext-columnview tbody tr td > ul { + padding: 0; +} +table.fancytree-ext-columnview tbody tr td > ul li { + list-style-image: none; + list-style-position: outside; + list-style-type: none; + -moz-background-clip: border; + -moz-background-inline-policy: continuous; + -moz-background-origin: padding; + background-attachment: scroll; + background-color: transparent; + background-position: 0px 0px; + background-repeat: repeat-y; + background-image: none; + /* no v-lines */ + margin: 0; +} +table.fancytree-ext-columnview span.fancytree-node { + position: relative; + /* allow positioning of embedded spans */ + display: inline-block; +} +table.fancytree-ext-columnview span.fancytree-node.fancytree-expanded { + background-color: #e0e0e0; +} +table.fancytree-ext-columnview span.fancytree-node.fancytree-active { + background-color: #cbe8f6; +} +table.fancytree-ext-columnview .fancytree-has-children span.fancytree-cv-right { + position: absolute; + right: 3px; + background-position: 0px -80px; +} +table.fancytree-ext-columnview .fancytree-has-children span.fancytree-cv-right:hover { + background-position: -16px -80px; +} +/*------------------------------------------------------------------------------ + * 'filter' extension + *----------------------------------------------------------------------------*/ +.fancytree-ext-filter-dimm span.fancytree-node span.fancytree-title { + color: #c0c0c0; + font-weight: lighter; +} +.fancytree-ext-filter-dimm tr.fancytree-submatch span.fancytree-title, +.fancytree-ext-filter-dimm span.fancytree-node.fancytree-submatch span.fancytree-title { + color: black; + font-weight: normal; +} +.fancytree-ext-filter-dimm tr.fancytree-match span.fancytree-title, +.fancytree-ext-filter-dimm span.fancytree-node.fancytree-match span.fancytree-title { + color: black; + font-weight: bold; +} +.fancytree-ext-filter-hide tr.fancytree-hide, +.fancytree-ext-filter-hide span.fancytree-node.fancytree-hide { + display: none; +} +.fancytree-ext-filter-hide tr.fancytree-submatch span.fancytree-title, +.fancytree-ext-filter-hide span.fancytree-node.fancytree-submatch span.fancytree-title { + color: #c0c0c0; + font-weight: lighter; +} +.fancytree-ext-filter-hide tr.fancytree-match span.fancytree-title, +.fancytree-ext-filter-hide span.fancytree-node.fancytree-match span.fancytree-title { + color: black; + font-weight: normal; +} +/* Hide expanders if all child nodes are hidden by filter */ +.fancytree-ext-filter-hide-expanders tr.fancytree-match span.fancytree-expander, +.fancytree-ext-filter-hide-expanders span.fancytree-node.fancytree-match span.fancytree-expander { + visibility: hidden; +} +.fancytree-ext-filter-hide-expanders tr.fancytree-submatch span.fancytree-expander, +.fancytree-ext-filter-hide-expanders span.fancytree-node.fancytree-submatch span.fancytree-expander { + visibility: visible; +} +.fancytree-ext-childcounter span.fancytree-icon, +.fancytree-ext-filter span.fancytree-icon, +.fancytree-ext-childcounter span.fancytree-custom-icon, +.fancytree-ext-filter span.fancytree-custom-icon { + position: relative; +} +.fancytree-ext-childcounter span.fancytree-childcounter, +.fancytree-ext-filter span.fancytree-childcounter { + color: #fff; + background: #777; + border: 1px solid gray; + position: absolute; + top: -6px; + right: -6px; + min-width: 10px; + height: 10px; + line-height: 1; + vertical-align: baseline; + border-radius: 10px; + padding: 2px; + text-align: center; + font-size: 9px; +} +/*------------------------------------------------------------------------------ + * 'wide' extension + *----------------------------------------------------------------------------*/ +ul.fancytree-ext-wide { + position: relative; + min-width: 100%; + z-index: 2; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; +} +ul.fancytree-ext-wide span.fancytree-node > span { + position: relative; + z-index: 2; +} +ul.fancytree-ext-wide span.fancytree-node span.fancytree-title { + position: absolute; + z-index: 1; + left: 0px; + min-width: 100%; + margin-left: 0; + margin-right: 0; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; +} +/*------------------------------------------------------------------------------ + * 'fixed' extension + *----------------------------------------------------------------------------*/ +.fancytree-ext-fixed-wrapper .fancytree-ext-fixed-hidden { + display: none; +} +.fancytree-ext-fixed-wrapper div.fancytree-ext-fixed-scroll-border-bottom { + border-bottom: 3px solid rgba(0, 0, 0, 0.75); +} +.fancytree-ext-fixed-wrapper div.fancytree-ext-fixed-scroll-border-right { + border-right: 3px solid rgba(0, 0, 0, 0.75); +} +.fancytree-ext-fixed-wrapper div.fancytree-ext-fixed-wrapper-tl { + position: absolute; + overflow: hidden; + z-index: 3; + top: 0px; + left: 0px; +} +.fancytree-ext-fixed-wrapper div.fancytree-ext-fixed-wrapper-tr { + position: absolute; + overflow: hidden; + z-index: 2; + top: 0px; +} +.fancytree-ext-fixed-wrapper div.fancytree-ext-fixed-wrapper-bl { + position: absolute; + overflow: hidden; + z-index: 2; + left: 0px; +} +.fancytree-ext-fixed-wrapper div.fancytree-ext-fixed-wrapper-br { + position: absolute; + overflow: scroll; + z-index: 1; +} +/******************************************************************************* + * Styles specific to this skin. + * + * This section is automatically generated from the `ui-fancytree.less` template. + ******************************************************************************/ +/******************************************************************************* + * Tree container + */ +ul.fancytree-container li { + background-image: url("../skin-xp/vline.gif"); + background-position: 0 0; +} +ul.fancytree-container.fancytree-rtl li { + background-position: right 0; + background-image: url("../skin-xp/vline-rtl.gif"); +} +ul.fancytree-container.fancytree-rtl .fancytree-exp-n span.fancytree-expander { + background-image: url("../skin-xp/icons-rtl.gif"); + background-position: 0px -64px; +} +ul.fancytree-container.fancytree-rtl .fancytree-exp-nl span.fancytree-expander { + background-image: url("../skin-xp/icons-rtl.gif"); + background-position: -16px -64px; +} +ul.fancytree-container li.fancytree-lastsib { + background-image: none; +} +ul.fancytree-no-connector > li { + background-image: none; +} +.fancytree-exp-n span.fancytree-expander, +.fancytree-exp-nl span.fancytree-expander { + background-image: url("../skin-xp/icons.gif"); +} +.fancytree-exp-n span.fancytree-expander, +.fancytree-exp-n span.fancytree-expander:hover { + background-position: 0px -64px; +} +.fancytree-exp-nl span.fancytree-expander, +.fancytree-exp-nl span.fancytree-expander:hover { + background-position: -16px -64px; +} +/******************************************************************************* + * Node titles + */ +span.fancytree-title { + border: 0 solid transparent; +} +span.fancytree-title:hover { + background-color: #F2F7FD; + border-color: #B8D6FB; +} +span.fancytree-focused span.fancytree-title { + outline: 1px dotted black; + background-color: #EFEBDE; +} +.fancytree-folder span.fancytree-title { + font-weight: bold; +} +.fancytree-selected span.fancytree-title { + color: green; + font-style: italic; +} +.fancytree-active span.fancytree-title { + background-color: #3169C6 !important; + color: white !important; +} +/******************************************************************************* + * 'table' extension + */ +table.fancytree-ext-table { + border-collapse: collapse; +} +table.fancytree-ext-table tbody tr.fancytree-focused { + background-color: #99DEFD; +} +table.fancytree-ext-table tbody tr.fancytree-active { + background-color: royalblue; +} +table.fancytree-ext-table tbody tr.fancytree-selected { + background-color: #99FDDE; +} diff --git a/plugins/55/indexmenu/scripts/fancytree/skin-xp/ui.fancytree.less b/plugins/55/indexmenu/scripts/fancytree/skin-xp/ui.fancytree.less new file mode 100644 index 0000000..9e5bb30 --- /dev/null +++ b/plugins/55/indexmenu/scripts/fancytree/skin-xp/ui.fancytree.less @@ -0,0 +1,133 @@ +/*! + * Fancytree "XP" skin. + * + * DON'T EDIT THE CSS FILE DIRECTLY, since it is automatically generated from + * the LESS templates. + */ + +// Import common styles +@import "skin-common.less"; + + +/******************************************************************************* + * Styles specific to this skin. + * + * This section is automatically generated from the `ui-fancytree.less` template. + ******************************************************************************/ + +// Override the variable after the import. +// NOTE: Variables are always resolved as the last definition, even if it is +// after where it is used. +@fancy-use-sprites: true; // false: suppress all background images (i.e. icons) + +@fancy-icon-width: 16px; +@fancy-icon-height: 16px; +@fancy-icon-spacing: 3px; +@fancy-node-border-width: 0; +@fancy-node-v-spacing: 0px; // gap between two node borders + +// We need to define this variable here (not in skin-common.less) to make it +// work with grunt and webpack: +@fancy-image-prefix: "./skin-xp/"; + +// Use 'data-uri(...)' to embed the image into CSS instead of linking to 'loading.gif': +// @fancy-loading-url: data-uri("@{fancy-image-prefix}loading.gif"); +// Set to `true` to use `data-uri(...)` which will embed icons.gif into CSS +// instead of linking to that file: +// @fancy-inline-sprites: true; + +//default 10pt, which is used in a relative manner resulting in 13.3 in dokuwiki-template. +@fancy-font-size: 93%; + +/******************************************************************************* + * Tree container + */ +ul.fancytree-container { + li { + // background-image: url("vline.gif"); + // Use 'data-uri(...)' to embed the image into CSS instead of linking to 'loading.gif': + /* CHANGE: replace data-uri() with url() */ + background-image: url("@{fancy-image-prefix}vline.gif"); + background-position: 0 1px; + } + &.fancytree-rtl { + li { + background-position: right 1px; + background-image: url("@{fancy-image-prefix}vline-rtl.gif"); + } + .fancytree-exp-n span.fancytree-expander { + background-image: url("@{fancy-image-prefix}icons-rtl.gif"); + .useSprite(0, 4); + } + .fancytree-exp-nl span.fancytree-expander { + background-image: url("@{fancy-image-prefix}icons-rtl.gif"); + .useSprite(1, 4); + } + } + // Suppress lines for last child node + li.fancytree-lastsib { + background-image: none; + } +} +// Suppress lines if level is fixed expanded (option minExpandLevel) +ul.fancytree-no-connector > li { + background-image: none; +} + +// XP theme always displays connectors (not only when .fancytree-connectors is set) +.fancytree-exp-n span.fancytree-expander, +.fancytree-exp-nl span.fancytree-expander { + .setBgImageUrl("icons.gif"); + // margin-top: 0; +} +.fancytree-exp-n span.fancytree-expander, // End-node, not last sibling +.fancytree-exp-n span.fancytree-expander:hover { + .useSprite(0, 4); +} +.fancytree-exp-nl span.fancytree-expander, // End-node, last sibling +.fancytree-exp-nl span.fancytree-expander:hover { + .useSprite(1, 4); +} + +/******************************************************************************* + * Node titles + */ + +span.fancytree-title { + border: @fancy-node-border-width solid transparent; // avoid jumping, when a border is added on hover +} +span.fancytree-title:hover { + background-color: #F2F7FD; // light blue + border-color: #B8D6FB; // darker light blue +} +span.fancytree-focused span.fancytree-title { + outline: 1px dotted black; + background-color: #EFEBDE; // gray +} +.fancytree-folder span.fancytree-title { + font-weight: bold; +} +.fancytree-selected span.fancytree-title { + color: green; + font-style: italic; +} +.fancytree-active span.fancytree-title { + background-color: #3169C6 !important; + color: white !important; // @ IE6 +} + +///******************************************************************************* +// * 'table' extension +// */ +//table.fancytree-ext-table { +// border-collapse: collapse; +// tbody tr.fancytree-focused { +// background-color: #99DEFD; +// } +// tbody tr.fancytree-active { +// background-color: royalblue; +// } +// tbody tr.fancytree-selected { +// background-color: #99FDDE; +// } +//} diff --git a/plugins/55/indexmenu/scripts/fancytree/skin-xp/ui.fancytree.min.css b/plugins/55/indexmenu/scripts/fancytree/skin-xp/ui.fancytree.min.css new file mode 100644 index 0000000..7d70f5e --- /dev/null +++ b/plugins/55/indexmenu/scripts/fancytree/skin-xp/ui.fancytree.min.css @@ -0,0 +1,6 @@ +/*! + * Fancytree "XP" skin. + * + * DON'T EDIT THE CSS FILE DIRECTLY, since it is automatically generated from + * the LESS templates. + */.fancytree-helper-hidden{display:none}.fancytree-helper-indeterminate-cb{color:#777}.fancytree-helper-disabled{color:silver}.fancytree-helper-spin{-webkit-animation:spin 1s infinite linear;animation:spin 1s infinite linear}@-webkit-keyframes spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}ul.fancytree-container{font-family:tahoma,arial,helvetica;font-size:10pt;white-space:nowrap;padding:3px;margin:0;background-color:#fff;border:1px dotted gray;min-height:0;position:relative}ul.fancytree-container ul{padding:0 0 0 16px;margin:0}ul.fancytree-container ul>li:before{content:none}ul.fancytree-container li{list-style-image:none;list-style-position:outside;list-style-type:none;-moz-background-clip:border;-moz-background-inline-policy:continuous;-moz-background-origin:padding;background-attachment:scroll;background-color:transparent;background-position:0 0;background-repeat:repeat-y;background-image:none;margin:0}ul.fancytree-container li.fancytree-lastsib{background-image:none}.ui-fancytree-disabled ul.fancytree-container{opacity:.5;background-color:silver}ul.fancytree-connectors.fancytree-container li{background-image:url("../skin-xp/vline.gif");background-position:0 0}ul.fancytree-container li.fancytree-lastsib,ul.fancytree-no-connector>li{background-image:none}li.fancytree-animating{position:relative}#fancytree-drop-marker,span.fancytree-checkbox,span.fancytree-drag-helper-img,span.fancytree-empty,span.fancytree-expander,span.fancytree-icon,span.fancytree-vline{width:16px;height:16px;display:inline-block;vertical-align:top;background-repeat:no-repeat;background-image:url("../skin-xp/icons.gif");background-position:0 0}span.fancytree-checkbox,span.fancytree-custom-icon,span.fancytree-expander,span.fancytree-icon{margin-top:0}span.fancytree-custom-icon{width:16px;height:16px;display:inline-block;margin-left:3px;background-position:0 0}img.fancytree-icon{width:16px;height:16px;margin-left:3px;margin-top:0;vertical-align:top;border-style:none}span.fancytree-expander{cursor:pointer}.fancytree-exp-n span.fancytree-expander,.fancytree-exp-nl span.fancytree-expander{background-image:none;cursor:default}.fancytree-connectors .fancytree-exp-n span.fancytree-expander,.fancytree-connectors .fancytree-exp-nl span.fancytree-expander{background-image:url("../skin-xp/icons.gif");margin-top:0}.fancytree-connectors .fancytree-exp-n span.fancytree-expander,.fancytree-connectors .fancytree-exp-n span.fancytree-expander:hover{background-position:0 -64px}.fancytree-connectors .fancytree-exp-nl span.fancytree-expander,.fancytree-connectors .fancytree-exp-nl span.fancytree-expander:hover{background-position:-16px -64px}.fancytree-exp-c span.fancytree-expander{background-position:0 -80px}.fancytree-exp-c span.fancytree-expander:hover{background-position:-16px -80px}.fancytree-exp-cl span.fancytree-expander{background-position:0 -96px}.fancytree-exp-cl span.fancytree-expander:hover{background-position:-16px -96px}.fancytree-exp-cd span.fancytree-expander{background-position:-64px -80px}.fancytree-exp-cd span.fancytree-expander:hover{background-position:-80px -80px}.fancytree-exp-cdl span.fancytree-expander{background-position:-64px -96px}.fancytree-exp-cdl span.fancytree-expander:hover{background-position:-80px -96px}.fancytree-exp-e span.fancytree-expander,.fancytree-exp-ed span.fancytree-expander{background-position:-32px -80px}.fancytree-exp-e span.fancytree-expander:hover,.fancytree-exp-ed span.fancytree-expander:hover{background-position:-48px -80px}.fancytree-exp-edl span.fancytree-expander,.fancytree-exp-el span.fancytree-expander{background-position:-32px -96px}.fancytree-exp-edl span.fancytree-expander:hover,.fancytree-exp-el span.fancytree-expander:hover{background-position:-48px -96px}.fancytree-fade-expander span.fancytree-expander{transition:opacity 1.5s;opacity:0}.fancytree-fade-expander .fancytree-treefocus span.fancytree-expander,.fancytree-fade-expander [class*=fancytree-statusnode-] span.fancytree-expander,.fancytree-fade-expander.fancytree-treefocus span.fancytree-expander,.fancytree-fade-expander:hover span.fancytree-expander{transition:opacity .6s;opacity:1}span.fancytree-checkbox{margin-left:3px;background-position:0 -32px}span.fancytree-checkbox:hover{background-position:-16px -32px}span.fancytree-checkbox.fancytree-radio{background-position:0 -48px}span.fancytree-checkbox.fancytree-radio:hover{background-position:-16px -48px}.fancytree-partsel span.fancytree-checkbox{background-position:-64px -32px}.fancytree-partsel span.fancytree-checkbox:hover{background-position:-80px -32px}.fancytree-partsel span.fancytree-checkbox.fancytree-radio{background-position:-64px -48px}.fancytree-partsel span.fancytree-checkbox.fancytree-radio:hover{background-position:-80px -48px}.fancytree-selected span.fancytree-checkbox{background-position:-32px -32px}.fancytree-selected span.fancytree-checkbox:hover{background-position:-48px -32px}.fancytree-selected span.fancytree-checkbox.fancytree-radio{background-position:-32px -48px}.fancytree-selected span.fancytree-checkbox.fancytree-radio:hover{background-position:-48px -48px}.fancytree-unselectable span.fancytree-checkbox{opacity:.4}.fancytree-unselectable span.fancytree-checkbox:hover{background-position:0 -32px}.fancytree-unselectable span.fancytree-checkbox.fancytree-radio:hover{background-position:0 -48px}.fancytree-unselectable.fancytree-partsel span.fancytree-checkbox:hover{background-position:-64px -32px}.fancytree-unselectable.fancytree-selected span.fancytree-checkbox:hover{background-position:-32px -32px}.fancytree-unselectable.fancytree-selected span.fancytree-checkbox.fancytree-radio:hover{background-position:-32px -48px}.fancytree-container.fancytree-checkbox-auto-hide span.fancytree-checkbox{visibility:hidden}.fancytree-container.fancytree-checkbox-auto-hide .fancytree-node.fancytree-selected span.fancytree-checkbox,.fancytree-container.fancytree-checkbox-auto-hide .fancytree-node:hover span.fancytree-checkbox,.fancytree-container.fancytree-checkbox-auto-hide tr.fancytree-selected td span.fancytree-checkbox,.fancytree-container.fancytree-checkbox-auto-hide tr:hover td span.fancytree-checkbox{visibility:unset}.fancytree-container.fancytree-checkbox-auto-hide.fancytree-treefocus .fancytree-node.fancytree-active span.fancytree-checkbox,.fancytree-container.fancytree-checkbox-auto-hide.fancytree-treefocus tr.fancytree-active td span.fancytree-checkbox{visibility:unset}span.fancytree-icon{margin-left:3px;background-position:0 0}.fancytree-ico-c span.fancytree-icon:hover{background-position:-16px 0}.fancytree-has-children.fancytree-ico-c span.fancytree-icon{background-position:-32px 0}.fancytree-has-children.fancytree-ico-c span.fancytree-icon:hover{background-position:-48px 0}.fancytree-ico-e span.fancytree-icon{background-position:-64px 0}.fancytree-ico-e span.fancytree-icon:hover{background-position:-80px 0}.fancytree-ico-cf span.fancytree-icon{background-position:0 -16px}.fancytree-ico-cf span.fancytree-icon:hover{background-position:-16px -16px}.fancytree-has-children.fancytree-ico-cf span.fancytree-icon{background-position:-32px -16px}.fancytree-has-children.fancytree-ico-cf span.fancytree-icon:hover{background-position:-48px -16px}.fancytree-ico-ef span.fancytree-icon{background-position:-64px -16px}.fancytree-ico-ef span.fancytree-icon:hover{background-position:-80px -16px}.fancytree-loading span.fancytree-expander,.fancytree-loading span.fancytree-expander:hover,.fancytree-statusnode-loading span.fancytree-icon,.fancytree-statusnode-loading span.fancytree-icon:hover,span.fancytree-icon.fancytree-icon-loading{background-image:url("../skin-xp/loading.gif");background-position:0 0}.fancytree-statusnode-error span.fancytree-icon,.fancytree-statusnode-error span.fancytree-icon:hover{background-position:0 -112px}span.fancytree-node{display:inherit;width:100%;margin-top:1px;min-height:16px}span.fancytree-title{color:#000;cursor:pointer;display:inline-block;vertical-align:top;min-height:16px;padding:0 3px 0 3px;margin:0 0 0 3px;border:0 solid transparent;-webkit-border-radius:0px;-moz-border-radius:0;-ms-border-radius:0px;-o-border-radius:0;border-radius:0}span.fancytree-node.fancytree-error span.fancytree-title{color:red}span.fancytree-childcounter{color:#fff;background:#337ab7;border:1px solid gray;border-radius:10px;padding:2px;text-align:center}div.fancytree-drag-helper span.fancytree-childcounter,div.fancytree-drag-helper span.fancytree-dnd-modifier{display:inline-block;color:#fff;background:#337ab7;border:1px solid gray;min-width:10px;height:10px;line-height:1;vertical-align:baseline;border-radius:10px;padding:2px;text-align:center;font-size:9px}div.fancytree-drag-helper span.fancytree-childcounter{position:absolute;top:-6px;right:-6px}div.fancytree-drag-helper span.fancytree-dnd-modifier{background:#5cb85c;border:none;font-weight:bolder}div.fancytree-drag-helper.fancytree-drop-accept span.fancytree-drag-helper-img{background-position:-32px -112px}div.fancytree-drag-helper.fancytree-drop-reject span.fancytree-drag-helper-img{background-position:-16px -112px}#fancytree-drop-marker{width:32px;position:absolute;background-position:0 -128px;margin:0}#fancytree-drop-marker.fancytree-drop-after,#fancytree-drop-marker.fancytree-drop-before{width:64px;background-position:0 -144px}#fancytree-drop-marker.fancytree-drop-copy{background-position:-64px -128px}#fancytree-drop-marker.fancytree-drop-move{background-position:-32px -128px}span.fancytree-drag-source.fancytree-drag-remove{opacity:.15}.fancytree-container.fancytree-rtl span.fancytree-connector,.fancytree-container.fancytree-rtl span.fancytree-drag-helper-img,.fancytree-container.fancytree-rtl span.fancytree-expander,.fancytree-container.fancytree-rtl span.fancytree-icon{background-image:url("../skin-xp/icons-rtl.gif")}.fancytree-container.fancytree-rtl .fancytree-exp-n span.fancytree-expander,.fancytree-container.fancytree-rtl .fancytree-exp-nl span.fancytree-expander{background-image:none}.fancytree-container.fancytree-rtl.fancytree-connectors .fancytree-exp-n span.fancytree-expander,.fancytree-container.fancytree-rtl.fancytree-connectors .fancytree-exp-nl span.fancytree-expander{background-image:url("../skin-xp/icons-rtl.gif")}ul.fancytree-container.fancytree-rtl ul{padding:0 16px 0 0}ul.fancytree-container.fancytree-rtl.fancytree-connectors li{background-position:right 0;background-image:url("../skin-xp/vline-rtl.gif")}ul.fancytree-container.fancytree-rtl li.fancytree-lastsib,ul.fancytree-container.fancytree-rtl.fancytree-no-connector>li{background-image:none}#fancytree-drop-marker.fancytree-rtl{background-image:url("../skin-xp/icons-rtl.gif")}table.fancytree-ext-table{font-family:tahoma,arial,helvetica;font-size:10pt;border-collapse:collapse}table.fancytree-ext-table span.fancytree-node{display:inline-block;box-sizing:border-box}table.fancytree-ext-table td.fancytree-status-merged{text-align:center;font-style:italic;color:silver}table.fancytree-ext-table tr.fancytree-statusnode-error td.fancytree-status-merged{color:red}table.fancytree-ext-table.fancytree-ext-ariagrid.fancytree-cell-mode>tbody>tr.fancytree-active>td{background-color:#eee}table.fancytree-ext-table.fancytree-ext-ariagrid.fancytree-cell-mode>tbody>tr>td.fancytree-active-cell{background-color:#cbe8f6}table.fancytree-ext-table.fancytree-ext-ariagrid.fancytree-cell-mode.fancytree-cell-nav-mode>tbody>tr>td.fancytree-active-cell{background-color:#3875d7}table.fancytree-ext-columnview tbody tr td{position:relative;border:1px solid gray;vertical-align:top;overflow:auto}table.fancytree-ext-columnview tbody tr td>ul{padding:0}table.fancytree-ext-columnview tbody tr td>ul li{list-style-image:none;list-style-position:outside;list-style-type:none;-moz-background-clip:border;-moz-background-inline-policy:continuous;-moz-background-origin:padding;background-attachment:scroll;background-color:transparent;background-position:0 0;background-repeat:repeat-y;background-image:none;margin:0}table.fancytree-ext-columnview span.fancytree-node{position:relative;display:inline-block}table.fancytree-ext-columnview span.fancytree-node.fancytree-expanded{background-color:#e0e0e0}table.fancytree-ext-columnview span.fancytree-node.fancytree-active{background-color:#cbe8f6}table.fancytree-ext-columnview .fancytree-has-children span.fancytree-cv-right{position:absolute;right:3px;background-position:0 -80px}table.fancytree-ext-columnview .fancytree-has-children span.fancytree-cv-right:hover{background-position:-16px -80px}.fancytree-ext-filter-dimm span.fancytree-node span.fancytree-title{color:silver;font-weight:lighter}.fancytree-ext-filter-dimm span.fancytree-node.fancytree-submatch span.fancytree-title,.fancytree-ext-filter-dimm tr.fancytree-submatch span.fancytree-title{color:#000;font-weight:400}.fancytree-ext-filter-dimm span.fancytree-node.fancytree-match span.fancytree-title,.fancytree-ext-filter-dimm tr.fancytree-match span.fancytree-title{color:#000;font-weight:700}.fancytree-ext-filter-hide span.fancytree-node.fancytree-hide,.fancytree-ext-filter-hide tr.fancytree-hide{display:none}.fancytree-ext-filter-hide span.fancytree-node.fancytree-submatch span.fancytree-title,.fancytree-ext-filter-hide tr.fancytree-submatch span.fancytree-title{color:silver;font-weight:lighter}.fancytree-ext-filter-hide span.fancytree-node.fancytree-match span.fancytree-title,.fancytree-ext-filter-hide tr.fancytree-match span.fancytree-title{color:#000;font-weight:400}.fancytree-ext-filter-hide-expanders span.fancytree-node.fancytree-match span.fancytree-expander,.fancytree-ext-filter-hide-expanders tr.fancytree-match span.fancytree-expander{visibility:hidden}.fancytree-ext-filter-hide-expanders span.fancytree-node.fancytree-submatch span.fancytree-expander,.fancytree-ext-filter-hide-expanders tr.fancytree-submatch span.fancytree-expander{visibility:visible}.fancytree-ext-childcounter span.fancytree-custom-icon,.fancytree-ext-childcounter span.fancytree-icon,.fancytree-ext-filter span.fancytree-custom-icon,.fancytree-ext-filter span.fancytree-icon{position:relative}.fancytree-ext-childcounter span.fancytree-childcounter,.fancytree-ext-filter span.fancytree-childcounter{color:#fff;background:#777;border:1px solid gray;position:absolute;top:-6px;right:-6px;min-width:10px;height:10px;line-height:1;vertical-align:baseline;border-radius:10px;padding:2px;text-align:center;font-size:9px}ul.fancytree-ext-wide{position:relative;min-width:100%;z-index:2;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}ul.fancytree-ext-wide span.fancytree-node>span{position:relative;z-index:2}ul.fancytree-ext-wide span.fancytree-node span.fancytree-title{position:absolute;z-index:1;left:0;min-width:100%;margin-left:0;margin-right:0;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.fancytree-ext-fixed-wrapper .fancytree-ext-fixed-hidden{display:none}.fancytree-ext-fixed-wrapper div.fancytree-ext-fixed-scroll-border-bottom{border-bottom:3px solid rgba(0,0,0,.75)}.fancytree-ext-fixed-wrapper div.fancytree-ext-fixed-scroll-border-right{border-right:3px solid rgba(0,0,0,.75)}.fancytree-ext-fixed-wrapper div.fancytree-ext-fixed-wrapper-tl{position:absolute;overflow:hidden;z-index:3;top:0;left:0}.fancytree-ext-fixed-wrapper div.fancytree-ext-fixed-wrapper-tr{position:absolute;overflow:hidden;z-index:2;top:0}.fancytree-ext-fixed-wrapper div.fancytree-ext-fixed-wrapper-bl{position:absolute;overflow:hidden;z-index:2;left:0}.fancytree-ext-fixed-wrapper div.fancytree-ext-fixed-wrapper-br{position:absolute;overflow:scroll;z-index:1}ul.fancytree-container li{background-image:url("../skin-xp/vline.gif");background-position:0 0}ul.fancytree-container.fancytree-rtl li{background-position:right 0;background-image:url("../skin-xp/vline-rtl.gif")}ul.fancytree-container.fancytree-rtl .fancytree-exp-n span.fancytree-expander{background-image:url("../skin-xp/icons-rtl.gif");background-position:0 -64px}ul.fancytree-container.fancytree-rtl .fancytree-exp-nl span.fancytree-expander{background-image:url("../skin-xp/icons-rtl.gif");background-position:-16px -64px}ul.fancytree-container li.fancytree-lastsib{background-image:none}ul.fancytree-no-connector>li{background-image:none}.fancytree-exp-n span.fancytree-expander,.fancytree-exp-nl span.fancytree-expander{background-image:url("../skin-xp/icons.gif")}.fancytree-exp-n span.fancytree-expander,.fancytree-exp-n span.fancytree-expander:hover{background-position:0 -64px}.fancytree-exp-nl span.fancytree-expander,.fancytree-exp-nl span.fancytree-expander:hover{background-position:-16px -64px}span.fancytree-title{border:0 solid transparent}span.fancytree-title:hover{background-color:#f2f7fd;border-color:#b8d6fb}span.fancytree-focused span.fancytree-title{outline:1px dotted black;background-color:#efebde}.fancytree-folder span.fancytree-title{font-weight:700}.fancytree-selected span.fancytree-title{color:green;font-style:italic}.fancytree-active span.fancytree-title{background-color:#3169c6!important;color:#fff!important}table.fancytree-ext-table{border-collapse:collapse}table.fancytree-ext-table tbody tr.fancytree-focused{background-color:#99defd}table.fancytree-ext-table tbody tr.fancytree-active{background-color:#4169e1}table.fancytree-ext-table tbody tr.fancytree-selected{background-color:#99fdde}
\ No newline at end of file diff --git a/plugins/55/indexmenu/scripts/fancytree/skin-xp/vline-rtl.gif b/plugins/55/indexmenu/scripts/fancytree/skin-xp/vline-rtl.gif Binary files differnew file mode 100644 index 0000000..0400cb3 --- /dev/null +++ b/plugins/55/indexmenu/scripts/fancytree/skin-xp/vline-rtl.gif diff --git a/plugins/55/indexmenu/scripts/fancytree/skin-xp/vline.gif b/plugins/55/indexmenu/scripts/fancytree/skin-xp/vline.gif Binary files differnew file mode 100644 index 0000000..1b00ae5 --- /dev/null +++ b/plugins/55/indexmenu/scripts/fancytree/skin-xp/vline.gif diff --git a/plugins/55/indexmenu/scripts/indexmenu.js b/plugins/55/indexmenu/scripts/indexmenu.js new file mode 100644 index 0000000..d9b8d61 --- /dev/null +++ b/plugins/55/indexmenu/scripts/indexmenu.js @@ -0,0 +1,1008 @@ +/*--------------------------------------------------------| + | dTree 2.05 | www.destroydrop.com/javascript/tree/ | + |--------------------------------------------------------| + | Copyright (c) 2002-2003 Geir Landro | + | | + | This script can be used freely as long as all | + | copyright messages are intact. | + | | + | Updated: 17.04.2003 | + |--------------------------------------------------------| + | Modified for Dokuwiki by | + | Samuele Tognini <samuele@samuele.netsons.org> | + | under GPL 2 license | + | (http://www.gnu.org/licenses/gpl.html) | + | Updated: 29.08.2009 | + |--------------------------------------------------------| + | Modified for Dokuwiki by | + | Rene Hadler <rene.hadler@iteas.at> | + | under GPL 2 license | + | (http://www.gnu.org/licenses/gpl.html) | + | Updated: 07.08.2012 | + |--------------------------------------------------------| + | jQuery update - 27 02 2012 | + | Gerrit Uitslag <klapinklapin@gmail.com | + |--------------------------------------------------------| + | indexmenu | https://www.dokuwiki.org/plugin:indexmenu | + |-------------------------------------------------------*/ +/* global DOKU_COOKIE_PARAM */ +/* global DOKU_BASE */ + +/* + * ids used in the dTree: + * - div#cdtree_<id indexmenu> div top level + * - div#dtree_<id indexmenu> div contains all nodes + * - div#toc_<id indexmenu> ?? + * - div.dtreeNode + * - img#i<id indexmenu><nodenr?> icon + * - a#s<id indexmenu><nodenr?> url to page/namespace with title + * - div#t<id indexmenu><nodenr?> button for opening ToC, included if hovered + * - div.d<id indexmenu><nodenr?> + * repeats: - div.dtreeNode (with img#i, a#s and div#t) + * repeats: - div.d<id indexmenu><nodenr?> + * - z<id indexmenu> scroll rightward arrows + * - left_<id indexmenu> scroll leftward arrows + * + * at the end of body: + * - picker_<id indexmenu> popup with ToC + * - r<id indexmenu> rightmouse button menu + */ + +/** + * dTreeNode object + * + * @param {string} dokuid page id of node + * @param {number} id node id + * @param {number} pid parent node id + * @param {string} name Page Title + * @param {number|string} hns page id of headpage of namespace + * @param {number} isdir is directory? + * @param {number} ajax load subnodes by ajax + * @constructor + */ +function dTreeNode(dokuid, id, pid, name, hns, isdir, ajax) { + /** @type {string} */ + this.dokuid = dokuid; // page id of node + /** @type {number} */ + this.id = id; // id number of node + /** @type {number} */ + this.pid = pid; // id number of parent node + /** @type {string} */ + this.name = name; // ns/page title + /** @type {number|string} */ + this.hns = hns; // headpage of namespace or zero + /** @type {boolean} */ + this.isdir = Boolean(isdir); // is directory + /** @type {boolean} */ + this.ajax = Boolean(ajax); // load its nodes by ajax + /** @type {boolean} */ + this._io = false; // is node open + /** @type {boolean} */ + this._is = false; // is selected + /** @type {boolean} */ + this._ls = false; // is last sibling + /** @type {boolean} */ + this._hc = Boolean(ajax); // has children + /** @type {number} */ + this._ai = 0; // id number of first child.... + /** @type {dTreeNode} */ + this._p = undefined; // parent dTreeNode + /** @type {number} */ + this._lvl = 0; // level + /** @type {boolean} */ + this._ok = false; // all children are loaded + /** @type {boolean} */ + this._cp = false; // current page + /** @type {string} */ + this.icon = ''; // icon of closed node + /** @type {string} */ + this.iconOpen = ''; // icon of opened node +} + +/** + * Tree object + * + * @param {string} treeName id of the indexmenu, has form 'indexmenu_<identifier>' + * @param {string} theme name of theme dir + * @constructor + */ +function dTree(treeName, theme) { + let imgExt = IndexmenuUtils.determineExtension(theme); + this.config = { + urlbase: DOKU_BASE + 'doku.php?id=', // base of dokuwiki (set in page) + plugbase: DOKU_BASE + 'lib/plugins/indexmenu', // base of plugin folder + useCookies: true, // use cookies (set in page) e.g. disabled for context option + scroll: true, // enable scrolling of tree in too small columns (set in page) + toc: true, // enable ToC popups in tree (set in page) + maxjs: 1, // number set by maxjs option (set in page) + jsajax: '', // &max=#&sort=(t|d)&msort=(indexmenu_n|<metakey>)&rsort=1&nsort=1&hsort=1&nopg=1&skipns=+=/.../&skipfile=+=/.../(set in page) + sepchar: ':', // value ':', ';' or '/' (set in page) + theme: theme // dir name of theme folder + }; + let imagePath = this.config.plugbase + '/images/' + theme + '/'; + this.icon = { + root: imagePath + 'base.' + imgExt, + folder: imagePath + 'folder.' + imgExt, + folderH: imagePath + 'folderh.' + imgExt, + folderOpen: imagePath + 'folderopen.' + imgExt, + folderHOpen: imagePath + 'folderhopen.' + imgExt, + node: imagePath + 'page.' + imgExt, + empty: imagePath + 'empty.' + imgExt, + line: imagePath + 'line.' + imgExt, + join: imagePath + 'join.' + imgExt, + joinBottom: imagePath + 'joinbottom.' + imgExt, + plus: imagePath + 'plus.' + imgExt, + plusBottom: imagePath + 'plusbottom.' + imgExt, + minus: imagePath + 'minus.' + imgExt, + minusBottom: imagePath + 'minusbottom.' + imgExt, + nlPlus: imagePath + 'nolines_plus.' + imgExt, + nlMinus: imagePath + 'nolines_minus.' + imgExt + }; + /** @type {string} */ + this.treeName = treeName; // (unique) name of this indexmenu + /** @type {dTreeNode[]} */ + this.aNodes = []; // array of nodes + /** @type {number[]} */ + this.aIndent = []; // array stores the indents of the tree (contains values 0 or 1) + /** @type {dTreeNode} */ + this.root = new dTreeNode(false, -1); + /** @type {number} */ + this.selectedNode = undefined; // node id + /** @type {boolean} */ + this.selectedFound = false; // set to true when found + /** @type {boolean} */ + this.completed = false; // succesfull written js tree to the page + /** @type {number} */ + this.scrllTmr = 0; // store timer id for horizontal scrolling the page + /** @type {string} */ + this.pageid = JSINFO.id || ''; // current page + + this.fajax = false; // if retrieve next level of opened nodes +} +/** + * CSS classes: + * + * a.nodeFdUrl Namespace with url link (headpage) + * a.node Namespace without url link + * a.nodeUrl Page + * a.nodeSel Last visited page + * a.navSel Current page + */ + + +/** + * Adds a new node to the node array + * + * @param {string} dokuid page id of node + * @param {number} id node id + * @param {number} pid parent node id + * @param {string} name Page Title + * @param {number|string} hns page id of headpage of namespace + * @param {number} isdir is directory? + * @param {number} ajax load subnodes by ajax + */ +dTree.prototype.add = function (dokuid, id, pid, name, hns, isdir, ajax) { + this.aNodes[this.aNodes.length] = new dTreeNode(dokuid, id, pid, name, hns, isdir, ajax); +}; + +/** + * Open all nodes, if no node status was stored in cookie + */ +dTree.prototype.openAll = function () { + if (!this.getCookie('co' + this.treeName)) { + this.oAll(true); + } +}; + +/** + * Outputs the tree to the page. Called by document.write after adding the nodes to the tree. + * + * @returns {string} html of whole tree + */ +dTree.prototype.toString = function () { + let str = ''; + this.pageid = this.pageid.replace(/:/g,this.config.sepchar); + if (this.config.scroll) { + str += '<div id="cdtree_' + this.treeName + '" class="dtree" style="position:relative;overflow:hidden;width:100%;">'; + } + str += '<div id="dtree_' + this.treeName + '" class="dtree ' + this.config.theme + '" style="overflow:'; + if (this.config.scroll) { + str += 'visible;position:relative;width:100%"'; + } else { + str += 'hidden;"'; + } + str += '>'; + if (jQuery('#dtree_' + this.treeName)[0]) { + str += '<div class="error">Indexmenu id conflict</div>'; + } + if (this.config.toc) { + str += '<div id="t' + this.treeName + '" class="indexmenu_tocbullet ' + this.config.theme + '" style="display:none;" title="Table of contents"></div>'; + str += '<div id="toc_' + this.treeName + '" style="display:none;"></div>'; + } + if (this.config.useCookies) { + this.selectedNode = this.getSelected(); + } + str += this.addNode(this.root) + '</div>'; + if (this.config.scroll) { + str += '<div id="z' + this.treeName + '" class="indexmenu_rarrow"></div>'; + str += '<div id="left_' + this.treeName + '" class="indexmenu_larrow" style="display:none;" title="Click to scroll back" onmousedown="' + this.treeName + '.scroll(\'r\',1)" onmouseup="' + this.treeName + '.stopscroll()"></div>'; + str += '</div>'; + } + this.completed = true; + //hide the fallback nojs indexmenu + jQuery('#nojs_' + this.treeName).css("display", "none"); //using .hide(); let's crash opera + return str; +}; + +/** + * Creates the tree structure + * + * @param {dTreeNode} pNode + * @returns {string} html of node (inclusive children) + */ +dTree.prototype.addNode = function (pNode) { + let str = '', cn, n = pNode._ai, l = pNode._lvl + 1; + for (n; n < this.aNodes.length; n++) { + if (this.aNodes[n].pid === pNode.id) { + cn = this.aNodes[n]; + cn._p = pNode; + cn._ai = n; + cn._lvl = l; + this.setCS(cn); + if (cn._hc && !cn._io && this.config.useCookies) { + cn._io = this.isOpen(cn.id); + } + if (this.pageid === (!cn.hns && cn.dokuid || cn.hns)) { + cn._cp = true; + } else if (cn.id === this.selectedNode && !this.selectedFound) { + cn._is = true; + this.selectedNode = n; + this.selectedFound = true; + } + if (!cn._hc && cn.isdir && !cn.ajax && !cn.hns) { + if (cn._ls) { + str += this.noderr(cn, n); + } + } else { + str += this.node(cn, n); + } + if (cn._ls) { + break; + } + } + } + return str; +}; + +/** + * Create empty node + * + * @param {dTreeNode} node + * @param {int} nodeId + * @returns {string} html of empty node + */ +dTree.prototype.noderr = function (node, nodeId) { + let str = '<div class="dTreeNode">' + this.indent(node, nodeId); + str += '<div class="emptynode" title="Empty"></div></div>'; + return str; +}; + +/** + * Creates the node icon, url and text + * + * @param {dTreeNode} node + * @param {int} nodeId + * @returns {string} html of node (inclusive children) + */ +dTree.prototype.node = function (node, nodeId) { + let h = 1, jsfnc, str; + jsfnc = 'onmouseover="' + this.treeName + '.show_feat(\'' + nodeId + '\');" onmousedown="return IndexmenuContextmenu.checkcontextm(\'' + nodeId + '\',' + this.treeName + ',event);" oncontextmenu="return IndexmenuContextmenu.stopevt(event)"'; + if (node._lvl > this.config.maxjs) { + h = 0; + } else { + node._ok = true; + } + str = '<div class="dTreeNode">' + this.indent(node, nodeId); + node.icon = (this.root.id === node.pid) ? this.icon.root : ((node.hns) ? this.icon.folderH : ((node._hc) ? this.icon.folder : this.icon.node)); + node.iconOpen = (node._hc) ? ((node.hns) ? this.icon.folderHOpen : this.icon.folderOpen) : this.icon.node; + if (this.root.id === node.pid) { + node.icon = this.icon.root; + node.iconOpen = this.icon.root; + } + str += '<img id="i' + this.treeName + nodeId + '" src="' + ((node._io) ? node.iconOpen : node.icon) + '" alt="" />'; + if (!node._hc || node.hns) { + str += '<a id="s' + this.treeName + nodeId + '" class="' + ((node._cp) ? 'navSel' : ((node._is) ? 'nodeSel' : (node._hc) ? 'nodeFdUrl' : 'nodeUrl')); + str += '" href="' + this.config.urlbase; + (node.hns) ? str += node.hns : str += node.dokuid; + str += '"' + ' title="' + node.name + '"' + jsfnc; + str += ' onclick="javascript: ' + this.treeName + '.s(' + nodeId + ');"'; + str += '>' + node.name + '</a>'; + } + else if (node.pid !== this.root.id) { + str += '<a id="s' + this.treeName + nodeId + '" href="javascript: ' + this.treeName + '.o(' + nodeId + '); " class="node"' + jsfnc + '>' + node.name + '</a>'; + } else { + str += node.name; + } + str += '</div>'; + if (node._hc) { + str += '<div id="d' + this.treeName + nodeId + '" class="clip" style="display:' + ((this.root.id === node.pid || node._io) ? 'block' : 'none') + ';">'; + if (h) { + str += this.addNode(node); + } + str += '</div>'; + } + this.aIndent.pop(); + return str; +}; + +/** + * Adds the empty and line icons which indent the node + * + * @param {dTreeNode} node + * @param {int} nodeId + * @returns {string} html of indent icons + */ +dTree.prototype.indent = function (node, nodeId) { + let n, str = ''; + if (this.root.id !== node.pid) { + for (n = 0; n < this.aIndent.length; n++) { + str += '<img src="' + ( (this.aIndent[n] === 1) ? this.icon.line : this.icon.empty ) + '" alt="" />'; + } + if (node._ls) { + this.aIndent.push(0); + } else { + this.aIndent.push(1); + } + if (node._hc) { + str += '<a href="javascript: ' + this.treeName + '.o(' + nodeId + ');">' + + '<img id="j' + this.treeName + nodeId + '" src="' + + ( (node._io) ? ((node._ls) ? this.icon.minusBottom : this.icon.minus) : ((node._ls) ? this.icon.plusBottom : this.icon.plus ) ) + + '" alt="" /></a>'; + } else { + str += '<img src="' + ((node._ls) ? this.icon.joinBottom : this.icon.join) + '" alt="" />'; + } + } + return str; +}; + +/** + * Checks if a node has any children and if it is the last sibling + * + * @param {dTreeNode} node + */ +dTree.prototype.setCS = function (node) { + let lastId, n; + for (n = 0; n < this.aNodes.length; n++) { + if (this.aNodes[n].pid === node.id) { + node._hc = true; + } + if (this.aNodes[n].pid === node.pid) { + lastId = this.aNodes[n].id; + } + } + if (lastId === node.id) { + node._ls = true; + } +}; + +/** + * Returns the selected node as stored in cookie + * + * @returns {int} node id + */ +dTree.prototype.getSelected = function () { + let sn = this.getCookie('cs' + this.treeName); + return (sn) ? parseInt(sn, 10) : null; +}; + +/** + * Highlights the selected node + * + * @param {int} id node id + */ +dTree.prototype.s = function (id) { + let eOld, eNew, cn = this.aNodes[id]; + if (this.selectedNode !== id) { + eNew = jQuery("#s" + this.treeName + id)[0]; + if (!eNew) { + return; + } + if (this.selectedNode || this.selectedNode === 0) { + eOld = jQuery("#s" + this.treeName + this.selectedNode)[0]; + eOld.className = "node"; + } + eNew.className = "nodeSel"; + this.selectedNode = id; + if (this.config.useCookies) { + this.setCookie('cs' + this.treeName, cn.id); + } + } +}; + +/** + * Toggle Open or close + * + * @param {int} id node id + */ +dTree.prototype.o = function (id) { + let cn = this.aNodes[id]; + this.nodeStatus(!cn._io, id, cn._ls); + cn._io = !cn._io; + if (this.config.useCookies) { + this.updateCookie(); + } + // scroll + this.divdisplay('z', false); + this.resizescroll("block"); +}; + +/** + * Open or close all nodes + * + * @param {boolean} status if true open + */ +dTree.prototype.oAll = function (status) { + for (let n = 0; n < this.aNodes.length; n++) { + if (this.aNodes[n]._hc && this.aNodes[n].pid !== this.root.id) { + this.nodeStatus(status, n, this.aNodes[n]._ls); + this.aNodes[n]._io = status; + } + } + if (this.config.useCookies) { + this.updateCookie(); + } +}; + +/** + * Opens the tree to a specific node + * + * @param {number} nId node id + * @param {boolean} bSelect + * @param {boolean} bFirst + */ +dTree.prototype.openTo = function (nId, bSelect, bFirst) { + let n, cn; + if (!bFirst) { + for (n = 0; n < this.aNodes.length; n++) { + if (this.aNodes[n].id === nId) { + nId = n; + break; + } + } + } + this.fill(this.aNodes[nId].pid); + cn = this.aNodes[nId]; + if (cn.pid === this.root.id || !cn._p) { + return; + } + cn._io = 1; + if (this.completed && cn._hc) { + this.nodeStatus(true, cn._ai, cn._ls); + } + if (cn._is) { + (this.completed) ? this.s(cn._ai) : this._sn = cn._ai; + } + this.openTo(cn._p._ai, false, true); +}; + +/** + * Open the given nodes, if no node status is already stored + * + * @param {Array|string} nodes array of nodes to open or empty string to open all nodes + */ +dTree.prototype.getOpenTo = function (nodes) { + if (nodes === '') { + this.openAll(); + } else if (!this.config.useCookies || !this.getCookie('co' + this.treeName)) { + for (let n = 0; n < nodes.length; n++) { + this.openTo(nodes[n], false, true); + } + } +}; + +/** + * Change the status of a node(open or closed) + * + * @param {boolean} status true if open + * @param {int} id node id + * @param {boolean} bottom true if bottom node + */ +dTree.prototype.nodeStatus = function (status, id, bottom) { + if (status && !this.fill(id)) { + return; + } + let eJoin, eIcon; + eJoin = jQuery('#j' + this.treeName + id)[0]; + eIcon = jQuery('#i' + this.treeName + id)[0]; + eIcon.src = (status) ? this.aNodes[id].iconOpen : this.aNodes[id].icon; + eJoin.src = ((status) ? ((bottom) ? this.icon.minusBottom : this.icon.minus) : ((bottom) ? this.icon.plusBottom : this.icon.plus)); + jQuery('#d' + this.treeName + id)[0].style.display = (status) ? 'block' : 'none'; +}; + +/** + * [Cookie] Clears a cookie + */ +dTree.prototype.clearCookie = function () { + let now, yday; + now = new Date(); + yday = new Date(now.getTime() - 1000 * 60 * 60 * 24); + this.setCookie('co' + this.treeName, 'cookieValue', yday); + this.setCookie('cs' + this.treeName, 'cookieValue', yday); +}; + +/** + * [Cookie] Sets value in a cookie + * + * @param {string} cookieName + * @param {string} cookieValue + * @param {boolean|Date} expires + */ +dTree.prototype.setCookie = function (cookieName, cookieValue, expires = false) { + document.cookie = + encodeURIComponent(cookieName) + '=' + encodeURIComponent(cookieValue) + + (expires ? '; expires=' + expires.toUTCString() : '') + + '; path=' + DOKU_COOKIE_PARAM.path + + '; secure=' + DOKU_COOKIE_PARAM.secure; +}; + +/** + * [Cookie] Gets a value from a cookie + * + * @param cookieName + * @returns {string} + */ +dTree.prototype.getCookie = function (cookieName) { + let cookieValue = '', pN, posValue, endPos; + pN = document.cookie.indexOf(encodeURIComponent(cookieName) + '='); + if (pN !== -1) { + posValue = pN + (encodeURIComponent(cookieName) + '=').length; + endPos = document.cookie.indexOf(';', posValue); + if (endPos !== -1) { + cookieValue = decodeURIComponent(document.cookie.substring(posValue, endPos)); + } + else { + cookieValue = decodeURIComponent(document.cookie.substring(posValue)); + } + } + return (cookieValue); +}; + +/** + * [Cookie] Stores ids of open nodes as a string in cookie + */ +dTree.prototype.updateCookie = function () { + let str = '', n; + for (n = 0; n < this.aNodes.length; n++) { + if (this.aNodes[n]._io && this.aNodes[n].pid !== this.root.id) { + if (str) { + str += '.'; + } + str += this.aNodes[n].id; + } + } + this.setCookie('co' + this.treeName, str); +}; + +/** + * [Cookie] Checks if a node id is in the cookie + * + * @param {int} id node id + * @return {Boolean} if open true + */ +dTree.prototype.isOpen = function (id) { + let n, aOpen = this.getCookie('co' + this.treeName).split('.'); + for (n = 0; n < aOpen.length; n++) { + if (parseInt(aOpen[n],10) === id) { + return true; + } + } + return false; +}; + +/** + * Open the node of the current namespace + * + * @param {int} max + */ +dTree.prototype.openCurNS = function (max) { + let r, cn, match, t, i, n, cnsa, cna; + let cns = this.pageid; + r = new RegExp("\\b" + this.config.sepchar + "\\b", "g"); + match = cns.match(r) || -1; + if (max > 0 && match.length >= max) { + t = cns.split(this.config.sepchar); + n = (this.aNodes[0].dokuid === '') ? 0 : this.aNodes[0].dokuid.split(this.config.sepchar).length; + t.splice(max + n, t.length); + cnsa = t.join(this.config.sepchar); + } + for (i = 0; i < this.aNodes.length; i++) { + cn = this.aNodes[i]; + if (cns === cn.dokuid || cns === cn.hns) { + this.openTo(cn.id, false, true); + this.fajax = false; + if (cn.pid >= 0) { + jQuery(this.scroll("l", 4, cn.pid, 1)); + } + break; + } + if (cnsa === cn.dokuid || cnsa === cn.hns) { + cna = cn; + this.fajax = true; + } + } + if (cna) { + this.openTo(cna.id, false, true); + } +}; + +/** + * Load children when not available + * + * @param {int} id node id + * @returns {boolean} + */ +dTree.prototype.fill = function (id) { + if (id === -1 || this.aNodes[id]._ok) { + return true; + } + let n = id, $eLoad, a, rd, ln, eDiv; + if (this.aNodes[n].ajax) { + //temporary load indicator + $eLoad = jQuery('#l' + this.treeName); + if (!$eLoad.length) { + $eLoad = IndexmenuUtils.createPicker('l' + this.treeName, 'picker'); + } + jQuery('#s' + this.treeName + n).parent().append($eLoad); + $eLoad + .html('Loading ...') + .css({width: 'auto'}) + .show(); + + //retrieves children + this.getAjax(n); + return true; + } + rd = []; + while (!this.aNodes[n]._ok) { + rd[rd.length] = n; + n = this.aNodes[n].pid; + } + for (ln = rd.length - 1; ln >= 0; ln--) { + id = rd[ln]; + a = this.aNodes[id]; + eDiv = jQuery('#d' + this.treeName + id)[0]; + if (!eDiv) { + return false; + } + this.aIndent = []; + n = a; + while (n.pid >= 0) { + if (n._ls) { + this.aIndent.unshift(0); + } else { + this.aIndent.unshift(1); + } + n = n._p; + } + eDiv.innerHTML = this.addNode(a); + a._ok = true; + } + return true; +}; + +/** + * Open the nodes stored in cookie + */ +dTree.prototype.openCookies = function () { + let n, cn, aOpen = this.getCookie('co' + this.treeName).split('.'); + for (n = 0; n < aOpen.length; n++) { + if (aOpen[n] === "") { + break; + } + cn = this.aNodes[aOpen[n]]; + if (!cn._ok) { + this.nodeStatus(true, aOpen[n], cn._ls); + cn._io = true; + } + } +}; + +/** + * Scrolls the index + * + * @param {string} where to move to + * @param {int} s start + * @param {int} n parent node id + * @param {int} i + */ +dTree.prototype.scroll = function (where, s, n, i) { + if (!this.config.scroll) { + return false; + } + let w, dtree, dtreel, nodeId; + dtree = jQuery('#dtree_' + this.treeName)[0]; + dtreel = parseInt(dtree.offsetLeft); + if (where === "r") { + jQuery('#left_' + this.treeName)[0].style.border = "thin inset"; + this.scrollRight(dtreel, s); + } else { + nodeId = jQuery('#s' + this.treeName + n)[0]; + if (nodeId == null) { + return false; + } + w = parseInt(dtree.parentNode.offsetWidth - nodeId.offsetWidth - nodeId.offsetLeft); + if (this.config.toc) { + w = w - 11; + } + if (dtreel <= w) { + return; + } + this.resizescroll("none"); + this.stopscroll(); + this.scrollLeft(dtreel, s, w - 3, i); + } +}; + +/** + * Scroll index to the left + * + * @param {int} lft current position + * @param {int} s start + * @param {int} w width + * @param {int} i + */ +dTree.prototype.scrollLeft = function (lft, s, w, i) { + if (lft < w - i - 10) { + this.divdisplay('z', false); + this.scrllTmr = 0; + return; + } + var self = this; + jQuery('#dtree_' + self.treeName)[0].style.left = lft + "px"; + this.scrllTmr = setTimeout(function () { + self.scrollLeft(lft - s, s + i, w, i); + }, 20); +}; + +/** + * Scroll Index back to the right + * + * @param {int} lft current position + * @param {int} s start + */ +dTree.prototype.scrollRight = function (lft, s) { + if (lft >= s) { + this.divdisplay('left_', false); + this.stopscroll(); + return; + } + var self = this; + jQuery('#dtree_' + self.treeName)[0].style.left = lft + "px"; + if (lft > -15) { + s = 1; + } + this.scrllTmr = setTimeout(function () { + self.scrollRight(lft + s, s + 1); + }, 20); +}; + +/** + * Stop scroll movement + */ +dTree.prototype.stopscroll = function () { + jQuery('#left_' + this.treeName)[0].style.border = "none"; + clearTimeout(this.scrllTmr); + this.scrllTmr = 0; +}; + +/** + * Show features and add event handlers for ToC and scroll + * + * @param {int} n node id + */ +dTree.prototype.show_feat = function (n) { + var w, div, id, dtree, dtreel, self, node = jQuery('#s' + this.treeName + n)[0]; + self = this; + if (this.config.toc && node.className !== "node") { + div = jQuery('#t' + this.treeName)[0]; + id = (this.aNodes[n].hns) ? this.aNodes[n].hns : this.aNodes[n].dokuid; + div.onmousedown = function () { + IndexmenuContextmenu.createTocMenu('call=indexmenu&req=toc&id=' + decodeURIComponent(id), 'picker_' + self.treeName, 't' + self.treeName); + }; + node.parentNode.appendChild(div); + if (div.style.display === "none") { + div.style.display = "inline"; + } + } + if (this.config.scroll) { + div = jQuery('#z' + this.treeName)[0]; + div.onmouseover = function () { + div.style.border = "none"; + self.scroll("l", 1, n, 0); + }; + div.onmousedown = function () { + div.style.border = "thin inset"; + self.scroll("l", 4, n, 1); + }; + div.onmouseout = function () { + div.style.border = "none"; + self.stopscroll(); + }; + div.onmouseup = div.onmouseover; + dtree = jQuery('#dtree_' + this.treeName)[0]; + dtreel = parseInt(dtree.offsetLeft); + w = parseInt(dtree.parentNode.offsetWidth - node.offsetWidth - node.offsetLeft + 1); + if (dtreel > w) { + div.style.display = "none"; + div.style.top = node.offsetTop + "px"; + div.style.left = parseInt(node.offsetLeft + node.offsetWidth + w - 12) + "px"; + div.style.display = "block"; + } + } +}; + +/** + * Show and resize the scroll-back button relatively to size of tree + * + * @param {string} status 'block' or 'none' + */ +dTree.prototype.resizescroll = function (status) { + let dtree, w, h, left = jQuery('#left_' + this.treeName)[0]; + if (!left) { + return; + } + if (left.style.display === status) { + dtree = jQuery('#dtree_' + this.treeName)[0]; + w = Math.trunc(dtree.offsetHeight / 3); + h = Math.trunc(w / 50) * 50; + if (h < 50) { + h = 50; + } + left.style.height = h + "px"; + left.style.top = w + "px"; + if (status === "none") { + left.style.display = "block"; + } + } +}; + +/** + * Toggle Open or close + * + * @param {int} n node id + */ +dTree.prototype.getAjax = function (n) { + var node, selft = this; + let req, curns; + node = selft.aNodes[n]; + + req = 'req=index&idx=' + node.dokuid + decodeURIComponent(this.config.jsajax); + + curns = this.pageid.substring(0, this.pageid.lastIndexOf(this.config.sepchar)); + if (this.fajax) { + req += '&nss=' + curns + '&max=1'; + } + + var onCompletion = function (data) { + var i, ajxnodes, ajxnode, plus; + plus = selft.aNodes.length - 1; + eval(data); + if (!ajxnodes instanceof Array || ajxnodes.length < 1) { + ajxnodes = [ + ['', 1, 0, '', 0, 1, 0] + ]; + } + node.ajax = false; + for (i = 0; i < ajxnodes.length; i++) { + ajxnode = ajxnodes[i]; + ajxnode[2] = (ajxnode[2] == 0) ? node.id : ajxnode[2] + plus; + ajxnode[1] += plus; + selft.add(ajxnode[0], ajxnode[1], ajxnode[2], ajxnode[3], ajxnode[4], ajxnode[5], ajxnode[6]); + } + if (selft.fajax) { + selft.fajax = false; + selft.openCurNS(0); + } else { + selft.openTo(node.id, false, true); + } + jQuery('#l' + selft.treeName).hide(); + }; + + jQuery.post( + DOKU_BASE + 'lib/exe/ajax.php', + 'call=indexmenu&'+req, + onCompletion, + 'html' + ); +}; + +/** + * Load custom css for theme + */ +dTree.prototype.loadCss = function () { + let oLink = document.createElement("link"); + oLink.href = this.config.plugbase + '/images/' + this.config.theme + '/style.css'; + oLink.rel = "stylesheet"; + oLink.type = "text/css"; + document.getElementsByTagName('head')[0].appendChild(oLink); +}; + +/** + * Show the contextmenu + * + * @param {int} n node id + * @param {Event} e event + * @returns {boolean} + */ +dTree.prototype.contextmenu = function (n, e) { + let type, node, cdtree, $rmenu; + cdtree = jQuery("#cdtree_" + this.treeName)[0]; + $rmenu = jQuery('#r' + this.treeName)[0]; + if (!$rmenu) { + return true; + } + IndexmenuContextmenu.mouseposition($rmenu, e); + let cmenu = window.indexmenu_contextmenu; + node = this.aNodes[n]; + $rmenu.innerHTML = '<div class="indexmenu_rmenuhead" title="' + node.name + '">' + node.name + "</div>"; + $rmenu.appendChild(document.createElement('ul')); + type = (node.isdir || node._hc) ? 'ns' : 'pg'; + IndexmenuContextmenu.arrconcat(cmenu['all'][type], this, n); + if (node.hns) { + IndexmenuContextmenu.arrconcat(cmenu[type], this, n); + type = 'pg'; + IndexmenuContextmenu.arrconcat(cmenu['all'][type], this, n); + } + IndexmenuContextmenu.arrconcat(cmenu[type], this, n); + $rmenu.style.display = 'inline'; + return false; +}; + +/** + * Show/hide object with given id of current indexmenu + * + * @param {string} objName name of object, which is combined with the unique id of the indexmenu + * @param {boolean} visible true: visible, false: hide. + */ +dTree.prototype.divdisplay = function (objName, visible) { + let o = jQuery('#' + objName + this.treeName)[0]; + if (!o) { + return; + } + (visible) ? o.style.display = 'inline' : o.style.display = 'none'; +}; + +/** + * Initialise the dTree index + * + * @param {int} hasstyle has an additional css style sheet + * @param {int} nocookies use no cookies + * @param {string} opennodes string of initial opened nodes + * @param {int} nav is navbar option set + * @param {int} max max level of available nodes (deeper levels are included with js) + * @param {int} nomenu show no menu + */ +dTree.prototype.init = function (hasstyle, nocookies, opennodes, nav, max, nomenu) { + if (hasstyle) { + this.loadCss(); + } + if (!nocookies) { + this.openCookies(); + } + //open given nodes + if (opennodes) { + this.getOpenTo(opennodes.split(" ")); + } + if (nav) { + this.openCurNS(max); + } + //create contextmenu + if (!nomenu) { + var self = this; + IndexmenuUtils.createPicker('r' + this.treeName, 'indexmenu_rmenu ' + this.config.theme); + jQuery('#r' + this.treeName)[0].oncontextmenu = IndexmenuContextmenu.stopevt; + jQuery(document).on("click",function() { + self.divdisplay('r', false); + }); + } +}; diff --git a/plugins/55/indexmenu/scripts/nojsindex.js b/plugins/55/indexmenu/scripts/nojsindex.js new file mode 100644 index 0000000..970f353 --- /dev/null +++ b/plugins/55/indexmenu/scripts/nojsindex.js @@ -0,0 +1,27 @@ +/** + * Javascript for index view + * + * @author Gerrit Uitslag <klapinklapin@gmail.com> + */ + +jQuery(function () { + + jQuery('.indexmenu_nojs').each(function () { + let $tree = jQuery(this); + let jsajax = $tree.data('jsajax'); + + $tree.dw_tree({ + toggle_selector: 'a.indexmenu_idx', + load_data: function (show_sublist, $clicky) { + + jQuery.post( + DOKU_BASE + 'lib/exe/ajax.php', + 'call=indexmenu&req=index&nojs=1&' + $clicky[0].search.substring(1) + '&max=1' + decodeURIComponent(jsajax), + show_sublist, + 'html' + ); + } + }); + }); + +}); diff --git a/plugins/55/indexmenu/scripts/toolbarindexwizard.js b/plugins/55/indexmenu/scripts/toolbarindexwizard.js new file mode 100644 index 0000000..3a81b4b --- /dev/null +++ b/plugins/55/indexmenu/scripts/toolbarindexwizard.js @@ -0,0 +1,349 @@ +/** + * The Indexmenu Wizard + * + * @author Gerrit Uitslag + * based on Linkwiz by + * @author Andreas Gohr <gohr@cosmocode.de> + * @author Pierre Spring <pierre.spring@caillou.ch> + * and the concepts of the old indexmenu wizard + */ +const indexmenu_wiz = { + $wiz: null, + timer: null, + textArea: null, + + defaulttheme: 'default', + fields: { + div1: { + elems: { + jstoggle: {label: 'js'} + } + }, + div2: { + tlbclass: 'jsitem theme', + elems: { + el1: {headerid: 'theme'} + } + }, + div3: { + elems: { + el2: {headerid: 'navigation'}, + navbar: {}, + context: {}, + nocookie: {tlbclass: 'jsitem'}, + noscroll: {tlbclass: 'jsitem'}, + notoc: {tlbclass: 'jsitem'} + } + }, + div4: { + elems: { + el3: {headerid: 'sort'}, + tsort: {}, + dsort: {}, + msort: {}, + hsort: {}, + rsort: {}, + nsort: {} + } + }, + div5: { + elems: { + el4: {headerid: 'filter'}, + nons: {}, + nopg: {} + } + }, + div6: { + tlbclass: 'jsitem', + elems: { + el5: {headerid: 'performance'}, + max: {tlbclass: 'jsitem', numberinput: ['maxn', 'maxm']}, + maxjs: {tlbclass: 'jsitem', numberinput: ['maxjsn']}, + id: {tlbclass: 'jsitem', numberinput: ['idn']} + } + } + }, + + /** + * Initialize the indexmenu_wiz by creating the needed HTML + * and attaching the eventhandlers + */ + init: function ($editor) { + // position relative to the text area + const pos = $editor.position(); + + // create HTML Structure + indexmenu_wiz.$wiz = jQuery(document.createElement('div')) + .dialog({ + autoOpen: false, + draggable: true, + title: LANG.plugins.indexmenu.indexmenuwizard, + resizable: false + }) + .html( + '<fieldset class="indexmenu_index"><legend>' + LANG.plugins.indexmenu.index + '</legend>' + + '<div><label>' + LANG.plugins.indexmenu.namespace + '<input id="namespace" type="text"></label></div>' + + '<div><label class="number">' + LANG.plugins.indexmenu.nsdepth + ' #<input id="nsdepth" type="text" value=1></label></div>' + + '</fieldset>' + + + '<fieldset class="indexmenu_options"><legend>' + LANG.plugins.indexmenu.options + '</legend>' + + '</fieldset>' + + '<input type="submit" value="' + LANG.plugins.indexmenu.insert + '" class="button" id="indexmenu__insert">' + + + '<fieldset class="indexmenu_metanumber">' + + '<label class="number">' + LANG.plugins.indexmenu.metanum + '<input type="text" id="metanumber"></label>' + + '<input type="submit" value="' + LANG.plugins.indexmenu.insertmetanum + '" class="button" id="indexmenu__insertmetanum">' + + '</fieldset>' + ) + .parent() + .attr('id', 'indexmenu__wiz') + .css({ + 'position': 'absolute', + 'top': (pos.top + 20) + 'px', + 'left': (pos.left + 80) + 'px' + }) + .hide() + .appendTo('.dokuwiki:first'); + + indexmenu_wiz.textArea = $editor[0]; + let $opt_fieldset = jQuery('#indexmenu__wiz fieldset.indexmenu_options'); + + jQuery.each(indexmenu_wiz.fields, function (i, section) { + let div = jQuery('<div>').addClass(section.tlbclass); + + jQuery.each(section.elems, function (elid, props) { + if (props.headerid) { + div.append('<strong>' + LANG.plugins.indexmenu[props.headerid] + '</strong><br />'); + } else { + let label = props.label || elid; + //checkbox + jQuery("<label>") + .addClass(props.tlbclass).addClass(props.numberinput ? ' hasnumber' : '') + .html('<input id="' + elid + '" type="checkbox">' + label) + .attr({title: LANG.plugins.indexmenu[elid]}) + .appendTo(div); + + //number inputs + if (props.numberinput) { + jQuery.each(props.numberinput, function (j, numid) { + jQuery("<label>") + .attr({title: LANG.plugins.indexmenu[elid]}) + .addClass("number " + props.tlbclass) + .html('#<input type="text" id="' + numid + '">') + .appendTo(div); + }); + } + } + }); + $opt_fieldset.append(div); + }); + + indexmenu_wiz.includeThemes(); + + if (JSINFO && JSINFO.namespace) { + jQuery('#namespace').val(':' + JSINFO.namespace); + } + + // attach event handlers + + //toggle js fields + jQuery('#jstoggle') + .on('change', function () { + jQuery('#indexmenu__wiz .jsitem').toggle(this.checked); + }).trigger('change') + .parent().css({display: 'inline-block', width: '40px'}); //enlarge clickable area of label + + //interactive number fields + jQuery('label.number input').on('keydown keyup', function () { + //allow only numbers + indexmenu_wiz.filterNumberinput(this); + //checked the option if a number in input + indexmenu_wiz.autoCheckboxForNumbers(this); + }); + + jQuery('#indexmenu__insert').on('click', indexmenu_wiz.insertIndexmenu); + jQuery('#indexmenu__insertmetanum').on('click', indexmenu_wiz.insertMetaNumber); + + jQuery('#indexmenu__wiz').find('.ui-dialog-titlebar-close').on('click', indexmenu_wiz.hide); + }, + + /** + * Request and include themes in wizard + */ + includeThemes: function () { + + let addButtons = function (data) { + jQuery('<div>') + .attr('id', 'themebar') + .addClass('toolbar') + .appendTo('div.theme'); + + jQuery.each(data.themes, function (i, theme) { + let themeName = theme.split('.'); + + let icoUrl = DOKU_BASE + data.themebase + '/' + theme + '/base.' + IndexmenuUtils.determineExtension(theme); + let $ico = jQuery('<div>') + .css({background: 'url(' + icoUrl + ') no-repeat center'}); + jQuery('<button>') + .addClass('themebutton toolbutton') + .attr('id', theme) + .attr('title', themeName[0]) + .append($ico) + .on('click', indexmenu_wiz.selectTheme) + .appendTo('div#themebar'); + }); + + //select default theme + jQuery('#themebar button#' + indexmenu_wiz.defaulttheme).trigger('click'); + }; + + jQuery.post( + DOKU_BASE + 'lib/exe/ajax.php', + {call: 'indexmenu', req: 'local'}, + addButtons, + 'json' + ); + }, + + /** + * set class 'selected' to clicked theme, remove from other + */ + selectTheme: function () { + jQuery('.themebutton').toggleClass('selected', false); + jQuery(this).toggleClass('selected', true); + }, + + /** + * Allow only number, by direct removing other characters from input + */ + filterNumberinput: function (elem) { + if (elem.value.match(/\D/)) { + elem.value = this.value.replace(/\D/g, ''); + } + }, + + /** + * When a number larger than zero is inputted, check the checkbox + */ + autoCheckboxForNumbers: function (elem) { + let checkboxid = elem.id.substring(0, elem.id.length - 1); + let value = elem.value; + //exception for second number field of max: only uncheck when first field is also empty + if (elem.id === 'maxm' && !(elem.value > 0)) { + value = parseInt(jQuery('input#maxn').val()); + } + jQuery('input#' + checkboxid).prop('checked', value > 0); + }, + + /** + * Insert the indexmenu with options to the textarea, + * replacing the current selection or at the cursor position. + */ + insertIndexmenu: function () { + let options = ''; + jQuery('fieldset.indexmenu_options input').each(function (i, input) { + let $label = jQuery(this).parent(); + + if (input.checked && (!$label.hasClass('jsitem') || jQuery('input#jstoggle').is(':checked'))) { + if (input.id === 'jstoggle') { + //add js options + options += ' js'; + //add theme + let themename = jQuery('#themebar button.selected').attr('id'); + if (indexmenu_wiz.defaulttheme !== themename) { //skip default theme + options += '#' + themename; + } + } else { + //add option + options += ' ' + input.id; + //add numbers + if ($label.hasClass('hasnumber')) { + jQuery.each(indexmenu_wiz.fields.div6.elems[input.id].numberinput, function (j, numid) { + let num = parseInt(jQuery('input#' + numid).val()); + options += num ? '#' + num : ''; + }); + } + } + } + + }); + options = options ? '|' + options.trim() : ''; + + let sel, ns, depth, syntax, eo; + + // XXX: Compatibility Fix for 2014-05-05 "Ponder Stibbons", splitbrain/dokuwiki#505 + if (DWgetSelection) { + sel = DWgetSelection(indexmenu_wiz.textArea); + } else { + sel = getSelection(indexmenu_wiz.textArea); + } + + + ns = jQuery('#namespace').val(); + depth = parseInt(jQuery('#nsdepth').val()); + depth = depth ? '#' + depth : ''; + + syntax = '{{indexmenu>' + ns + depth + options + '}}'; + eo = depth.length + options.length + 2; + + pasteText(sel, syntax, {startofs: 12, endofs: eo}); + indexmenu_wiz.hide(); + }, + + /** + * Insert meta number for sorting in textarea + * Takes number from input, otherwise tries the selection in textarea + */ + insertMetaNumber: function () { + let sel, selnum, syntax, number; + + // XXX: Compatibility Fix for 2014-05-05 "Ponder Stibbons", splitbrain/dokuwiki#505 + if (DWgetSelection) { + sel = DWgetSelection(indexmenu_wiz.textArea); + } else { + sel = getSelection(indexmenu_wiz.textArea); + } + + selnum = parseInt(sel.getText()); + number = parseInt(jQuery('input#metanumber').val()); + number = number || selnum || 1; + syntax = '{{indexmenu_n>' + number + '}}'; + + pasteText(sel, syntax, {startofs: 14, endofs: 2}); + indexmenu_wiz.hide(); + }, + + /** + * Show the indexmenu wizard + */ + show: function () { + // XXX: Compatibility Fix for 2014-05-05 "Ponder Stibbons", splitbrain/dokuwiki#505 + if (DWgetSelection) { + indexmenu_wiz.selection = DWgetSelection(indexmenu_wiz.textArea); + } else { + indexmenu_wiz.selection = getSelection(indexmenu_wiz.textArea); + } + + indexmenu_wiz.$wiz.show(); + jQuery('#namespace').trigger('focus'); + }, + + /** + * Hide the indexmenu wizard + */ + hide: function () { + indexmenu_wiz.$wiz.hide(); + indexmenu_wiz.textArea.focus(); //pure js + }, + + /** + * Toggle the indexmenu wizard + */ + toggle: function () { + if (indexmenu_wiz.$wiz.css('display') === 'none') { + indexmenu_wiz.show(); + } else { + indexmenu_wiz.hide(); + } + } +}; |