/// <summary> /// Creates a new shadow root. /// </summary> internal ShadowRoot(Element host, ShadowRootMode mode) : base(host.Owner, "#shadow-root", NodeType.DocumentFragment) { _host = host; _styleSheets = this.CreateStyleSheets(); _mode = mode; }
internal static DocumentRequestProcessor Create(Element element) { var document = element.Owner; var configuration = document.Options; var loader = document.Loader; return configuration != null && loader != null ? new DocumentRequestProcessor(document, configuration, loader) : null; }
/// <summary> /// Adds an element to the list of active formatting elements. /// </summary> /// <param name="formatting">The list of formatting elements to modify.</param> /// <param name="element">The element to add.</param> public static void AddFormatting(this List<Element> formatting, Element element) { var count = 0; for (var i = formatting.Count - 1; i >= 0; i--) { var format = formatting[i]; if (format == null) break; if (format.NodeName == element.NodeName && format.NamespaceUri == element.NamespaceUri && format.Attributes.AreEqual(element.Attributes) && ++count == 3) { formatting.RemoveAt(i); break; } } formatting.Add(element); }
/// <summary> /// Creates a new document fragment with the given nodelist as /// children. /// </summary> /// <param name="context">The context for the fragment mode.</param> /// <param name="html">The HTML source code to use.</param> internal DocumentFragment(Element context, String html) : this(context.Owner) { var source = new TextSource(html); var document = new HtmlDocument(Owner.Context, source); var parser = new HtmlDomBuilder(document); var options = new HtmlParserOptions { IsEmbedded = false, IsScripting = Owner.Options.IsScripting() }; var root = parser.ParseFragment(options, context).DocumentElement; while (root.HasChildNodes) { var child = root.FirstChild; root.RemoveChild(child); this.PreInsert(child, null); } }
/// <summary> /// Copies the element and its attributes to create a new element. /// </summary> /// <param name="element">The old element (source).</param> /// <returns>The new element (target).</returns> Element CopyElement(Element element) { return (Element)element.Clone(false); }
/// <summary> /// Resets the current insertation mode to the rules according to the /// algorithm specified in 8.2.3.1 The insertion mode. /// http://www.w3.org/html/wg/drafts/html/master/syntax.html#the-insertion-mode /// </summary> void Reset(Element context = null) { var last = false; var node = default(Element); for (var i = _openElements.Count - 1; i >= 0; i--) { node = _openElements[i]; if (i == 0) { last = true; node = context ?? node; } var tagName = node.LocalName; if (tagName.Is(TagNames.Select)) _currentMode = HtmlTreeMode.InSelect; else if (TagNames.AllTableCells.Contains(tagName)) _currentMode = last ? HtmlTreeMode.InBody : HtmlTreeMode.InCell; else if (tagName.Is(TagNames.Tr)) _currentMode = HtmlTreeMode.InRow; else if (TagNames.AllTableSections.Contains(tagName)) _currentMode = HtmlTreeMode.InTableBody; else if (tagName.Is(TagNames.Body)) _currentMode = HtmlTreeMode.InBody; else if (tagName.Is(TagNames.Table)) _currentMode = HtmlTreeMode.InTable; else if (tagName.Is(TagNames.Caption)) _currentMode = HtmlTreeMode.InCaption; else if (tagName.Is(TagNames.Colgroup)) _currentMode = HtmlTreeMode.InColumnGroup; else if (tagName.Is(TagNames.Template)) _currentMode = _templateModes.Peek(); else if (tagName.Is(TagNames.Html)) _currentMode = HtmlTreeMode.BeforeHead; else if (tagName.Is(TagNames.Head)) _currentMode = last ? HtmlTreeMode.InBody : HtmlTreeMode.InHead; else if (tagName.Is(TagNames.Frameset)) _currentMode = HtmlTreeMode.InFrameset; else if (last) _currentMode = HtmlTreeMode.InBody; else continue; break; } }
/// <summary> /// Switches to the fragment algorithm with the specified context /// element. Then parses the given source and creates the document. /// </summary> /// <param name="options">The options to use for parsing.</param> /// <param name="context"> /// The context element where the algorithm is applied to. /// </param> public HtmlDocument ParseFragment(HtmlParserOptions options, Element context) { if (context == null) { throw new ArgumentNullException("context"); } var tagName = context.LocalName; if (tagName.IsOneOf(TagNames.Title, TagNames.Textarea)) { _tokenizer.State = HtmlParseMode.RCData; } else if (tagName.IsOneOf(TagNames.Style, TagNames.Xmp, TagNames.Iframe, TagNames.NoEmbed, TagNames.NoFrames)) { _tokenizer.State = HtmlParseMode.Rawtext; } else if (tagName.Is(TagNames.Script)) { _tokenizer.State = HtmlParseMode.Script; } else if (tagName.Is(TagNames.Plaintext)) { _tokenizer.State = HtmlParseMode.Plaintext; } else if (tagName.Is(TagNames.NoScript) && options.IsScripting) { _tokenizer.State = HtmlParseMode.Rawtext; } var root = new HtmlHtmlElement(_document); _document.AddNode(root); _openElements.Add(root); if (context is HtmlTemplateElement) { _templateModes.Push(HtmlTreeMode.InTemplate); } Reset(context); _fragmentContext = context; _tokenizer.IsAcceptingCharacterData = !AdjustedCurrentNode.Flags.HasFlag(NodeFlags.HtmlMember); do { if (context is HtmlFormElement) { _currentFormElement = (HtmlFormElement)context; break; } context = context.ParentElement as Element; } while (context != null); return Parse(options); }
/// <summary> /// Copies the attributes from the source element to the target /// element. Each attribute will be recreated on the target. /// </summary> /// <param name="source">The source of the attributes.</param> /// <param name="target"> /// The target where to create the attributes. /// </param> protected static void CopyAttributes(Element source, Element target) { for (int i = 0; i < source._attributes.Count; i++) target._attributes.Add(new Attr(target, source._attributes[i].Name, source._attributes[i].Value)); }
/// <summary> /// Returns a duplicate of the node on which this method was called. /// </summary> /// <param name="deep"> /// Optional value: true if the children of the node should also be /// cloned, or false to clone only the specified node. /// </param> /// <returns>The duplicate node.</returns> public override INode Clone(Boolean deep = true) { var node = new Element(Owner, LocalName, _prefix, _namespace, Flags); CopyProperties(this, node, deep); CopyAttributes(this, node); return node; }
/// <summary> /// Appends a configured node to the current node. /// </summary> /// <param name="element">The node which will be added to the list.</param> void AddElement(Element element) { var node = CurrentNode; if (_foster && TagNames.AllTableMajor.Contains(node.LocalName)) { AddElementWithFoster(element); } else { node.AddNode(element); } _openElements.Add(element); _tokenizer.IsAcceptingCharacterData = !element.Flags.HasFlag(NodeFlags.HtmlMember); }
/// <summary> /// Copies the attributes from the source element to the target /// element. Each attribute will be recreated on the target. /// </summary> /// <param name="source">The source of the attributes.</param> /// <param name="target"> /// The target where to create the attributes. /// </param> protected static void CopyAttributes(Element source, Element target) { foreach (var attribute in source._attributes) { var attr = new Attr(attribute.Prefix, attribute.LocalName, attribute.Value, attribute.NamespaceUri); target._attributes.FastAddItem(attr); } }
private void AuxiliarySetupSteps(Element element, HtmlTagToken tag) { if (_options.OnCreated != null) { _options.OnCreated.Invoke(element, tag.Position); } }
private void CloseNode(Element element) { element.SetupElement(); _openElements.Remove(element); }
/// <summary> /// Modifies the node by appending all attributes and /// acknowledging the self-closing flag if set. /// </summary> /// <param name="element">The node which will be added to the list.</param> /// <param name="tag">The associated tag token.</param> /// <param name="acknowledgeSelfClosing">Should the self-closing be acknowledged?</param> void SetupElement(Element element, HtmlTagToken tag, Boolean acknowledgeSelfClosing) { if (tag.IsSelfClosing && !acknowledgeSelfClosing) { RaiseErrorOccurred(HtmlParseError.TagCannotBeSelfClosed, tag); } element.SetAttributes(tag.Attributes); }
/// <summary> /// Creates a new element with the given tag name and namespace URI. /// </summary> /// <param name="namespaceUri"> /// Specifies the namespace URI to associate with the element. /// </param> /// <param name="qualifiedName"> /// A string that specifies the type of element to be created. /// </param> /// <returns>The created element.</returns> public IElement CreateElement(String namespaceUri, String qualifiedName) { if (String.IsNullOrEmpty(namespaceUri)) namespaceUri = null; if (!qualifiedName.IsXmlName()) throw new DomException(DomError.InvalidCharacter); else if (!qualifiedName.IsQualifiedName()) throw new DomException(DomError.Namespace); var parts = qualifiedName.Split(':'); var prefix = parts.Length == 2 ? parts[0] : null; var localName = parts.Length == 2 ? parts[1] : qualifiedName; if ((prefix == Namespaces.XmlPrefix && namespaceUri != Namespaces.XmlUri) || ((qualifiedName == Namespaces.XmlNsPrefix || prefix == Namespaces.XmlNsPrefix) && namespaceUri != Namespaces.XmlNsUri) || (namespaceUri == Namespaces.XmlNsUri && (qualifiedName != Namespaces.XmlNsPrefix || prefix != Namespaces.XmlNsPrefix))) throw new DomException(DomError.Namespace); var element = default(Element); if (namespaceUri == Namespaces.HtmlUri) element = Factory.HtmlElements.Create(this, localName, prefix); else if (namespaceUri == Namespaces.SvgUri) element = Factory.SvgElements.Create(this, localName, prefix); else if (namespaceUri == Namespaces.MathMlUri) element = Factory.MathElements.Create(this, localName, prefix); else element = new Element(this, localName, prefix, namespaceUri); return element; }
/// <summary> /// Appends a node to the current node and /// modifies the node by appending all attributes and /// acknowledging the self-closing flag if set. /// </summary> /// <param name="element">The node which will be added to the list.</param> /// <param name="tag">The associated tag token.</param> /// <param name="acknowledgeSelfClosing">Should the self-closing be acknowledged?</param> void AddElement(Element element, HtmlTagToken tag, Boolean acknowledgeSelfClosing = false) { SetupElement(element, tag, acknowledgeSelfClosing); AddElement(element); }
public BoundLocation(Element parent, String attributeName) { _parent = parent; _attributeName = attributeName; }
/// <summary> /// Appends a node to the appropriate foster parent. /// http://www.w3.org/html/wg/drafts/html/master/syntax.html#foster-parent /// </summary> /// <param name="element">The node which will be added to the list.</param> void AddElementWithFoster(Element element) { var table = false; var index = _openElements.Count; while (--index != 0) { if (_openElements[index].LocalName.Is(TagNames.Template)) { _openElements[index].AddNode(element); return; } else if (_openElements[index].LocalName.Is(TagNames.Table)) { table = true; break; } } var foster = _openElements[index].Parent ?? _openElements[index + 1]; if (table && _openElements[index].Parent != null) { for (int i = 0; i < foster.ChildNodes.Length; i++) { if (foster.ChildNodes[i] == _openElements[index]) { foster.InsertNode(i, element); break; } } } else { foster.AddNode(element); } }
/// <summary> /// Creates a new element with the given tag name and namespace URI. /// </summary> /// <param name="namespaceUri"> /// Specifies the namespace URI to associate with the element. /// </param> /// <param name="qualifiedName"> /// A string that specifies the type of element to be created. /// </param> /// <returns>The created element.</returns> public IElement CreateElement(String namespaceUri, String qualifiedName) { var localName = default(String); var prefix = default(String); GetPrefixAndLocalName(qualifiedName, ref namespaceUri, out prefix, out localName); if (namespaceUri.Is(NamespaceNames.HtmlUri)) { var element = Factory.HtmlElements.Create(this, localName, prefix); element.SetupElement(); return element; } else if (namespaceUri.Is(NamespaceNames.SvgUri)) { var element = Factory.SvgElements.Create(this, localName, prefix); element.SetupElement(); return element; } else if (namespaceUri.Is(NamespaceNames.MathMlUri)) { var element = Factory.MathElements.Create(this, localName, prefix); element.SetupElement(); return element; } else { var element = new Element(this, localName, prefix, namespaceUri); element.SetupElement(); return element; } }