// Client sniffing
var isGecko = (navigator.userAgent.indexOf("Gecko") != -1);
var isFirefox = (navigator.userAgent.toLowerCase().indexOf("firefox") != -1);
var isNav = (navigator.appName.indexOf("Netscape") != -1);
var isIE = (navigator.appName.indexOf("Microsoft") != -1);
var isMac = (navigator.appVersion.indexOf("Macintosh") >= 0);
var isUx = (navigator.appVersion.indexOf("X11") >= 0);
var isChrome = (navigator.userAgent.toLowerCase().indexOf("chrome") != -1);
var isSafari = (navigator.userAgent.indexOf("Safari") != -1);
var browserName = navigator.appName;
// Browser version
var gVersion = GetVersion();
//
// Returns the URL to the custom stylesheet for the client
//
function GetCSS()
{
var sCSS = "ds";
// Customize for Windows IE or Mac IE 5 and up
if (isIE) {
if ((!isMac) || (gVersion >= 5))
sCSS += "_ie_fcd6b2e8a7528f3cad291f928116726523210b49fc598c08e2ece12ace89dcb0.css";
else
sCSS += "_fcd6b2e8a7528f3cad291f928116726523210b49fc598c08e2ece12ace89dcb0.css";
}
// Customize for Mozilla
// TODO: Should this change to isGecko?
else if ((isNav) && (gVersion >= 5)) {
sCSS += "_nav_fcd6b2e8a7528f3cad291f928116726523210b49fc598c08e2ece12ace89dcb0.css";
}
else {
sCSS += "_fcd6b2e8a7528f3cad291f928116726523210b49fc598c08e2ece12ace89dcb0.css";
}
return (sCSS);
}
//
// Includes the current stylesheet in the HTML
//
function WriteCSS()
{
var sCSS = GetCSS();
if (sCSS.length > 0) document.write("");
}
// Add a CSS based on theme
function WriteThemeCSS(theme)
{
var sCSS = GetCSS();
if ( (typeof(theme) != "undefined") && (theme != "")) {
var str = "" ;
if (sCSS.length > 0) document.write(str);
}
else {
if (sCSS.length > 0) document.write("");
}
}
function WriteVanillaCSS()
{
var path = "";
var args = WriteVanillaCSS.arguments;
var nNumArgs = args.length;
if (nNumArgs > 0) {
path = args[0];
}
WriteCSS(null, false, path);
}
// Get the browser version. Digs into appVersion for IE, since MS doesn't
// understand what version numbers are for. Otherwise just parses the appVersion.
function GetVersion() {
var s = navigator.appVersion;
var n = s.indexOf("MSIE");
var v = 0;
// Grab the first number appearing after "MSIE"
if (n != -1) {
v = parseFloat(s.substr(n + 4));
} else if (s.indexOf("Trident") != -1) {
//Support for IE11+
var r = s.indexOf(" rv:");
if (r != -1) {
v = parseFloat(s.substr(r + 4));
}
}
else {
v = parseFloat(s);
}
return v;
}
function GetGeckoVersion() {
// Gecko version is YYYYMMDD format following GeckoProductToken.
// See: http://www.mozilla.org/build/revised-user-agent-strings.html
var s = navigator.userAgent;
var nStart = s.indexOf("Gecko/");
var nVersion = null;
if (nStart != -1) {
nStart += 6;
s = s.substring(nStart, nStart+8);
nVersion = parseInt(s);
}
return nVersion;
}
//
// This function handles the situation when the user selects a separator in a drop down list. It assumes
// that a separator will never be the first item in the list. If the item is a separator, the selectedIndex
// is adjusted up by one, and the function returns true. Otherwise it returns false. It is up to the calling
// function to check the return value and respond accordingly.
//
function HandleSeparator(cmb,nDefaultIndex) {
var opt = cmb.options[cmb.selectedIndex];
var bWeHandled = false;
if (IsSeparator(cmb)) {
if (nDefaultIndex == -1)
cmb.selectedIndex--;
else
cmb.selectedIndex = nDefaultIndex;
bWeHandled = true;
}
return bWeHandled;
}
function IsSeparator(cmb) {
return (cmb.options[cmb.selectedIndex].text == "--");
}
//
// DOM-related functions
//
// Returns the first parentNode of element elm with the given tagName. Null if
// no parent has that tagName.
function GetContainingElementByTagName(elm, sContainerTagName) {
var tagName;
var elmID;
elm = elm.parentNode;
do {
tagName = elm.tagName;
tagName = tagName.toLowerCase();
elmID = elm.id;
if (tagName == sContainerTagName) {
return elm;
}
else {
elm = elm.parentNode;
}
} while ((elm != null) && (typeof(elm.tagName) != "undefined"));
return null;
}
//
// Handles select/unselect all behavior for list checkboxes.
// Takes an array of the checkboxes.
//
function SelectAll(chkArray){
var nNumChecked = 0;
var nCount = GetNumSelectCheckboxes(chkArray);
var n;
if (nCount == 1) {
// if one item, toggle it
chkArray.checked = !(chkArray.checked);
}
else if (nCount > 1) {
// if more than one item, go through the array and check any checkbox
// that isn't checked
for (n = 0; n < nCount; n++) {
var chk = chkArray[n];
if (!chk.checked) {
chk.checked = true;
}
else {
nNumChecked++;
}
}
// if it turns out that all the checkboxes were already checked,
// uncheck all the checkboxes
if (nNumChecked == nCount) {
for (n = 0; n < nCount; n++) {
chkArray[n].checked = false;
}
}
}
}
function UnselectAll(chkArray) {
var nCount = GetNumSelectCheckboxes(chkArray);
//alert(nCount);
if (nCount == 1) {
chkArray.checked = false;
}
else if (nCount > 1) {
for (var n = 0; n < nCount; n++) {
chkArray[n].checked = false;
}
}
}
function GetNumSelected(chkArray) {
var nNumChecked = 0;
var nCount = GetNumSelectCheckboxes(chkArray);
if (nCount == 1) {
if (chkArray.checked) {
nNumChecked++;
}
}
else if (nCount > 1) {
// count the number of checked checkboxes
for (var n = 0; n < nCount; n++) {
if (chkArray[n].checked) {
nNumChecked++;
}
}
}
return nNumChecked;
}
function GetNumSelectCheckboxes(chkArray) {
var nCount = 0;
// if the array isn't null
if (chkArray && (typeof(chkArray) != "undefined")) {
// if the array actually IS an array
if (chkArray.length) {
nCount = chkArray.length;
}
else {
nCount = 1;
}
}
return nCount;
}
//
// HTML EVENT FUNCTIONS
// The following code coordinates certain event handling functions.
// Specifically, it allows clients to register KeyDown event handlers and
// Click event handlers, so different features can hook into these user
// interactions. It also defines a standardized event object for keyboard
// events and mouse events, helping to encapsulate some vexing browser
// differences.
//
// Note that pages MUST go through the registration functions...they should
// not simply hook their own event handler. The whole point of this is to
// make it easier for clients to hook these events without stepping on other
// features ability to also do so.
//
// Finally, registered event handlers are called in the order they were
// registered, and if a handler explicitly returns false, then no other
// event handlers will be called.
//
var gOnloadHandlers = null;
var gKeyDownHandlers = null;
var gClickHandlers = null;
function ClearOnloadHandlers() {
gOnloadHandlers = null;
}
function AddOnloadHandler(cbk) {
if (gOnloadHandlers == null) {
gOnloadHandlers = new Array();
}
var nNumHandlers = gOnloadHandlers.length;
gOnloadHandlers[nNumHandlers] = cbk;
}
function GDocumentOnKeyDown(evt) {
var bStopProcessing = false;
var rv = true;
// If there are keydown handlers and we have a valid event
if (gKeyDownHandlers != null) {
var e = new StdKeyEvent(evt);
if ((e != null) &&
(e.keyCode != 16) && // Don't report keydown for shift modifier key
(e.keyCode != 17) && // Don't report keydown for ctrl modifier key
(e.keyCode != 18)) { // Don't report keydown for alt modifier key
var f;
var nNumHandlers = gKeyDownHandlers.length;
// Call all registered handlers
for (var n=0; ((n < nNumHandlers) && !bStopProcessing); n++) {
f = gKeyDownHandlers[n];
rv = f(e);
if ((typeof rv == "boolean") && (rv == false)) {
bStopProcessing = true;
}
}
}
}
return rv;
}
function ClearKeyDownHandlers() {
gKeyDownHandlers = null;
}
function AddKeyDownHandler(cbk) {
if (gKeyDownHandlers == null) {
gKeyDownHandlers = new Array();
}
var nNumHandlers = gKeyDownHandlers.length;
gKeyDownHandlers[nNumHandlers] = cbk;
}
// Calls registered event handlers in the order they were registered,
// until encountering one that explicitly returns false, at which point
// it considers the event handled and returns false. If no handler
// returns false, it returns the last return value.
function GDocumentOnClick(evt) {
var bStopProcessing = false;
var rv = true;
//alert("GDocumentOnClick()");
// If there are click handlers and we have a valid event
if (gClickHandlers != null) {
var e = new StdMouseEvent(evt);
//alert(gClickHandlers.length + " click handlers");
if (e != null) {
var f;
var nNumHandlers = gClickHandlers.length;
// Call registered event handlers in the order they were registered,
for (var n=0; ((n < nNumHandlers) && !bStopProcessing); n++) {
f = gClickHandlers[n];
rv = f(e);
if ((typeof rv == "boolean") && (rv == false)) {
bStopProcessing = true;
}
}
}
}
return rv;
}
// Added 2004/2/11 to make it easier for clients to cancel events. Primarily useful for
// click events. Ordinarily could just return false to cancel a default action, such as
// navigating when clicking on a hyperlink, but now we have a global Click handler, which
// throws a wrench in the simple method. Thus, we need an explicit way to cancel an event,
// and here it is.
function CancelEvent(evt) {
// for IE
if (typeof evt.cancelBubble != "undefined") {
evt.cancelBubble = true;
evt.returnValue = false;
}
// for W3C/Mozilla
else if (typeof evt.stopPropagation != "undefined") {
evt.stopPropagation();
}
// so handlers can just return our return value.
return false;
}
function ClearClickHandlers() {
gClickHandlers = null;
}
function AddClickHandler(cbk) {
if (gClickHandlers == null) {
gClickHandlers = new Array();
}
var nNumHandlers = gClickHandlers.length;
gClickHandlers[nNumHandlers] = cbk;
}
/*
Some wrappers to hide browser differences for event objects
*/
function StdKeyEvent(e) {
if (e) {
this.event = e;
}
else if (window.event) {
this.event = window.event;
e = this.event;
}
else {
return null;
}
if (e.srcElement && e.keyCode) {
this.target = e.srcElement;
this.keyCode = e.keyCode;
}
else if (e.target && e.which) {
this.target = e.target;
this.keyCode = e.which;
}
else {
return null;
}
if (typeof e.shiftKey != "undefined") {
this.altKey = e.altKey;
this.ctrlKey = e.ctrlKey;
this.shiftKey = e.shiftKey;
}
else if (typeof e.modifiers != "undefined") {
this.altKey = e.modifiers & Event.ALT_MASK;
this.ctrlKey = e.modifiers & Event.CONTROL_MASK;
this.shiftKey = e.modifiers & Event.SHIFT_MASK;
}
else {
return null;
}
/*
if (typeof e.cancelBubble != "undefined") {
this.stopPropagation = new Function("this.event.cancelBubble = true;");
}
else if (typeof e.stopPropagation != "undefined") {
this.stopPropagation = new Function("this.event.stopPropagation();");
}
else {
this.stopPropagation = null;
}*/
}
function StdMouseEvent(e) {
if (e) {
this.event = e;
}
else if (window.event) {
this.event = window.event;
e = this.event;
}
else {
return null;
}
if (e.srcElement) {
this.target = e.srcElement;
}
else if (e.target) {
this.target = e.target;
}
else {
return null;
}
if (!e.pageX) {
e.pageX = e.clientX + document.body.scrollLeft;
e.pageY = e.clientY + document.body.scrollTop;
}
/* if (typeof e.cancelBubble != "undefined") {
this.stopPropagation = new Function("this.event.cancelBubble = true;");
}
else if (typeof e.stopPropagation != "undefined") {
this.stopPropagation = new Function("this.event.stopPropagation();");
}
else {
this.stopPropagation = null;
}
if (typeof e.shiftKey != "undefined") { Dbg("ie");
this.altKey = e.altKey;
this.ctrlKey = e.ctrlKey;
this.shiftKey = e.shiftKey;
}
else if (typeof e.modifiers != "undefined") { Dbg("nn");
this.altKey = e.modifiers & Event.ALT_MASK;
this.ctrlKey = e.modifiers & Event.CONTROL_MASK;
this.shiftKey = e.modifiers & Event.SHIFT_MASK;
}
else { Dbg("unknown");
return null;
}*/
}
function Dbg(s) {
// alert(s);
}
function DbgObject(o) {
var n = 0;
var s = o.toString();
for (p in o) {
s += p + " = " + o[p];
n++;
if ((n % 5) == 0) {
s += "\n";
}
else {
s += " ";
}
}
alert(s);
}
// ====================================================
// Begin functions for listbox sort and move
// ====================================================
// -------------------------------------------------------------------
// hasOptions(obj)
// Utility function to determine if a select object has an options array
// -------------------------------------------------------------------
function hasOptions(obj) {
if (obj!=null && obj.options!=null) { return true; }
return false;
}
// -------------------------------------------------------------------
// selectUnselectMatchingOptions(select_object,regex,select/unselect,true/false)
// This is a general function used by the select functions below, to
// avoid code duplication
// -------------------------------------------------------------------
function selectUnselectMatchingOptions(obj,regex,which,only) {
if (window.RegExp) {
if (which == "select") {
var selected1=true;
var selected2=false;
}
else if (which == "unselect") {
var selected1=false;
var selected2=true;
}
else {
return;
}
var re = new RegExp(regex);
if (!hasOptions(obj)) { return; }
for (var i=0; i (b.text+"")) { return 1; }
return 0;
}
);
for (var i=0; i object as follows:
// onDblClick="moveSelectedOptions(this,this.form.target)
// This way, when the user double-clicks on a value in one box, it
// will be transferred to the other (in browsers that support the
// onDblClick() event handler).
// -------------------------------------------------------------------
function moveSelectedOptions(from,to) {
// Unselect matching options, if required
if (arguments.length>3) {
var regex = arguments[3];
if (regex != "") {
unSelectMatchingOptions(from,regex);
}
}
// Move them over
if (!hasOptions(from)) { return; }
for (var i=0; i=0; i--) {
var o = from.options[i];
if (o.selected) {
from.options[i] = null;
}
}
if ((arguments.length<3) || (arguments[2]==true)) {
sortSelect(from);
sortSelect(to);
}
from.selectedIndex = -1;
to.selectedIndex = -1;
}
// -------------------------------------------------------------------
// copySelectedOptions(select_object,select_object[,autosort(true/false)])
// This function copies options between select boxes instead of
// moving items. Duplicates in the target list are not allowed.
// -------------------------------------------------------------------
function copySelectedOptions(from,to) {
var options = new Object();
if (hasOptions(to)) {
for (var i=0; i=0; i--) {
if (obj.options[i].selected) {
if (i != (obj.options.length-1) && ! obj.options[i+1].selected) {
swapOptions(obj,i,i+1);
obj.options[i+1].selected = true;
}
}
}
}
// -------------------------------------------------------------------
// removeSelectedOptions(select_object)
// Remove all selected options from a list
// (Thanks to Gene Ninestein)
// -------------------------------------------------------------------
function removeSelectedOptions(from) {
if (!hasOptions(from)) { return; }
for (var i=(from.options.length-1); i>=0; i--) {
var o=from.options[i];
if (o.selected) {
from.options[i] = null;
}
}
from.selectedIndex = -1;
}
// -------------------------------------------------------------------
// removeAllOptions(select_object)
// Remove all options from a list
// -------------------------------------------------------------------
function removeAllOptions(from) {
if (!hasOptions(from)) { return; }
for (var i=(from.options.length-1); i>=0; i--) {
from.options[i] = null;
}
from.selectedIndex = -1;
}
// -------------------------------------------------------------------
// addOption(select_object,display_text,value,selected)
// Add an option to a list
// -------------------------------------------------------------------
function addOption(obj,text,value,selected) {
if (obj!=null && obj.options!=null) {
obj.options[obj.options.length] = new Option(text, value, false, selected);
}
}