public override bool Process(Token t, HtmlTreeBuilder tb)
            {
                switch (t.Type)
                {
                case TokenType.Character:

                    Token.Character c = t.AsCharacter();
                    if (c.Data.Equals(NullString))
                    {
                        // TODO: confirm that check
                        tb.Error(this);
                        return(false);
                    }
                    else if (IsWhitespace(c))
                    {
                        tb.ReconstructFormattingElements();
                        tb.Insert(c);
                    }
                    else
                    {
                        tb.ReconstructFormattingElements();
                        tb.Insert(c);
                        tb.FramesetOK = false;
                    }
                    break;

                case TokenType.Comment:
                    tb.Insert(t.AsComment());
                    break;

                case TokenType.Doctype:
                    tb.Error(this);
                    return(false);

                case TokenType.StartTag:
                    bool?result = HandleStartTag(t, tb);
                    if (result.HasValue)
                    {
                        return(result.Value);
                    }

                    break;

                case TokenType.EndTag:
                    result = HandleEndTag(t, tb);
                    if (result.HasValue)
                    {
                        return(result.Value);
                    }

                    break;

                case TokenType.EOF:
                    // TODO: error if stack contains something not dd, dt, li, p, tbody, td, tfoot, th, thead, tr, body, html
                    // stop parsing
                    break;
                }

                return(true);
            }
Пример #2
0
 private static void HandleRawtext(Token.StartTag startTag, HtmlTreeBuilder tb)
 {
     tb.Insert(startTag);
     tb.tokeniser.Transition(TokeniserState.Rawtext);
     tb.MarkInsertionMode();
     tb.Transition(Text);
 }
Пример #3
0
            public override bool Process(Token t, HtmlTreeBuilder tb)
            {
                if (t.IsComment)
                {
                    tb.Insert(t.AsComment());
                }
                else if (t.IsDoctype || IsWhitespace(t) ||
                         (t.IsStartTag && t.AsStartTag().Name.Equals("html")))
                {
                    return(tb.Process(t, InBody));
                }
                else if (t.IsEOF)
                {
                    // nice work chuck
                }
                else if (t.IsStartTag && t.AsStartTag().Name.Equals("noframes"))
                {
                    return(tb.Process(t, InHead));
                }
                else
                {
                    tb.Error(this);
                    return(false);
                }

                return(true);
            }
Пример #4
0
 public override bool Process(Token t, HtmlTreeBuilder tb)
 {
     if (IsWhitespace(t))
     {
         return(true);
     }
     else if (t.IsComment)
     {
         tb.Insert(t.AsComment());
     }
     else if (t.IsDoctype)
     {
         tb.Error(this);
         return(false);
     }
     else if (t.IsStartTag &&
              t.AsStartTag().Name.Equals("html"))
     {
         return(InBody.Process(t, tb)); // does not transition
     }
     else if (t.IsStartTag &&
              t.AsStartTag().Name.Equals("head"))
     {
         HtmlElement head = tb.Insert(t.AsStartTag());
         tb.HeadElement = head;
         tb.Transition(InHead);
     }
     else if (t.IsEndTag && (StringUtil.In(t.AsEndTag().Name, "head", "body", "html", "br")))
     {
         tb.Process(new Token.StartTag("head"));
         return(tb.Process(t));
     }
     else if (t.IsEndTag)
     {
         tb.Error(this);
         return(false);
     }
     else
     {
         tb.Process(new Token.StartTag("head"));
         return(tb.Process(t));
     }
     return(true);
 }
