public override void AppendStartTagToken(TreeConstruction tree, StartTagToken token) { if(token.IsStartTag("html")){ OnMessageRaised(new MultipleHtmlElementError()); XmlElement topElement = tree.StackOfOpenElements[0]; tree.MergeAttribute(topElement, token); return; } if(token.IsStartTag("base", "basefont", "bgsound", "command", "link", "meta", "noframes", "script", "style", "title")){ tree.AppendToken<InHeadInsertionMode>(token); return; } if(token.IsStartTag("body")){ OnMessageRaised(new MultipleBodyElementError()); XmlElement bodyElement = tree.StackOfOpenElements[1]; if(bodyElement == null || bodyElement.Name != "body") return; tree.Parser.FramesetOK = false; tree.MergeAttribute(bodyElement, token); return; } if(token.IsStartTag("frameset")){ OnMessageRaised(new UnexpectedFramesetElementError()); XmlElement bodyElement = tree.StackOfOpenElements[1]; if(bodyElement == null || bodyElement.Name != "body") return; if(tree.Parser.FramesetOK == false) return; bodyElement.ParentNode.RemoveChild(bodyElement); while(tree.StackOfOpenElements.Count > 1) tree.StackOfOpenElements.Pop(); tree.InsertElementForToken(token); tree.ChangeInsertionMode<InFramesetInsertionMode>(); return; } if(token.IsStartTag("address", "article", "aside", "blockquote", "center", "details", "dir", "div", "dl", "fieldset", "figcaption", "figure", "footer", "header", "hgroup", "menu", "nav", "ol", "p", "section", "summary", "ul")){ if(tree.StackOfOpenElements.HaveElementInButtonScope("p")){ EndTagPHadBeSeen(tree, token); } tree.InsertElementForToken(token); return; } if(token.IsStartTag(myHeadingElements)){ if(tree.StackOfOpenElements.HaveElementInButtonScope("p")){ EndTagPHadBeSeen(tree, token); } if(tree.StackOfOpenElements.IsCurrentNameMatch(myHeadingElements)){ OnMessageRaised(new NestedHeadingElementError(tree.CurrentNode.Name, token.Name)); tree.StackOfOpenElements.Pop(); } tree.InsertElementForToken(token); return; } if(token.IsStartTag("pre", "listing")){ if(tree.StackOfOpenElements.HaveElementInButtonScope("p")){ EndTagPHadBeSeen(tree, token); } tree.InsertElementForToken(token); tree.Parser.FramesetOK = false; tree.IgnoreNextLineFeed = true; return; } if(token.IsStartTag("form")){ if(tree.FormElementPointer != null){ OnMessageRaised(new NestedFormElementError()); return; } if(tree.StackOfOpenElements.HaveElementInButtonScope("p")){ EndTagPHadBeSeen(tree, token); } XmlElement form = tree.InsertElementForToken(token); tree.FormElementPointer = form; return; } if(token.IsStartTag("li")){ tree.Parser.FramesetOK = false; foreach(XmlElement e in tree.StackOfOpenElements){ if(StackOfElements.IsNameMatch(e, "li")){ EndTagHadBeSeen(tree, "li"); break; } if(StackOfElements.IsSpecialElement(e)){ if(!StackOfElements.IsNameMatch(e, "address", "div", "p")){ break; } } } if(tree.StackOfOpenElements.HaveElementInButtonScope("p")){ EndTagPHadBeSeen(tree, token); } tree.InsertElementForToken(token); return; } if(token.IsStartTag("dd", "dt")){ tree.Parser.FramesetOK = false; foreach(XmlElement e in tree.StackOfOpenElements){ if(StackOfElements.IsNameMatch(e, "dd", "dt")){ EndTagHadBeSeen(tree, token.Name); break; } if(StackOfElements.IsSpecialElement(e)){ if(!StackOfElements.IsNameMatch(e, "address", "div", "p")){ break; } } } if(tree.StackOfOpenElements.HaveElementInButtonScope("p")){ EndTagPHadBeSeen(tree, token); } tree.InsertElementForToken(token); return; } if(token.IsStartTag("plaintext")){ if(tree.StackOfOpenElements.HaveElementInButtonScope("p")){ EndTagPHadBeSeen(tree, token); } tree.InsertElementForToken(token); tree.Parser.ChangeTokenState<PLAINTEXTState>(); return; } if(token.IsStartTag("button")){ if(tree.StackOfOpenElements.HaveElementInScope("button")){ OnMessageRaised(new NestedButtonElementError()); EndTagHadBeSeen(tree, "button"); tree.ReprocessFlag = true; return; } Reconstruct(tree, token); tree.InsertElementForToken(token); tree.Parser.FramesetOK = false; return; } if(token.IsStartTag("a")){ var list = tree.ListOfActiveFormatElements; var stack = tree.StackOfOpenElements; int index = list.GetAfterMarkerIndexByName("a"); if(index >=0){ XmlElement aElement = list.GetAfterMarkerByAfterIndex(index); OnMessageRaised(new NestedAnchorElementError()); EndTagHadBeSeen(tree, "a"); stack.Remove(aElement); list.Remove(aElement); } Reconstruct(tree, token); XmlElement e = tree.InsertElementForToken(token); tree.ListOfActiveFormatElements.Push(e, token); return; } if(token.IsStartTag("b", "big", "code", "em", "font", "i", "s", "small", "strike", "strong", "tt", "u")){ Reconstruct(tree, token); XmlElement e = tree.InsertElementForToken(token); tree.ListOfActiveFormatElements.Push(e, token); return; } if(token.IsStartTag("nobr")){ Reconstruct(tree, token); if(!tree.StackOfOpenElements.HaveElementInScope(token.Name)){ OnMessageRaised(new NestedNobrElementError()); FormatEndTagHadBeSeen(tree, token, "nobr"); Reconstruct(tree, token); return; } XmlElement e = tree.InsertElementForToken(token); tree.ListOfActiveFormatElements.Push(e, token); return; } if(token.IsStartTag("applet", "marquee", "object")){ Reconstruct(tree, token); tree.InsertElementForToken(token); tree.Parser.FramesetOK = false; tree.ListOfActiveFormatElements.InsertMarker(); return; } if(token.IsStartTag("table")){ if(tree.Document.DocumentMode == DocumentMode.Quirks && tree.StackOfOpenElements.HaveElementInButtonScope("p")){ EndTagPHadBeSeen(tree, token); } tree.InsertElementForToken(token); tree.Parser.FramesetOK = false; tree.ChangeInsertionMode<InTableInsertionMode>(); return; } if(token.IsStartTag("area", "br", "embed", "img", "keygen", "wbr")){ Reconstruct(tree, token); tree.InsertElementForToken(token); tree.PopFromStack(); tree.AcknowledgeSelfClosingFlag(token); tree.Parser.FramesetOK = false; return; } if(token.IsStartTag("input")){ Reconstruct(tree, token); tree.InsertElementForToken(token); tree.PopFromStack(); tree.AcknowledgeSelfClosingFlag(token); if(!token.IsHiddenType()){ tree.Parser.FramesetOK = false; } return; } if(token.IsStartTag("param", "source", "track")){ tree.InsertElementForToken(token); tree.AcknowledgeSelfClosingFlag(token); tree.PopFromStack(); return; } if(token.IsStartTag("hr")){ if(tree.StackOfOpenElements.HaveElementInButtonScope("p")){ EndTagPHadBeSeen(tree, token); } tree.InsertElementForToken(token); tree.AcknowledgeSelfClosingFlag(token); tree.PopFromStack(); return; } if(token.IsStartTag("image")){ OnMessageRaised(new ImageElementError()); token.Name = "img"; tree.ReprocessFlag = true; return; } if(token.IsStartTag("isindex")){ OnMessageRaised(new IsindexElementError()); XmlElement node = tree.FormElementPointer; if(node != null) return; tree.AcknowledgeSelfClosingFlag(token); StartTagHadBeSeen(tree, "form"); XmlElement form = (XmlElement)tree.CurrentNode; string actionAttrValue = token.GetAttributeValue("action"); if(actionAttrValue != null) form.SetAttribute("action", actionAttrValue); StartTagHadBeSeen(tree, "hr"); StartTagHadBeSeen(tree, "label"); string promptAttrValue = token.GetAttributeValue("prompt"); if(promptAttrValue == null){ tree.InsertText("This is a searchable index. Enter search keywords:"); } else { tree.InsertText(promptAttrValue); } StartTagHadBeSeen(tree, "input"); XmlElement input = (XmlElement)tree.CurrentNode["input"]; input.SetAttribute("name", "isindex"); foreach(AttributeToken at in token.Attributes){ if(at.Name == "name" || at.Name == "action" || at.Name == "prompt") continue; input.SetAttribute(at.Name, at.Value); } EndTagHadBeSeen(tree, "label"); StartTagHadBeSeen(tree, "hr"); EndTagHadBeSeen(tree, "form"); return; } if(token.IsStartTag("textarea")){ tree.InsertElementForToken(token); tree.IgnoreNextLineFeed = true; tree.Parser.ChangeTokenState<RCDATAState>(); tree.OriginalInsertionMode = tree.CurrentInsertionMode; tree.Parser.FramesetOK = false; tree.ChangeInsertionMode<TextInsertionMode>(); return; } if(token.IsStartTag("xmp")){ if(tree.StackOfOpenElements.HaveElementInButtonScope("p")){ EndTagPHadBeSeen(tree, token); } Reconstruct(tree, token); tree.Parser.FramesetOK = false; GenericRawtextElementParsingAlgorithm(tree, token); return; } if(token.IsStartTag("iframe")){ tree.Parser.FramesetOK = false; GenericRawtextElementParsingAlgorithm(tree, token); return; } // start tag whose tag name is "noscript", if the scripting flag is enabled if(token.IsStartTag("noembed")){ GenericRawtextElementParsingAlgorithm(tree, token); return; } if(token.IsStartTag("select")){ Reconstruct(tree, token); tree.InsertElementForToken(token); tree.Parser.FramesetOK = false; if(tree.CurrentInsertionMode is TableRelatedInsertionMode){ tree.ChangeInsertionMode<InSelectInTableInsertionMode>(); } else { tree.ChangeInsertionMode<InSelectInsertionMode>(); } return; } if(token.IsStartTag("optgroup", "option")){ if(tree.CurrentNode.Name == "option") EndTagHadBeSeen(tree, "option"); Reconstruct(tree, token); tree.InsertElementForToken(token); return; } if(token.IsStartTag("rp", "rt")){ if(tree.StackOfOpenElements.HaveElementInScope("ruby")){ GenerateImpliedEndTags(tree, token); if(!tree.StackOfOpenElements.IsCurrentNameMatch("ruby")){ OnMessageRaised(new DirectParentRequiredError(token.Name, "ruby", tree.CurrentNode.Name)); tree.StackOfOpenElements.PopUntilSameTagName("ruby"); } } tree.InsertElementForToken(token); return; } if(token.IsStartTag("math")){ Reconstruct(tree, token); token.AdjustMathMLAttributes(); token.AdjustForeignAttributes(); XmlElement result = tree.CreateElementForToken(token, Document.MathMLNamespace); tree.InsertElement(result); if(token.SelfClosing){ tree.AcknowledgeSelfClosingFlag(token); tree.PopFromStack(); } return; } if(token.IsStartTag("svg")){ Reconstruct(tree, token); token.AdjustSVGAttributes(); token.AdjustForeignAttributes(); XmlElement result = tree.CreateElementForToken(token, Document.SVGNamespace); tree.InsertElement(result); if(token.SelfClosing){ tree.AcknowledgeSelfClosingFlag(token); tree.PopFromStack(); } return; } if(token.IsStartTag("caption", "col", "colgroup", "frame", "head", "tbody", "td", "tfoot", "th", "thead", "tr")){ OnMessageRaised(new ElementContextError(token.Name)); return; } // Any Other Start Tags. Reconstruct(tree, token); tree.InsertElementForToken(token); return; }
public override void AppendStartTagToken(TreeConstruction tree, StartTagToken token) { if(token.IsStartTag("html")){ tree.AppendToken<InBodyInsertionMode>(token); return; } if(token.IsStartTag("base", "basefont", "bgsound", "command", "link")){ tree.InsertElementForToken(token); tree.PopFromStack(); tree.AcknowledgeSelfClosingFlag(token); return; } if(token.IsStartTag("meta")){ tree.InsertElementForToken(token); tree.PopFromStack(); tree.AcknowledgeSelfClosingFlag(token); // charset判定 string charsetValue = token.GetAttributeValue("charset"); string httpEquivValue = token.GetAttributeValue("http-equiv"); string contentValue = token.GetAttributeValue("content"); string charsetName = null; if(charsetValue != null){ OnMessageRaised(new GenericVerbose(string.Format("meta要素のcharset属性が指定されています。: {0}", charsetValue))); charsetName = charsetValue; if(charsetName == ""){ OnMessageRaised(new EmptyCharsetWarning()); return; } OnMessageRaised(new GenericVerbose(string.Format("meta charset で文字符号化方式が指定されています。: {0}", charsetValue))); } else if(httpEquivValue != null && httpEquivValue.Equals("Content-Type", StringComparison.InvariantCultureIgnoreCase) && contentValue != null){ charsetName = EncodingSniffer.ExtractEncodingNameFromMetaElement(contentValue); if(string.IsNullOrEmpty(charsetName)){ OnMessageRaised(new EmptyCharsetWarning()); return; } OnMessageRaised(new GenericVerbose(string.Format("meta http-equivで文字符号化方式が指定されています。: {0}({1})", contentValue, charsetName))); } if(charsetName == null) return; InputStream stream = tree.Parser.InputStream; if(stream.EncodingConfidence == EncodingConfidence.Irrelevant){ OnMessageRaised(new GenericVerbose(string.Format("metaで文字符号化方式が指定されていますが、文字符号化方式の判別が必要ないモードであるため、指定を無視します。"))); return; } OnMessageRaised(new GenericVerbose(string.Format("metaの属性値から文字符号化方式を決定します。"))); Encoding enc = EncodingSniffer.GetEncodingByName(charsetName); if(enc == null){ OnMessageRaised(new UnknownCharsetWarning(charsetName)); return; } if(stream.EncodingConfidence == EncodingConfidence.Certain){ if(enc == stream.Encoding){ OnMessageRaised(new SameCharsetInformation(enc.EncodingName)); } else { OnMessageRaised(new DifferentDoubleCharsetWarning(enc.EncodingName)); } return; } // ToDo: Encodingを変更する stream.ChangeEncoding(enc); return; } if(token.IsStartTag("title")){ GenericRCDATAElementParsingAlgorithm(tree, token); return; } // RedFaceParserは常にScriptingDisabled if(token.IsStartTag("noframes", "style")){ GenericRawtextElementParsingAlgorithm(tree, token); return; } // RedFaceParserは常にScriptingDisabled if(token.IsStartTag("noscript")){ tree.InsertElementForToken(token); tree.ChangeInsertionMode<InHeadNoscriptInsertionMode>(); return; } if(token.IsStartTag("script")){ XmlElement scriptElement = tree.CreateElementForToken(token); tree.AppendChild(scriptElement); tree.PutToStack(scriptElement); tree.Parser.ChangeTokenState<ScriptDataState>(); tree.OriginalInsertionMode = tree.CurrentInsertionMode; tree.ChangeInsertionMode<TextInsertionMode>(); return; } if(token.IsStartTag("head")){ OnMessageRaised(new MultipleHeadElementError()); return; } AppendAnythingElse(tree, token); }