Beispiel #1
0
        internal void AfterEvent(NodeChangedEventArgs args)
        {
            if (args != null)
            {
                switch (args.Action)
                {
                case NodeChangedAction.Insert:
                    if (onNodeInsertedDelegate != null)
                    {
                        onNodeInsertedDelegate(this, args);
                    }
                    break;

                case NodeChangedAction.Remove:
                    if (onNodeRemovedDelegate != null)
                    {
                        onNodeRemovedDelegate(this, args);
                    }
                    break;

                case NodeChangedAction.Change:
                    if (onNodeChangedDelegate != null)
                    {
                        onNodeChangedDelegate(this, args);
                    }
                    break;
                }
            }
        }
Beispiel #2
0
        public virtual Node removeChild(Node oldChild)
        {
            if (oldChild.parentNode != this)
            {
                throw new ArgumentException("The operation would yield an incorrect node tree.");
            }

            Node oldNode = (Node)oldChild;

            string oldNodeValue       = oldNode.nodeValue;
            NodeChangedEventArgs args = ownerDocument.GetEventArgs(oldNode, this, null, oldNodeValue, oldNodeValue, NodeChangedAction.Remove);

            if (args != null)
            {
                ownerDocument.BeforeEvent(args);
            }

            Node lastNode = lastChild;

            if (oldNode == firstChild)
            {
                if (oldNode == lastNode)
                {
                    lastChild          = null;
                    oldNode.next       = null;
                    oldNode.parentNode = null;
                }
                else
                {
                    Node nextNode = oldNode.next;

                    if (nextNode.IsText)
                    {
                        if (oldNode.IsText)
                        {
                            UnnestTextNodes(oldNode, nextNode);
                        }
                    }

                    lastNode.next      = nextNode;
                    oldNode.next       = null;
                    oldNode.parentNode = null;
                }
            }
            else
            {
                if (oldNode == lastNode)
                {
                    Node prevNode = oldNode.previousSibling;
                    prevNode.next      = oldNode.next;
                    lastChild          = prevNode;
                    oldNode.next       = null;
                    oldNode.parentNode = null;
                }
                else
                {
                    Node prevNode = oldNode.previousSibling;
                    Node nextNode = oldNode.next;

                    if (nextNode.IsText)
                    {
                        if (prevNode.IsText)
                        {
                            NestTextNodes(prevNode, nextNode);
                        }
                        else
                        {
                            if (oldNode.IsText)
                            {
                                UnnestTextNodes(oldNode, nextNode);
                            }
                        }
                    }

                    prevNode.next      = nextNode;
                    oldNode.next       = null;
                    oldNode.parentNode = null;
                }
            }

            if (args != null)
            {
                ownerDocument.AfterEvent(args);
            }

            return(oldChild);
        }
Beispiel #3
0
        //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);
        }
Beispiel #4
0
        //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);
        }
Beispiel #5
0
        //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);
        }
Beispiel #6
0
        internal void BeforeEvent(NodeChangedEventArgs args)
        {
            if (args != null)
            {
                switch (args.Action)
                {
                    case NodeChangedAction.Insert:
                        if (onNodeInsertingDelegate != null)
                            onNodeInsertingDelegate(this, args);
                        break;

                    case NodeChangedAction.Remove:
                        if (onNodeRemovingDelegate != null)
                            onNodeRemovingDelegate(this, args);
                        break;

                    case NodeChangedAction.Change:
                        if (onNodeChangingDelegate != null)
                            onNodeChangingDelegate(this, args);
                        break;
                }
            }
        }