marko/runtime/vdom/Node.js
2017-01-05 18:56:10 -07:00

123 lines
3.4 KiB
JavaScript

/* jshint newcap:false */
function assignNamespace(node, namespaceURI) {
node.namespaceURI = namespaceURI;
var curChild = node.$__firstChild;
while(curChild) {
if (curChild.$__nsAware) {
assignNamespace(curChild, namespaceURI);
}
curChild = curChild.$__nextSibling;
}
}
function Node() {}
Node.prototype = {
$__Node: function(finalChildCount) {
this.$__finalChildCount = finalChildCount;
this.$__childCount = 0;
this.$__firstChild = undefined;
this.$__lastChild = undefined;
this.$__parentNode = undefined;
this.$__nextSibling = undefined;
},
// removeChildren: function() {
// this.$__firstChild = undefined;
// this.$__childCount = 0;
// this.$__lastChild = undefined;
// },
get firstChild() {
var firstChild = this.$__firstChild;
if (firstChild && firstChild.$__DocumentFragment) {
var nestedFirstChild = firstChild.firstChild;
// The first child is a DocumentFragment node.
// If the DocumentFragment node has a first child then we will return that.
// Otherwise, the DocumentFragment node is not *really* the first child and
// we need to skip to its next sibling
return nestedFirstChild || firstChild.nextSibling;
}
return firstChild;
},
get nextSibling() {
var nextSibling = this.$__nextSibling;
if (nextSibling) {
if (nextSibling.$__DocumentFragment) {
var firstChild = nextSibling.firstChild;
return firstChild || nextSibling.nextSibling;
}
} else {
var parentNode = this.$__parentNode;
if (parentNode && parentNode.$__DocumentFragment) {
return parentNode.nextSibling;
}
}
return nextSibling;
},
$__appendChild: function(child) {
this.$__childCount++;
if (this.$__isTextArea) {
if (child.$__Text) {
var childValue = child.nodeValue;
this.$__value = (this.$__value || '') + childValue;
} else {
throw TypeError();
}
} else {
var namespaceURI;
if (child.$__nsAware && (namespaceURI = this.namespaceURI) && !child.namespaceURI) {
assignNamespace(child, namespaceURI);
}
var lastChild = this.$__lastChild;
child.$__parentNode = this;
if (lastChild) {
lastChild.$__nextSibling = child;
} else {
this.$__firstChild = child;
}
this.$__lastChild = child;
}
return child;
},
$__finishChild: function finishChild() {
if (this.$__childCount === this.$__finalChildCount && this.$__parentNode) {
return this.$__parentNode.$__finishChild();
} else {
return this;
}
}
// ,toJSON: function() {
// var clone = Object.assign({
// nodeType: this.nodeType
// }, this);
//
// for (var k in clone) {
// if (k.startsWith('_')) {
// delete clone[k];
// }
// }
// delete clone._nextSibling;
// delete clone._lastChild;
// delete clone.parentNode;
// return clone;
// }
};
module.exports = Node;