github.com/graybobo/golang.org-package-offline-cache@v0.0.0-20200626051047-6608995c132f/x/tools/godoc/static/jquery.treeview.js (about)

     1  /*
     2   * Treeview 1.4.1 - 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 5759 2008-07-01 07:50:28Z joern.zaefferer $
    14   *
    15   */
    16  
    17  ;(function($) {
    18  
    19  	// TODO rewrite as a widget, removing all the extra plugins
    20  	$.extend($.fn, {
    21  		swapClass: function(c1, c2) {
    22  			var c1Elements = this.filter('.' + c1);
    23  			this.filter('.' + c2).removeClass(c2).addClass(c1);
    24  			c1Elements.removeClass(c1).addClass(c2);
    25  			return this;
    26  		},
    27  		replaceClass: function(c1, c2) {
    28  			return this.filter('.' + c1).removeClass(c1).addClass(c2).end();
    29  		},
    30  		hoverClass: function(className) {
    31  			className = className || "hover";
    32  			return this.hover(function() {
    33  				$(this).addClass(className);
    34  			}, function() {
    35  				$(this).removeClass(className);
    36  			});
    37  		},
    38  		heightToggle: function(animated, callback) {
    39  			animated ?
    40  				this.animate({ height: "toggle" }, animated, callback) :
    41  				this.each(function(){
    42  					jQuery(this)[ jQuery(this).is(":hidden") ? "show" : "hide" ]();
    43  					if(callback)
    44  						callback.apply(this, arguments);
    45  				});
    46  		},
    47  		heightHide: function(animated, callback) {
    48  			if (animated) {
    49  				this.animate({ height: "hide" }, animated, callback);
    50  			} else {
    51  				this.hide();
    52  				if (callback)
    53  					this.each(callback);				
    54  			}
    55  		},
    56  		prepareBranches: function(settings) {
    57  			if (!settings.prerendered) {
    58  				// mark last tree items
    59  				this.filter(":last-child:not(ul)").addClass(CLASSES.last);
    60  				// collapse whole tree, or only those marked as closed, anyway except those marked as open
    61  				this.filter((settings.collapsed ? "" : "." + CLASSES.closed) + ":not(." + CLASSES.open + ")").find(">ul").hide();
    62  			}
    63  			// return all items with sublists
    64  			return this.filter(":has(>ul)");
    65  		},
    66  		applyClasses: function(settings, toggler) {
    67  			// TODO use event delegation
    68  			this.filter(":has(>ul):not(:has(>a))").find(">span").unbind("click.treeview").bind("click.treeview", function(event) {
    69  				// don't handle click events on children, eg. checkboxes
    70  				if ( this == event.target )
    71  					toggler.apply($(this).next());
    72  			}).add( $("a", this) ).hoverClass();
    73  			
    74  			if (!settings.prerendered) {
    75  				// handle closed ones first
    76  				this.filter(":has(>ul:hidden)")
    77  						.addClass(CLASSES.expandable)
    78  						.replaceClass(CLASSES.last, CLASSES.lastExpandable);
    79  						
    80  				// handle open ones
    81  				this.not(":has(>ul:hidden)")
    82  						.addClass(CLASSES.collapsable)
    83  						.replaceClass(CLASSES.last, CLASSES.lastCollapsable);
    84  						
    85  	            // create hitarea if not present
    86  				var hitarea = this.find("div." + CLASSES.hitarea);
    87  				if (!hitarea.length)
    88  					hitarea = this.prepend("<div class=\"" + CLASSES.hitarea + "\"/>").find("div." + CLASSES.hitarea);
    89  				hitarea.removeClass().addClass(CLASSES.hitarea).each(function() {
    90  					var classes = "";
    91  					$.each($(this).parent().attr("class").split(" "), function() {
    92  						classes += this + "-hitarea ";
    93  					});
    94  					$(this).addClass( classes );
    95  				})
    96  			}
    97  			
    98  			// apply event to hitarea
    99  			this.find("div." + CLASSES.hitarea).click( toggler );
   100  		},
   101  		treeview: function(settings) {
   102  			
   103  			settings = $.extend({
   104  				cookieId: "treeview"
   105  			}, settings);
   106  			
   107  			if ( settings.toggle ) {
   108  				var callback = settings.toggle;
   109  				settings.toggle = function() {
   110  					return callback.apply($(this).parent()[0], arguments);
   111  				};
   112  			}
   113  		
   114  			// factory for treecontroller
   115  			function treeController(tree, control) {
   116  				// factory for click handlers
   117  				function handler(filter) {
   118  					return function() {
   119  						// reuse toggle event handler, applying the elements to toggle
   120  						// start searching for all hitareas
   121  						toggler.apply( $("div." + CLASSES.hitarea, tree).filter(function() {
   122  							// for plain toggle, no filter is provided, otherwise we need to check the parent element
   123  							return filter ? $(this).parent("." + filter).length : true;
   124  						}) );
   125  						return false;
   126  					};
   127  				}
   128  				// click on first element to collapse tree
   129  				$("a:eq(0)", control).click( handler(CLASSES.collapsable) );
   130  				// click on second to expand tree
   131  				$("a:eq(1)", control).click( handler(CLASSES.expandable) );
   132  				// click on third to toggle tree
   133  				$("a:eq(2)", control).click( handler() ); 
   134  			}
   135  		
   136  			// handle toggle event
   137  			function toggler() {
   138  				$(this)
   139  					.parent()
   140  					// swap classes for hitarea
   141  					.find(">.hitarea")
   142  						.swapClass( CLASSES.collapsableHitarea, CLASSES.expandableHitarea )
   143  						.swapClass( CLASSES.lastCollapsableHitarea, CLASSES.lastExpandableHitarea )
   144  					.end()
   145  					// swap classes for parent li
   146  					.swapClass( CLASSES.collapsable, CLASSES.expandable )
   147  					.swapClass( CLASSES.lastCollapsable, CLASSES.lastExpandable )
   148  					// find child lists
   149  					.find( ">ul" )
   150  					// toggle them
   151  					.heightToggle( settings.animated, settings.toggle );
   152  				if ( settings.unique ) {
   153  					$(this).parent()
   154  						.siblings()
   155  						// swap classes for hitarea
   156  						.find(">.hitarea")
   157  							.replaceClass( CLASSES.collapsableHitarea, CLASSES.expandableHitarea )
   158  							.replaceClass( CLASSES.lastCollapsableHitarea, CLASSES.lastExpandableHitarea )
   159  						.end()
   160  						.replaceClass( CLASSES.collapsable, CLASSES.expandable )
   161  						.replaceClass( CLASSES.lastCollapsable, CLASSES.lastExpandable )
   162  						.find( ">ul" )
   163  						.heightHide( settings.animated, settings.toggle );
   164  				}
   165  			}
   166  			this.data("toggler", toggler);
   167  			
   168  			function serialize() {
   169  				function binary(arg) {
   170  					return arg ? 1 : 0;
   171  				}
   172  				var data = [];
   173  				branches.each(function(i, e) {
   174  					data[i] = $(e).is(":has(>ul:visible)") ? 1 : 0;
   175  				});
   176  				$.cookie(settings.cookieId, data.join(""), settings.cookieOptions );
   177  			}
   178  			
   179  			function deserialize() {
   180  				var stored = $.cookie(settings.cookieId);
   181  				if ( stored ) {
   182  					var data = stored.split("");
   183  					branches.each(function(i, e) {
   184  						$(e).find(">ul")[ parseInt(data[i]) ? "show" : "hide" ]();
   185  					});
   186  				}
   187  			}
   188  			
   189  			// add treeview class to activate styles
   190  			this.addClass("treeview");
   191  			
   192  			// prepare branches and find all tree items with child lists
   193  			var branches = this.find("li").prepareBranches(settings);
   194  			
   195  			switch(settings.persist) {
   196  			case "cookie":
   197  				var toggleCallback = settings.toggle;
   198  				settings.toggle = function() {
   199  					serialize();
   200  					if (toggleCallback) {
   201  						toggleCallback.apply(this, arguments);
   202  					}
   203  				};
   204  				deserialize();
   205  				break;
   206  			case "location":
   207  				var current = this.find("a").filter(function() {
   208  					return this.href.toLowerCase() == location.href.toLowerCase();
   209  				});
   210  				if ( current.length ) {
   211  					// TODO update the open/closed classes
   212  					var items = current.addClass("selected").parents("ul, li").add( current.next() ).show();
   213  					if (settings.prerendered) {
   214  						// if prerendered is on, replicate the basic class swapping
   215  						items.filter("li")
   216  							.swapClass( CLASSES.collapsable, CLASSES.expandable )
   217  							.swapClass( CLASSES.lastCollapsable, CLASSES.lastExpandable )
   218  							.find(">.hitarea")
   219  								.swapClass( CLASSES.collapsableHitarea, CLASSES.expandableHitarea )
   220  								.swapClass( CLASSES.lastCollapsableHitarea, CLASSES.lastExpandableHitarea );
   221  					}
   222  				}
   223  				break;
   224  			}
   225  			
   226  			branches.applyClasses(settings, toggler);
   227  				
   228  			// if control option is set, create the treecontroller and show it
   229  			if ( settings.control ) {
   230  				treeController(this, settings.control);
   231  				$(settings.control).show();
   232  			}
   233  			
   234  			return this;
   235  		}
   236  	});
   237  	
   238  	// classes used by the plugin
   239  	// need to be styled via external stylesheet, see first example
   240  	$.treeview = {};
   241  	var CLASSES = ($.treeview.classes = {
   242  		open: "open",
   243  		closed: "closed",
   244  		expandable: "expandable",
   245  		expandableHitarea: "expandable-hitarea",
   246  		lastExpandableHitarea: "lastExpandable-hitarea",
   247  		collapsable: "collapsable",
   248  		collapsableHitarea: "collapsable-hitarea",
   249  		lastCollapsableHitarea: "lastCollapsable-hitarea",
   250  		lastCollapsable: "lastCollapsable",
   251  		lastExpandable: "lastExpandable",
   252  		last: "last",
   253  		hitarea: "hitarea"
   254  	});
   255  	
   256  })(jQuery);