1 var domWalk = require("dom-walk")
2 var dispatchEvent = require("./event/dispatch-event.js")
3 var addEventListener = require("./event/add-event-listener.js")
4 var removeEventListener = require("./event/remove-event-listener.js")
5 var serializeNode = require("./serialize.js")
7 var htmlns = "http://www.w3.org/1999/xhtml"
9 module.exports = DOMElement
11 function DOMElement(tagName, owner, namespace) {
12 if (!(this instanceof DOMElement)) {
13 return new DOMElement(tagName)
16 var ns = namespace === undefined ? htmlns : (namespace || null)
18 this.tagName = ns === htmlns ? String(tagName).toUpperCase() : tagName
19 this.nodeName = this.tagName
23 this.parentNode = null
25 this.ownerDocument = owner || null
26 this.namespaceURI = ns
29 if (this.tagName === 'INPUT') {
34 DOMElement.prototype.type = "DOMElement"
35 DOMElement.prototype.nodeType = 1
37 DOMElement.prototype.appendChild = function _Element_appendChild(child) {
38 if (child.parentNode) {
39 child.parentNode.removeChild(child)
42 this.childNodes.push(child)
43 child.parentNode = this
48 DOMElement.prototype.replaceChild =
49 function _Element_replaceChild(elem, needle) {
50 // TODO: Throw NotFoundError if needle.parentNode !== this
52 if (elem.parentNode) {
53 elem.parentNode.removeChild(elem)
56 var index = this.childNodes.indexOf(needle)
58 needle.parentNode = null
59 this.childNodes[index] = elem
60 elem.parentNode = this
65 DOMElement.prototype.removeChild = function _Element_removeChild(elem) {
66 // TODO: Throw NotFoundError if elem.parentNode !== this
68 var index = this.childNodes.indexOf(elem)
69 this.childNodes.splice(index, 1)
71 elem.parentNode = null
75 DOMElement.prototype.insertBefore =
76 function _Element_insertBefore(elem, needle) {
77 // TODO: Throw NotFoundError if referenceElement is a dom node
78 // and parentNode !== this
80 if (elem.parentNode) {
81 elem.parentNode.removeChild(elem)
84 var index = needle === null || needle === undefined ?
86 this.childNodes.indexOf(needle)
89 this.childNodes.splice(index, 0, elem)
91 this.childNodes.push(elem)
94 elem.parentNode = this
98 DOMElement.prototype.setAttributeNS =
99 function _Element_setAttributeNS(namespace, name, value) {
102 var colonPosition = name.indexOf(":")
103 if (colonPosition > -1) {
104 prefix = name.substr(0, colonPosition)
105 localName = name.substr(colonPosition + 1)
107 if (this.tagName === 'INPUT' && name === 'type') {
111 var attributes = this._attributes[namespace] || (this._attributes[namespace] = {})
112 attributes[localName] = {value: value, prefix: prefix}
116 DOMElement.prototype.getAttributeNS =
117 function _Element_getAttributeNS(namespace, name) {
118 var attributes = this._attributes[namespace];
119 var value = attributes && attributes[name] && attributes[name].value
120 if (this.tagName === 'INPUT' && name === 'type') {
123 if (typeof value !== "string") {
129 DOMElement.prototype.removeAttributeNS =
130 function _Element_removeAttributeNS(namespace, name) {
131 var attributes = this._attributes[namespace];
133 delete attributes[name]
137 DOMElement.prototype.hasAttributeNS =
138 function _Element_hasAttributeNS(namespace, name) {
139 var attributes = this._attributes[namespace]
140 return !!attributes && name in attributes;
143 DOMElement.prototype.setAttribute = function _Element_setAttribute(name, value) {
144 return this.setAttributeNS(null, name, value)
147 DOMElement.prototype.getAttribute = function _Element_getAttribute(name) {
148 return this.getAttributeNS(null, name)
151 DOMElement.prototype.removeAttribute = function _Element_removeAttribute(name) {
152 return this.removeAttributeNS(null, name)
155 DOMElement.prototype.hasAttribute = function _Element_hasAttribute(name) {
156 return this.hasAttributeNS(null, name)
159 DOMElement.prototype.removeEventListener = removeEventListener
160 DOMElement.prototype.addEventListener = addEventListener
161 DOMElement.prototype.dispatchEvent = dispatchEvent
164 DOMElement.prototype.focus = function _Element_focus() {
168 DOMElement.prototype.toString = function _Element_toString() {
169 return serializeNode(this)
172 DOMElement.prototype.getElementsByClassName = function _Element_getElementsByClassName(classNames) {
173 var classes = classNames.split(" ");
176 domWalk(this, function (node) {
177 if (node.nodeType === 1) {
178 var nodeClassName = node.className || ""
179 var nodeClasses = nodeClassName.split(" ")
181 if (classes.every(function (item) {
182 return nodeClasses.indexOf(item) !== -1
192 DOMElement.prototype.getElementsByTagName = function _Element_getElementsByTagName(tagName) {
193 tagName = tagName.toLowerCase()
196 domWalk(this.childNodes, function (node) {
197 if (node.nodeType === 1 && (tagName === '*' || node.tagName.toLowerCase() === tagName)) {
205 DOMElement.prototype.contains = function _Element_contains(element) {
206 return domWalk(this, function (node) {
207 return element === node