ref: 86a0926452f9152288b7aa7c283e15772754897e
dir: /domino/domino-lib/ChildNode.js/
"use strict"; var Node = require('./Node'); var LinkedList = require('./LinkedList'); var createDocumentFragmentFromArguments = function(document, args) { var docFrag = document.createDocumentFragment(); for (var i=0; i<args.length; i++) { var argItem = args[i]; var isNode = argItem instanceof Node; docFrag.appendChild(isNode ? argItem : document.createTextNode(String(argItem))); } return docFrag; }; // The ChildNode interface contains methods that are particular to `Node` // objects that can have a parent. It is implemented by `Element`, // `DocumentType`, and `CharacterData` objects. var ChildNode = { // Inserts a set of Node or String objects in the children list of this // ChildNode's parent, just after this ChildNode. String objects are // inserted as the equivalent Text nodes. after: { value: function after() { var argArr = Array.prototype.slice.call(arguments); var parentNode = this.parentNode, nextSibling = this.nextSibling; if (parentNode === null) { return; } // Find "viable next sibling"; that is, next one not in argArr while (nextSibling && argArr.some(function(v) { return v===nextSibling; })) nextSibling = nextSibling.nextSibling; // ok, parent and sibling are saved away since this node could itself // appear in argArr and we're about to move argArr to a document fragment. var docFrag = createDocumentFragmentFromArguments(this.doc, argArr); parentNode.insertBefore(docFrag, nextSibling); }}, // Inserts a set of Node or String objects in the children list of this // ChildNode's parent, just before this ChildNode. String objects are // inserted as the equivalent Text nodes. before: { value: function before() { var argArr = Array.prototype.slice.call(arguments); var parentNode = this.parentNode, prevSibling = this.previousSibling; if (parentNode === null) { return; } // Find "viable prev sibling"; that is, prev one not in argArr while (prevSibling && argArr.some(function(v) { return v===prevSibling; })) prevSibling = prevSibling.previousSibling; // ok, parent and sibling are saved away since this node could itself // appear in argArr and we're about to move argArr to a document fragment. var docFrag = createDocumentFragmentFromArguments(this.doc, argArr); var nextSibling = prevSibling ? prevSibling.nextSibling : parentNode.firstChild; parentNode.insertBefore(docFrag, nextSibling); }}, // Remove this node from its parent remove: { value: function remove() { if (this.parentNode === null) return; // Send mutation events if necessary if (this.doc) { this.doc._preremoveNodeIterators(this); if (this.rooted) { this.doc.mutateRemove(this); } } // Remove this node from its parents array of children // and update the structure id for all ancestors this._remove(); // Forget this node's parent this.parentNode = null; }}, // Remove this node w/o uprooting or sending mutation events // (But do update the structure id for all ancestors) _remove: { value: function _remove() { var parent = this.parentNode; if (parent === null) return; if (parent._childNodes) { parent._childNodes.splice(this.index, 1); } else if (parent._firstChild === this) { if (this._nextSibling === this) { parent._firstChild = null; } else { parent._firstChild = this._nextSibling; } } LinkedList.remove(this); parent.modify(); }}, // Replace this node with the nodes or strings provided as arguments. replaceWith: { value: function replaceWith() { var argArr = Array.prototype.slice.call(arguments); var parentNode = this.parentNode, nextSibling = this.nextSibling; if (parentNode === null) { return; } // Find "viable next sibling"; that is, next one not in argArr while (nextSibling && argArr.some(function(v) { return v===nextSibling; })) nextSibling = nextSibling.nextSibling; // ok, parent and sibling are saved away since this node could itself // appear in argArr and we're about to move argArr to a document fragment. var docFrag = createDocumentFragmentFromArguments(this.doc, argArr); if (this.parentNode === parentNode) { parentNode.replaceChild(docFrag, this); } else { // `this` was inserted into docFrag parentNode.insertBefore(docFrag, nextSibling); } }}, }; module.exports = ChildNode;