Skip to content

Instantly share code, notes, and snippets.

@think49
Created December 9, 2010 12:12
Show Gist options
  • Save think49/734657 to your computer and use it in GitHub Desktop.
Save think49/734657 to your computer and use it in GitHub Desktop.
ElementTraversal.js: W3C勧告の ElementTraversal を実装するJavaScriptライブラリ
/**
* ElementTraversal.js
*
* @version 1.0
* @author think49
*/
/**
* Interface Node
* http://www.w3.org/TR/DOM-Level-3-Core/core.html#ID-1950641247
*/
var Node = typeof Node === 'function' || typeof Node === 'object' ? Node : (function () {
function Node () { ; }
// NodeType
Node.ELEMENT_NODE = 1;
Node.ATTRIBUTE_NODE = 2;
Node.TEXT_NODE = 3;
Node.CDATA_SECTION_NODE = 4;
Node.ENTITY_REFERENCE_NODE = 5;
Node.ENTITY_NODE = 6;
Node.PROCESSING_INSTRUCTION_NODE = 7;
Node.COMMENT_NODE = 8;
Node.DOCUMENT_NODE = 9;
Node.DOCUMENT_TYPE_NODE = 10;
Node.DOCUMENT_FRAGMENT_NODE = 11;
Node.NOTATION_NODE = 12;
return Node;
})();
/**
* Interface ElementTraversal
* http://www.w3.org/TR/ElementTraversal/
* http://www.hcn.zaq.ne.jp/___/DOM/ElementTraversal.html
*/
if ('defineProperty' in Object && (Element === 'function' || typeof Element === 'object') && 'prototype' in Element &&
(!('firstElementChild' in document.createElement('p')) || !('lastElementChild' in document.createElement('p')) || !('previousElementSibling' in document.createElement('p')) || !('nextElementSibling' in document.createElement('p')) || !('childElementCount' in document.createElement('p')))) {
(function (element, ELEMENT_NODE) {
/**
* Element.prototype.firstElementChild
* readonly attribute Element
*/
if (!('firstElementChild' in element)) {
this.defineProperty(Element.prototype, 'firstElementChild', {get: function () {
var firstElementChild;
firstElementChild = this.firstChild;
while (firstElementChild) {
if (firstElementChild.nodeType === ELEMENT_NODE) {
break;
}
firstElementChild = firstElementChild.nextSibling;
}
return firstElementChild;
}});
}
/**
* Element.prototype.lastElementChild
* readonly attribute Element
*/
if (!('lastElementChild' in element)) {
this.defineProperty(Element.prototype, 'lastElementChild', {get: function () {
var lastElementChild;
lastElementChild = this.lastChild;
while (lastElementChild) {
if (lastElementChild.nodeType === ELEMENT_NODE) {
break;
}
lastElementChild = lastElementChild.previousSibling;
}
return lastElementChild;
}});
}
/**
* Element.prototype.previousElementSibling
* readonly attribute Element
*/
if (!('previousElementSibling' in element)) {
this.defineProperty(Element.prototype, 'previousElementSibling', {get: function () {
var previousElementSibling;
previousElementSibling = this.previousSibling;
while (previousElementSibling) {
if (previousElementSibling.nodeType === ELEMENT_NODE) {
break;
}
previousElementSibling = previousElementSibling.previousSibling;
}
return previousElementSibling;
}});
}
/**
* Element.prototype.nextElementSibling
* readonly attribute Element
*/
if (!('nextElementSibling' in element)) {
this.defineProperty(Element.prototype, 'nextElementSibling', {get: function () {
var nextElementSibling;
nextElementSibling = this.nextSibling;
while (nextElementSibling) {
if (nextElementSibling.nodeType === ELEMENT_NODE) {
break;
}
nextElementSibling = nextElementSibling.nextSibling;
}
return nextElementSibling;
}});
}
/**
* Element.prototype.childElementCount
* readonly attribute Element
*/
if (!('childElementCount' in element)) {
this.defineProperty(Element.prototype, 'childElementCount', {get: function () {
var childElementCount, childNodes, i, l;
childElementCount = 0;
childNodes = this.childNodes;
for (i = 0, l = childNodes.length; i < l; i++) {
if (childNodes[i].nodeType === ELEMENT_NODE) {
childElementCount++;
}
}
return childElementCount;
}});
}
}).call(Object, document.createElement('p'), Node.ELEMENT_NODE);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment