You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
209 lines
5.9 KiB
209 lines
5.9 KiB
var domWalk = require("dom-walk") |
|
var dispatchEvent = require("./event/dispatch-event.js") |
|
var addEventListener = require("./event/add-event-listener.js") |
|
var removeEventListener = require("./event/remove-event-listener.js") |
|
var serializeNode = require("./serialize.js") |
|
|
|
var htmlns = "http://www.w3.org/1999/xhtml" |
|
|
|
module.exports = DOMElement |
|
|
|
function DOMElement(tagName, owner, namespace) { |
|
if (!(this instanceof DOMElement)) { |
|
return new DOMElement(tagName) |
|
} |
|
|
|
var ns = namespace === undefined ? htmlns : (namespace || null) |
|
|
|
this.tagName = ns === htmlns ? String(tagName).toUpperCase() : tagName |
|
this.nodeName = this.tagName |
|
this.className = "" |
|
this.dataset = {} |
|
this.childNodes = [] |
|
this.parentNode = null |
|
this.style = {} |
|
this.ownerDocument = owner || null |
|
this.namespaceURI = ns |
|
this._attributes = {} |
|
|
|
if (this.tagName === 'INPUT') { |
|
this.type = 'text' |
|
} |
|
} |
|
|
|
DOMElement.prototype.type = "DOMElement" |
|
DOMElement.prototype.nodeType = 1 |
|
|
|
DOMElement.prototype.appendChild = function _Element_appendChild(child) { |
|
if (child.parentNode) { |
|
child.parentNode.removeChild(child) |
|
} |
|
|
|
this.childNodes.push(child) |
|
child.parentNode = this |
|
|
|
return child |
|
} |
|
|
|
DOMElement.prototype.replaceChild = |
|
function _Element_replaceChild(elem, needle) { |
|
// TODO: Throw NotFoundError if needle.parentNode !== this |
|
|
|
if (elem.parentNode) { |
|
elem.parentNode.removeChild(elem) |
|
} |
|
|
|
var index = this.childNodes.indexOf(needle) |
|
|
|
needle.parentNode = null |
|
this.childNodes[index] = elem |
|
elem.parentNode = this |
|
|
|
return needle |
|
} |
|
|
|
DOMElement.prototype.removeChild = function _Element_removeChild(elem) { |
|
// TODO: Throw NotFoundError if elem.parentNode !== this |
|
|
|
var index = this.childNodes.indexOf(elem) |
|
this.childNodes.splice(index, 1) |
|
|
|
elem.parentNode = null |
|
return elem |
|
} |
|
|
|
DOMElement.prototype.insertBefore = |
|
function _Element_insertBefore(elem, needle) { |
|
// TODO: Throw NotFoundError if referenceElement is a dom node |
|
// and parentNode !== this |
|
|
|
if (elem.parentNode) { |
|
elem.parentNode.removeChild(elem) |
|
} |
|
|
|
var index = needle === null || needle === undefined ? |
|
-1 : |
|
this.childNodes.indexOf(needle) |
|
|
|
if (index > -1) { |
|
this.childNodes.splice(index, 0, elem) |
|
} else { |
|
this.childNodes.push(elem) |
|
} |
|
|
|
elem.parentNode = this |
|
return elem |
|
} |
|
|
|
DOMElement.prototype.setAttributeNS = |
|
function _Element_setAttributeNS(namespace, name, value) { |
|
var prefix = null |
|
var localName = name |
|
var colonPosition = name.indexOf(":") |
|
if (colonPosition > -1) { |
|
prefix = name.substr(0, colonPosition) |
|
localName = name.substr(colonPosition + 1) |
|
} |
|
if (this.tagName === 'INPUT' && name === 'type') { |
|
this.type = value; |
|
} |
|
else { |
|
var attributes = this._attributes[namespace] || (this._attributes[namespace] = {}) |
|
attributes[localName] = {value: value, prefix: prefix} |
|
} |
|
} |
|
|
|
DOMElement.prototype.getAttributeNS = |
|
function _Element_getAttributeNS(namespace, name) { |
|
var attributes = this._attributes[namespace]; |
|
var value = attributes && attributes[name] && attributes[name].value |
|
if (this.tagName === 'INPUT' && name === 'type') { |
|
return this.type; |
|
} |
|
if (typeof value !== "string") { |
|
return null |
|
} |
|
return value |
|
} |
|
|
|
DOMElement.prototype.removeAttributeNS = |
|
function _Element_removeAttributeNS(namespace, name) { |
|
var attributes = this._attributes[namespace]; |
|
if (attributes) { |
|
delete attributes[name] |
|
} |
|
} |
|
|
|
DOMElement.prototype.hasAttributeNS = |
|
function _Element_hasAttributeNS(namespace, name) { |
|
var attributes = this._attributes[namespace] |
|
return !!attributes && name in attributes; |
|
} |
|
|
|
DOMElement.prototype.setAttribute = function _Element_setAttribute(name, value) { |
|
return this.setAttributeNS(null, name, value) |
|
} |
|
|
|
DOMElement.prototype.getAttribute = function _Element_getAttribute(name) { |
|
return this.getAttributeNS(null, name) |
|
} |
|
|
|
DOMElement.prototype.removeAttribute = function _Element_removeAttribute(name) { |
|
return this.removeAttributeNS(null, name) |
|
} |
|
|
|
DOMElement.prototype.hasAttribute = function _Element_hasAttribute(name) { |
|
return this.hasAttributeNS(null, name) |
|
} |
|
|
|
DOMElement.prototype.removeEventListener = removeEventListener |
|
DOMElement.prototype.addEventListener = addEventListener |
|
DOMElement.prototype.dispatchEvent = dispatchEvent |
|
|
|
// Un-implemented |
|
DOMElement.prototype.focus = function _Element_focus() { |
|
return void 0 |
|
} |
|
|
|
DOMElement.prototype.toString = function _Element_toString() { |
|
return serializeNode(this) |
|
} |
|
|
|
DOMElement.prototype.getElementsByClassName = function _Element_getElementsByClassName(classNames) { |
|
var classes = classNames.split(" "); |
|
var elems = [] |
|
|
|
domWalk(this, function (node) { |
|
if (node.nodeType === 1) { |
|
var nodeClassName = node.className || "" |
|
var nodeClasses = nodeClassName.split(" ") |
|
|
|
if (classes.every(function (item) { |
|
return nodeClasses.indexOf(item) !== -1 |
|
})) { |
|
elems.push(node) |
|
} |
|
} |
|
}) |
|
|
|
return elems |
|
} |
|
|
|
DOMElement.prototype.getElementsByTagName = function _Element_getElementsByTagName(tagName) { |
|
tagName = tagName.toLowerCase() |
|
var elems = [] |
|
|
|
domWalk(this.childNodes, function (node) { |
|
if (node.nodeType === 1 && (tagName === '*' || node.tagName.toLowerCase() === tagName)) { |
|
elems.push(node) |
|
} |
|
}) |
|
|
|
return elems |
|
} |
|
|
|
DOMElement.prototype.contains = function _Element_contains(element) { |
|
return domWalk(this, function (node) { |
|
return element === node |
|
}) || false |
|
}
|
|
|