private void ReplaceContent(NodeCollection nodes, Node target, string content, string raw) { if (nodes == null || target == null) { throw new ArgumentNullException(); } Node[] nn = CreateContent(content, raw); foreach (Node n in nn) { nodes.InsertBefore(target, n); } nodes.Remove(target); }
/// <summary> /// Sanitizes the stream of nodes into exclusively valid AOML. /// This process involves changing and removing nodes. /// </summary> public void Sanitize(NodeCollection nodes) { if (nodes == null) { throw new ArgumentNullException(); } // Loop through all nodes nodes.Reset(); Node node = null; while ((node = nodes.Next()) != null) { // Skip content nodes if (node.Type == NodeType.Content) { continue; } // Gather info OpenNode openNode = null; CloseNode closeNode = null; string name = null; if (node.Type == NodeType.Open) { openNode = (OpenNode)node; name = openNode.Name; // Check attributes for (int i = 0; i < openNode.Count; i++) { string attr = openNode.GetAttributeName(i); if (!validAttributes.Contains(attr)) { openNode.RemoveAttribute(attr); i--; } } } else if (node.Type == NodeType.Close) { closeNode = (CloseNode)node; name = closeNode.Name; } // Singular elements if (singularElements.Contains(name)) { // Singular elements don't have closing nodes if (closeNode != null) { nodes.Remove(closeNode); } // Singular elements are always self-closing if (openNode != null) { openNode.Closed = true; } continue; } else if (inlineElements.Contains(name) || blockElements.Contains(name)) { if (openNode == null) { continue; } // Let's not use self-closing elements here if (openNode.Closed) { openNode.Closed = false; nodes.InsertAfter(openNode, new CloseNode(name, "")); } continue; } // Replace node as content node if (this.InvalidElementsToContent) { // Replace node as content this.ReplaceContent(nodes, node, node.Raw, node.Raw); } else { // Remove node this.ReplaceContent(nodes, node, "", ""); } } // And we're done! nodes.Reset(); }