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.