//=======================================================\\
// 13thparallel.org \\
// Copyright (c) 2002 \\
// see (13thparallel.org/?title=about) for more info \\
//=======================================================\\
// Columns object to split a load of innerHTML into columns.
// 08/04/02
var Columns = {
singleTags : ["br", "img", "hr", "input", "!--"],
devmode : "off", // "on" or "off", if set to "on" some info will be displayed in the statusbar.
cols : new Array(), // Stores the columns during calculations.
onSplitStart : new Function(),
onSplitEnd : new Function(),
onSplit : new Function()
}
// The chop array holds strings that should be removed from the start of every column.
// Don't remove only one part of a tag pair, like
, always remove whole pairs, like .
Columns.chop = [
'',
'',
'
',
'
',
'
',
'
',
'',
''
]
// Splits a load of text into fragments that will fit in the
// specified width and height and returns them in an array.
// It automatically closes unclosed tags and creates opening tags for the following columns.
Columns.splitText = function(text, width, height) {
if (!document.getElementById
|| !document.getElementById("divSizer")
|| typeof document.getElementById("divSizer").innerHTML == "undefined") return;
this.onSplitStart(text, width, height);
this.cols = new Array();
this.innerHTMLHits = 0;
var startDate = new Date();
var x = "";
for (var i = 0; text != ""; i++) {
// put a fitting fragment in cols array and slice it from the text
this.cols[i] = this.getFragment(text, width, height);
text = text.slice(this.cols[i].length);
// remove chop strings from the start of the text
for (var j = 0; j < this.chop.length; j++) {
if (text.charAt(0) == "\n") text = text.slice(1);
x = this.chop[j];
while (text.indexOf(x) == 0) text = text.slice(x.length);
}
// add tags from opentags array
for (var k = this.openTags.length - 1; k >= 0; k--) {
this.cols[i] += "" + this.openTags[k].split(" ")[0] + ">";
if (text != "") text = "<" + this.openTags[k] + ">" + text;
}
// remove chop strings from the start of the text again
for (var m = 0; m < this.chop.length; m++) {
if (text.charAt(0) == "\n") text = text.slice(1);
x = this.chop[m];
while (text.indexOf(x) == 0) text = text.slice(x.length);
}
// fire onSplit event
this.onSplit(this.cols[i]);
}
if (this.devmode == "on") {
var endDate = new Date();
var message = "Time taken for splitting text = " + (endDate-startDate)/1000 + " seconds";
message += " Number of unclosed tags found = " + this.openTags.length;
message += " innerHTMLHits = " + this.innerHTMLHits;
defaultStatus = message;
}
this.onSplitEnd(this.cols);
return this.cols;
}
Columns.getFragment = function(text, width, height) {
var objSizer = document.getElementById("divSizer");
objSizer.style.width = width + "px";
var i = 0;
var limit = 0;
var add = 0;
var doloop = false;
this.openTags = new Array();
objSizer.innerHTML = text;
if (objSizer.offsetHeight <= height) i = text.length;
else {
doloop = true;
limit = text.length;
}
// This loop determines the raw piece of text that fits in the specified width and height.
// It is the most powerhungry part of the script because of the repeated innerHTML manipulation.
// It uses a binary search between 0 and text.length.
while (doloop) {
add = Math.round((limit - i) / 2);
if (add <= 1) doloop = false;
i += add;
objSizer.innerHTML = text.substr(0, i);
if (objSizer.offsetHeight > height){
limit = i;
i -= add;
}
this.innerHTMLHits ++;
}
// Making sure there are no broken words or tags like "");
var lastLess = text.substr(0, i).lastIndexOf("<");
if (lastLess <= lastGreater && lastNewline == i - 1) i = i;
else if (lastSpace != -1 && lastSpace > lastGreater && lastGreater > lastLess) i = lastSpace + 1;
else if (lastLess > lastGreater) i = lastLess;
else if (lastGreater != -1) i = lastGreater + 1;
}
// Doing the column breaks.
text = text.substr(0, i).split('')[0];
text = text.substr(0, i).split('')[0];
// Seeking unclosed tag pairs in this fragment and storing them in the openTags array.
var doPush = true;
var tags = text.split("<");
tags.shift();
for (var j=0; j" and taking the first item.
// Now we have the whole tag with its attributes and without "<" and ">".
tags[j] = tags[j].split(">")[0];
// If it's a selfclosing xhtml or xml tag there's no need to do anything with it.
if (tags[j].charAt(tags[j].length-1) == "/") continue;
if (tags[j].charAt(0) != "/") {
for (var k=0; k 0 ? this[this.length - 1] : undefined;
if (this.length > 0) this.length--;
return lastitem;
};
}
// shift removes the first element from an array and returns it
if (Array.prototype && !Array.prototype.shift) {
Array.prototype.shift = function() {
var firstitem = this.length > 0 ? this[0] : undefined;
for (var i=0; i 0) this.length--;
return firstitem;
};
}
// join returns a string value consisting of all the elements of an array
// concatenated together and separated by the separator argument
if (Array.prototype && !Array.prototype.join) {
Array.prototype.join = function(separator) {
if (typeof separator != "string") separator = ",";
var s = "";
for (var i=0; i= limit) break;
}
}
else {
while (s.length) {
sepIndex = s.indexOf(separator);
a[a.length] = s.substring(0, sepIndex);
s = s.substring(sepIndex+separator.length);
if (typeof limit == "number" && a.length >= limit) break;
if (s.length == 0) a[a.length] = s;
}
}
return a;
};
}
// end