Пример #5
0
            public override bool Process(Token t, HtmlTreeBuilder tb)
            {
                switch (t.Type)
                {
                case TokenType.Character:
                    Token.Character c = t.AsCharacter();
                    if (c.Data.Equals(NullString))
                    {
                        tb.Error(this);
                        return(false);
                    }
                    else
                    {
                        tb.GetPendingTableCharacters().Add(c);
                    }
                    break;

                default:
                    if (tb.GetPendingTableCharacters().Count > 0)
                    {
                        foreach (Token.Character char2 in tb.GetPendingTableCharacters())
                        {
                            if (!IsWhitespace(char2))
                            {
                                // InTable anything else section:
                                tb.Error(this);

                                if (StringUtil.In(tb.CurrentElement.NodeName, "table", "tbody", "tfoot", "thead", "tr"))
                                {
                                    tb.SetFosterInserts(true);
                                    tb.Process(char2, InBody);
                                    tb.SetFosterInserts(false);
                                }
                                else
                                {
                                    tb.Process(char2, InBody);
                                }
                            }
                            else
                            {
                                tb.Insert(char2);
                            }
                        }
                        tb.NewPendingTableCharacters();
                    }
                    tb.Transition(tb.OriginalState);
                    return(tb.Process(t));
                }

                return(true);
            }
            public override bool Process(Token t, HtmlTreeBuilder tb)
            {
                if (t.IsDoctype)
                {
                    tb.Error(this);
                    return(false);
                }
                else if (t.IsComment)
                {
                    tb.Insert(t.AsComment());
                }
                else if (IsWhitespace(t))
                {
                    return(true); // ignore whitespace
                }
                else if (t.IsStartTag && t.AsStartTag().Name.Equals("html"))
                {
                    tb.Insert(t.AsStartTag());
                    tb.Transition(BeforeHead);
                }
                else if (t.IsEndTag && (StringUtil.In(t.AsEndTag().Name, "head", "body", "html", "br")))
                {
                    return(AnythingElse(t, tb));
                }
                else if (t.IsEndTag)
                {
                    tb.Error(this);
                    return(false);
                }
                else
                {
                    return(AnythingElse(t, tb));
                }

                return(true);
            }
            public override bool Process(Token t, HtmlTreeBuilder tb)
            {
                if (IsWhitespace(t))
                {
                    return(tb.Process(t, InBody));
                }
                else if (t.IsComment)
                {
                    tb.Insert(t.AsComment()); // into html node
                }
                else if (t.IsDoctype)
                {
                    tb.Error(this);
                    return(false);
                }
                else if (t.IsStartTag && t.AsStartTag().Name.Equals("html"))
                {
                    return(tb.Process(t, InBody));
                }
                else if (t.IsEndTag && t.AsEndTag().Name.Equals("html"))
                {
                    if (tb.IsFragmentParsing())
                    {
                        tb.Error(this);
                        return(false);
                    }
                    else
                    {
                        tb.Transition(AfterAfterBody);
                    }
                }
                else if (t.IsEOF)
                {
                    // chillax! we're done
                }
                else
                {
                    tb.Error(this);
                    tb.Transition(InBody);
                    return(tb.Process(t));
                }

                return(true);
            }
Пример #8
0
            public override bool Process(Token t, HtmlTreeBuilder tb)
            {
                if (IsWhitespace(t))
                {
                    return(true); // ignore whitespace
                }
                else if (t.IsComment)
                {
                    tb.Insert(t.AsComment());
                }
                else if (t.IsDoctype)
                {
                    // TODO: parse error check on expected doctypes
                    // TODO: quirk state check on doctype ids
                    Token.Doctype d = t.AsDoctype();

                    var doctype = tb.Document.CreateDocumentType(
                        d.Name,
                        d.PublicIdentifier,
                        d.SystemIdentifier
                        );
                    doctype.BaseUri = tb.BaseUri;

                    tb.Document.Append(doctype);
                    if (d.ForceQuirks)
                    {
                        tb.Document.QuirksMode = QuirksMode.Quirks;
                    }

                    tb.Transition(BeforeHtml);
                }
                else
                {
                    // TODO: check not iframe srcdoc
                    tb.Transition(BeforeHtml);
                    return(tb.Process(t)); // re-process token
                }

                return(true);
            }
 // in script, style etc. normally treated as data tags
 public override bool Process(Token t, HtmlTreeBuilder tb)
 {
     if (t.IsCharacter)
     {
         tb.Insert(t.AsCharacter());
     }
     else if (t.IsEOF)
     {
         tb.Error(this);
         // if current node is script: already started
         tb.Pop();
         tb.Transition(tb.OriginalState);
         return(tb.Process(t));
     }
     else if (t.IsEndTag)
     {
         // if: An end tag whose tag name is "script" -- scripting nesting level, if evaluating scripts
         tb.Pop();
         tb.Transition(tb.OriginalState);
     }
     return(true);
 }
