PageSourceSearch

https://zamboni.com/wp-content/themes/zamboni/js/autocolumn.js

js zamboni.com collected 2026-10-02 04:01:37 UTC 13,109 bytes, 405 lines download raw bytes

1// version 1.4.0
2// http://welcome.totheinter.net/columnizer-jquery-plugin/
3// created by: Adam Wulf [email protected]
4
5(function($){
6
7 $.fn.columnize = function(options) {
8
9
10	var defaults = {
11		// default width of columnx
12		width: 400,
13		// optional # of columns instead of width
14		columns : false,
15		// true to build columns once regardless of window resize
16		// false to rebuild when content box changes bounds
17		buildOnce : false,
18		// an object with options if the text should overflow
19		// it's container if it can't fit within a specified height
20		overflow : false,
21		// this function is called after content is columnized
22		doneFunc : function(){},
23		// if the content should be columnized into a 
24		// container node other than it's own node
25		target : false,
26		// re-columnizing when images reload might make things
27		// run slow. so flip this to true if it's causing delays
28		ignoreImageLoading : true,
29		// should columns float left or right
30		float : "left",
31		// ensure the last column is never the tallest column
32		lastNeverTallest : false
33	};
34	var options = $.extend(defaults, options);
35
36    return this.each(function() {
37	    var $inBox = options.target ? $(options.target) : $(this);
38		var maxHeight = $(this).height();
39		var $cache = $('<div></div>'); // this is where we'll put the real content
40		var lastWidth = 0;
41		var columnizing = false;
42		$cache.append($(this).children().clone(true));
43	    
44	    // images loading after dom load
45	    // can screw up the column heights,
46	    // so recolumnize after images load
47	    if(!options.ignoreImageLoading && !options.target){
48	    	if(!$inBox.data("imageLoaded")){
49		    	$inBox.data("imageLoaded", true);
50		    	if($(this).find("img").length > 0){
51		    		// only bother if there are
52		    		// actually images...
53			    	var func = function($inBox,$cache){ return function(){
54				    	if(!$inBox.data("firstImageLoaded")){
55				    		$inBox.data("firstImageLoaded", "true");
56					    	$inBox.empty().append($cache.children().clone(true));
57					    	$inBox.columnize(options);
58				    	}
59			    	}}($(this), $cache);
60				    $(this).find("img").one("load", func);
61				    $(this).find("img").one("abort", func);
62				    return;
63		    	}
64	    	}
65	    }
66	    
67		$inBox.empty();
68		
69		columnizeIt();
70		
71		if(!options.buildOnce){
72			$(window).resize(function() {
73				if(!options.buildOnce && $.browser.msie){
74					if($inBox.data("timeout")){
75						clearTimeout($inBox.data("timeout"));
76					}
77					$inBox.data("timeout", setTimeout(columnizeIt, 200));
78				}else if(!options.buildOnce){
79					columnizeIt();
80				}else{
81					// don't rebuild
82				}
83			});
84		}
85		
86		/**
87		 * return a node that has a height
88		 * less than or equal to height
89		 *
90		 * @param putInHere, a dom element
91		 * @$pullOutHere, a jQuery element
92		 */
93		function columnize($putInHere, $pullOutHere, $parentColumn, height){
94			while($parentColumn.height() < height &&
95				  $pullOutHere[0].childNodes.length){
96				$putInHere.append($pullOutHere[0].childNodes[0]);
97			}
98			if($putInHere[0].childNodes.length == 0) return;
99			
100			// now we're too tall, undo the last one
101			var kids = $putInHere[0].childNodes;
102			var lastKid = kids[kids.length-1];
103			$putInHere[0].removeChild(lastKid);
104			var $item = $(lastKid);
105			
106			
107			if($item[0].nodeType == 3){
108				// it's a text node, split it up
109				var oText = $item[0].nodeValue;
110				var counter2 = options.width / 18;
111				if(options.accuracy)
112				counter2 = options.accuracy;
113				var columnText;
114				var latestTextNode = null;
115				while($parentColumn.height() < height && oText.length){
116					if (oText.indexOf(' ', counter2) != '-1') {
117						columnText = oText.substring(0, oText.indexOf(' ', counter2));
118					} else {
119						columnText = oText;
120					}
121					latestTextNode = document.createTextNode(columnText);
122					$putInHere.append(latestTextNode);
123					
124					if(oText.length > counter2){
125						oText = oText.substring(oText.indexOf(' ', counter2));
126					}else{
127						oText = "";
128					}
129				}
130				if($parentColumn.height() >= height && latestTextNode != null){
131					// too tall :(
132					$putInHere[0].removeChild(latestTextNode);
133					oText = latestTextNode.nodeValue + oText;
134				}
135				if(oText.length){
136					$item[0].nodeValue = oText;
137				}else{
138					return false; // we ate the whole text node, move on to the next node
139				}
140			}
141			
142			if($pullOutHere.children().length){
143				$pullOutHere.prepend($item);
144			}else{
145				$pullOutHere.append($item);
146			}
147			
148			return $item[0].nodeType == 3;
149		}
150		
151		function split($putInHere, $pullOutHere, $parentColumn, height){
152			if($pullOutHere.children().length){
153				$cloneMe = $pullOutHere.children(":first");
154				$clone = $cloneMe.clone(true);
155				if($clone.attr("nodeType") == 1 && !$clone.hasClass("dontend")){ 
156					$putInHere.append($clone);
157					if($clone.is("img") && $parentColumn.height() < height + 20){
158						$cloneMe.remove();
159					}else if(!$cloneMe.hasClass("dontsplit") && $parentColumn.height() < height + 20){
160						$cloneMe.remove();
161					}else if($clone.is("img") || $cloneMe.hasClass("dontsplit")){
162						$clone.remove();
163					}else{
164						$clone.empty();
165						if(!columnize($clone, $cloneMe, $parentColumn, height)){
166							if($cloneMe.children().length){
167								split($clone, $cloneMe, $parentColumn, height);
168							}
169						}
170						if($clone.get(0).childNodes.length == 0){
171							// it was split, but nothing is in it :(
172							$clone.remove();
173						}
174					}
175				}
176			}
177		}
178		
179		
180		function singleColumnizeIt() {
181			if ($inBox.data("columnized") && $inBox.children().length == 1) {
182				return;
183			}
184			$inBox.data("columnized", true);
185			$inBox.data("columnizing", true);
186			
187			$inBox.empty();
188			$inBox.append($("<div class='first last column' style='width:98%; padding: 3px; float: " + options.float + ";'></div>")); //"
189			$col = $inBox.children().eq($inBox.children().length-1);
190			$destroyable = $cache.clone(true);
191			if(options.overflow){
192				targetHeight = options.overflow.height;
193				columnize($col, $destroyable, $col, targetHeight);
194				// make sure that the last item in the column isn't a "dontend"
195				if(!$destroyable.children().find(":first-child").hasClass("dontend")){
196					split($col, $destroyable, $col, targetHeight);
197				}
198				
199				while(checkDontEndColumn($col.children(":last").length && $col.children(":last").get(0))){
200					var $lastKid = $col.children(":last");
201					$lastKid.remove();
202					$destroyable.prepend($lastKid);
203				}
204
205				var html = "";
206				var div = document.createElement('DIV');
207				while($destroyable[0].childNodes.length > 0){
208					var kid = $destroyable[0].childNodes[0];
209					for(var i=0;i<kid.attributes.length;i++){
210						if(kid.attributes[i].nodeName.indexOf("jQuery") == 0){
211							kid.removeAttribute(kid.attributes[i].nodeName);
212						}
213					}
214					div.innerHTML = "";
215					div.appendChild($destroyable[0].childNodes[0]);
216					html += div.innerHTML;
217				}
218				var overflow = $(options.overflow.id)[0];
219				overflow.innerHTML = html;
220
221			}else{
222				$col.append($destroyable);
223			}
224			$inBox.data("columnizing", false);
225			
226			if(options.overflow){
227				options.overflow.doneFunc();
228			}
229			
230		}
231		
232		function checkDontEndColumn(dom){
233			if(dom.nodeType != 1) return false;
234			if($(dom).hasClass("dontend")) return true;
235			if(dom.childNodes.length == 0) return false;
236			return checkDontEndColumn(dom.childNodes[dom.childNodes.length-1]);
237		}
238		
239		function columnizeIt() {
240			if(lastWidth == $inBox.width()) return;
241			lastWidth = $inBox.width();
242			
243			var numCols = Math.round($inBox.width() / options.width);
244			if(options.columns) numCols = options.columns;
245//			if ($inBox.data("columnized") && numCols == $inBox.children().length) {
246//				return;
247//			}
248			if(numCols <= 1){
249				return singleColumnizeIt();
250			}
251			if($inBox.data("columnizing")) return;
252			$inBox.data("columnized", true);
253			$inBox.data("columnizing", true);
254			
255			$inBox.empty();
256			$inBox.append($("<div style='width:" + (Math.round(100 / numCols) - 2)+ "%; padding: 3px; float: " + options.float + ";'></div>")); //"
257			$col = $inBox.children(":last");
258			$col.append($cache.clone());
259			maxHeight = $col.height();
260			$inBox.empty();
261			
262			var targetHeight = maxHeight / numCols;
263			var firstTime = true;
264			var maxLoops = 3;
265			var scrollHorizontally = false;
266			if(options.overflow){
267				maxLoops = 1;
268				targetHeight = options.overflow.height;
269			}else if(options.height && options.width){
270				maxLoops = 1;
271				targetHeight = options.height;
272				scrollHorizontally = true;
273			}
274			
275			for(var loopCount=0;loopCount<maxLoops;loopCount++){
276				$inBox.empty();
277				var $destroyable;
278				try{
279					$destroyable = $cache.clone(true);
280				}catch(e){
281					// jquery in ie6 can't clone with true
282					$destroyable = $cache.clone();
283				}
284				$destroyable.css("visibility", "hidden");
285				// create the columns
286				for (var i = 0; i < numCols; i++) {
287					/* create column */
288					var className = (i == 0) ? "first column" : "column";
289					var className = (i == numCols - 1) ? ("last " + className) : className;
290					$inBox.append($("<div class='" + className + "' style='width:" + (Math.round(100 / numCols) - 2)+ "%; float: " + options.float + ";'></div>")); //"
291				}
292				
293				// fill all but the last column (unless overflowing)
294				var i = 0;
295				while(i < numCols - (options.overflow ? 0 : 1) || scrollHorizontally && $destroyable.children().length){
296					if($inBox.children().length <= i){
297						// we ran out of columns, make another
298						$inBox.append($("<div class='" + className + "' style='width:" + (Math.round(100 / numCols) - 2)+ "%; float: " + options.float + ";'></div>")); //"
299					}
300					var $col = $inBox.children().eq(i);
301					columnize($col, $destroyable, $col, targetHeight);
302					// make sure that the last item in the column isn't a "dontend"
303					if(!$destroyable.children().find(":first-child").hasClass("dontend")){
304						split($col, $destroyable, $col, targetHeight);
305					}else{
306//						alert("not splitting a dontend");
307					}
308					
309					while(checkDontEndColumn($col.children(":last").length && $col.children(":last").get(0))){
310						var $lastKid = $col.children(":last");
311						$lastKid.remove();
312						$destroyable.prepend($lastKid);
313					}
314					i++;
315				}
316				if(options.overflow && !scrollHorizontally){
317					var IE6 = false /*@cc_on || @_jscript_version < 5.7 @*/;
318					var IE7 = (document.all) && (navigator.appVersion.indexOf("MSIE 7.") != -1);
319					if(IE6 || IE7){
320						var html = "";
321						var div = document.createElement('DIV');
322						while($destroyable[0].childNodes.length > 0){
323							var kid = $destroyable[0].childNodes[0];
324							for(var i=0;i<kid.attributes.length;i++){
325								if(kid.attributes[i].nodeName.indexOf("jQuery") == 0){
326									kid.removeAttribute(kid.attributes[i].nodeName);
327								}
328							}
329							div.innerHTML = "";
330							div.appendChild($destroyable[0].childNodes[0]);
331							html += div.innerHTML;
332						}
333						var overflow = $(options.overflow.id)[0];
334						overflow.innerHTML = html;
335					}else{
336						$(options.overflow.id).empty().append($destroyable.children().clone(true));
337					}
338				}else if(!scrollHorizontally){
339					// the last column in the series
340					$col = $inBox.children().eq($inBox.children().length-1);
341					while($destroyable.children().length) $col.append($destroyable.children(":first"));
342					var afterH = $col.height();
343					var diff = afterH - targetHeight;
344					var totalH = 0;
345					var min = 10000000;
346					var max = 0;
347					var lastIsMax = false;
348					$inBox.children().each(function($inBox){ return function($item){
349						var h = $inBox.children().eq($item).height();
350						lastIsMax = false;
351						totalH += h;
352						if(h > max) {
353							max = h;
354							lastIsMax = true;
355						}
356						if(h < min) min = h;
357					}}($inBox));
358
359					var avgH = totalH / numCols;
360					if(options.lastNeverTallest && lastIsMax){
361						// the last column is the tallest
362						// so allow columns to be taller
363						// and retry
364						targetHeight = targetHeight + 30;
365						if(loopCount == maxLoops-1) maxLoops++;
366					}else if(max - min > 30){
367						// too much variation, try again
368						targetHeight = avgH + 30;
369					}else if(Math.abs(avgH-targetHeight) > 20){
370						// too much variation, try again
371						targetHeight = avgH;
372					}else {
373						// solid, we're done
374						loopCount = maxLoops;
375					}
376				}else{
377					// it's scrolling horizontally, fix the width/classes of the columns
378					$inBox.children().each(function(i){
379						$col = $inBox.children().eq(i);
380						$col.width(options.width + "px");
381						if(i==0){
382							$col.addClass("first");
383						}else if(i==$inBox.children().length-1){
384							$col.addClass("last");
385						}else{
386							$col.removeClass("first");
387							$col.removeClass("last");
388						}
389					});
390					$inBox.width($inBox.children().length * options.width + "px");
391				}
392				$inBox.append($("<br style='clear:both;'>"));
393			}
394			$inBox.find('.column').find(':first.removeiffirst').remove();
395			$inBox.find('.column').find(':last.removeiflast').remove();
396			$inBox.data("columnizing", false);
397
398			if(options.overflow){
399				options.overflow.doneFunc();
400			}
401			options.doneFunc();
402		}
403    });
404 };
405})(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.