/* ***********************************************************
Example 4-3 (DHTMLapi.js)
"Dynamic HTML:The Definitive Reference"
2nd Edition
by Danny Goodman
Published by O'Reilly & Associates ISBN 1-56592-494-0
http://www.oreilly.com
Copyright 2002 Danny Goodman. All Rights Reserved.
************************************************************ */
// DHTMLapi.js custom API for cross-platform
// object positioning by Danny Goodman (http://www.dannyg.com).
// Release 2.0. Supports NN4, IE, and W3C DOMs.
// Global variables
var isCSS, isW3C, isIE4, isNN4, isIE, isIE6CSS;
// initialize upon load to let all browsers establish content objects
function initDHTMLAPI() {
if (document.images) {
isCSS = (document.body && document.body.style) ? true : false;
isW3C = (isCSS && document.getElementById) ? true : false;
isIE4 = (isCSS && document.all) ? true : false;
isNN4 = (document.layers) ? true : false;
isIE6CSS = (document.compatMode && document.compatMode.indexOf("CSS1") >= 0) ? true : false;
isIE = (navigator.userAgent.toLowerCase().indexOf("msie") > -1) ? true : false;
}
}
// Seek nested NN4 layer from string name
function seekLayer(doc, name) {
var theObj;
for (var i = 0; i < doc.layers.length; i++) {
if (doc.layers[i].name == name) {
theObj = doc.layers[i];
break;
}
// dive into nested layers if necessary
if (doc.layers[i].document.layers.length > 0) {
theObj = seekLayer(document.layers[i].document, name);
}
}
return theObj;
}
// Convert object name string or object reference
// into a valid element object reference
function getRawObject(obj) {
var theObj;
if (typeof obj == "string") {
if (isW3C) {
theObj = document.getElementById(obj);
} else if (isIE4) {
theObj = document.all(obj);
} else if (isNN4) {
theObj = seekLayer(document, obj);
}
} else {
// pass through object reference
theObj = obj;
}
return theObj;
}
// Convert object name string or object reference
// into a valid style (or NN4 layer) reference
function getObject(obj) {
var theObj = getRawObject(obj);
if (theObj && isCSS) {
theObj = theObj.style;
}
return theObj;
}
// Position an object at a specific pixel coordinate
function shiftTo(obj, x, y) {
var theObj = getObject(obj);
if (theObj) {
if (isCSS) {
// equalize incorrect numeric value type
var units = (typeof theObj.left == "string") ? "px" : 0 
theObj.left = x + units;
theObj.top = y + units;
} else if (isNN4) {
theObj.moveTo(x,y)
} else {
theObj.style.left = x + "px";
theObj.style.top = y + "px";
}
}
}
// Move an object by x and/or y pixels
function shiftBy(obj, deltaX, deltaY) {
var theObj = getObject(obj);
if (theObj) {
if (isCSS) {
// equalize incorrect numeric value type
var units = (typeof theObj.left == "string") ? "px" : 0 
theObj.left = getObjectLeft(obj) + deltaX + units;
theObj.top = getObjectTop(obj) + deltaY + units;
} else if (isNN4) {
theObj.moveBy(deltaX, deltaY);
}
}
}
// Set the z-order of an object
function setZIndex(obj, zOrder) {
var theObj = getObject(obj);
if (theObj) {
theObj.zIndex = zOrder;
}
}
// Set the background color of an object
function setBGColor(obj, color) {
var theObj = getObject(obj);
if (theObj) {
if (isNN4) {
theObj.bgColor = color;
} else if (isCSS) {
theObj.backgroundColor = color;
}
}
}
// Set the visibility of an object to visible
function show(obj) {
var theObj = getObject(obj);
if (theObj) {
theObj.visibility = "visible";
}
}
// Set the visibility of an object to hidden
function hide(obj) {
var theObj = getObject(obj);
if (theObj) {
theObj.visibility = "hidden";
}
}
// Retrieve the x coordinate of a positionable object
function getObjectLeft(obj) {
if (isIE)
{
var elem = getRawObject(obj);
var result = 0;
if (document.defaultView) {
var style = document.defaultView;
var cssDecl = style.getComputedStyle(elem, "");
result = cssDecl.getPropertyValue("left");
} else if (elem.currentStyle) {
result = elem.currentStyle.left;
} else if (elem.style) {
result = elem.style.left;
} else if (isNN4) {
result = elem.left;
}
return parseInt(result);
}
else
{
var elem = getRawObject(obj);
var result = 0;
if (elem.currentStyle) {
result = elem.currentStyle.left;
} else if (elem.style) {
result = elem.style.left;
} else if (isNN4) {
result = elem.left;
}
return parseInt(result);
}
}
// Retrieve the y coordinate of a positionable object
function getObjectTop(obj) {
if (isIE)
{
var elem = getRawObject(obj);
var result = 0;
if (document.defaultView) {
var style = document.defaultView;
var cssDecl = style.getComputedStyle(elem, "");
result = cssDecl.getPropertyValue("top");
} else if (elem.currentStyle) {
result = elem.currentStyle.top;
} else if (elem.style) {
result = elem.style.top;
} else if (isNN4) {
result = elem.top;
}
return parseInt(result);
}
else
{
var elem = getRawObject(obj);
var result = 0;
if (elem.currentStyle) {
result = elem.currentStyle.top;
} else if (elem.style) {
result = elem.style.top;
} else if (isNN4) {
result = elem.top;
}
return parseInt(result);
}
}
// Retrieve the rendered width of an element
function getObjectWidth(obj) {
var elem = getRawObject(obj);
var result = 0;
if (elem.offsetWidth) {
result = elem.offsetWidth;
} else if (elem.clip && elem.clip.width) {
result = elem.clip.width;
} else if (elem.style && elem.style.pixelWidth) {
result = elem.style.pixelWidth;
}
return parseInt(result);
}
function setObjectWidth(obj, value) {
var offset = 0;
// Create a width attribute if one does not exist
if (!obj.style.width)
obj.style.width = "1px";
if (!gIsIE)
offset = parseInt(obj.style.width) - getObjectWidth(obj);
obj.style.width = value + offset + "px";
}
// Retrieve the rendered height of an element
function getObjectHeight(obj) {
var elem = getRawObject(obj);
var result = 0;
if (elem.offsetHeight) {
result = elem.offsetHeight;
} else if (elem.clip && elem.clip.height) {
result = elem.clip.height;
} else if (elem.style && elem.style.pixelHeight) {
result = elem.style.pixelHeight;
}
return parseInt(result);
}
function setObjectHeight(obj, value) {
var offset = 0;
// Create a height attribute if one does not exist
if (!obj.style.height)
obj.style.height = "1px";
if (!gIsIE)
offset = parseInt(obj.style.height) - getObjectHeight(obj);
obj.style.height = value + offset + "px";
}
// Return the available content width space in browser window
function getInsideWindowWidth() {
if (window.innerWidth) {
return window.innerWidth;
} else if (isIE6CSS) {
// measure the html element's clientWidth
return document.body.parentElement.clientWidth;
} else if (document.body && document.body.clientWidth) {
return document.body.clientWidth;
}
return 0;
}
// Return the available content height space in browser window
function getInsideWindowHeight(window) {
if (window.innerHeight) {
return window.innerHeight;
} else if (window.document.compatMode && window.document.compatMode.indexOf("CSS1") >= 0) {
// measure the html element's clientHeight
return window.document.body.parentElement.clientHeight
} else if (window.document.body && window.document.body.clientHeight) {
return window.document.body.clientHeight;
}
return 0;
}
// From "Javascript & DHTML Cookbook", O'Reilly 2003
function getElementPosition(elem, root)
{
var offsetTrail = elem;
var offsetLeft = 0;
var offsetTop = 0;
while (offsetTrail && offsetTrail != root) {
offsetLeft += offsetTrail.offsetLeft;
offsetTop += offsetTrail.offsetTop;
offsetTrail = offsetTrail.offsetParent;
}
/*
if (navigation.userAgent.indexOf("Mac") != -1 &&
typeof document.body.leftMargin != "undefined") {
offsetLeft += document.body.leftMargin;
offsetTop += document.body.topMargin;
}
*/
return {left:offsetLeft, top:offsetTop};
}
// Returns { x: 50, y: 50 } with the x/y location of the mouse for the given event.
function getMousePosition(e, sourceFrame)
{
var posx = 0;
var posy = 0;
if (e.pageX || e.pageY)
{
posx = e.pageX;
posy = e.pageY;
}
else if (e.clientX || e.clientY)
{
posx = e.clientX + (sourceFrame.document.documentElement.scrollLeft > 0 ? sourceFrame.document.documentElement.scrollLeft : sourceFrame.document.body.scrollLeft);
posy = e.clientY + (sourceFrame.document.documentElement.scrollTop > 0 ? sourceFrame.document.documentElement.scrollTop : sourceFrame.document.body.scrollTop);
}
return { x: posx, y: posy };
}
// How far down we have scrolled
function getScrollY(sourceFrame)
{
// Gets the y scroll offset in a cross browser kinda way
return isDefined(sourceFrame.pageYOffset) ? sourceFrame.pageYOffset : (sourceFrame.document.documentElement.scrollTop > 0 ? sourceFrame.document.documentElement.scrollTop : sourceFrame.document.body.scrollTop);
}
function getScrollX(sourceFrame)
{
// Gets the x scroll offset in a cross browser kinda way
return isDefined(sourceFrame.pageXOffset) ? sourceFrame.pageXOffset : (sourceFrame.document.documentElement.scrollLeft > 0 ? sourceFrame.document.documentElement.scrollLeft : sourceFrame.document.body.scrollLeft);
}
function isDefined(object)
{
return (typeof(object) != 'undefined' && object != null);
}
// Change the scroll bars by dx and dy in the document body object passed.
// If the resulting position is greater or less than the range of scroll
// bar values, the scroll value will be set to its corresponding extreme
function incrementScrollBar(obj_body, dx, dy)
{
obj_body.scrollLeft = obj_body.scrollLeft + dx;
obj_body.scrollTop = obj_body.scrollTop + dy;
}