1/* 2* Treeview 1.4 - jQuery plugin to hide and show branches of a tree 3* 4* http://bassistance.de/jquery-plugins/jquery-plugin-treeview/ 5* http://docs.jquery.com/Plugins/Treeview 6* 7* Copyright (c) 2007 Jörn Zaefferer 8* 9* Dual licensed under the MIT and GPL licenses: 10* http://www.opensource.org/licenses/mit-license.php 11* http://www.gnu.org/licenses/gpl.html 12* 13* Revision: $Id: jquery.treeview.js 4684 2008-02-07 19:08:06Z joern.zaefferer $ 14* 15*/ 16 17; (function ($) { 18 19 $.extend($.fn, { 20 swapClass: function (c1, c2) { 21 var c1Elements = this.filter('.' + c1); 22 this.filter('.' + c2).removeClass(c2).addClass(c1); 23 c1Elements.removeClass(c1).addClass(c2); 24 return this; 25 }, 26 replaceClass: function (c1, c2) { 27 return this.filter('.' + c1).removeClass(c1).addClass(c2).end(); 28 }, 29 hoverClass: function (className) { 30 className = className || "hover"; 31 return this.hover(function () { 32 $(this).addClass(className); 33 }, function () { 34 $(this).removeClass(className); 35 }); 36 }, 37 heightToggle: function (animated, callback) { 38 animated ? 39 this.animate({ height: "toggle" }, animated, callback) : 40 this.each(function () { 41 jQuery(this)[jQuery(this).is(":hidden") ? "show" : "hide"](); 42 if (callback) 43 callback.apply(this, arguments); 44 }); 45 }, 46 heightHide: function (animated, callback) { 47 if (animated) { 48 this.animate({ height: "hide" }, animated, callback); 49 } else { 50 this.hide(); 51 if (callback) 52 this.each(callback); 53 } 54 }, 55 prepareBranches: function (settings) { 56 if (!settings.prerendered) { 57 // mark last tree items 58 this.filter(":last-child:not(ul)").addClass(CLASSES.last); 59 // collapse whole tree, or only those marked as closed, anyway except those marked as open 60 this.filter((settings.collapsed ? "" : "." + CLASSES.closed) + ":not(." + CLASSES.open + ")").find(">ul").hide(); 61 } 62 // return all items with sublists 63 return this.filter(":has(>ul)"); 64 }, 65 applyClasses: function (settings, toggler) { 66 this.filter(":has(>ul):not(:has(>a))").find(">span").click(function (event) { 67 toggler.apply($(this).next()); 68 }).add($("a", this)).hoverClass(); 69 70 if (!settings.prerendered) { 71 // handle closed ones first 72 this.filter(":has(>ul:hidden)") 73 .addClass(CLASSES.expandable) 74 .replaceClass(CLASSES.last, CLASSES.lastExpandable); 75 76 // handle open ones 77 this.not(":has(>ul:hidden)") 78 .addClass(CLASSES.collapsable) 79 .replaceClass(CLASSES.last, CLASSES.lastCollapsable); 80 81 // create hitarea 82 this.prepend("<div class=\"" + CLASSES.hitarea + "\"/>").find("div." + CLASSES.hitarea).each(function () { 83 var classes = ""; 84 $.each($(this).parent().attr("class").split(" "), function () { 85 classes += this + "-hitarea "; 86 });
87 $(this).addClass(classes); 88 }); 89 } 90 91 // apply event to hitarea 92 this.find("div." + CLASSES.hitarea).click(toggler); 93 }, 94 treeview: function (settings) { 95 96 settings = $.extend({ 97 cookieId: "treeview" 98 }, settings); 99 100 if (settings.add) { 101 return this.trigger("add", [settings.add]); 102 } 103 104 if (settings.toggle) { 105 var callback = settings.toggle; 106 settings.toggle = function () { 107 return callback.apply($(this).parent()[0], arguments); 108 }; 109 } 110 111 // factory for treecontroller 112 function treeController(tree, control) { 113 // factory for click handlers 114 function handler(filter) { 115 return function () { 116 // reuse toggle event handler, applying the elements to toggle 117 // start searching for all hitareas 118 toggler.apply($("div." + CLASSES.hitarea, tree).filter(function () { 119 // for plain toggle, no filter is provided, otherwise we need to check the parent element 120 return filter ? $(this).parent("." + filter).length : true; 121 })); 122 return false; 123 }; 124 } 125 // click on first element to collapse tree 126 $("a:eq(0)", control).click(handler(CLASSES.collapsable)); 127 // click on second to expand tree 128 $("a:eq(1)", control).click(handler(CLASSES.expandable)); 129 // click on third to toggle tree 130 $("a:eq(2)", control).click(handler()); 131 } 132 133 // handle toggle event 134 function toggler() { 135 $(this) 136 .parent() 137 // swap classes for hitarea 138 .find(">.hitarea") 139 .swapClass(CLASSES.collapsableHitarea, CLASSES.expandableHitarea) 140 .swapClass(CLASSES.lastCollapsableHitarea, CLASSES.lastExpandableHitarea) 141 .end() 142 // swap classes for parent li 143 .swapClass(CLASSES.collapsable, CLASSES.expandable) 144 .swapClass(CLASSES.lastCollapsable, CLASSES.lastExpandable) 145 // find child lists 146 .find(">ul") 147 // toggle them 148 .heightToggle(settings.animated, settings.toggle); 149 if (settings.unique) { 150 $(this).parent() 151 .siblings() 152 // swap classes for hitarea 153 .find(">.hitarea") 154 .replaceClass(CLASSES.collapsableHitarea, CLASSES.expandableHitarea) 155 .replaceClass(CLASSES.lastCollapsableHitarea, CLASSES.lastExpandableHitarea) 156 .end() 157 .replaceClass(CLASSES.collapsable, CLASSES.expandable) 158 .replaceClass(CLASSES.lastCollapsable, CLASSES.lastExpandable) 159 .find(">ul") 160 .heightHide(settings.animated, settings.toggle); 161 } 162 } 163 164 function serialize() { 165 function binary(arg) { 166 return arg ? 1 : 0; 167 } 168 var data = []; 169 branches.each(function (i, e) { 170 data[i] = $(e).is(":has(>ul:visible)") ? 1 : 0; 171 }); 172 $.cookie(settings.cookieId, data.join("")); 173 } 174 175 function deserialize() { 176 var stored = $.cookie(settings.cookieId); 177 if (stored) { 178 var data = stored.split(""); 179 branches.each(function (i, e) { 180 $(e).find(">ul")[parseInt(data[i]) ? "show" : "hide"](); 181 }); 182 } 183 } 184 185 // add treeview class to activate styles 186 this.addClass("treeview"); 187 188 // prepare branches and find all tree items with child lists 189 var branches = this.find("li").prepareBranches(settings); 190 191 switch (settings.persist) { 192 case "cookie": 193 var toggleCallback = settings.toggle; 194 settings.toggle = function () { 195 serialize(); 196 if (toggleCallback) { 197 toggleCallback.apply(this, arguments); 198 } 199 }; 200 deserialize(); 201 break; 202 case "location": 203 var current = this.find("a").filter(function () { return this.href.toLowerCase() == location.href.toLowerCase(); }); 204 if (current.length) { 205 current.addClass("selected").parents("ul, li").add(current.next()).show(); 206 } 207 break; 208 } 209 210 branches.applyClasses(settings, toggler); 211 212 // if control option is set, create the treecontroller and show it 213 if (settings.control) { 214 treeController(this, settings.control); 215 $(settings.control).show(); 216 } 217 218 return this.bind("add", function (event, branches) { 219 $(branches).prev() 220 .removeClass(CLASSES.last) 221 .removeClass(CLASSES.lastCollapsable) 222 .removeClass(CLASSES.lastExpandable) 223 .find(">.hitarea") 224 .removeClass(CLASSES.lastCollapsableHitarea) 225 .removeClass(CLASSES.lastExpandableHitarea); 226 $(branches).find("li").andSelf().prepareBranches(settings).applyClasses(settings, toggler); 227 }); 228 } 229 });
230 231 // classes used by the plugin 232 // need to be styled via external stylesheet, see first example 233 var CLASSES = $.fn.treeview.classes = { 234 open: "open", 235 closed: "closed", 236 expandable: "expandable", 237 expandableHitarea: "expandable-hitarea", 238 lastExpandableHitarea: "lastExpandable-hitarea", 239 collapsable: "collapsable", 240 collapsableHitarea: "collapsable-hitarea", 241 lastCollapsableHitarea: "lastCollapsable-hitarea", 242 lastCollapsable: "lastCollapsable", 243 lastExpandable: "lastExpandable", 244 last: "last", 245 hitarea: "hitarea" 246 }; 247 248 // provide backwards compability 249 $.fn.Treeview = $.fn.treeview; 250 251})(jQuery);
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.