urltomarkdown/node_modules/domino/lib/ContainerNode.js

81 lines
2.1 KiB
JavaScript
Executable File

"use strict";
module.exports = ContainerNode;
var Node = require('./Node');
var NodeList = require('./NodeList');
// This class defines common functionality for node subtypes that
// can have children
function ContainerNode() {
Node.call(this);
this._firstChild = this._childNodes = null;
}
// Primary representation is a circular linked list of siblings
ContainerNode.prototype = Object.create(Node.prototype, {
hasChildNodes: { value: function() {
if (this._childNodes) {
return this._childNodes.length > 0;
}
return this._firstChild !== null;
}},
childNodes: { get: function() {
this._ensureChildNodes();
return this._childNodes;
}},
firstChild: { get: function() {
if (this._childNodes) {
return this._childNodes.length === 0 ? null : this._childNodes[0];
}
return this._firstChild;
}},
lastChild: { get: function() {
var kids = this._childNodes, first;
if (kids) {
return kids.length === 0 ? null: kids[kids.length-1];
}
first = this._firstChild;
if (first === null) { return null; }
return first._previousSibling; // circular linked list
}},
_ensureChildNodes: { value: function() {
if (this._childNodes) { return; }
var first = this._firstChild,
kid = first,
childNodes = this._childNodes = new NodeList();
if (first) do {
childNodes.push(kid);
kid = kid._nextSibling;
} while (kid !== first); // circular linked list
this._firstChild = null; // free memory
}},
// Remove all of this node's children. This is a minor
// optimization that only calls modify() once.
removeChildren: { value: function removeChildren() {
var root = this.rooted ? this.ownerDocument : null,
next = this.firstChild,
kid;
while (next !== null) {
kid = next;
next = kid.nextSibling;
if (root) root.mutateRemove(kid);
kid.parentNode = null;
}
if (this._childNodes) {
this._childNodes.length = 0;
} else {
this._firstChild = null;
}
this.modify(); // Update last modified type once only
}},
});