/// <summary> /// Runs the mutation macro as defined in 5.2.2 Mutation methods /// of http://www.w3.org/TR/domcore/. /// </summary> /// <param name="nodes">The nodes array to add.</param> /// <returns>A (single) node.</returns> public static INode MutationMacro(this INode[] nodes) { if (nodes.Length > 1) { var node = new DocumentFragment(); for (int i = 0; i < nodes.Length; i++) { node.AppendChild(nodes[i]); } return(node); } return(nodes[0]); }
public IDocumentFragment CopyContent() { var fragment = new DocumentFragment { Owner = _start.Node.Owner as Document }; if (_start.Equals(_end)) { return(fragment); } 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); return(fragment); } var commonAncestor = originalStart.Node; while (!commonAncestor.IsInclusiveAncestorOf(originalEnd.Node)) { commonAncestor = commonAncestor.Parent; } var firstPartiallyContainedChild = !originalStart.Node.IsInclusiveAncestorOf(originalEnd.Node) ? commonAncestor.GetElements <INode>(predicate: IsPartiallyContained).FirstOrDefault() : null; var lastPartiallyContainedchild = !originalEnd.Node.IsInclusiveAncestorOf(originalStart.Node) ? commonAncestor.GetElements <INode>(predicate: IsPartiallyContained).LastOrDefault() : null; var containedChildren = commonAncestor.GetElements <INode>(predicate: Intersects).ToList(); if (containedChildren.OfType <IDocumentType>().Any()) { throw new DomException(ErrorCode.HierarchyRequest); } 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); } else if (firstPartiallyContainedChild != null) { var clone = firstPartiallyContainedChild.Clone(); fragment.AppendChild(clone); var subrange = new Range(originalStart, new Boundary { Node = firstPartiallyContainedChild, Offset = firstPartiallyContainedChild.ChildNodes.Length }); var subfragment = subrange.CopyContent(); fragment.AppendChild(subfragment); } foreach (var child in containedChildren) { fragment.AppendChild(child.Clone()); } if (lastPartiallyContainedchild is ICharacterData) { var text = (ICharacterData)originalEnd.Node; var clone = (ICharacterData)text.Clone(); clone.Data = text.Substring(0, originalEnd.Offset); fragment.AppendChild(clone); } else if (lastPartiallyContainedchild != null) { var clone = lastPartiallyContainedchild.Clone(); fragment.AppendChild(clone); var subrange = new Range(new Boundary { Node = lastPartiallyContainedchild, Offset = 0 }, originalEnd); var subfragment = subrange.CopyContent(); fragment.AppendChild(subfragment); } return(fragment); }