1/*! 2 * jquery.fancytree.glyph.js 3 * 4 * Use glyph-fonts, ligature-fonts, or SVG icons instead of icon sprites. 5 * (Extension module for jquery.fancytree.js: https://github.com/mar10/fancytree/) 6 * 7 * Copyright (c) 2008-2023, Martin Wendt (https://wwWendt.de) 8 * 9 * Released under the MIT license 10 * https://github.com/mar10/fancytree/wiki/LicenseInfo 11 * 12 * @version 2.38.3 13 * @date 2023-02-01T20:52:50Z 14 */ 15 16(function (factory) { 17 if (typeof define === "function" && define.amd) { 18 // AMD. Register as an anonymous module. 19 define(["jquery", "./jquery.fancytree"], factory); 20 } else if (typeof module === "object" && module.exports) { 21 // Node/CommonJS 22 require("./jquery.fancytree"); 23 module.exports = factory(require("jquery")); 24 } else { 25 // Browser globals 26 factory(jQuery); 27 } 28})(function ($) { 29 "use strict"; 30 31 /****************************************************************************** 32 * Private functions and variables 33 */ 34 35 var FT = $.ui.fancytree, 36 PRESETS = { 37 awesome3: { 38 // Outdated! 39 _addClass: "", 40 checkbox: "icon-check-empty", 41 checkboxSelected: "icon-check", 42 checkboxUnknown: "icon-check icon-muted", 43 dragHelper: "icon-caret-right", 44 dropMarker: "icon-caret-right", 45 error: "icon-exclamation-sign", 46 expanderClosed: "icon-caret-right", 47 expanderLazy: "icon-angle-right", 48 expanderOpen: "icon-caret-down", 49 loading: "icon-refresh icon-spin", 50 nodata: "icon-meh", 51 noExpander: "", 52 radio: "icon-circle-blank", 53 radioSelected: "icon-circle", 54 // radioUnknown: "icon-circle icon-muted", 55 // Default node icons. 56 // (Use tree.options.icon callback to define custom icons based on node data) 57 doc: "icon-file-alt", 58 docOpen: "icon-file-alt", 59 folder: "icon-folder-close-alt", 60 folderOpen: "icon-folder-open-alt", 61 }, 62 awesome4: { 63 _addClass: "fa", 64 checkbox: "fa-square-o", 65 checkboxSelected: "fa-check-square-o", 66 checkboxUnknown: "fa-square fancytree-helper-indeterminate-cb", 67 dragHelper: "fa-arrow-right", 68 dropMarker: "fa-long-arrow-right", 69 error: "fa-warning", 70 expanderClosed: "fa-caret-right", 71 expanderLazy: "fa-angle-right", 72 expanderOpen: "fa-caret-down", 73 // We may prevent wobbling rotations on FF by creating a separate sub element: 74 loading: { html: "<span class='fa fa-spinner fa-pulse' />" }, 75 nodata: "fa-meh-o", 76 noExpander: "", 77 radio: "fa-circle-thin", // "fa-circle-o" 78 radioSelected: "fa-circle", 79 // radioUnknown: "fa-dot-circle-o", 80 // Default node icons. 81 // (Use tree.options.icon callback to define custom icons based on node data) 82 doc: "fa-file-o", 83 docOpen: "fa-file-o", 84 folder: "fa-folder-o", 85 folderOpen: "fa-folder-open-o", 86 }, 87 awesome5: { 88 // fontawesome 5 have several different base classes 89 // "far, fas, fal and fab" The rendered svg puts that prefix 90 // in a different location so we have to keep them separate here 91 _addClass: "", 92 checkbox: "far fa-square", 93 checkboxSelected: "far fa-check-square", 94 // checkboxUnknown: "far fa-window-close", 95 checkboxUnknown: 96 "fas fa-square fancytree-helper-indeterminate-cb", 97 radio: "far fa-circle", 98 radioSelected: "fas fa-circle", 99 radioUnknown: "far fa-dot-circle", 100 dragHelper: "fas fa-arrow-right", 101 dropMarker: "fas fa-long-arrow-alt-right", 102 error: "fas fa-exclamation-triangle", 103 expanderClosed: "fas fa-caret-right", 104 expanderLazy: "fas fa-angle-right", 105 expanderOpen: "fas fa-caret-down", 106 loading: "fas fa-spinner fa-pulse", 107 nodata: "far fa-meh", 108 noExpander: "", 109 // Default node icons. 110 // (Use tree.options.icon callback to define custom icons based on node data) 111 doc: "far fa-file", 112 docOpen: "far fa-file", 113 folder: "far fa-folder", 114 folderOpen: "far fa-folder-open", 115 }, 116 bootstrap3: { 117 _addClass: "glyphicon", 118 checkbox: "glyphicon-unchecked", 119 checkboxSelected: "glyphicon-check", 120 checkboxUnknown: 121 "glyphicon-expand fancytree-helper-indeterminate-cb", // "glyphicon-share", 122 dragHelper: "glyphicon-play", 123 dropMarker: "glyphicon-arrow-right", 124 error: "glyphicon-warning-sign", 125 expanderClosed: "glyphicon-menu-right", // glyphicon-plus-sign 126 expanderLazy: "glyphicon-menu-right", // glyphicon-plus-sign 127 expanderOpen: "glyphicon-menu-down", // glyphicon-minus-sign 128 loading: "glyphicon-refresh fancytree-helper-spin", 129 nodata: "glyphicon-info-sign", 130 noExpander: "", 131 radio: "glyphicon-remove-circle", // "glyphicon-unchecked", 132 radioSelected: "glyphicon-ok-circle", // "glyphicon-check", 133 // radioUnknown: "glyphicon-ban-circle", 134 // Default node icons. 135 // (Use tree.options.icon callback to define custom icons based on node data) 136 doc: "glyphicon-file", 137 docOpen: "glyphicon-file", 138 folder: "glyphicon-folder-close", 139 folderOpen: "glyphicon-folder-open", 140 }, 141 material: { 142 _addClass: "material-icons", 143 checkbox: { text: "check_box_outline_blank" }, 144 checkboxSelected: { text: "check_box" }, 145 checkboxUnknown: { text: "indeterminate_check_box" }, 146 dragHelper: { text: "play_arrow" }, 147 dropMarker: { text: "arrow-forward" }, 148 error: { text: "warning" }, 149 expanderClosed: { text: "chevron_right" }, 150 expanderLazy: { text: "last_page" }, 151 expanderOpen: { text: "expand_more" }, 152 loading: { 153 text: "autorenew", 154 addClass: "fancytree-helper-spin", 155 }, 156 nodata: { text: "info" }, 157 noExpander: { text: "" }, 158 radio: { text: "radio_button_unchecked" }, 159 radioSelected: { text: "radio_button_checked" }, 160 // Default node icons. 161 // (Use tree.options.icon callback to define custom icons based on node data) 162 doc: { text: "insert_drive_file" }, 163 docOpen: { text: "insert_drive_file" }, 164 folder: { text: "folder" }, 165 folderOpen: { text: "folder_open" }, 166 }, 167 }; 168 169 function setIcon(node, span, baseClass, opts, type) { 170 var map = opts.map, 171 icon = map[type], 172 $span = $(span), 173 $counter = $span.find(".fancytree-childcounter"), 174 setClass = baseClass + " " + (map._addClass || ""); 175 176 // #871 Allow a callback 177 if (typeof icon === "function") { 178 icon = icon.call(this, node, span, type); 179 } 180 // node.debug( "setIcon(" + baseClass + ", " + type + "): " + "oldIcon" + " -> " + icon ); 181 // #871: propsed this, but I am not sure how robust this is, e.g. 182 // the prefix (fas, far) class changes are not considered? 183 // if (span.tagName === "svg" && opts.preset === "awesome5") { 184 // // fa5 script converts <i> to <svg> so call a specific handler. 185 // var oldIcon = "fa-" + $span.data("icon"); 186 // // node.debug( "setIcon(" + baseClass + ", " + type + "): " + oldIcon + " -> " + icon ); 187 // if (typeof oldIcon === "string") { 188 // $span.removeClass(oldIcon); 189 // } 190 // if (typeof icon === "string") { 191 // $span.addClass(icon); 192 // } 193 // return; 194 // } 195 if (typeof icon === "string") { 196 // #883: remove inner html that may be added by prev. mode 197 span.innerHTML = ""; 198 $span.attr("class", setClass + " " + icon).append($counter); 199 } else if (icon) { 200 if (icon.text) { 201 span.textContent = "" + icon.text; 202 } else if (icon.html) { 203 span.innerHTML = icon.html; 204 } else { 205 span.innerHTML = ""; 206 } 207 $span 208 .attr("class", setClass + " " + (icon.addClass || "")) 209 .append($counter); 210 } 211 } 212 213 $.ui.fancytree.registerExtension({ 214 name: "glyph", 215 version: "2.38.3", 216 // Default options for this extension. 217 options: { 218 preset: null, // 'awesome3', 'awesome4', 'bootstrap3', 'material' 219 map: {}, 220 }, 221 222 treeInit: function (ctx) { 223 var tree = ctx.tree, 224 opts = ctx.options.glyph; 225 226 if (opts.preset) { 227 FT.assert( 228 !!PRESETS[opts.preset], 229 "Invalid value for `options.glyph.preset`: " + opts.preset 230 ); 231 opts.map = $.extend({}, PRESETS[opts.preset], opts.map); 232 } else { 233 tree.warn("ext-glyph: missing `preset` option."); 234 } 235 this._superApply(arguments); 236 tree.$container.addClass("fancytree-ext-glyph"); 237 }, 238 nodeRenderStatus: function (ctx) { 239 var checkbox, 240 icon, 241 res, 242 span, 243 node = ctx.node, 244 $span = $(node.span), 245 opts = ctx.options.glyph; 246 247 res = this._super(ctx); 248 249 if (node.isRootNode()) { 250 return res; 251 } 252 span = $span.children(".fancytree-expander").get(0); 253 if (span) { 254 // if( node.isLoading() ){ 255 // icon = "loading"; 256 if (node.expanded && node.hasChildren()) { 257 icon = "expanderOpen"; 258 } else if (node.isUndefined()) { 259 icon = "expanderLazy"; 260 } else if (node.hasChildren()) { 261 icon = "expanderClosed"; 262 } else { 263 icon = "noExpander"; 264 } 265 // span.className = "fancytree-expander " + map[icon]; 266 setIcon(node, span, "fancytree-expander", opts, icon); 267 } 268 269 if (node.tr) { 270 span = $("td", node.tr).find(".fancytree-checkbox").get(0); 271 } else { 272 span = $span.children(".fancytree-checkbox").get(0); 273 } 274 if (span) { 275 checkbox = FT.evalOption("checkbox", node, node, opts, false); 276 if ( 277 (node.parent && node.parent.radiogroup) || 278 checkbox === "radio" 279 ) { 280 icon = node.selected ? "radioSelected" : "radio"; 281 setIcon( 282 node, 283 span, 284 "fancytree-checkbox fancytree-radio", 285 opts, 286 icon 287 ); 288 } else { 289 // eslint-disable-next-line no-nested-ternary 290 icon = node.selected 291 ? "checkboxSelected" 292 : node.partsel 293 ? "checkboxUnknown" 294 : "checkbox"; 295 // span.className = "fancytree-checkbox " + map[icon]; 296 setIcon(node, span, "fancytree-checkbox", opts, icon); 297 } 298 } 299 300 // Standard icon (note that this does not match .fancytree-custom-icon, 301 // that might be set by opts.icon callbacks) 302 span = $span.children(".fancytree-icon").get(0); 303 if (span) { 304 if (node.statusNodeType) { 305 icon = node.statusNodeType; // loading, error 306 } else if (node.folder) { 307 icon = 308 node.expanded && node.hasChildren() 309 ? "folderOpen" 310 : "folder"; 311 } else { 312 icon = node.expanded ? "docOpen" : "doc"; 313 } 314 setIcon(node, span, "fancytree-icon", opts, icon); 315 } 316 return res; 317 }, 318 nodeSetStatus: function (ctx, status, message, details) { 319 var res, 320 span, 321 opts = ctx.options.glyph, 322 node = ctx.node; 323 324 res = this._superApply(arguments); 325 326 if ( 327 status === "error" || 328 status === "loading" || 329 status === "nodata" 330 ) { 331 if (node.parent) { 332 span = $(".fancytree-expander", node.span).get(0); 333 if (span) { 334 setIcon(node, span, "fancytree-expander", opts, status); 335 } 336 } else { 337 // 338 span = $( 339 ".fancytree-statusnode-" + status, 340 node[this.nodeContainerAttrName] 341 ) 342 .find(".fancytree-icon") 343 .get(0); 344 if (span) { 345 setIcon(node, span, "fancytree-icon", opts, status); 346 } 347 } 348 } 349 return res; 350 }, 351 }); 352 // Value returned by `require('jquery.fancytree..')` 353 return $.ui.fancytree; 354}); // End of closure 355