/// <summary> /// See 8.2.5.4.2 The "before html" insertion mode. /// </summary> /// <param name="token">The passed token.</param> void BeforeHtml(HtmlToken token) { if (token.Type == HtmlTokenType.DOCTYPE) { RaiseErrorOccurred(ErrorCode.DoctypeTagInappropriate); return; } else if (token.Type == HtmlTokenType.Comment) { AddComment(doc, token); return; } else if (token.Type == HtmlTokenType.StartTag && ((HtmlTagToken)token).Name == HTMLHtmlElement.Tag) { AddRoot(token); //TODO //If the Document is being loaded as part of navigation of a browsing context, then: // if the newly created element has a manifest attribute whose value is not the empty string, // then resolve the value of that attribute to an absolute URL, relative to the newly created element, // and if that is successful, run the application cache selection algorithm with the result of applying // the URL serializer algorithm to the resulting parsed URL with the exclude fragment flag set; // otherwise, if there is no such attribute, or its value is the empty string, or resolving its value fails, // run the application cache selection algorithm with no manifest. The algorithm must be passed the Document object. insert = HtmlTreeMode.BeforeHead; return; } else if(token.IsEndTagInv(HTMLHtmlElement.Tag, HTMLBodyElement.Tag, HTMLBRElement.Tag, HTMLHeadElement.Tag)) { RaiseErrorOccurred(ErrorCode.TagCannotEndHere); return; } else if(token.Type == HtmlTokenType.Character) { var chars = (HtmlCharacterToken)token; chars.TrimStart(); if (chars.IsEmpty) return; } BeforeHtml(HtmlToken.OpenTag(HTMLHtmlElement.Tag)); //TODO //If the Document is being loaded as part of navigation of a browsing context, then: // run the application cache selection algorithm with no manifest, passing it the Document object. BeforeHead(token); }
/// <summary> /// See 8.2.5.4.3 The "before head" insertion mode. /// </summary> /// <param name="token">The passed token.</param> void BeforeHead(HtmlToken token) { if (token.Type == HtmlTokenType.Comment) { AddComment(CurrentNode, token); return; } else if (token.Type == HtmlTokenType.DOCTYPE) { RaiseErrorOccurred(ErrorCode.DoctypeTagInappropriate); return; } else if (token.Type == HtmlTokenType.StartTag && ((HtmlTagToken)token).Name == HTMLHtmlElement.Tag) { InBody(token); return; } else if (token.Type == HtmlTokenType.StartTag && ((HtmlTagToken)token).Name == HTMLHeadElement.Tag) { var element = new HTMLHeadElement(); AddElementToCurrentNode(element, token); insert = HtmlTreeMode.InHead; return; } else if (token.IsEndTagInv(HTMLHtmlElement.Tag, HTMLBodyElement.Tag, HTMLBRElement.Tag, HTMLHeadElement.Tag)) { RaiseErrorOccurred(ErrorCode.TagCannotEndHere); return; } else if(token.Type == HtmlTokenType.Character) { var chars = (HtmlCharacterToken)token; chars.TrimStart(); if (chars.IsEmpty) return; } BeforeHead(HtmlToken.OpenTag(HTMLHeadElement.Tag)); InHead(token); }
/// <summary> /// See 8.2.5.4.5 The "in head noscript" insertion mode. /// </summary> /// <param name="token">The passed token.</param> void InHeadNoScript(HtmlToken token) { if (token.Type == HtmlTokenType.DOCTYPE) { RaiseErrorOccurred(ErrorCode.DoctypeTagInappropriate); return; } else if (token.IsStartTag(HTMLHtmlElement.Tag)) { InBody(token); return; } else if (token.IsEndTag(HTMLNoElement.NoScriptTag)) { CloseCurrentNode(); insert = HtmlTreeMode.InHead; return; } else if (token.Type == HtmlTokenType.Character) { var chars = (HtmlCharacterToken)token; var str = chars.TrimStart(); InsertCharacters(str); if (chars.IsEmpty) return; } else if (token.Type == HtmlTokenType.Comment) { InHead(token); return; } else if (token.IsStartTag(HTMLBaseFontElement.Tag, HTMLBgsoundElement.Tag, HTMLLinkElement.Tag, HTMLMetaElement.Tag, HTMLNoElement.NoFramesTag, HTMLStyleElement.Tag)) { InHead(token); return; } else if (token.IsStartTag(HTMLHeadElement.Tag, HTMLNoElement.NoScriptTag)) { RaiseErrorOccurred(ErrorCode.TagInappropriate); return; } else if (token.IsEndTagInv(HTMLBRElement.Tag)) { RaiseErrorOccurred(ErrorCode.TagCannotEndHere); return; } RaiseErrorOccurred(ErrorCode.TokenNotPossible); CloseCurrentNode(); insert = HtmlTreeMode.InHead; InHead(token); }
/// <summary> /// See 8.2.5.4.6 The "after head" insertion mode. /// </summary> /// <param name="token">The passed token.</param> void AfterHead(HtmlToken token) { if (token.Type == HtmlTokenType.Character) { var chars = (HtmlCharacterToken)token; var str = chars.TrimStart(); InsertCharacters(str); if (chars.IsEmpty) return; } else if (token.Type == HtmlTokenType.Comment) { AddComment(CurrentNode, token); return; } else if (token.Type == HtmlTokenType.DOCTYPE) { RaiseErrorOccurred(ErrorCode.DoctypeTagInappropriate); return; } else if (token.IsStartTag(HTMLHtmlElement.Tag)) { InBody(token); return; } else if (token.IsStartTag(HTMLBodyElement.Tag)) { AfterHeadStartTagBody((HtmlTagToken)token); return; } else if (token.IsStartTag(HTMLFrameSetElement.Tag)) { var element = new HTMLFrameSetElement(); AddElementToCurrentNode(element, token); insert = HtmlTreeMode.InFrameset; return; } else if (token.IsStartTag(HTMLBaseElement.Tag, HTMLBaseFontElement.Tag, HTMLBgsoundElement.Tag, HTMLLinkElement.Tag, HTMLMetaElement.Tag, HTMLNoElement.NoFramesTag, HTMLScriptElement.Tag, HTMLStyleElement.Tag, HTMLTitleElement.Tag)) { RaiseErrorOccurred(ErrorCode.TagMustBeInHead); var index = open.Count; open.Add(doc.Head); InHead(token); open.RemoveAt(index); return; } else if (token.IsStartTag(HTMLHeadElement.Tag)) { RaiseErrorOccurred(ErrorCode.HeadTagMisplaced); return; } else if (token.IsEndTagInv(HTMLHtmlElement.Tag, HTMLBodyElement.Tag, HTMLBRElement.Tag)) { RaiseErrorOccurred(ErrorCode.TagCannotEndHere); return; } AfterHeadStartTagBody(HtmlToken.OpenTag(HTMLBodyElement.Tag)); frameset = true; Consume(token); }
/// <summary> /// See 8.2.5.4.4 The "in head" insertion mode. /// </summary> /// <param name="token">The passed token.</param> void InHead(HtmlToken token) { if (token.Type == HtmlTokenType.Character) { var chars = (HtmlCharacterToken)token; var str = chars.TrimStart(); InsertCharacters(str); if (chars.IsEmpty) return; } else if (token.Type == HtmlTokenType.Comment) { AddComment(CurrentNode, token); return; } else if (token.Type == HtmlTokenType.DOCTYPE) { RaiseErrorOccurred(ErrorCode.DoctypeTagInappropriate); return; } else if (token.IsStartTag(HTMLHtmlElement.Tag)) { InBody(token); return; } else if (token.IsStartTag(HTMLBaseElement.Tag, HTMLBaseFontElement.Tag, HTMLBgsoundElement.Tag, HTMLLinkElement.Tag)) { var name = ((HtmlTagToken)token).Name; var element = HTMLElement.Factory(name); AddElementToCurrentNode(element, token, true); CloseCurrentNode(); return; } else if (token.IsStartTag(HTMLMetaElement.Tag)) { var element = new HTMLMetaElement(); AddElementToCurrentNode(element, token, true); CloseCurrentNode(); var charset = element.GetAttribute(HtmlEncoding.CHARSET); if (charset != null && HtmlEncoding.IsSupported(charset)) { SetCharset(charset); return; } charset = element.GetAttribute("http-equiv"); if (charset != null && charset.Equals("Content-Type", StringComparison.OrdinalIgnoreCase)) { charset = element.GetAttribute("content") ?? string.Empty; charset = HtmlEncoding.Extract(charset); if (HtmlEncoding.IsSupported(charset)) SetCharset(charset); } return; } else if (token.IsStartTag(HTMLTitleElement.Tag)) { RCDataAlgorithm((HtmlTagToken)token); return; } else if (token.IsStartTag(HTMLNoElement.NoFramesTag, HTMLStyleElement.Tag) || (doc.IsScripting && token.IsStartTag(HTMLNoElement.NoScriptTag))) { RawtextAlgorithm((HtmlTagToken)token); return; } else if (token.IsStartTag(HTMLNoElement.NoScriptTag)) { var element = new HTMLElement(); AddElementToCurrentNode(element, token); insert = HtmlTreeMode.InHeadNoScript; return; } else if (token.IsStartTag(HTMLScriptElement.Tag)) { var element = new HTMLScriptElement(); //element.IsParserInserted = true; //element.IsAlreadyStarted = fragment; AddElementToCurrentNode(element, token); tokenizer.Switch(HtmlParseMode.Script); originalInsert = insert; insert = HtmlTreeMode.Text; return; } else if (token.IsEndTag(HTMLHeadElement.Tag)) { CloseCurrentNode(); insert = HtmlTreeMode.AfterHead; return; } else if (token.IsStartTag(HTMLHeadElement.Tag)) { RaiseErrorOccurred(ErrorCode.HeadTagMisplaced); return; } else if (token.IsEndTagInv(HTMLHtmlElement.Tag, HTMLBodyElement.Tag, HTMLBRElement.Tag)) { RaiseErrorOccurred(ErrorCode.TagCannotEndHere); return; } CloseCurrentNode(); insert = HtmlTreeMode.AfterHead; AfterHead(token); }