//Moving a Node, with methods such as Document.adoptNode, Node.appendChild, or Range.extractContents [DOM Range], must not cause the event listeners attached to it to be removed or un-registered. public Node appendChild(Node newChild) { Document thisDoc = ownerDocument; if (thisDoc == null) { thisDoc = this as Document; } //if (newChild.parentNode != this) // throw new ArgumentException("The operation would yield an incorrect node tree."); if (this == newChild || AncestorNode(newChild)) { throw new ArgumentException("The operation would yield an incorrect node tree."); } Document childDoc = newChild.ownerDocument; if (childDoc != null && childDoc != thisDoc && childDoc != this) { throw new ArgumentException("The operation would yield an incorrect node tree."); } if (newChild.parentNode != null) { newChild.parentNode.removeChild(newChild); } // special case for doc-fragment. if (newChild.nodeType == (int)NodeType.DOCUMENT_FRAGMENT_NODE) { Node first = newChild.firstChild; Node node = first; while (node != null) { Node next = node.nextSibling; newChild.removeChild(node); appendChild(node); node = next; } return(first); } string newChildValue = newChild.nodeValue; NodeChangedEventArgs args = thisDoc.GetEventArgs(newChild, newChild.parentNode, this, newChildValue, newChildValue, NodeChangedAction.Insert); if (args != null) { thisDoc.BeforeEvent(args); } Node refNode = lastChild; Node newNode = newChild; if (refNode == null) { newNode.next = newNode; lastChild = newNode; newNode.parentNode = this; } else { newNode.next = refNode.next; refNode.next = newNode; lastChild = newNode; newNode.parentNode = this; if (refNode.IsText && newNode.IsText) { NestTextNodes(refNode, newNode); } } if (args != null) { thisDoc.AfterEvent(args); } return(newNode); }
//public Node insertBefore(Node node, Node child) //child CAN BE NULL //{ // if (child != null && child.parentNode != this) // throw new ArgumentException("Node not contains such child"); // if (node == null) // throw new ArgumentNullException(); // Node parent = child != null ? child.parentNode : null; // if (node.contains(parent)) // throw new DOMError("HierarchyRequestError"); // NodeType type = (NodeType)node.nodeType; // if (type != NodeType.DOCUMENT_NODE || // type != NodeType.DOCUMENT_FRAGMENT_NODE || // type != NodeType.ELEMENT_NODE || // type != NodeType.DOCUMENT_TYPE_NODE || // type != NodeType.TEXT_NODE || // type != NodeType.PROCESSING_INSTRUCTION_NODE || // type != NodeType.COMMENT_NODE) // throw new DOMError("HierarchyRequestError"); // if (type == NodeType.DOCUMENT_TYPE_NODE && type != NodeType.DOCUMENT_NODE) // throw new DOMError("HierarchyRequestError"); // if (parent.nodeType == (short)NodeType.DOCUMENT_NODE) // { // if (type == NodeType.DOCUMENT_FRAGMENT_NODE) // { // /* // //If node has more than one element child or has a Text node child, throw a "HierarchyRequestError" and terminate these steps. // if (node.childNodes.length > 1 || node.childNodes.Any((n) => { return n.nodeType == (short)NodeType.TEXT_NODE true : false; })) // throw new DOMError("HierarchyRequestError"); // */ // /* // If node has one element child, and parent has an element child, child is a doctype, or child is not null and a doctype is following child, throw a "HierarchyRequestError" and terminate these steps. // */ // } // /* // If node is an element, and parent has an element child, child is a doctype, or child is not null and a doctype is following child, throw a "HierarchyRequestError" and terminate these steps. // If node is a doctype and either parent has a doctype child, an element is preceding child, or child is null and parent has an element child, throw a "HierarchyRequestError" and terminate these steps. // */ // } // node.ownerDocument = this.ownerDocument; // if (node.childNodes != null) // { // for (int i = 0; i < node.childNodes.length; i++) // { // childNodes[i].ownerDocument = asociatedDocument; // } // } // Node previous = child != null ? child.previousSibling : null; // node.previousSibling = previous; // if (child != null) child.previousSibling = node; // node.nextSibling = child; // int index = childNodes.IndexOf(child); // index = index != -1 ? index : childNodes.Count - 1; // childNodes.Insert(index, node); // return node; //} public virtual Node InsertAfter(Node newChild, Node refChild) { if (this == newChild || AncestorNode(newChild)) { throw new ArgumentException("Node not contains such child"); } if (refChild == null) { return(PrependChild(newChild)); } if (refChild.parentNode != this) { throw new ArgumentException("Node not contains such child"); } if (newChild == refChild) { return(newChild); } Document childDoc = newChild.ownerDocument; Document thisDoc = ownerDocument; if (childDoc != null && childDoc != thisDoc && childDoc != this) { throw new ArgumentException("Node not contains such child"); } if (newChild.parentNode != null) { newChild.parentNode.removeChild(newChild); } // special case for doc-fragment. if (newChild.nodeType == (int)NodeType.DOCUMENT_FRAGMENT_NODE) { Node last = refChild; Node first = newChild.firstChild; Node node = first; while (node != null) { Node next = node.nextSibling; newChild.removeChild(node); InsertAfter(node, last); last = node; node = next; } return(first); } Node newNode = (Node)newChild; Node refNode = (Node)refChild; string newChildValue = newChild.nodeValue; NodeChangedEventArgs args = ownerDocument.GetEventArgs(newChild, newChild.parentNode, this, newChildValue, newChildValue, NodeChangedAction.Insert); if (args != null) { ownerDocument.BeforeEvent(args); } if (refNode == lastChild) { newNode.next = refNode.next; refNode.next = newNode; lastChild = newNode; newNode.parentNode = this; if (refNode.IsText) { if (newNode.IsText) { NestTextNodes(refNode, newNode); } } } else { Node nextNode = refNode.next; newNode.next = nextNode; refNode.next = newNode; newNode.parentNode = this;; if (refNode.IsText) { if (newNode.IsText) { NestTextNodes(refNode, newNode); if (nextNode.IsText) { NestTextNodes(newNode, nextNode); } } else { if (nextNode.IsText) { UnnestTextNodes(refNode, nextNode); } } } else { if (newNode.IsText) { if (nextNode.IsText) { NestTextNodes(newNode, nextNode); } } } } if (args != null) { ownerDocument.AfterEvent(args); } return(newNode); }
//NEW //not real supported, need queue mutation record public virtual Node insertBefore(Node newChild, Node refChild) { if (this == newChild || AncestorNode(newChild)) { throw new ArgumentException("The operation would yield an incorrect node tree."); } if (refChild == null) { return(appendChild(newChild)); } if (refChild.parentNode != this) { throw new ArgumentException("The operation would yield an incorrect node tree."); } if (newChild == refChild) { return(newChild); } Document childDoc = newChild.ownerDocument; Document thisDoc = ownerDocument; if (childDoc != null && childDoc != thisDoc && childDoc != this) { throw new ArgumentException("The operation would yield an incorrect node tree."); } if (newChild.parentNode != null) { newChild.parentNode.removeChild(newChild); } // special case for doc-fragment. if (newChild.nodeType == (int)NodeType.DOCUMENT_FRAGMENT_NODE) { Node first = newChild.firstChild; Node node = first; if (node != null) { newChild.removeChild(node); insertBefore(node, refChild); // insert the rest of the children after this one. InsertAfter(newChild, node); } return(first); } Node newNode = newChild; Node refNode = refChild; string newChildValue = newChild.nodeValue; NodeChangedEventArgs args = ownerDocument.GetEventArgs(newChild, newChild.parentNode, this, newChildValue, newChildValue, NodeChangedAction.Insert); if (args != null) { ownerDocument.BeforeEvent(args); } if (refNode == firstChild) { newNode.next = refNode; lastChild.next = newNode; newNode.parentNode = this; if (newNode.IsText) { if (refNode.IsText) { NestTextNodes(newNode, refNode); } } } else { Node prevNode = refNode.previousSibling; newNode.next = refNode; prevNode.next = newNode; newNode.parentNode = this; if (prevNode.IsText) { if (newNode.IsText) { NestTextNodes(prevNode, newNode); if (refNode.IsText) { NestTextNodes(newNode, refNode); } } else { if (refNode.IsText) { UnnestTextNodes(prevNode, refNode); } } } else { if (newNode.IsText) { if (refNode.IsText) { NestTextNodes(newNode, refNode); } } } } if (args != null) { ownerDocument.AfterEvent(args); } return(newNode); }
//NEW //not real supported, need queue mutation record public virtual Node insertBefore(Node newChild, Node refChild) { if (this == newChild || AncestorNode(newChild)) throw new ArgumentException("The operation would yield an incorrect node tree."); if (refChild == null) return appendChild(newChild); if (refChild.parentNode != this) throw new ArgumentException("The operation would yield an incorrect node tree."); if (newChild == refChild) return newChild; Document childDoc = newChild.ownerDocument; Document thisDoc = ownerDocument; if (childDoc != null && childDoc != thisDoc && childDoc != this) throw new ArgumentException("The operation would yield an incorrect node tree."); if (newChild.parentNode != null) newChild.parentNode.removeChild(newChild); // special case for doc-fragment. if (newChild.nodeType == (int)NodeType.DOCUMENT_FRAGMENT_NODE) { Node first = newChild.firstChild; Node node = first; if (node != null) { newChild.removeChild(node); insertBefore(node, refChild); // insert the rest of the children after this one. InsertAfter(newChild, node); } return first; } Node newNode = newChild; Node refNode = refChild; string newChildValue = newChild.nodeValue; NodeChangedEventArgs args = ownerDocument.GetEventArgs(newChild, newChild.parentNode, this, newChildValue, newChildValue, NodeChangedAction.Insert); if (args != null) ownerDocument.BeforeEvent(args); if (refNode == firstChild) { newNode.next = refNode; lastChild.next = newNode; newNode.parentNode = this; if (newNode.IsText) { if (refNode.IsText) { NestTextNodes(newNode, refNode); } } } else { Node prevNode = refNode.previousSibling; newNode.next = refNode; prevNode.next = newNode; newNode.parentNode = this; if (prevNode.IsText) { if (newNode.IsText) { NestTextNodes(prevNode, newNode); if (refNode.IsText) { NestTextNodes(newNode, refNode); } } else { if (refNode.IsText) { UnnestTextNodes(prevNode, refNode); } } } else { if (newNode.IsText) { if (refNode.IsText) { NestTextNodes(newNode, refNode); } } } } if (args != null) ownerDocument.AfterEvent(args); return newNode; }
//public Node insertBefore(Node node, Node child) //child CAN BE NULL //{ // if (child != null && child.parentNode != this) // throw new ArgumentException("Node not contains such child"); // if (node == null) // throw new ArgumentNullException(); // Node parent = child != null ? child.parentNode : null; // if (node.contains(parent)) // throw new DOMError("HierarchyRequestError"); // NodeType type = (NodeType)node.nodeType; // if (type != NodeType.DOCUMENT_NODE || // type != NodeType.DOCUMENT_FRAGMENT_NODE || // type != NodeType.ELEMENT_NODE || // type != NodeType.DOCUMENT_TYPE_NODE || // type != NodeType.TEXT_NODE || // type != NodeType.PROCESSING_INSTRUCTION_NODE || // type != NodeType.COMMENT_NODE) // throw new DOMError("HierarchyRequestError"); // if (type == NodeType.DOCUMENT_TYPE_NODE && type != NodeType.DOCUMENT_NODE) // throw new DOMError("HierarchyRequestError"); // if (parent.nodeType == (short)NodeType.DOCUMENT_NODE) // { // if (type == NodeType.DOCUMENT_FRAGMENT_NODE) // { // /* // //If node has more than one element child or has a Text node child, throw a "HierarchyRequestError" and terminate these steps. // if (node.childNodes.length > 1 || node.childNodes.Any((n) => { return n.nodeType == (short)NodeType.TEXT_NODE true : false; })) // throw new DOMError("HierarchyRequestError"); // */ // /* // If node has one element child, and parent has an element child, child is a doctype, or child is not null and a doctype is following child, throw a "HierarchyRequestError" and terminate these steps. // */ // } // /* // If node is an element, and parent has an element child, child is a doctype, or child is not null and a doctype is following child, throw a "HierarchyRequestError" and terminate these steps. // If node is a doctype and either parent has a doctype child, an element is preceding child, or child is null and parent has an element child, throw a "HierarchyRequestError" and terminate these steps. // */ // } // node.ownerDocument = this.ownerDocument; // if (node.childNodes != null) // { // for (int i = 0; i < node.childNodes.length; i++) // { // childNodes[i].ownerDocument = asociatedDocument; // } // } // Node previous = child != null ? child.previousSibling : null; // node.previousSibling = previous; // if (child != null) child.previousSibling = node; // node.nextSibling = child; // int index = childNodes.IndexOf(child); // index = index != -1 ? index : childNodes.Count - 1; // childNodes.Insert(index, node); // return node; //} public virtual Node InsertAfter(Node newChild, Node refChild) { if (this == newChild || AncestorNode(newChild)) throw new ArgumentException("Node not contains such child"); if (refChild == null) return PrependChild(newChild); if (refChild.parentNode != this) throw new ArgumentException("Node not contains such child"); if (newChild == refChild) return newChild; Document childDoc = newChild.ownerDocument; Document thisDoc = ownerDocument; if (childDoc != null && childDoc != thisDoc && childDoc != this) throw new ArgumentException("Node not contains such child"); if (newChild.parentNode != null) newChild.parentNode.removeChild(newChild); // special case for doc-fragment. if (newChild.nodeType == (int)NodeType.DOCUMENT_FRAGMENT_NODE) { Node last = refChild; Node first = newChild.firstChild; Node node = first; while (node != null) { Node next = node.nextSibling; newChild.removeChild(node); InsertAfter(node, last); last = node; node = next; } return first; } Node newNode = (Node)newChild; Node refNode = (Node)refChild; string newChildValue = newChild.nodeValue; NodeChangedEventArgs args = ownerDocument.GetEventArgs(newChild, newChild.parentNode, this, newChildValue, newChildValue, NodeChangedAction.Insert); if (args != null) ownerDocument.BeforeEvent(args); if (refNode == lastChild) { newNode.next = refNode.next; refNode.next = newNode; lastChild = newNode; newNode.parentNode = this; if (refNode.IsText) { if (newNode.IsText) { NestTextNodes(refNode, newNode); } } } else { Node nextNode = refNode.next; newNode.next = nextNode; refNode.next = newNode; newNode.parentNode = this;; if (refNode.IsText) { if (newNode.IsText) { NestTextNodes(refNode, newNode); if (nextNode.IsText) { NestTextNodes(newNode, nextNode); } } else { if (nextNode.IsText) { UnnestTextNodes(refNode, nextNode); } } } else { if (newNode.IsText) { if (nextNode.IsText) { NestTextNodes(newNode, nextNode); } } } } if (args != null) ownerDocument.AfterEvent(args); return newNode; }
//Moving a Node, with methods such as Document.adoptNode, Node.appendChild, or Range.extractContents [DOM Range], must not cause the event listeners attached to it to be removed or un-registered. public Node appendChild(Node newChild) { Document thisDoc = ownerDocument; if (thisDoc == null) { thisDoc = this as Document; } //if (newChild.parentNode != this) // throw new ArgumentException("The operation would yield an incorrect node tree."); if (this == newChild || AncestorNode(newChild)) throw new ArgumentException("The operation would yield an incorrect node tree."); Document childDoc = newChild.ownerDocument; if (childDoc != null && childDoc != thisDoc && childDoc != this) throw new ArgumentException("The operation would yield an incorrect node tree."); if (newChild.parentNode != null) newChild.parentNode.removeChild(newChild); // special case for doc-fragment. if (newChild.nodeType == (int)NodeType.DOCUMENT_FRAGMENT_NODE) { Node first = newChild.firstChild; Node node = first; while (node != null) { Node next = node.nextSibling; newChild.removeChild(node); appendChild(node); node = next; } return first; } string newChildValue = newChild.nodeValue; NodeChangedEventArgs args = thisDoc.GetEventArgs(newChild, newChild.parentNode, this, newChildValue, newChildValue, NodeChangedAction.Insert); if (args != null) thisDoc.BeforeEvent(args); Node refNode = lastChild; Node newNode = newChild; if (refNode == null) { newNode.next = newNode; lastChild = newNode; newNode.parentNode = this; } else { newNode.next = refNode.next; refNode.next = newNode; lastChild = newNode; newNode.parentNode = this; if (refNode.IsText && newNode.IsText) { NestTextNodes(refNode, newNode); } } if (args != null) thisDoc.AfterEvent(args); return newNode; }