Beispiel #1
0
        /// <summary>
        /// Replaces all nodes with the given node, if any.
        /// </summary>
        /// <param name="node">The node to insert, if any.</param>
        /// <param name="suppressObservers">If mutation observers should be surpressed.</param>
        internal void ReplaceAll(Node node, Boolean suppressObservers)
        {
            if (node != null)
            {
                _owner.AdoptNode(node);
            }

            var removedNodes = new NodeList(_children);
            var addedNodes   = new NodeList();

            if (node != null)
            {
                if (node is IDocumentFragment)
                {
                    addedNodes.AddRange(node._children);
                }
                else
                {
                    addedNodes.Add(node);
                }
            }

            for (int i = 0; i < removedNodes.Length; i++)
            {
                RemoveChild(removedNodes[i], true);
            }

            for (int i = 0; i < addedNodes.Length; i++)
            {
                InsertBefore(addedNodes[i], null, true);
            }

            _owner.QueueMutation(MutationRecord.ChildList(
                                     target: this,
                                     addedNodes: addedNodes,
                                     removedNodes: removedNodes));
        }
Beispiel #2
0
        /// <summary>
        /// Replaces one child node of the specified element with another.
        /// </summary>
        /// <param name="node">The new node to replace oldChild. If it already exists in the DOM, it is first removed.</param>
        /// <param name="child">The existing child to be replaced.</param>
        /// <param name="suppressObservers">If mutation observers should be surpressed.</param>
        /// <returns>The replaced node. This is the same node as oldChild.</returns>
        internal INode ReplaceChild(Node node, Node child, Boolean suppressObservers)
        {
            if (_type != NodeType.Document && _type != NodeType.DocumentFragment && _type != NodeType.Element)
            {
                throw new DomException(ErrorCode.HierarchyRequest);
            }
            else if (node.IsHostIncludingInclusiveAncestor(this))
            {
                throw new DomException(ErrorCode.HierarchyRequest);
            }
            else if (child.Parent != this)
            {
                throw new DomException(ErrorCode.NotFound);
            }

            if (node is IElement || node is ICharacterData || node is IDocumentFragment || node is IDocumentType)
            {
                var document = _parent as IDocument;

                if (document != null)
                {
                    var forbidden = false;

                    switch (node._type)
                    {
                    case NodeType.DocumentType:
                        forbidden = document.Doctype != child || child.IsPrecededByElement();
                        break;

                    case NodeType.Element:
                        forbidden = document.DocumentElement != child || child.IsFollowedByDoctype();
                        break;

                    case NodeType.DocumentFragment:
                        var elements = node.GetElementCount();
                        forbidden = elements > 1 || node.HasTextNodes() || (elements == 1 && (document.DocumentElement != child || child.IsFollowedByDoctype()));
                        break;
                    }

                    if (forbidden)
                    {
                        throw new DomException(ErrorCode.HierarchyRequest);
                    }
                }

                var referenceChild = child.NextSibling;

                if (referenceChild == node)
                {
                    referenceChild = node.NextSibling;
                }

                _owner.AdoptNode(node);
                RemoveChild(child, true);
                InsertBefore(node, referenceChild, true);
                var addedNodes   = new NodeList();
                var removedNodes = new NodeList();
                removedNodes.Add(child);

                if (node._type == NodeType.DocumentFragment)
                {
                    addedNodes.AddRange(node._children);
                }
                else
                {
                    addedNodes.Add(node);
                }

                _owner.QueueMutation(MutationRecord.ChildList(
                                         target: this,
                                         addedNodes: addedNodes,
                                         removedNodes: removedNodes,
                                         previousSibling:
                                         child.PreviousSibling,
                                         nextSibling: referenceChild));

                return(child);
            }
            else
            {
                throw new DomException(ErrorCode.HierarchyRequest);
            }
        }