dom.js
Summary
A collection of objects and methods to extend the Document Object Model.
Version: 0.8
$Id: overview-summary-dom.js.html,v 1.12 2006/08/23 23:30:17 jameso Exp $
Author: James A. Overton
mozile.provide("mozile.dom.*");
mozile.provide("mozile.dom.Range");
mozile.provide("mozile.dom.Selection");
mozile.dom = new Object();
mozile.dom.prototype = new mozile.Module;
mozile.dom.ELEMENT_NODE = 1;
mozile.dom.ATTRIBUTE_NODE = 2;
mozile.dom.TEXT_NODE = 3;
mozile.dom.CDATA_SECTION_NODE = 4;
mozile.dom.ENTITY_REFERENCE_NODE = 5;
mozile.dom.ENTITY_NODE = 6;
mozile.dom.PROCESSING_INSTRUCTION_NODE = 7;
mozile.dom.COMMENT_NODE = 8;
mozile.dom.DOCUMENT_NODE = 9;
mozile.dom.DOCUMENT_TYPE_NODE = 10;
mozile.dom.DOCUMENT_FRAGMENT_NODE = 11;
mozile.dom.NOTATION_NODE = 12;
mozile.dom.links = new Array();
mozile.dom.getBody = function(node) {
var doc = document;
if(node) doc = node.ownerDocument;
var elements = doc.getElementsByTagName("body");
if(elements && elements[0]) return elements[0];
else return doc.documentElement;
}
mozile.dom.getHead = function(node) {
var doc = document;
if(node) doc = node.ownerDocument;
var elements = doc.getElementsByTagName("head");
if(elements && elements[0]) return elements[0];
else return doc.documentElement;
}
mozile.dom.getFirstChildElement = function(parent) {
for(var i=0; i < parent.childNodes.length; i++) {
if(parent.childNodes[i].nodeType == mozile.dom.ELEMENT_NODE)
return parent.childNodes[i];
}
return null;
}
mozile.dom.getChildElements = function(parent) {
var children = new Array();
for(var i=0; i < parent.childNodes.length; i++) {
if(parent.childNodes[i].nodeType == mozile.dom.ELEMENT_NODE)
children.push(parent.childNodes[i]);
}
return children;
}
mozile.dom.getNextSiblingElement = function(node) {
var sibling = node.nextSibling;
while(sibling) {
if(sibling.nodeType == mozile.dom.ELEMENT_NODE) return sibling;
sibling = sibling.nextSibling;
}
return null;
}
mozile.dom.insertAfter = function(newNode, refNode) {
if(!newNode) throw("Error [mozile.dom.insertAfter]: No newNode. newNode: "+ newNode +" refNode: "+ refNode);
if(!refNode) throw("Error [mozile.dom.insertAfter]: No refNode. newNode: "+ newNode +" refNode: "+ refNode);
var parentNode = refNode.parentNode;
if(!parentNode) return null;
if(refNode.nextSibling) return parentNode.insertBefore(newNode, refNode.nextSibling);
else return parentNode.appendChild(newNode);
}
mozile.dom.prependChild = function(newNode, parentNode) {
if(parentNode.firstChild) return parentNode.insertBefore(newNode, parentNode.firstChild);
else return parentNode.appendChild(newNode);
}
mozile.dom.isAncestorOf = function(ancestorNode, descendantNode, limitNode) {
var checkNode = descendantNode;
while(checkNode) {
if(checkNode == ancestorNode) return true;
else if(checkNode == limitNode) return false;
else checkNode = checkNode.parentNode;
}
return false;
}
mozile.dom.getCommonAncestor = function(firstNode, secondNode) {
var ancestor = firstNode;
while(ancestor) {
if(mozile.dom.isAncestorOf(ancestor, secondNode)) return ancestor;
else ancestor = ancestor.parentNode;
}
return null;
}
mozile.dom._matchNonWhitespace = /\S/;
mozile.dom.isWhitespace = function(node) {
if(!node || !node.nodeValue) return false;
if(node.nodeValue.match(mozile.dom._matchNonWhitespace)) return false;
return true;
}
mozile.dom.isHTML = function(node) {
if(!node) node = document;
var doc = node;
if(node.ownerDocument) doc = node.ownerDocument;
if(!doc.documentElement) return false;
var name = doc.documentElement.nodeName;
if(doc.documentElement.nodeName) name = doc.documentElement.nodeName;
if(name.toLowerCase() == "html") return true;
else return false;
}
mozile.dom.isIgnored = function(node) {
if(node.nodeType == mozile.dom.ATTRIBUTE_NODE){
if(node.nodeName.indexOf("xmlns") == 0) return true;
if(mozile.browser.isOpera && node.nodeName.toLowerCase() == "shape") return true;
}
return false;
}
mozile.dom.getLocalName = function(node) {
if(!node) return null;
if(node.localName) return node.localName;
else if(node.nodeName && node.nodeName.indexOf(":") > -1)
return node.nodeName.substring(node.nodeName.indexOf(":") + 1);
else return node.nodeName;
}
mozile.dom.getPrefix = function(node) {
if(!node) return null;
if(node.prefix) return node.prefix;
else if(node.nodeName.indexOf(":") > -1)
return node.nodeName.substring(0, node.nodeName.indexOf(":"));
else return null;
}
mozile.dom.getIndex = function(node) {
if(!node.parentNode) return null;
for(var c=0; c < node.parentNode.childNodes.length; c++) {
if(node.parentNode.childNodes[c] == node) return c;
}
return c;
}
mozile.dom.getPosition = function(node) {
if(!node.parentNode) return null;
var s=1;
for(var c=0; c < node.parentNode.childNodes.length; c++) {
if(node.parentNode.childNodes[c] == node) break;
else if(node.nodeType == mozile.dom.ELEMENT_NODE) {
if(node.parentNode.childNodes[c].nodeName == node.nodeName) s++;
}
else if(node.parentNode.childNodes[c].nodeType == node.nodeType) s++;
}
return s;
}
mozile.dom.removeChildNodes = function(node) {
if(node.childNodes.length == 0) return;
while(node.firstChild) {
node.removeChild(node.firstChild);
}
}
mozile.dom.getNamespaceURI = function(node) {
if(node.namespaceURI) return node.namespaceURI;
else if(node.nodeName.indexOf(":") > -1) {
var prefix = node.nodeName.substring(0, node.nodeName.indexOf(":"));
return mozile.dom.lookupNamespaceURI(node, prefix);
}
return mozile.dom.getDefaultNamespaceURI(node);
}
mozile.dom.getDefaultNamespaceURI = function(node) {
var namespaceURI = null;
while(node) {
if(node.nodeType == mozile.dom.ELEMENT_NODE && node.getAttribute("xmlns"))
return node.getAttribute("xmlns");
node = node.parentNode;
}
return namespaceURI;
}
mozile.dom.lookupNamespaceURI = function(node, prefix) {
if(!prefix) prefix = mozile.dom.getPrefix(node);
var attr = "xmlns";
if(prefix && node.lookupNamespaceURI) {
while(node) {
var ns = node.lookupNamespaceURI(prefix);
if(ns) return ns;
else node = node.parentNode;
}
return null;
}
if(prefix && mozile.browser.isSafari) {
while(node && node.getAttributeNS) {
if(node.getAttributeNS(attr, prefix)) return node.getAttributeNS(attr, prefix);
else node = node.parentNode;
}
return null;
}
if(prefix) attr = "xmlns:"+prefix;
while(node) {
if(node.getAttribute(attr)) return node.getAttribute(attr);
else node = node.parentNode;
}
return null;
}
mozile.dom.lookupPrefix = function(node, namespaceURI) {
if(!namespaceURI) namespaceURI = node.namespaceURI;
if(!namespaceURI) return null;
while(node && node.attributes) {
for(var i=0; i < node.attributes.length; i++) {
if(node.attributes[i].nodeName.indexOf("xmlns:") == 0 &&
node.attributes[i].nodeValue == namespaceURI) {
return node.attributes[i].nodeName.substring(6);
}
}
node = node.parentNode;
}
return null;
}
mozile.dom.convertStyleName = function(styleName) {
if(!styleName || typeof(styleName) != "string") return null;
return styleName.replace(/\-(\w)/g, function (strMatch, p1){
return p1.toUpperCase();
});
}
mozile.dom.getStyle = function(node, cssRule) {
var value = "";
if(!node) return value;
if(node.nodeType != mozile.dom.ELEMENT_NODE) node = node.parentNode;
if(!node || node.nodeType != mozile.dom.ELEMENT_NODE) return value;
if(document.defaultView && document.defaultView.getComputedStyle){
value = document.defaultView.getComputedStyle(node, "").getPropertyValue(cssRule);
}
else if(node.currentStyle){
cssRule = mozile.dom.convertStyleName(cssRule);
value = node.currentStyle[cssRule];
}
return value;
}
mozile.dom.setStyle = function(element, rule, value) {
if(!element) return;
if(!rule || typeof(rule) != "string") return;
rule = mozile.dom.convertStyleName(rule);
if(element.style) element.style[rule] = value;
else mozile.debug.debug("mozile.dom.setStyle", "Element does not have a 'style' attribute.");
}
mozile.dom.addStyleSheet = function(href, type) {
var link;
if(mozile.defaultNS != null) {
mozile.require("mozile.xml");
link = mozile.dom.createElementNS(mozile.xml.ns.xhtml, "link");
}
else link = mozile.dom.createElement("link");
link.setAttribute("class", "mozileLink");
link.setAttribute("href", href);
link.setAttribute("rel", "stylesheet");
if(!type) type = "text/css";
link.setAttribute("type", type);
mozile.dom.getHead().appendChild(link);
mozile.dom.links.push(link);
}
mozile.dom.getX = function(obj, container) {
var x = 0;
if(obj.offsetParent) {
while(obj.offsetParent) {
x += obj.offsetLeft;
obj = obj.offsetParent;
if(obj == container) break;
}
}
else if (obj.x) x += obj.x;
return x;
}
mozile.dom.getY = function(obj, container) {
var y = 0;
if(obj.offsetParent) {
while(obj.offsetParent) {
y += obj.offsetTop;
obj = obj.offsetParent;
if(obj == container) break;
}
}
else if (obj.y) y += obj.y;
return y;
}
mozile.dom.selection = new Object();
mozile.dom.selection.prototype = new mozile.Module;
mozile.dom.selection.get = function() {
if(!mozile.dom._selection) mozile.dom._selection = new mozile.dom.Selection();
else if(mozile.browser.isIE) mozile.dom._selection._init();
return mozile.dom._selection;
}
mozile.dom.getAttributeNS = function(element, namespaceURI, name) {
if(!element) return null;
if(element.getAttributeNS) return element.getAttributeNS(namespaceURI, name);
else {
prefix = mozile.dom.lookupPrefix(element, namespaceURI);
if(prefix) return element.getAttribute(prefix+":"+name);
}
return null;
}
mozile.dom.createElement = function(name) {
if(mozile.defaultNS) {
return mozile.dom.createElementNS(mozile.defaultNS, name);
} else {
return document.createElement(name);
}
}
mozile.dom.createElementNS = function(namespaceURI, name) {
if(document.createElementNS && !mozile.browser.isSafari) return document.createElementNS(namespaceURI, name);
else {
mozile.require("mozile.xml");
return mozile.xml.parseElement('<'+ name +' xmlns="'+ namespaceURI +'"/>');
}
return null;
}
mozile.dom.Range = function(selectRange) {
if (document.createRange) {
var range;
if(selectRange) range = selectRange.cloneRange();
else range = document.createRange();
for(var field in mozile.dom.Range.prototype)
range[field] = mozile.dom.Range.prototype[field];
return range;
} else {
if(selectRange && selectRange._range) {
var range = new mozile.dom.InternetExplorerRange(selectRange._range.duplicate());
range._init();
return range;
}
else return new mozile.dom.InternetExplorerRange();
}
}
mozile.dom.Range.prototype.store = function () {
var state = new Object();
if(false && this._range) {
state.format = "IE";
state.bookmark = this._range.getBookmark();
}
else {
mozile.require("mozile.xpath");
state.type = "Range";
state.format = "W3C";
state.startContainer = mozile.xpath.getXPath(this.startContainer);
state.startOffset = this.startOffset;
if(this.startContainer == this.endContainer)
state.endContainer = state.startContainer;
else state.endContainer = mozile.xpath.getXPath(this.endContainer);
state.endContainer = mozile.xpath.getXPath(this.endContainer);
state.endOffset = this.endOffset;
}
return state;
}
mozile.dom.Range.prototype.restore = function(state) {
try {
if(false && this._range) {
this._range.moveToBookmark(state.bookmark);
this._init();
}
else {
mozile.require("mozile.xpath");
var startContainer, endContainer;
startContainer = mozile.xpath.getNode(state.startContainer);
this.setStart(startContainer, state.startOffset);
if(state.endContainer == state.startContainer)
endContainer = startContainer;
else endContainer = mozile.xpath.getNode(state.endContainer);
this.setEnd(endContainer, state.endOffset);
}
} catch(e) {
alert("Error [mozile.dom.Range.restore]:\n"+ mozile.dumpError(e))
}
}
mozile.dom.Selection = function() {
if (window.getSelection) {
var selection = window.getSelection();
for(var field in mozile.dom.Selection.prototype)
selection[field] = mozile.dom.Selection.prototype[field];
return selection;
} else {
return new mozile.dom.InternetExplorerSelection();
}
}
mozile.dom.Selection.prototype.store = function(oldState, newOffset) {
var state = new Object();
if(oldState) {
for(var i in oldState) state[i] = oldState[i];
state.anchorOffset = newOffset;
state.focusOffset = newOffset;
return state;
}
else if(this.rangeCount > 0) {
mozile.require("mozile.xpath");
state.type = "Selection";
state.format = "W3C";
state.anchorNode = mozile.xpath.getXPath(this.anchorNode);
state.anchorOffset = this.anchorOffset;
if(this.focusNode == this.anchorNode) state.focusNode = state.anchorNode;
else state.focusNode = mozile.xpath.getXPath(this.focusNode);
state.focusOffset = this.focusOffset;
state.isCollapsed = this.isCollapsed;
return state;
}
return null;
}
mozile.dom.Selection.prototype.restore = function(state) {
if(state) {
if(state.type == "Selection") {
mozile.require("mozile.xpath");
var anchorNode, focusNode;
anchorNode = mozile.xpath.getNode(state.anchorNode);
this.collapse(anchorNode, state.anchorOffset);
if(state.focusNode != state.anchorNode ||
state.focusOffset != state.anchorOffset ) {
if(state.focusNode == state.anchorNode) focusNode = anchorNode;
else focusNode = mozile.xpath.getNode(state.focusNode);
try {
this.extend(focusNode, state.focusOffset);
} catch(e) {
mozile.debug.debug("mozile.dom.Selection.restore", "Error extending selection to '"+ state.focusNode +" "+ state.focusOffset +"'.\n"+ mozile.dumpError(e) );
}
}
}
else if(state.type == "Range") {
var range = new mozile.dom.Range();
range.restore(state);
this.removeAllRanges();
this.addRange(range);
}
}
else if(mozile.dom.selection.last) {
this.collapse(mozile.dom.selection.last.anchorNode,
mozile.dom.selection.last.anchorOffset);
if(!mozile.dom.selection.last.isCollapsed) {
this.extend(mozile.dom.selection.last.focusNode,
mozile.dom.selection.last.focusOffset);
}
}
}
mozile.dom.Selection.getSelection = function () {
if(window.getSelection) {
return window.getSelection();
} else if (document.getSelection) {
return document.getSelection();
} else if(document.selection) {
return new mozile.dom.Selection();
}
return null;
}
if(mozile.browser.isIE) {
mozile.require("mozile.dom.TreeWalker");
mozile.require("mozile.dom.InternetExplorerRange");
mozile.require("mozile.dom.InternetExplorerSelection");
}
else {
mozile.dom.NodeFilter = NodeFilter;
mozile.dom.TreeWalker = TreeWalker;
}
Documentation generated by
JSDoc on Wed Aug 23 18:45:51 2006