Exemple #1
0
        public IDocumentFragment ExtractContent()
        {
            var fragment = _start.Node.Owner !.CreateDocumentFragment();

            if (!_start.Equals(_end))
            {
                var newBoundary   = _start;
                var originalStart = _start;
                var originalEnd   = _end;

                if (originalStart.Node == originalEnd.Node && _start.Node is ICharacterData)
                {
                    var text  = (ICharacterData)originalStart.Node;
                    var strt  = originalStart.Offset;
                    var span  = originalEnd.Offset - originalStart.Offset;
                    var clone = (ICharacterData)text.Clone();
                    clone.Data = text.Substring(strt, span);
                    fragment.AppendChild(clone);
                    text.Replace(strt, span, String.Empty);
                }
                else
                {
                    var commonAncestor = originalStart.Node;

                    while (!commonAncestor.IsInclusiveAncestorOf(originalEnd.Node))
                    {
                        commonAncestor = commonAncestor.Parent !;
                    }

                    var firstPartiallyContainedChild = !originalStart.Node.IsInclusiveAncestorOf(originalEnd.Node) ?
                                                       commonAncestor.GetNodes <INode>(predicate: IsPartiallyContained).FirstOrDefault() : null;
                    var lastPartiallyContainedchild = !originalEnd.Node.IsInclusiveAncestorOf(originalStart.Node) ?
                                                      commonAncestor.GetNodes <INode>(predicate: IsPartiallyContained).LastOrDefault() : null;
                    var containedChildren = commonAncestor.GetNodes <INode>(predicate: Intersects).ToList();

                    if (containedChildren.OfType <IDocumentType>().Any())
                    {
                        throw new DomException(DomError.HierarchyRequest);
                    }

                    if (!originalStart.Node.IsInclusiveAncestorOf(originalEnd.Node))
                    {
                        var referenceNode = originalStart.Node;

                        while (referenceNode.Parent != null && !referenceNode.IsInclusiveAncestorOf(originalEnd.Node))
                        {
                            referenceNode = referenceNode.Parent;
                        }

                        newBoundary = new Boundary(referenceNode, referenceNode.Parent !.ChildNodes.Index(referenceNode) + 1);
                    }

                    if (firstPartiallyContainedChild is ICharacterData)
                    {
                        var text  = (ICharacterData)originalStart.Node;
                        var strt  = originalStart.Offset;
                        var span  = text.Length - originalStart.Offset;
                        var clone = (ICharacterData)text.Clone();
                        clone.Data = text.Substring(strt, span);
                        fragment.AppendChild(clone);
                        text.Replace(strt, span, String.Empty);
                    }
                    else if (firstPartiallyContainedChild != null)
                    {
                        var clone = firstPartiallyContainedChild.Clone();
                        fragment.AppendChild(clone);
                        var subrange    = new Range(originalStart, new Boundary(firstPartiallyContainedChild, firstPartiallyContainedChild.ChildNodes.Length));
                        var subfragment = subrange.ExtractContent();
                        fragment.AppendChild(subfragment);
                    }

                    foreach (var child in containedChildren)
                    {
                        fragment.AppendChild(child);
                    }

                    if (lastPartiallyContainedchild is ICharacterData)
                    {
                        var text  = (ICharacterData)originalEnd.Node;
                        var clone = (ICharacterData)text.Clone();
                        clone.Data = text.Substring(0, originalEnd.Offset);
                        fragment.AppendChild(clone);
                        text.Replace(0, originalEnd.Offset, String.Empty);
                    }
                    else if (lastPartiallyContainedchild != null)
                    {
                        var clone = lastPartiallyContainedchild.Clone();
                        fragment.AppendChild(clone);
                        var subrange    = new Range(new Boundary(lastPartiallyContainedchild, 0), originalEnd);
                        var subfragment = subrange.ExtractContent();
                        fragment.AppendChild(subfragment);
                    }

                    _start = newBoundary;
                    _end   = newBoundary;
                }
            }

            return(fragment);
        }
Exemple #2
0
        public void Insert(INode node)
        {
            if (node is null)
            {
                throw new ArgumentNullException(nameof(node));
            }

            var snode  = _start.Node;
            var type   = snode.NodeType;
            var istext = type == NodeType.Text;

            if (type == NodeType.ProcessingInstruction || type == NodeType.Comment || (istext && snode.Parent is null))
            {
                throw new DomException(DomError.HierarchyRequest);
            }

            var referenceNode = istext ? snode : _start.ChildAtOffset;
            var parent        = referenceNode is null ? snode : referenceNode.Parent;

            parent !.EnsurePreInsertionValidity(node, referenceNode);

            if (istext)
            {
                referenceNode = ((IText)snode).Split(_start.Offset);
                parent        = referenceNode.Parent;
            }

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

            node.Parent?.RemoveChild(node);
            var newOffset = referenceNode is null ? parent !.ChildNodes.Length : parent !.ChildNodes.Index(referenceNode);

            newOffset += node.NodeType == NodeType.DocumentFragment ? node.ChildNodes.Length : 1;
            parent.PreInsert(node, referenceNode);

            if (_start.Equals(_end))
            {
                _end = new Boundary(parent, newOffset);
            }
        }
Exemple #3
0
        public void ClearContent()
        {
            if (!_start.Equals(_end))
            {
                var newBoundary   = new Boundary();
                var originalStart = _start;
                var originalEnd   = _end;

                if (originalEnd.Node == originalStart.Node && originalStart.Node is ICharacterData)
                {
                    var strt = originalStart.Offset;
                    var text = (ICharacterData)originalStart.Node;
                    var span = originalEnd.Offset - originalStart.Offset;
                    text.Replace(strt, span, String.Empty);
                }
                else
                {
                    var nodesToRemove = Nodes.Where(m => !Intersects(m.Parent !)).ToArray();

                    if (!originalStart.Node.IsInclusiveAncestorOf(originalEnd.Node))
                    {
                        var referenceNode = originalStart.Node;

                        while (referenceNode.Parent != null && referenceNode.Parent.IsInclusiveAncestorOf(originalEnd.Node))
                        {
                            referenceNode = referenceNode.Parent;
                        }

                        newBoundary = new Boundary(referenceNode.Parent !, referenceNode.Parent !.ChildNodes.Index(referenceNode) + 1);
                    }
                    else
                    {
                        newBoundary = originalStart;
                    }

                    if (originalStart.Node is ICharacterData)
                    {
                        var strt = originalStart.Offset;
                        var text = (ICharacterData)originalStart.Node;
                        var span = originalEnd.Offset - originalStart.Offset;
                        text.Replace(strt, span, String.Empty);
                    }

                    foreach (var node in nodesToRemove)
                    {
                        node.Parent !.RemoveChild(node);
                    }

                    if (originalEnd.Node is ICharacterData)
                    {
                        var strt = 0;
                        var text = (ICharacterData)originalEnd.Node;
                        var span = originalEnd.Offset;
                        text.Replace(strt, span, String.Empty);
                    }

                    _start = newBoundary;
                    _end   = newBoundary;
                }
            }
        }