Пример #10
0
            public override bool Process(Token t, HtmlTreeBuilder tb)
            {
                switch (t.Type)
                {
                case TokenType.Character:
                    Token.Character c = t.AsCharacter();
                    if (c.Data.Equals(NullString))
                    {
                        tb.Error(this);
                        return(false);
                    }
                    else
                    {
                        tb.Insert(c);
                    }
                    break;

                case TokenType.Comment:
                    tb.Insert(t.AsComment());
                    break;

                case TokenType.Doctype:
                    tb.Error(this);
                    return(false);

                case TokenType.StartTag:
                    Token.StartTag start = t.AsStartTag();
                    string         name  = start.Name;
                    if (name.Equals("html"))
                    {
                        return(tb.Process(start, InBody));
                    }

                    else if (name.Equals("option"))
                    {
                        tb.Process(new Token.EndTag("option"));
                        tb.Insert(start);
                    }
                    else if (name.Equals("optgroup"))
                    {
                        if (tb.CurrentElement.NodeName.Equals("option"))
                        {
                            tb.Process(new Token.EndTag("option"));
                        }

                        else if (tb.CurrentElement.NodeName.Equals("optgroup"))
                        {
                            tb.Process(new Token.EndTag("optgroup"));
                        }

                        tb.Insert(start);
                    }
                    else if (name.Equals("select"))
                    {
                        tb.Error(this);
                        return(tb.Process(new Token.EndTag("select")));
                    }
                    else if (StringUtil.In(name, "input", "keygen", "textarea"))
                    {
                        tb.Error(this);

                        if (!tb.InSelectScope("select"))
                        {
                            return(false);    // frag
                        }
                        tb.Process(new Token.EndTag("select"));
                        return(tb.Process(start));
                    }
                    else if (name.Equals("script"))
                    {
                        return(tb.Process(t, InHead));
                    }
                    else
                    {
                        return(AnythingElse(t, tb));
                    }
                    break;

                case TokenType.EndTag:
                    Token.EndTag end = t.AsEndTag();
                    name = end.Name;

                    if (name.Equals("optgroup"))
                    {
                        if (tb.CurrentElement.NodeName.Equals("option") &&
                            tb.AboveOnStack(tb.CurrentElement) != null &&
                            tb.AboveOnStack(tb.CurrentElement).NodeName.Equals("optgroup"))
                        {
                            tb.Process(new Token.EndTag("option"));
                        }

                        if (tb.CurrentElement.NodeName.Equals("optgroup"))
                        {
                            tb.Pop();
                        }
                        else
                        {
                            tb.Error(this);
                        }
                    }
                    else if (name.Equals("option"))
                    {
                        if (tb.CurrentElement.NodeName.Equals("option"))
                        {
                            tb.Pop();
                        }
                        else
                        {
                            tb.Error(this);
                        }
                    }
                    else if (name.Equals("select"))
                    {
                        if (!tb.InSelectScope(name))
                        {
                            tb.Error(this);
                            return(false);
                        }
                        else
                        {
                            tb.PopStackToClose(name);
                            tb.ResetInsertionMode();
                        }
                    }
                    else
                    {
                        return(AnythingElse(t, tb));
                    }
                    break;

                case TokenType.EOF:
                    if (!tb.CurrentElement.NodeName.Equals("html"))
                    {
                        tb.Error(this);
                    }
                    break;

                default:
                    return(AnythingElse(t, tb));
                }

                return(true);
            }
            public override bool Process(Token t, HtmlTreeBuilder tb)
            {
                if (t.IsStartTag)
                {
                    Token.StartTag startTag = t.AsStartTag();
                    string         name     = startTag.Name;

                    if (StringUtil.In(name, "th", "td"))
                    {
                        tb.ClearStackToTableRowContext();
                        tb.Insert(startTag);
                        tb.Transition(InCell);
                        tb.InsertMarkerToFormattingElements();
                    }
                    else if (StringSet.Create("caption col colgroup tbody tfoot thead tr").Contains(name))
                    {
                        return(HandleMissingTr(t, tb));
                    }
                    else
                    {
                        return(AnythingElse(t, tb));
                    }
                }
                else if (t.IsEndTag)
                {
                    Token.EndTag endTag = t.AsEndTag();
                    string       name   = endTag.Name;

                    if (name.Equals("tr"))
                    {
                        if (!tb.InTableScope(name))
                        {
                            tb.Error(this); // frag
                            return(false);
                        }

                        tb.ClearStackToTableRowContext();
                        tb.Pop(); // tr
                        tb.Transition(InTableBody);
                    }
                    else if (name.Equals("table"))
                    {
                        return(HandleMissingTr(t, tb));
                    }
                    else if (StringUtil.In(name, "tbody", "tfoot", "thead"))
                    {
                        if (!tb.InTableScope(name))
                        {
                            tb.Error(this);
                            return(false);
                        }

                        tb.Process(new Token.EndTag("tr"));
                        return(tb.Process(t));
                    }
                    else if (StringSet.Create("body caption col colgroup html td th").Contains(name))
                    {
                        tb.Error(this);
                        return(false);
                    }
                    else
                    {
                        return(AnythingElse(t, tb));
                    }
                }
                else
                {
                    return(AnythingElse(t, tb));
                }

                return(true);
            }
 private bool AnythingElse(Token t, HtmlTreeBuilder tb)
 {
     tb.Insert("html");
     tb.Transition(BeforeHead);
     return(tb.Process(t));
 }
            public override bool Process(Token t, HtmlTreeBuilder tb)
            {
                switch (t.Type)
                {
                case TokenType.StartTag:
                    Token.StartTag startTag = t.AsStartTag();
                    string         name     = startTag.Name;

                    if (name.Equals("tr"))
                    {
                        tb.ClearStackToTableBodyContext();
                        tb.Insert(startTag);
                        tb.Transition(InRow);
                    }
                    else if (StringUtil.In(name, "th", "td"))
                    {
                        tb.Error(this);
                        tb.Process(new Token.StartTag("tr"));
                        return(tb.Process(startTag));
                    }
                    else if (StringSet.Create("caption col colgroup tbody tfoot thead").Contains(name))
                    {
                        return(ExitTableBody(t, tb));
                    }
                    else
                    {
                        return(AnythingElse(t, tb));
                    }

                    break;

                case TokenType.EndTag:
                    Token.EndTag endTag = t.AsEndTag();
                    name = endTag.Name;

                    if (StringUtil.In(name, "tbody", "tfoot", "thead"))
                    {
                        if (!tb.InTableScope(name))
                        {
                            tb.Error(this);
                            return(false);
                        }
                        else
                        {
                            tb.ClearStackToTableBodyContext();
                            tb.Pop();
                            tb.Transition(InTable);
                        }
                    }
                    else if (name.Equals("table"))
                    {
                        return(ExitTableBody(t, tb));
                    }
                    else if (StringSet.Create("body caption col colgroup html td th tr").Contains(name))
                    {
                        tb.Error(this);
                        return(false);
                    }
                    else
                    {
                        return(AnythingElse(t, tb));
                    }

                    break;

                default:
                    return(AnythingElse(t, tb));
                }
                return(true);
            }
