Files
2014-05-30 10:31:51 -07:00

576 lines
23 KiB
JavaScript

/**
* Some knowledge picked up and generally applicable in the future:
* - Every 'node' in the tree has a parent node which is accessable via the 'parentNode' attribute (IE/Mozilla).
* - Custom attributes must be accessed by 'getAttribute("customAttribute")' and 'setAttribute("customAttribute", value)'.
* - The attribute 'tagName' gives the exact (in caps) name of any node.
*/
//
// Loads HTML and places inside the provided component.
//
function loadInnerHtml(url, component) {
loadInnerHtml(url, component, null);
}
//
// Loads HTML and places inside the provided component.
// url: The URL to invoke.
// component: The optional id of the HTML component whose inner html will be set to the response content.
// handler: The optional handler invoked after the response is succesfully received, and is passed a boolean indicating whether the response was success, and the integer response code. Example (refreshes): function(success, code) {if(!success && code == 412) {window.history.go(0);}}
//
function loadInnerHtml(url, component, handler) {
var httpRequest = null;
if(window.XMLHttpRequest) {
httpRequest = new XMLHttpRequest();
}
else if(window.ActiveXObject) {
httpRequest = new ActiveXObject("Microsoft.XMLHTTP");
}
else {
return;
}
if(httpRequest != null) {
httpRequest.onreadystatechange = function() {
if(httpRequest.readyState == 4) {
if((httpRequest.status == 200) || (httpRequest.status == 0)) {
if(component) {
var element = document.getElementById(component);
if(element) {
element.innerHTML = httpRequest.responseText;
}
}
if(handler) {
handler();
}
}
else {
//Note: Currently using 412 for a refresh - error numbers should never be cached by the browser.//
if(httpRequest.status == 412) {
//Refresh the current page.//
window.history.go(0);
}
}
}
}
httpRequest.open("GET",url,true);
httpRequest.send(null);
}
}
//Sends a ping to the server on a regular basis to prevent loss of the session.
// interval: The time increment between pings to the server, in milliseconds.
function ping(interval) {
var url = "/PingController.java";
var httpRequest = null;
if(window.XMLHttpRequest) {
httpRequest = new XMLHttpRequest();
}
else if(window.ActiveXObject) {
httpRequest = new ActiveXObject("Microsoft.XMLHTTP");
}
else {
return;
}
if(httpRequest != null) {
httpRequest.onreadystatechange = function() {
if(httpRequest.readyState == 4) {
if((httpRequest.status == 200) || (httpRequest.status == 0)) {
setTimeout("ping('" + interval + "')", interval);
}
}
}
httpRequest.open("POST",url,true);
httpRequest.send(null);
}
}
<!-- Changes the class of style used by the element with the given id to the new class. -->
function changeStyles(id, newClass) {
identity = document.getElementById(id);
identity.className = newClass;
}
<!-- Changes the PNG or GIF image used as the background for the given div tag's id. The GIF will only be used if the browser doesn't support PNG. The pngPath parameters must not have an extension. -->
<!-- Warning: In IE, the div tag must specify a height and width, otherwise the image will not repeat to fill the div. In Mozilla the image always repeats automatically. -->
<!-- Note: I have successfully gotten this to work passing the id for a list item instead of a div. I don't know what other tags support this (tested with firefox 1.5 & IE 6.0). -->
function changePng(divId, pngPath) {
var ns = (document.all) ? false : true;
var browserVersion = parseFloat(navigator.appVersion);
var style = getElementStyleById(divId);
if(pngPath) {
if((browser.isIE55 || browser.isIE6up) && browser.isWin32) {
style.filter = "progid:DXImageTransform.Microsoft.AlphaImageLoader(src='" + pngPath + ".png', sizingMethod='scale')";
} else if ((browser.isGecko) || (browser.isIE5up && browser.isMac) || (browser.isOpera && browser.isWin && browser.versionMajor >= 6) || (browser.isOpera && browser.isUnix && browser.versionMajor >= 6) || (browser.isOpera && browser.isMac && browser.versionMajor >= 5) || (browser.isOmniweb && browser.versionMinor >= 3.1) || (browser.isIcab && browser.versionMinor >= 1.9) || (browser.isWebtv) || (browser.isDreamcast)) {
style.backgroundImage = "url('" + pngPath + ".png')";
} else {
style.backgroundImage = "url('" + pngPath + ".gif')";
}
} else {
style.filter = "";
style.backgroundImage = "";
}
}
<!-- Changes the PNG or GIF image used as the background for the given div tag's id. The GIF will only be used if the browser doesn't support PNG. The pngPath parameters must not have an extension. -->
<!-- Warning: In IE, the div tag must specify a height and width, otherwise the image will not repeat to fill the div. In Mozilla the image always repeats automatically. -->
<!-- Note: I have successfully gotten this to work passing the id for a list item instead of a div. I don't know what other tags support this (tested with firefox 1.5 & IE 6.0). -->
function changeBackground(divId, imagePath) {
var ns = (document.all) ? false : true;
var browserVersion = parseFloat(navigator.appVersion);
var style = getElementStyleById(divId);
if(imagePath != null) {
var isPng = (imagePath.length > 4) && (imagePath.substring(imagePath.length - 4, imagePath.length) == ".png");
if(isPng) {
if((browser.isIE55 || browser.isIE6up) && browser.isWin32) {
internalRemoveIEFilter(style, "progid:DXImageTransform.Microsoft.AlphaImageLoader(");
style.filter += "progid:DXImageTransform.Microsoft.AlphaImageLoader(src='" + imagePath + "', sizingMethod='scale')";
}
else if ((browser.isGecko) || (browser.isIE5up && browser.isMac) || (browser.isOpera && browser.isWin && browser.versionMajor >= 6) || (browser.isOpera && browser.isUnix && browser.versionMajor >= 6) || (browser.isOpera && browser.isMac && browser.versionMajor >= 5) || (browser.isOmniweb && browser.versionMinor >= 3.1) || (browser.isIcab && browser.versionMinor >= 1.9) || (browser.isWebtv) || (browser.isDreamcast)) {
style.backgroundImage = "url('" + imagePath + "')";
}
else {
//Try to load a GIF instead!//
style.backgroundImage = "url('" + imagePath.substring(0, imagePath.length - 4) + ".gif')";
}
}
else {
style.backgroundImage = "url('" + imagePath + "')";
}
}
else {
internalRemoveIEFilter(style, "progid:DXImageTransform.Microsoft.AlphaImageLoader(");
style.backgroundImage = "";
}
}
//Removes a filter from the IE filter property of an object if the filter property contains the given filter.
// style: The object's style whose filter will be removed.
// ieFilter: The starting text for the filter. For example: "progid:DXImageTransform.Microsoft.Alpha(".
function internalRemoveIEFilter(style, ieFilter) {
if(style.filter != null) {
var startIndex = style.filter.indexOf(ieFilter);
//Remove the alpha from the filter if it already exists.//
if(startIndex != -1) {
var endIndex = style.filter.indexOf(")", startIndex + ieFilter.length) + 1;
if(endIndex != -1) {
style.filter = style.filter.substring(0, startIndex) + style.filter.substring(endIndex, style.filter.length);
}
}
}
}
//IE Note: IE requires either the width or height to be specified for the object, or object.style.writingMode=tb-rl, or object.contentEditable=true (HTML: contenteditable='true').
// id: The id of the component being faded.
// opacityStart: The starting opacity of the component 0 = not visible, 100 = fully visible.
// opacityEnd: The ending opacity of the component.
// fadeTime: The number of milliseconds the fade should occur over.
// opacityIncrement: The increment size for each opacity change (must be a whole number >= 1).
// delay: The number of milliseconds of wait before begining the first fade increment.
// enterFunction: The optional function to be called when the fade begins.
// exitFunction: The optional function to be called when the fade ends.
function fade(id, opacityStart, opacityEnd, fadeTime, opacityIncrement, delay, enterFunction, exitFunction) {
var ns = (document.all) ? false : true;
if(ns) {
changeOpacity(opacityStart, id);
var opacityDelta = Math.abs(opacityEnd - opacityStart);
if(opacityIncrement < 1) {
opacityIncrement = 1;
}
else if(opacityIncrement > opacityDelta) {
opacityIncrement = opacityDelta;
}
else {
opacityIncrement = Math.round(opacityIncrement);
}
var granularity = 10;
var maxTimeIncrements = Math.floor(fadeTime / granularity);
var maxOpacityChangeIncrements = Math.ceil(opacityDelta / opacityIncrement);
var waitTime;
var opacityChange;
var timeIncrements;
if(maxOpacityChangeIncrements > maxTimeIncrements) {
waitTime = Math.floor(fadeTime / maxTimeIncrements);
opacityChange = Math.round(opacityDelta / maxTimeIncrements);
timeIncrements = maxTimeIncrements;
}
else {
waitTime = Math.floor(fadeTime / maxOpacityChangeIncrements);
opacityChange = opacityIncrement;
timeIncrements = maxOpacityChangeIncrements;
}
internalFade(id, opacityStart, opacityEnd, waitTime, opacityChange, timeIncrements, delay, enterFunction, exitFunction);
}
}
//IE Note: IE requires either the width or height to be specified for the object, or object.style.writingMode=tb-rl, or object.contentEditable=true (HTML: contenteditable='true').
// id: The id of the component being faded.
// lastOpacity: The last known opacity for the component. If the opacity isn't this value then the timer will discontinue to prevent flickering.
// opacityEnd: The ending opacity of the component.
// waitTime: The number of milliseconds to wait before performing the next fade increment.
// opacityChange: The amount the opacity should change each increment.
// remainingTimeIncrements: The number of increments remaining before the ending opacity is reached.
// delay: The number of milliseconds of wait before begining the first fade increment.
// enterFunction: The optional function to be called when the fade begins.
// exitFunction: The optional function to be called when the fade ends.
function internalFade(id, lastOpacity, opacityEnd, waitTime, opacityChange, remainingTimeIncrements, delay, enterFunction, exitFunction) {
//This could be null if another script has removed the elements we are fading.
if(document.getElementById(id) != null) {
if(delay != 0) {
setTimeout("internalFade('" + id + "'," + lastOpacity + "," + opacityEnd + "," + waitTime + "," + opacityChange + "," + remainingTimeIncrements + ",0," + enterFunction + "," + exitFunction + ")", delay);
}
else if(Math.round(getOpacity(id) * 100) == lastOpacity) {
if(enterFunction != null) {
enterFunction();
}
if(remainingTimeIncrements > 0) {
if(lastOpacity > opacityEnd) {
lastOpacity -= opacityChange;
}
else {
lastOpacity += opacityChange;
}
}
else {
lastOpacity = opacityEnd;
}
changeOpacity(lastOpacity, id);
if(remainingTimeIncrements-- > 0) {
setTimeout("internalFade('" + id + "'," + lastOpacity + "," + opacityEnd + "," + waitTime + "," + opacityChange + "," + remainingTimeIncrements + ",0,null," + exitFunction + ")", waitTime);
}
else if(exitFunction != null) {
exitFunction();
}
}
}
}
//IE Note: IE requires either the width or height to be specified for the object, or object.style.writingMode=tb-rl, or object.contentEditable=true (HTML: contenteditable='true').
//Replaces one component with another via a fade.
// fromId: The id of the component being faded out.
// fromFadeTime: The number of milliseconds the fade should occur over. This should be zero, negative, or null if no fade should occur.
// fromOpacityIncrement: The increment size for each opacity change (must be a whole number >= 1).
// toId: The id of the component being faded out.
// toFadeTime: The number of milliseconds the fade should occur over. This should be zero, negative, or null if no fade should occur.
// toOpacityIncrement: The increment size for each opacity change (must be a whole number >= 1).
// focusId: The ID of the component that will receive focus when the two fades finish.
function replaceFade(fromId, fromFadeTime, fromOpacityIncrement, toId, toFadeTime, toOpacityIncrement, focusId) {
var ns = (document.all) ? false : true;
if(ns && ((fromFadeTime && fromFadeTime > 0) || (toFadeTime && toFadeTime > 0))) {
var opacityDelta = 100;
if(fromOpacityIncrement < 1) {
fromOpacityIncrement = 1;
}
else if(fromOpacityIncrement > opacityDelta) {
fromOpacityIncrement = opacityDelta;
}
else {
fromOpacityIncrement = Math.round(fromOpacityIncrement);
}
if(toOpacityIncrement < 1) {
toOpacityIncrement = 1;
}
else if(toOpacityIncrement > opacityDelta) {
toOpacityIncrement = opacityDelta;
}
else {
toOpacityIncrement = Math.round(toOpacityIncrement);
}
var granularity = 10;
var fromMaxTimeIncrements = 0;
var fromMaxOpacityChangeIncrements = 0;
var fromWaitTime = 0;
var fromOpacityChange = 0;
var fromTimeIncrements = 0;
var toMaxTimeIncrements = 0;
var toMaxOpacityChangeIncrements = 0;
var toWaitTime = 0;
var toOpacityChange = 0;
var toTimeIncrements = 0;
if(fromFadeTime && fromFadeTime > 0) {
fromMaxTimeIncrements = Math.floor(fromFadeTime / granularity);
fromMaxOpacityChangeIncrements = Math.ceil(opacityDelta / fromOpacityIncrement);
if(fromMaxOpacityChangeIncrements > fromMaxTimeIncrements) {
fromWaitTime = Math.floor(fromFadeTime / fromMaxTimeIncrements);
fromOpacityChange = Math.round(opacityDelta / fromMaxTimeIncrements);
fromTimeIncrements = fromMaxTimeIncrements;
}
else {
fromWaitTime = Math.floor(fromFadeTime / fromMaxOpacityChangeIncrements);
fromOpacityChange = fromOpacityIncrement;
fromTimeIncrements = fromMaxOpacityChangeIncrements - 1;
}
}
if(toFadeTime && toFadeTime > 0) {
toMaxTimeIncrements = Math.floor(toFadeTime / granularity);
toMaxOpacityChangeIncrements = Math.ceil(opacityDelta / toOpacityIncrement);
if(toMaxOpacityChangeIncrements > toMaxTimeIncrements) {
toWaitTime = Math.floor(toFadeTime / toMaxTimeIncrements);
toOpacityChange = Math.round(opacityDelta / toMaxTimeIncrements);
toTimeIncrements = toMaxTimeIncrements;
}
else {
toWaitTime = Math.floor(toFadeTime / toMaxOpacityChangeIncrements);
toOpacityChange = toOpacityIncrement;
toTimeIncrements = toMaxOpacityChangeIncrements - 1;
}
}
if(fromId) {
changeOpacity(100, fromId);
}
internalReplaceFade(fromId, fromWaitTime, fromOpacityChange, fromTimeIncrements, toId, toWaitTime, toOpacityChange, toTimeIncrements, 100, focusId);
}
else {
var fromObject = document.getElementById(fromId);
var toObject = document.getElementById(toId);
if(fromObject) {
fromObject.style.visibility = "hidden";
fromObject.style.display = "none";
}
if(toObject) {
toObject.style.visibility = "visible";
toObject.style.display = "block";
}
if(focusId != null && focusId != 'null' && focusId != '') {
var focusComponent = document.getElementById(focusId);
if(focusComponent != null) {
focusComponent.focus();
if(focusComponent.type != null && focusComponent.type == "text") {
focusComponent.select();
}
}
else {
//alert("Can't find the focus component: " + focusId);
}
}
}
}
//IE Note: IE requires either the width or height to be specified for the object, or object.style.writingMode=tb-rl, or object.contentEditable=true (HTML: contenteditable='true').
//Internal use only.
// fromId: The id of the component being faded out.
// fromWaitTime: The number of milliseconds of wait between fade increments.
// fromOpacityChange: The opacity change for each increment.
// fromTimeIncrements: The number of remaining time increments.
// toId: The id of the component being faded out.
// toWaitTime: The number of milliseconds of wait between fade increments.
// toOpacityChange: The opacity change for each increment.
// toTimeIncrements: The number of remaining time increments.
// lastOpacity: The last opacity of the currently fading component.
// focusId: The ID of the component that will receive focus when the two fades finish.
function internalReplaceFade(fromId, fromWaitTime, fromOpacityChange, fromTimeIncrements, toId, toWaitTime, toOpacityChange, toTimeIncrements, lastOpacity, focusId) {
var fromObject = document.getElementById(fromId);
var toObject = document.getElementById(toId);
//This could be null if another script has removed the elements we are fading.
if(fromObject != null && toObject != null) {
if(fromTimeIncrements > 0) {
if(Math.round(getOpacity(fromId) * 100) == lastOpacity) {
var waitTime = fromWaitTime;
if(fromTimeIncrements > 1) {
lastOpacity -= fromOpacityChange;
changeOpacity(lastOpacity, fromId);
}
else {
lastOpacity = 0;
fromObject.style.visibility = "hidden";
fromObject.style.display = "none";
changeOpacity(0, fromId);
changeOpacity(0, toId);
toObject.style.visibility = "visible";
toObject.style.display = "block";
waitTime = toWaitTime;
if(focusId != null && focusId != 'null' && focusId != '') {
var focusComponent = document.getElementById(focusId);
if(focusComponent != null) {
focusComponent.focus();
if(focusComponent.type != null && focusComponent.type == "text") {
focusComponent.select();
}
}
else {
//alert("Can't find the focus component: " + focusId);
}
}
}
fromTimeIncrements--;
setTimeout("internalReplaceFade('" + fromId + "'," + fromWaitTime + "," + fromOpacityChange + "," + fromTimeIncrements + ",'" + toId + "'," + toWaitTime + "," + toOpacityChange + "," + toTimeIncrements + "," + lastOpacity + ",'" + focusId + "')", waitTime);
}
}
else {
if(Math.round(getOpacity(toId) * 100) == lastOpacity) {
if(toTimeIncrements > 1) {
lastOpacity += toOpacityChange;
}
else {
lastOpacity = 100;
}
changeOpacity(lastOpacity, toId);
if(toTimeIncrements-- > 0) {
setTimeout("internalReplaceFade('" + fromId + "'," + fromWaitTime + "," + fromOpacityChange + "," + fromTimeIncrements + ",'" + toId + "'," + toWaitTime + "," + toOpacityChange + "," + toTimeIncrements + "," + lastOpacity + ",'" + focusId + "')", toWaitTime);
}
}
}
}
}
function getOpacity(id) {
var object = document.getElementById(id).style;
return object.opacity;
}
//IE Note: IE requires either the width or height to be specified for the object, or object.style.writingMode=tb-rl, or object.contentEditable=true (HTML: contenteditable='true').
//Sets the opacity for an element.
// opacity: How visible the element is on a scale of 0..100 (not visible..fully visible).
// id: The id of the element whose opacity is being set.
function changeOpacity(opacity, id) {
var style = document.getElementById(id).style;
style.opacity = (opacity / 100);
style.MozOpacity = (opacity / 100);
style.KhtmlOpacity = (opacity / 100);
internalRemoveIEFilter(style, "progid:DXImageTransform.Microsoft.Alpha(");
style.filter = "progid:DXImageTransform.Microsoft.Alpha(opacity=" + opacity + ")" + style.filter;
}
// Browser Detect Lite v2.1
// http://www.dithered.com/javascript/browser_detect/index.html
// modified by Chris Nott (chris@NOSPAMdithered.com - remove NOSPAM)
//
// modified by Michael Lovitt to include OmniWeb and Dreamcast
function BrowserDetectLite() {
var ua = navigator.userAgent.toLowerCase();
this.ua = ua;
// browser name
this.isGecko = (ua.indexOf('gecko') != -1);
this.isMozilla = (this.isGecko && ua.indexOf("gecko/") + 14 == ua.length);
this.isNS = ( (this.isGecko) ? (ua.indexOf('netscape') != -1) : ( (ua.indexOf('mozilla') != -1) && (ua.indexOf('spoofer') == -1) && (ua.indexOf('compatible') == -1) && (ua.indexOf('opera') == -1) && (ua.indexOf('webtv') == -1) && (ua.indexOf('hotjava') == -1) ) );
this.isIE = ( (ua.indexOf("msie") != -1) && (ua.indexOf("opera") == -1) && (ua.indexOf("webtv") == -1) );
this.isOpera = (ua.indexOf("opera") != -1);
this.isKonqueror = (ua.indexOf("konqueror") != -1);
this.isIcab = (ua.indexOf("icab") != -1);
this.isAol = (ua.indexOf("aol") != -1);
this.isWebtv = (ua.indexOf("webtv") != -1);
this.isOmniweb = (ua.indexOf("omniweb") != -1);
this.isDreamcast = (ua.indexOf("dreamcast") != -1);
// spoofing and compatible browsers
this.isIECompatible = ( (ua.indexOf("msie") != -1) && !this.isIE);
this.isNSCompatible = ( (ua.indexOf("mozilla") != -1) && !this.isNS && !this.isMozilla);
// browser version
this.versionMinor = parseFloat(navigator.appVersion);
// correct version number for NS6+
if (this.isNS && this.isGecko) {
this.versionMinor = parseFloat( ua.substring( ua.lastIndexOf('/') + 1 ) );
}
// correct version number for IE4+
else if (this.isIE && this.versionMinor >= 4) {
this.versionMinor = parseFloat( ua.substring( ua.indexOf('msie ') + 5 ) );
}
// correct version number for Opera
else if (this.isOpera) {
if (ua.indexOf('opera/') != -1) {
this.versionMinor = parseFloat( ua.substring( ua.indexOf('opera/') + 6 ) );
}
else {
this.versionMinor = parseFloat( ua.substring( ua.indexOf('opera ') + 6 ) );
}
}
// correct version number for Konqueror
else if (this.isKonqueror) {
this.versionMinor = parseFloat( ua.substring( ua.indexOf('konqueror/') + 10 ) );
}
// correct version number for iCab
else if (this.isIcab) {
if (ua.indexOf('icab/') != -1) {
this.versionMinor = parseFloat( ua.substring( ua.indexOf('icab/') + 6 ) );
}
else {
this.versionMinor = parseFloat( ua.substring( ua.indexOf('icab ') + 6 ) );
}
}
// correct version number for WebTV
else if (this.isWebtv) {
this.versionMinor = parseFloat( ua.substring( ua.indexOf('webtv/') + 6 ) );
}
this.versionMajor = parseInt(this.versionMinor);
this.geckoVersion = ( (this.isGecko) ? ua.substring( (ua.lastIndexOf('gecko/') + 6), (ua.lastIndexOf('gecko/') + 14) ) : -1 );
// platform
this.isWin = (ua.indexOf('win') != -1);
this.isWin32 = (this.isWin && ( ua.indexOf('95') != -1 || ua.indexOf('98') != -1 || ua.indexOf('nt') != -1 || ua.indexOf('win32') != -1 || ua.indexOf('32bit') != -1) );
this.isMac = (ua.indexOf('mac') != -1);
this.isUnix = (ua.indexOf('unix') != -1 || ua.indexOf('linux') != -1 || ua.indexOf('sunos') != -1 || ua.indexOf('bsd') != -1 || ua.indexOf('x11') != -1)
// specific browser shortcuts
this.isNS4x = (this.isNS && this.versionMajor == 4);
this.isNS40x = (this.isNS4x && this.versionMinor < 4.5);
this.isNS47x = (this.isNS4x && this.versionMinor >= 4.7);
this.isNS4up = (this.isNS && this.versionMinor >= 4);
this.isNS6x = (this.isNS && this.versionMajor == 6);
this.isNS6up = (this.isNS && this.versionMajor >= 6);
this.isIE4x = (this.isIE && this.versionMajor == 4);
this.isIE4up = (this.isIE && this.versionMajor >= 4);
this.isIE5x = (this.isIE && this.versionMajor == 5);
this.isIE55 = (this.isIE && this.versionMinor == 5.5);
this.isIE5up = (this.isIE && this.versionMajor >= 5);
this.isIE6x = (this.isIE && this.versionMajor == 6);
this.isIE6up = (this.isIE && this.versionMajor >= 6);
this.isIE4xMac = (this.isIE4x && this.isMac);
}
var browser = new BrowserDetectLite();