You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

258 lines
7.6 KiB

  1. /*!
  2. * jquery.fancytree.wide.js
  3. * Support for 100% wide selection bars.
  4. * (Extension module for jquery.fancytree.js: https://github.com/mar10/fancytree/)
  5. *
  6. * Copyright (c) 2008-2023, Martin Wendt (https://wwWendt.de)
  7. *
  8. * Released under the MIT license
  9. * https://github.com/mar10/fancytree/wiki/LicenseInfo
  10. *
  11. * @version 2.38.3
  12. * @date 2023-02-01T20:52:50Z
  13. */
  14. (function (factory) {
  15. if (typeof define === "function" && define.amd) {
  16. // AMD. Register as an anonymous module.
  17. define(["jquery", "./jquery.fancytree"], factory);
  18. } else if (typeof module === "object" && module.exports) {
  19. // Node/CommonJS
  20. require("./jquery.fancytree");
  21. module.exports = factory(require("jquery"));
  22. } else {
  23. // Browser globals
  24. factory(jQuery);
  25. }
  26. })(function ($) {
  27. "use strict";
  28. var reNumUnit = /^([+-]?(?:\d+|\d*\.\d+))([a-z]*|%)$/; // split "1.5em" to ["1.5", "em"]
  29. /*******************************************************************************
  30. * Private functions and variables
  31. */
  32. // var _assert = $.ui.fancytree.assert;
  33. /* Calculate inner width without scrollbar */
  34. // function realInnerWidth($el) {
  35. // // http://blog.jquery.com/2012/08/16/jquery-1-8-box-sizing-width-csswidth-and-outerwidth/
  36. // // inst.contWidth = parseFloat(this.$container.css("width"), 10);
  37. // // 'Client width without scrollbar' - 'padding'
  38. // return $el[0].clientWidth - ($el.innerWidth() - parseFloat($el.css("width"), 10));
  39. // }
  40. /* Create a global embedded CSS style for the tree. */
  41. function defineHeadStyleElement(id, cssText) {
  42. id = "fancytree-style-" + id;
  43. var $headStyle = $("#" + id);
  44. if (!cssText) {
  45. $headStyle.remove();
  46. return null;
  47. }
  48. if (!$headStyle.length) {
  49. $headStyle = $("<style />")
  50. .attr("id", id)
  51. .addClass("fancytree-style")
  52. .prop("type", "text/css")
  53. .appendTo("head");
  54. }
  55. try {
  56. $headStyle.html(cssText);
  57. } catch (e) {
  58. // fix for IE 6-8
  59. $headStyle[0].styleSheet.cssText = cssText;
  60. }
  61. return $headStyle;
  62. }
  63. /* Calculate the CSS rules that indent title spans. */
  64. function renderLevelCss(
  65. containerId,
  66. depth,
  67. levelOfs,
  68. lineOfs,
  69. labelOfs,
  70. measureUnit
  71. ) {
  72. var i,
  73. prefix = "#" + containerId + " span.fancytree-level-",
  74. rules = [];
  75. for (i = 0; i < depth; i++) {
  76. rules.push(
  77. prefix +
  78. (i + 1) +
  79. " span.fancytree-title { padding-left: " +
  80. (i * levelOfs + lineOfs) +
  81. measureUnit +
  82. "; }"
  83. );
  84. }
  85. // Some UI animations wrap the UL inside a DIV and set position:relative on both.
  86. // This breaks the left:0 and padding-left:nn settings of the title
  87. rules.push(
  88. "#" +
  89. containerId +
  90. " div.ui-effects-wrapper ul li span.fancytree-title, " +
  91. "#" +
  92. containerId +
  93. " li.fancytree-animating span.fancytree-title " + // #716
  94. "{ padding-left: " +
  95. labelOfs +
  96. measureUnit +
  97. "; position: static; width: auto; }"
  98. );
  99. return rules.join("\n");
  100. }
  101. // /**
  102. // * [ext-wide] Recalculate the width of the selection bar after the tree container
  103. // * was resized.<br>
  104. // * May be called explicitly on container resize, since there is no resize event
  105. // * for DIV tags.
  106. // *
  107. // * @alias Fancytree#wideUpdate
  108. // * @requires jquery.fancytree.wide.js
  109. // */
  110. // $.ui.fancytree._FancytreeClass.prototype.wideUpdate = function(){
  111. // var inst = this.ext.wide,
  112. // prevCw = inst.contWidth,
  113. // prevLo = inst.lineOfs;
  114. // inst.contWidth = realInnerWidth(this.$container);
  115. // // Each title is precceeded by 2 or 3 icons (16px + 3 margin)
  116. // // + 1px title border and 3px title padding
  117. // // TODO: use code from treeInit() below
  118. // inst.lineOfs = (this.options.checkbox ? 3 : 2) * 19;
  119. // if( prevCw !== inst.contWidth || prevLo !== inst.lineOfs ) {
  120. // this.debug("wideUpdate: " + inst.contWidth);
  121. // this.visit(function(node){
  122. // node.tree._callHook("nodeRenderTitle", node);
  123. // });
  124. // }
  125. // };
  126. /*******************************************************************************
  127. * Extension code
  128. */
  129. $.ui.fancytree.registerExtension({
  130. name: "wide",
  131. version: "2.38.3",
  132. // Default options for this extension.
  133. options: {
  134. iconWidth: null, // Adjust this if @fancy-icon-width != "16px"
  135. iconSpacing: null, // Adjust this if @fancy-icon-spacing != "3px"
  136. labelSpacing: null, // Adjust this if padding between icon and label != "3px"
  137. levelOfs: null, // Adjust this if ul padding != "16px"
  138. },
  139. treeCreate: function (ctx) {
  140. this._superApply(arguments);
  141. this.$container.addClass("fancytree-ext-wide");
  142. var containerId,
  143. cssText,
  144. iconSpacingUnit,
  145. labelSpacingUnit,
  146. iconWidthUnit,
  147. levelOfsUnit,
  148. instOpts = ctx.options.wide,
  149. // css sniffing
  150. $dummyLI = $(
  151. "<li id='fancytreeTemp'><span class='fancytree-node'><span class='fancytree-icon' /><span class='fancytree-title' /></span><ul />"
  152. ).appendTo(ctx.tree.$container),
  153. $dummyIcon = $dummyLI.find(".fancytree-icon"),
  154. $dummyUL = $dummyLI.find("ul"),
  155. // $dummyTitle = $dummyLI.find(".fancytree-title"),
  156. iconSpacing =
  157. instOpts.iconSpacing || $dummyIcon.css("margin-left"),
  158. iconWidth = instOpts.iconWidth || $dummyIcon.css("width"),
  159. labelSpacing = instOpts.labelSpacing || "3px",
  160. levelOfs = instOpts.levelOfs || $dummyUL.css("padding-left");
  161. $dummyLI.remove();
  162. iconSpacingUnit = iconSpacing.match(reNumUnit)[2];
  163. iconSpacing = parseFloat(iconSpacing, 10);
  164. labelSpacingUnit = labelSpacing.match(reNumUnit)[2];
  165. labelSpacing = parseFloat(labelSpacing, 10);
  166. iconWidthUnit = iconWidth.match(reNumUnit)[2];
  167. iconWidth = parseFloat(iconWidth, 10);
  168. levelOfsUnit = levelOfs.match(reNumUnit)[2];
  169. if (
  170. iconSpacingUnit !== iconWidthUnit ||
  171. levelOfsUnit !== iconWidthUnit ||
  172. labelSpacingUnit !== iconWidthUnit
  173. ) {
  174. $.error(
  175. "iconWidth, iconSpacing, and levelOfs must have the same css measure unit"
  176. );
  177. }
  178. this._local.measureUnit = iconWidthUnit;
  179. this._local.levelOfs = parseFloat(levelOfs);
  180. this._local.lineOfs =
  181. (1 +
  182. (ctx.options.checkbox ? 1 : 0) +
  183. (ctx.options.icon === false ? 0 : 1)) *
  184. (iconWidth + iconSpacing) +
  185. iconSpacing;
  186. this._local.labelOfs = labelSpacing;
  187. this._local.maxDepth = 10;
  188. // Get/Set a unique Id on the container (if not already exists)
  189. containerId = this.$container.uniqueId().attr("id");
  190. // Generated css rules for some levels (extended on demand)
  191. cssText = renderLevelCss(
  192. containerId,
  193. this._local.maxDepth,
  194. this._local.levelOfs,
  195. this._local.lineOfs,
  196. this._local.labelOfs,
  197. this._local.measureUnit
  198. );
  199. defineHeadStyleElement(containerId, cssText);
  200. },
  201. treeDestroy: function (ctx) {
  202. // Remove generated css rules
  203. defineHeadStyleElement(this.$container.attr("id"), null);
  204. return this._superApply(arguments);
  205. },
  206. nodeRenderStatus: function (ctx) {
  207. var containerId,
  208. cssText,
  209. res,
  210. node = ctx.node,
  211. level = node.getLevel();
  212. res = this._super(ctx);
  213. // Generate some more level-n rules if required
  214. if (level > this._local.maxDepth) {
  215. containerId = this.$container.attr("id");
  216. this._local.maxDepth *= 2;
  217. node.debug(
  218. "Define global ext-wide css up to level " +
  219. this._local.maxDepth
  220. );
  221. cssText = renderLevelCss(
  222. containerId,
  223. this._local.maxDepth,
  224. this._local.levelOfs,
  225. this._local.lineOfs,
  226. this._local.labelSpacing,
  227. this._local.measureUnit
  228. );
  229. defineHeadStyleElement(containerId, cssText);
  230. }
  231. // Add level-n class to apply indentation padding.
  232. // (Setting element style would not work, since it cannot easily be
  233. // overriden while animations run)
  234. $(node.span).addClass("fancytree-level-" + level);
  235. return res;
  236. },
  237. });
  238. // Value returned by `require('jquery.fancytree..')`
  239. return $.ui.fancytree;
  240. }); // End of closure