Example #1
0
        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;
        }
Example #2
0
        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);
        }