Пример #14
0
            public override bool Process(Token t, HtmlTreeBuilder tb)
            {
                if (IsWhitespace(t))
                {
                    tb.Insert(t.AsCharacter());
                    return(true);
                }

                switch (t.Type)
                {
                case TokenType.Comment:
                    tb.Insert(t.AsComment());
                    break;

                case TokenType.Doctype:
                    tb.Error(this);
                    return(false);

                case TokenType.StartTag:
                    Token.StartTag start = t.AsStartTag();
                    string         name  = start.Name;

                    if (name.Equals("html"))
                    {
                        return(InBody.Process(t, tb));
                    }
                    else if (StringUtil.In(name, "base", "basefont", "bgsound", "command", "link"))
                    {
                        HtmlElement el = tb.InsertEmpty(start);
                        // jsoup special: update base the frist time it is seen
                        if (name.Equals("base") && el.HasAttribute("href"))
                        {
                            tb.MaybeSetBaseUri(el);
                        }
                    }
                    else if (name.Equals("meta"))
                    {
                        HtmlElement meta = tb.InsertEmpty(start);
                        // TODO: charset switches
                    }
                    else if (name.Equals("title"))
                    {
                        HandleRcData(start, tb);
                    }
                    else if (StringUtil.In(name, "noframes", "style"))
                    {
                        HandleRawtext(start, tb);
                    }
                    else if (name.Equals("noscript"))
                    {
                        // else if noscript && scripting flag = true: rawtext (jsoup doesn't run script, to handle as noscript)
                        tb.Insert(start);
                        tb.Transition(InHeadNoscript);
                    }
                    else if (name.Equals("script"))
                    {
                        // skips some script rules as won't execute them
                        tb.Insert(start);
                        tb.tokeniser.Transition(TokeniserState.ScriptData);
                        tb.MarkInsertionMode();
                        tb.Transition(Text);
                    }
                    else if (name.Equals("head"))
                    {
                        tb.Error(this);
                        return(false);
                    }
                    else
                    {
                        return(AnythingElse(t, tb));
                    }
                    break;

                case TokenType.EndTag:
                    Token.EndTag end = t.AsEndTag();
                    name = end.Name;
                    if (name.Equals("head"))
                    {
                        tb.Pop();
                        tb.Transition(AfterHead);
                    }
                    else if (StringUtil.In(name, "body", "html", "br"))
                    {
                        return(AnythingElse(t, tb));
                    }
                    else
                    {
                        tb.Error(this);
                        return(false);
                    }
                    break;

                default:
                    return(AnythingElse(t, tb));
                }
                return(true);
            }
            private Nullable <bool> HandleStartTag(Token t, HtmlTreeBuilder tb)
            {
                Token.StartTag startTag = t.AsStartTag();
                string         name     = startTag.Name;

                if (name.Equals("html"))
                {
                    tb.Error(this);
                    // merge attributes onto real html
                    var html = tb.Stack.First();
                    foreach (HtmlAttribute attribute in startTag.Attributes)
                    {
                        if (!html.HasAttribute(attribute.Name))
                        {
                            html.Attributes.Add(attribute);
                        }
                    }
                }
                else if (StringSet.Create("base basefont bgsound command link meta noframes script style title").Contains(name))
                {
                    return(tb.Process(t, InHead));
                }
                else if (name.Equals("body"))
                {
                    tb.Error(this);
                    DescendableLinkedList <DomContainer> stack = tb.Stack;
                    if (stack.Count == 1 || (stack.Count > 2 && !stack.ElementAt(1).NodeName.Equals("body")))
                    {
                        // only in fragment case
                        return(false); // ignore
                    }
                    else
                    {
                        tb.FramesetOK = false;
                        var body = stack.First();
                        foreach (HtmlAttribute attribute in startTag.Attributes)
                        {
                            if (!body.HasAttribute(attribute.Name))
                            {
                                body.Attributes.Add(attribute);
                            }
                        }
                    }
                }
                else if (name.Equals("frameset"))
                {
                    tb.Error(this);
                    DescendableLinkedList <DomContainer> stack = tb.Stack;
                    if (stack.Count == 1 || (stack.Count > 2 && !stack.ElementAt(1).NodeName.Equals("body")))
                    {
                        // only in fragment case
                        return(false); // ignore
                    }
                    else if (!tb.FramesetOK)
                    {
                        return(false); // ignore frameset
                    }
                    else
                    {
                        var second = stack.ElementAt(1);
                        if (second.Parent != null)
                        {
                            second.Remove();
                        }

                        // pop up to html element
                        while (stack.Count > 1)
                        {
                            stack.RemoveLast();
                        }

                        tb.Insert(startTag);
                        tb.Transition(InFrameset);
                    }
                }
                else if (StringSet.Create(
                             @"address article aside blockquote center details dir div dl
                                           fieldset figcaption figure footer header hgroup menu nav ol
                                           p section summary ul").Contains(name))
                {
                    if (tb.InButtonScope("p"))
                    {
                        tb.Process(new Token.EndTag("p"));
                    }
                    tb.Insert(startTag);
                }
                else if (HeadingTags.Contains(name))
                {
                    if (tb.InButtonScope("p"))
                    {
                        tb.Process(new Token.EndTag("p"));
                    }

                    if (HeadingTags.Contains(tb.CurrentElement.NodeName))
                    {
                        tb.Error(this);
                        tb.Pop();
                    }
                    tb.Insert(startTag);
                }
                else if (StringUtil.In(name, "pre", "listing"))
                {
                    if (tb.InButtonScope("p"))
                    {
                        tb.Process(new Token.EndTag("p"));
                    }

                    tb.Insert(startTag);
                    // TODO: ignore LF if next token
                    tb.FramesetOK = false;
                }
                else if (name.Equals("form"))
                {
                    if (tb.FormElement != null)
                    {
                        tb.Error(this);
                        return(false);
                    }
                    if (tb.InButtonScope("p"))
                    {
                        tb.Process(new Token.EndTag("p"));
                    }

                    HtmlElement form = tb.Insert(startTag);
                    tb.FormElement = form;
                }
                else if (name.Equals("li"))
                {
                    tb.FramesetOK = false;

                    DescendableLinkedList <DomContainer> stack = tb.Stack;
                    for (int i = stack.Count - 1; i > 0; i--)
                    {
                        var el = stack.ElementAt(i); // TODO Performance of this?
                        if (el.NodeName.Equals("li"))
                        {
                            tb.Process(new Token.EndTag("li"));
                            break;
                        }

                        if (tb.IsSpecial(el) && !StringUtil.In(el.NodeName, "address", "div", "p"))
                        {
                            break;
                        }
                    }
                    if (tb.InButtonScope("p"))
                    {
                        tb.Process(new Token.EndTag("p"));
                    }
                    tb.Insert(startTag);
                }
                else if (StringUtil.In(name, "dd", "dt"))
                {
                    tb.FramesetOK = false;
                    DescendableLinkedList <DomContainer> stack = tb.Stack;
                    for (int i = stack.Count - 1; i > 0; i--)
                    {
                        var el = stack.ElementAt(i);
                        if (StringUtil.In(el.NodeName, "dd", "dt"))
                        {
                            tb.Process(new Token.EndTag(el.NodeName));
                            break;
                        }
                        if (tb.IsSpecial(el) && !StringUtil.In(el.NodeName, "address", "div", "p"))
                        {
                            break;
                        }
                    }

                    if (tb.InButtonScope("p"))
                    {
                        tb.Process(new Token.EndTag("p"));
                    }
                    tb.Insert(startTag);
                }
                else if (name.Equals("plaintext"))
                {
                    if (tb.InButtonScope("p"))
                    {
                        tb.Process(new Token.EndTag("p"));
                    }
                    tb.Insert(startTag);
                    tb.tokeniser.Transition(TokeniserState.PLAINTEXT); // once in, never gets out
                }
                else if (name.Equals("button"))
                {
                    if (tb.InButtonScope("button"))
                    {
                        // close and reprocess
                        tb.Error(this);
                        tb.Process(new Token.EndTag("button"));
                        tb.Process(startTag);
                    }
                    else
                    {
                        tb.ReconstructFormattingElements();
                        tb.Insert(startTag);
                        tb.FramesetOK = false;
                    }
                }
                else if (name.Equals("a"))
                {
                    if (tb.GetActiveFormattingElement("a") != null)
                    {
                        tb.Error(this);
                        tb.Process(new Token.EndTag("a"));

                        // still on stack?
                        var remainingA = tb.GetFromStack("a");
                        if (remainingA != null)
                        {
                            tb.RemoveFromActiveFormattingElements(remainingA);
                            tb.RemoveFromStack(remainingA);
                        }
                    }
                    tb.ReconstructFormattingElements();
                    HtmlElement a = tb.Insert(startTag);
                    tb.PushActiveFormattingElements(a);
                }
                else if (StringSet.Create("b big code em font i s small strike strong tt u").Contains(name))
                {
                    tb.ReconstructFormattingElements();
                    HtmlElement el = tb.Insert(startTag);
                    tb.PushActiveFormattingElements(el);
                }
                else if (name.Equals("nobr"))
                {
                    tb.ReconstructFormattingElements();
                    if (tb.InScope("nobr"))
                    {
                        tb.Error(this);
                        tb.Process(new Token.EndTag("nobr"));
                        tb.ReconstructFormattingElements();
                    }
                    HtmlElement el = tb.Insert(startTag);
                    tb.PushActiveFormattingElements(el);
                }
                else if (StringUtil.In(name, "applet", "marquee", "object"))
                {
                    tb.ReconstructFormattingElements();
                    tb.Insert(startTag);
                    tb.InsertMarkerToFormattingElements();
                    tb.FramesetOK = false;
                }
                else if (name.Equals("table"))
                {
                    if (tb.Document.QuirksMode != QuirksMode.Quirks && tb.InButtonScope("p"))
                    {
                        tb.Process(new Token.EndTag("p"));
                    }
                    tb.Insert(startTag);
                    tb.FramesetOK = false;
                    tb.Transition(InTable);
                }
                else if (StringSet.Create("area br embed img keygen wbr").Contains(name))
                {
                    tb.ReconstructFormattingElements();
                    tb.InsertEmpty(startTag);
                    tb.FramesetOK = false;
                }
                else if (name.Equals("input"))
                {
                    tb.ReconstructFormattingElements();
                    HtmlElement el = tb.InsertEmpty(startTag);

                    if (!el.Attribute("type").Equals("hidden", StringComparison.OrdinalIgnoreCase))
                    {
                        tb.FramesetOK = false;
                    }
                }
                else if (StringUtil.In(name, "param", "source", "track"))
                {
                    tb.InsertEmpty(startTag);
                }
                else if (name.Equals("hr"))
                {
                    if (tb.InButtonScope("p"))
                    {
                        tb.Process(new Token.EndTag("p"));
                    }
                    tb.InsertEmpty(startTag);
                    tb.FramesetOK = false;
                }
                else if (name.Equals("image"))
                {
                    // we're not supposed to ask.
                    startTag.Name = "img";
                    return(tb.Process(startTag));
                }
                else if (name.Equals("isindex"))
                {
                    // how much do we care about the early 90s?
                    tb.Error(this);
                    if (tb.FormElement != null)
                    {
                        return(false);
                    }

                    tb.tokeniser.AcknowledgeSelfClosingFlag();
                    tb.Process(new Token.StartTag("form"));

                    if (startTag.Attributes.Contains("action"))
                    {
                        HtmlElement form = tb.FormElement;
                        form.Attribute("action", startTag.Attributes["action"]);
                    }

                    tb.Process(new Token.StartTag("hr"));
                    tb.Process(new Token.StartTag("label"));

                    // hope you like english.
                    string prompt = startTag.Attributes.Contains("prompt") ?
                                    startTag.Attributes["prompt"] :
                                    "This is a searchable index. Enter search keywords: ";

                    tb.Process(new Token.Character(prompt));

                    // input
                    var inputStToken = new Token.StartTag("input");
                    HtmlAttributeCollection inputAttribs = inputStToken.Attributes;
                    inputAttribs["name"] = "isindex";

                    foreach (HtmlAttribute attr in startTag.Attributes)
                    {
                        if (!StringUtil.In(attr.Name.LocalName, "name", "action", "prompt"))
                        {
                            inputAttribs.Add(attr);
                        }
                    }

                    tb.Process(inputStToken);
                    tb.Process(new Token.EndTag("label"));
                    tb.Process(new Token.StartTag("hr"));

                    tb.Process(new Token.EndTag("form"));
                }
                else if (name.Equals("textarea"))
                {
                    tb.Insert(startTag);
                    // TODO: If the next token is a U+000A LINE FEED (LF) char token, then ignore that token and move on to the next one. (Newlines at the start of textarea elements are ignored as an authoring convenience.)
                    tb.tokeniser.Transition(TokeniserState.Rcdata);
                    tb.MarkInsertionMode();
                    tb.FramesetOK = false;
                    tb.Transition(Text);
                }
                else if (name.Equals("xmp"))
                {
                    if (tb.InButtonScope("p"))
                    {
                        tb.Process(new Token.EndTag("p"));
                    }
                    tb.ReconstructFormattingElements();
                    tb.FramesetOK = false;
                    HandleRawtext(startTag, tb);
                }
                else if (name.Equals("iframe"))
                {
                    tb.FramesetOK = false;
                    HandleRawtext(startTag, tb);
                }
                else if (name.Equals("noembed"))
                {
                    // also handle noscript if script enabled
                    HandleRawtext(startTag, tb);
                }
                else if (name.Equals("select"))
                {
                    tb.ReconstructFormattingElements();
                    tb.Insert(startTag);
                    tb.FramesetOK = false;

                    HtmlTreeBuilderState state = tb.State;
                    if (state.Equals(InTable) || state.Equals(InCaption) || state.Equals(InTableBody) || state.Equals(InRow) || state.Equals(InCell))
                    {
                        tb.Transition(InSelectInTable);
                    }
                    else
                    {
                        tb.Transition(InSelect);
                    }
                }
                else if (StringUtil.In(name, "optgroup", "option"))
                {
                    if (tb.CurrentElement.NodeName.Equals("option"))
                    {
                        tb.Process(new Token.EndTag("option"));
                    }
                    tb.ReconstructFormattingElements();
                    tb.Insert(startTag);
                }
                else if (StringUtil.In(name, "rp", "rt"))
                {
                    if (tb.InScope("ruby"))
                    {
                        tb.GenerateImpliedEndTags();
                        if (!tb.CurrentElement.NodeName.Equals("ruby"))
                        {
                            tb.Error(this);
                            tb.PopStackToBefore("ruby"); // i.e. close up to but not include name
                        }
                        tb.Insert(startTag);
                    }
                }
                else if (name.Equals("math"))
                {
                    tb.ReconstructFormattingElements();
                    // TODO: handle A start tag whose tag name is "math" (i.e. foreign, mathml)
                    tb.Insert(startTag);
                    tb.tokeniser.AcknowledgeSelfClosingFlag();
                }
                else if (name.Equals("svg"))
                {
                    tb.ReconstructFormattingElements();
                    // TODO: handle A start tag whose tag name is "svg" (xlink, svg)
                    tb.Insert(startTag);
                    tb.tokeniser.AcknowledgeSelfClosingFlag();
                }
                else if (StringSet.Create("caption col colgroup frame head tbody td tfoot th thead tr").Contains(name))
                {
                    tb.Error(this);
                    return(false);
                }
                else
                {
                    tb.ReconstructFormattingElements();
                    tb.Insert(startTag);
                }

                return(null);
            }
            public override bool Process(Token t, HtmlTreeBuilder tb)
            {
                if (IsWhitespace(t))
                {
                    tb.Insert(t.AsCharacter());
                    return(true);
                }

                switch (t.Type)
                {
                case TokenType.Comment:
                    tb.Insert(t.AsComment());
                    break;

                case TokenType.Doctype:
                    tb.Error(this);
                    break;

                case TokenType.StartTag:
                    Token.StartTag startTag = t.AsStartTag();
                    string         name     = startTag.Name;

                    if (name.Equals("html"))
                    {
                        return(tb.Process(t, InBody));
                    }

                    else if (name.Equals("col"))
                    {
                        tb.InsertEmpty(startTag);
                    }

                    else
                    {
                        return(AnythingElse(t, tb));
                    }
                    break;

                case TokenType.EndTag:
                    Token.EndTag endTag = t.AsEndTag();
                    name = endTag.Name;

                    if (name.Equals("colgroup"))
                    {
                        if (tb.CurrentElement.NodeName.Equals("html"))       // frag case
                        {
                            tb.Error(this);
                            return(false);
                        }
                        else
                        {
                            tb.Pop();
                            tb.Transition(InTable);
                        }
                    }
                    else
                    {
                        return(AnythingElse(t, tb));
                    }
                    break;

                case TokenType.EOF:
                    if (tb.CurrentElement.NodeName.Equals("html"))
                    {
                        return(true);    // stop parsing; frag case
                    }
                    else
                    {
                        return(AnythingElse(t, tb));
                    }

                default:
                    return(AnythingElse(t, tb));
                }

                return(true);
            }
            public override bool Process(Token t, HtmlTreeBuilder tb)
            {
                if (t.IsCharacter)
                {
                    tb.NewPendingTableCharacters();
                    tb.MarkInsertionMode();
                    tb.Transition(InTableText);
                    return(tb.Process(t));
                }
                else if (t.IsComment)
                {
                    tb.Insert(t.AsComment());
                    return(true);
                }
                else if (t.IsDoctype)
                {
                    tb.Error(this);
                    return(false);
                }
                else if (t.IsStartTag)
                {
                    Token.StartTag startTag = t.AsStartTag();
                    string         name     = startTag.Name;

                    switch (name)
                    {
                    case "caption":
                        tb.ClearStackToTableContext();
                        tb.InsertMarkerToFormattingElements();
                        tb.Insert(startTag);
                        tb.Transition(InCaption);
                        break;

                    case "colgroup":
                        tb.ClearStackToTableContext();
                        tb.Insert(startTag);
                        tb.Transition(InColumnGroup);
                        break;

                    case "col":
                        tb.Process(new Token.StartTag("colgroup"));
                        return(tb.Process(t));

                    case "table":
                        tb.Error(this);
                        bool processed = tb.Process(new Token.EndTag("table"));
                        if (processed)     // only ignored if in fragment
                        {
                            return(tb.Process(t));
                        }
                        break;

                    case "tbody":
                    case "tfoot":
                    case "thead":
                        tb.ClearStackToTableContext();
                        tb.Insert(startTag);
                        tb.Transition(InTableBody);
                        break;

                    case "td":
                    case "th":
                    case "tr":
                        tb.Process(new Token.StartTag("tbody"));
                        return(tb.Process(t));

                    case "style":
                    case "script":
                        return(tb.Process(t, InHead));

                    case "input":
                        if (!startTag.Attributes["type"]
                            .Equals("hidden", StringComparison.OrdinalIgnoreCase))
                        {
                            return(AnythingElse(t, tb));
                        }
                        else
                        {
                            tb.InsertEmpty(startTag);
                        }
                        break;

                    case "form":
                        tb.Error(this);
                        if (tb.FormElement != null)
                        {
                            return(false);
                        }

                        else
                        {
                            HtmlElement form = tb.InsertEmpty(startTag);
                            tb.FormElement = form;
                        }
                        break;

                    default:
                        return(AnythingElse(t, tb));
                    }
                }
                else if (t.IsEndTag)
                {
                    Token.EndTag endTag = t.AsEndTag();
                    string       name   = endTag.Name;

                    switch (name)
                    {
                    case "table":
                        if (!tb.InTableScope(name))
                        {
                            tb.Error(this);
                            return(false);
                        }
                        else
                        {
                            tb.PopStackToClose("table");
                        }
                        tb.ResetInsertionMode();
                        break;

                    case "body":
                    case "caption":
                    case "col":
                    case "colgroup":
                    case "html":
                    case "tbody":
                    case "td":
                    case "tfoot":
                    case "th":
                    case "thead":
                    case "tr":
                        tb.Error(this);
                        return(false);

                    default:
                        return(AnythingElse(t, tb));
                    }
                }
                else if (t.IsEOF)
                {
                    if (tb.CurrentElement.NodeName.Equals("html"))
                    {
                        tb.Error(this);
                    }

                    return(true); // stops parsing
                }

                return(AnythingElse(t, tb));
            }
            public override bool Process(Token t, HtmlTreeBuilder tb)
            {
                if (IsWhitespace(t))
                {
                    tb.Insert(t.AsCharacter());
                }
                else if (t.IsComment)
                {
                    tb.Insert(t.AsComment());
                }
                else if (t.IsDoctype)
                {
                    tb.Error(this);
                }
                else if (t.IsStartTag)
                {
                    Token.StartTag startTag = t.AsStartTag();
                    string         name     = startTag.Name;

                    switch (name)
                    {
                    case "html":
                        return(tb.Process(t, InBody));

                    case "body":
                        tb.Insert(startTag);
                        tb.FramesetOK = false;
                        tb.Transition(InBody);
                        break;

                    case "frameset":
                        tb.Insert(startTag);
                        tb.Transition(InFrameset);
                        break;

                    case "base":
                    case "basefont":
                    case "bgsound":
                    case "link":
                    case "meta":
                    case "noframes":
                    case "script":
                    case "style":
                    case "title":
                        tb.Error(this);

                        HtmlElement head = tb.HeadElement;
                        tb.Push(head);
                        tb.Process(t, InHead);
                        tb.RemoveFromStack(head);
                        break;

                    case "head":
                        tb.Error(this);
                        return(false);

                    default:
                        AnythingElse(t, tb);
                        break;
                    }
                }
                else if (t.IsEndTag)
                {
                    if (StringUtil.In(t.AsEndTag().Name, "body", "html"))
                    {
                        AnythingElse(t, tb);
                    }
                    else
                    {
                        tb.Error(this);
                        return(false);
                    }
                }
                else
                {
                    AnythingElse(t, tb);
                }
                return(true);
            }
Пример #19
0
            public override bool Process(Token t, HtmlTreeBuilder tb)
            {
                if (IsWhitespace(t))
                {
                    tb.Insert(t.AsCharacter());
                }
                else if (t.IsComment)
                {
                    tb.Insert(t.AsComment());
                }
                else if (t.IsDoctype)
                {
                    tb.Error(this);
                    return(false);
                }
                else if (t.IsStartTag)
                {
                    Token.StartTag start = t.AsStartTag();
                    switch (start.Name)
                    {
                    case "html":
                        return(tb.Process(start, InBody));

                    case "frameset":
                        tb.Insert(start);
                        break;

                    case "frame":
                        tb.InsertEmpty(start);
                        break;

                    case "noframes":
                        return(tb.Process(start, InHead));

                    default:
                        tb.Error(this);
                        return(false);
                    }
                }
                else if (t.IsEndTag && t.AsEndTag().Name.Equals("frameset"))
                {
                    if (tb.CurrentElement.NodeName.Equals("html"))   // frag
                    {
                        tb.Error(this);
                        return(false);
                    }
                    else
                    {
                        tb.Pop();
                        if (!tb.IsFragmentParsing() && !tb.CurrentElement.NodeName.Equals("frameset"))
                        {
                            tb.Transition(AfterFrameset);
                        }
                    }
                }
                else if (t.IsEOF)
                {
                    if (!tb.CurrentElement.NodeName.Equals("html"))
                    {
                        tb.Error(this);
                        return(true);
                    }
                }
                else
                {
                    tb.Error(this);
                    return(false);
                }

                return(true);
            }