Beispiel #1
1
 public void CSSStyleDeclarationBoundOutboundDirectionIndirect()
 {
     var element = new HTMLElement();
     var text = "background: red; color: black";
     element.SetAttribute("style", text);
     Assert.AreEqual(text, element.Style.CssText);
     Assert.AreEqual(2, element.Style.Length);
 }
Beispiel #2
1
 public void CSSStyleDeclarationBoundInboundDirection()
 {
     var element = new HTMLElement();
     var text = "background: red; color: black";
     element.Style.CssText = text;
     Assert.AreEqual(text, element.Attributes["style"].Value);
     Assert.AreEqual(2, element.Style.Length);
 }
Beispiel #3
1
        void SubmitForm(HTMLElement from, Boolean submittedFromSubmitMethod)
        {
            var formDocument = OwnerDocument;

            //TODO
            //If form document has no associated browsing context or its active
            //sandboxing flag set has its sandboxed forms browsing context flag
            //set, then abort these steps without doing anything.

            var browsingContext = new object();//TODO

            if (!submittedFromSubmitMethod && from.Attributes[AttributeNames.FORMNOVALIDATE] == null && NoValidate)
            {
                if (!CheckValidity())
                {
                    FireSimpleEvent(EventNames.INVALID);
                    return;
                }
            }

            var formDataSet = ConstructDataSet();
            var action = Action;

            if (String.IsNullOrEmpty(action))
                action = formDocument.DocumentURI;

            if (!Location.IsAbsolute(action))
                action = Location.MakeAbsolute(from.BaseURI, action);

            //Enctype
            //Method
            //Target

            //TODO
            //If the user indicated a specific browsing context to use when submitting
            //the form, then let target browsing context be that browsing context.
            //Otherwise, apply the rules for choosing a browsing context given a browsing
            //context name using target as the name and form browsing context as the
            //context in which the algorithm is executed, and let target browsing context
            //be the resulting browsing context.

            //TODO
            //If target browsing context was created in the previous step, or, alternatively,
            //if the form document has not yet completely loaded and the submitted from
            //submit() method is set, then let replace be true. Otherwise, let it be false

            var replace = false;
            var location = new Location(action);

            switch (location.Protocol)
            {
                case "http:":
                case "https:":
                    if (Method == HttpMethod.GET)
                        MutateActionUrl();
                    else if (Method == HttpMethod.POST)
                        SubmitAsEntityBody();
                    break;

                case "ftp:":
                case "javascript:":
                    GetActionUrl();
                    break;

                case "data:":
                    if (Method == HttpMethod.GET)
                        GetActionUrl();
                    else if (Method == HttpMethod.POST)
                        PostToData();
                    break;

                case "mailto:":
                    if (Method == HttpMethod.GET)
                        MailWithHeaders();
                    else if (Method == HttpMethod.POST)
                        MailAsBody();
                    break;
            }

            //TODO
        }
        internal override void ConstructDataSet(FormDataSet dataSet, HTMLElement submitter)
        {
            for (int i = 0; i < _options.Length; i++)
            {
                var option = _options.GetOptionAt(i);

                if (option.IsSelected && !option.IsDisabled)
                    dataSet.Append(Name, option.Value, Type);
            }
        }
Beispiel #5
0
 public void CSSStyleDeclarationBoundOutboundDirectionDirect()
 {
     var element = new HTMLElement();
     var text = "background: red; color: black";
     element.SetAttribute("style", String.Empty);
     Assert.AreEqual(String.Empty, element.Style.CssText);
     element.Attributes["style"].Value = text;
     Assert.AreEqual(text, element.Style.CssText);
     Assert.AreEqual(2, element.Style.Length);
 }
Beispiel #6
0
        internal override void ConstructDataSet(FormDataSet dataSet, HTMLElement submitter)
        {
            var options = _options.Elements;

            foreach (var option in options)
            {
                if (option.Selected && !option.Disabled)
                    dataSet.Append(Name, option.Value, Multiple ? "select-one" : "select-multiple");
            }
        }
Beispiel #7
0
        FormDataSet ConstructDataSet(HTMLElement submitter = null)
        {
            var formDataSet = new FormDataSet();
            var fields = _elements.Elements;

            foreach (var field in fields)
            {
                if (field.ParentElement is HTMLDataListElement)
                    continue;
                else if (field.Disabled)
                    continue;

                field.ConstructDataSet(formDataSet, submitter);
            }

            return formDataSet;
        }
 /// <summary>
 /// Constucts the data set (called from a form).
 /// </summary>
 /// <param name="dataSet">The dataset to construct.</param>
 /// <param name="submitter">The given submitter.</param>
 internal virtual void ConstructDataSet(FormDataSet dataSet, HTMLElement submitter)
 {
 }
Beispiel #9
0
 /// <summary>
 /// Constucts the data set (called from a form).
 /// </summary>
 /// <param name="dataSet">The dataset to construct.</param>
 /// <param name="submitter">The given submitter.</param>
 internal override void ConstructDataSet(FormDataSet dataSet, HTMLElement submitter)
 {
     if (this == submitter)
         return;
     else if (Type == ButtonType.Submit || Type == ButtonType.Reset)
         dataSet.Append(Name, Value, Type.ToString());
 }
Beispiel #10
0
        /// <summary>
        /// Constucts the data set (called from a form).
        /// </summary>
        /// <param name="dataSet">The dataset to construct.</param>
        /// <param name="submitter">The given submitter.</param>
        internal override void ConstructDataSet(FormDataSet dataSet, HTMLElement submitter)
        {
            switch (Type)
            {
                case InputType.Radio:
                case InputType.Checkbox:
                {
                    if (Checked)
                    {
                        var value = "on";

                        if (!String.IsNullOrEmpty(Value))
                            value = Value;

                        dataSet.Append(Name, value, Type.ToString());
                    }

                    break;
                }
                case InputType.Image:
                {
                    if (!String.IsNullOrEmpty(Name))
                    {
                        var name = String.Empty;

                        if (!String.IsNullOrEmpty(Value))
                            name = Value + ".";

                        var namex = name + "x";
                        var namey = name + "y";

                        //TODO get x and y of submitter and save those
                        dataSet.Append(namex, "0", Type.ToString());
                        dataSet.Append(namey, "0", Type.ToString());
                    }

                    break;
                }
                case InputType.File:
                {
                    if(_files.Length == 0)
                        dataSet.Append(Name, String.Empty, "application/octet-stream");

                    foreach (var file in _files)
                        dataSet.Append(Name, file, Type.ToString());

                    break;
                }
                case InputType.Text:
                case InputType.Search:
                {
                    dataSet.Append(Name, Value, Type.ToString());

                    if (_attributes[AttributeNames.DIRNAME] != null)
                    {
                        var dirname = _attributes[AttributeNames.DIRNAME].Value;

                        if (String.IsNullOrEmpty(dirname))
                            break;

                        dataSet.Append(dirname, Dir.ToString().ToLower(), "Direction");
                    }

                    break;
                }
                default:
                {
                    dataSet.Append(Name, Value, Type.ToString());
                    break;
                }
            }
        }
Beispiel #11
0
        /// <summary>
        /// Constucts the data set (called from a form).
        /// </summary>
        /// <param name="dataSet">The dataset to construct.</param>
        /// <param name="submitter">The given submitter.</param>
        internal override void ConstructDataSet(FormDataSet dataSet, HTMLElement submitter)
        {
            dataSet.Append(Name, Value, Type.ToString());

            if (_attributes[AttributeNames.DIRNAME] != null)
            {
                var dirname = _attributes[AttributeNames.DIRNAME].Value;

                if (String.IsNullOrEmpty(dirname))
                    return;

                dataSet.Append(dirname, Dir.ToString().ToLower(), "Direction");
            }
        }
Beispiel #12
0
        /// <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);
        }
Beispiel #13
0
        /// <summary>
        /// See 8.2.5.4.7 The "in body" insertion mode.
        /// </summary>
        /// <param name="token">The passed token.</param>
        void InBody(HtmlToken token)
        {
            if (token.Type == HtmlTokenType.Character)
            {
                var chrs = (HtmlCharacterToken)token;
                ReconstructFormatting();
                InsertCharacters(chrs.Data);

                if(chrs.HasContent)
                    frameset = false;
            }
            else if (token.Type == HtmlTokenType.Comment)
                AddComment(CurrentNode, token);
            else if (token.Type == HtmlTokenType.DOCTYPE)
                RaiseErrorOccurred(ErrorCode.DoctypeTagInappropriate);
            else if (token.Type == HtmlTokenType.StartTag)
            {
                var tag = (HtmlTagToken)token;

                switch (tag.Name)
                {
                    case HTMLHtmlElement.Tag:
                    {
                        RaiseErrorOccurred(ErrorCode.HtmlTagMisplaced);
                        AppendAttributes(tag, open[0]);
                        break;
                    }
                    case HTMLBaseElement.Tag:
                    case HTMLBaseFontElement.Tag:
                    case HTMLBgsoundElement.Tag:
                    case HTMLLinkElement.Tag:
                    case HTMLMenuItemElement.Tag:
                    case HTMLMetaElement.Tag:
                    case HTMLNoElement.NoFramesTag:
                    case HTMLScriptElement.Tag:
                    case HTMLStyleElement.Tag:
                    case HTMLTitleElement.Tag:
                    {
                        InHead(token);
                        break;
                    }
                    case HTMLBodyElement.Tag:
                    {
                        RaiseErrorOccurred(ErrorCode.BodyTagMisplaced);

                        if (open.Count > 1 && open[1] is HTMLBodyElement)
                        {
                            frameset = false;
                            AppendAttributes(tag, open[1]);
                        }

                        break;
                    }
                    case HTMLFrameSetElement.Tag:
                    {
                        RaiseErrorOccurred(ErrorCode.FramesetMisplaced);

                        if (open.Count != 1 && open[1] is HTMLBodyElement && frameset)
                        {
                            open[1].ParentNode.RemoveChild(open[1]);

                            while (open.Count > 1)
                                CloseCurrentNode();

                            var element = new HTMLFrameSetElement();
                            AddElementToCurrentNode(element, token);
                            insert = HtmlTreeMode.InFrameset;
                        }

                        break;
                    }
                    case HTMLSemanticElement.AddressTag:
                    case HTMLSemanticElement.ArticleTag:
                    case HTMLSemanticElement.AsideTag:
                    case HTMLQuoteElement.BlockTag:
                    case HTMLSemanticElement.CenterTag:
                    case HTMLDetailsElement.Tag:
                    case HTMLDialogElement.Tag:
                    case HTMLDirectoryElement.Tag:
                    case HTMLDivElement.Tag:
                    case HTMLDListElement.Tag:
                    case HTMLFieldSetElement.Tag:
                    case HTMLSemanticElement.FigcaptionTag:
                    case HTMLSemanticElement.FigureTag:
                    case HTMLSemanticElement.FooterTag:
                    case HTMLSemanticElement.HeaderTag:
                    case HTMLSemanticElement.HgroupTag:
                    case HTMLMenuElement.Tag:
                    case HTMLSemanticElement.NavTag:
                    case HTMLOListElement.Tag:
                    case HTMLParagraphElement.Tag:
                    case HTMLSemanticElement.SectionTag:
                    case HTMLSemanticElement.SummaryTag:
                    case HTMLUListElement.Tag:
                    {
                        if (IsInButtonScope(HTMLParagraphElement.Tag))
                            InBodyEndTagParagraph();

                        var element = HTMLElement.Factory(tag.Name);
                        AddElementToCurrentNode(element, token);
                        break;
                    }
                    case HTMLHeadingElement.ChapterTag:
                    case HTMLHeadingElement.SubSubSubSubSectionTag:
                    case HTMLHeadingElement.SubSubSubSectionTag:
                    case HTMLHeadingElement.SubSubSectionTag:
                    case HTMLHeadingElement.SubSectionTag:
                    case HTMLHeadingElement.SectionTag:
                    {
                        if (IsInButtonScope(HTMLParagraphElement.Tag))
                            InBodyEndTagParagraph();

                        if (CurrentNode is HTMLHeadingElement)
                        {
                            RaiseErrorOccurred(ErrorCode.HeadingNested);
                            CloseCurrentNode();
                        }

                        var element = new HTMLHeadingElement();
                        AddElementToCurrentNode(element, token);
                        break;
                    }
                    case HTMLPreElement.Tag:
                    case HTMLSemanticElement.ListingTag:
                    {
                        if (IsInButtonScope(HTMLParagraphElement.Tag))
                            InBodyEndTagParagraph();

                        var element = new HTMLPreElement();
                        AddElementToCurrentNode(element, token);
                        frameset = false;
                        PreventNewLine();
                        break;
                    }
                    case HTMLFormElement.Tag:
                    {
                        if (form == null)
                        {
                            if (IsInButtonScope(HTMLParagraphElement.Tag))
                                InBodyEndTagParagraph();

                            var element = new HTMLFormElement();
                            AddElementToCurrentNode(element, token);
                            form = element;
                        }
                        else
                            RaiseErrorOccurred(ErrorCode.FormAlreadyOpen);

                        break;
                    }
                    case HTMLLIElement.ItemTag:
                    {
                        InBodyStartTagListItem(tag);
                        break;
                    }
                    case HTMLLIElement.DefinitionTag:
                    case HTMLLIElement.DescriptionTag:
                    {
                        InBodyStartTagDefinitionItem(tag);
                        break;
                    }
                    case HTMLSemanticElement.PlaintextTag:
                    {
                        if (IsInButtonScope(HTMLParagraphElement.Tag))
                            InBodyEndTagParagraph();

                        var plaintext = new HTMLElement();
                        AddElementToCurrentNode(plaintext, token);
                        tokenizer.Switch(HtmlParseMode.Plaintext);
                        break;
                    }
                    case HTMLButtonElement.Tag:
                    {
                        if (IsInScope(tag.Name))
                        {
                            RaiseErrorOccurred(ErrorCode.ButtonInScope);
                            InBodyEndTagBlock(tag.Name);
                            InBody(token);
                        }
                        else
                        {
                            ReconstructFormatting();
                            var element = new HTMLButtonElement();
                            AddElementToCurrentNode(element, token);
                            frameset = false;
                        }
                        break;
                    }
                    case HTMLAnchorElement.Tag:
                    {
                        for (var i = formatting.Count - 1; i >= 0; i--)
                        {
                            if (formatting[i] is ScopeMarkerNode)
                                break;
                            else if (formatting[i].NodeName == HTMLAnchorElement.Tag)
                            {
                                var format = formatting[i];
                                RaiseErrorOccurred(ErrorCode.AnchorNested);
                                HeisenbergAlgorithm(HtmlToken.CloseTag(HTMLAnchorElement.Tag));
                                if(open.Contains(format)) open.Remove(format);
                                if(formatting.Contains(format)) formatting.RemoveAt(i);
                                break;
                            }
                        }

                        ReconstructFormatting();
                        var element = new HTMLAnchorElement();
                        AddElementToCurrentNode(element, token);
                        AddFormattingElement(element);
                        break;
                    }
                    case HTMLFormattingElement.BTag:
                    case HTMLFormattingElement.BigTag:
                    case HTMLFormattingElement.CodeTag:
                    case HTMLFormattingElement.EmTag:
                    case HTMLFontElement.Tag:
                    case HTMLFormattingElement.ITag:
                    case HTMLFormattingElement.STag:
                    case HTMLFormattingElement.SmallTag:
                    case HTMLFormattingElement.StrikeTag:
                    case HTMLFormattingElement.StrongTag:
                    case HTMLFormattingElement.TtTag:
                    case HTMLFormattingElement.UTag:
                    {
                        ReconstructFormatting();
                        var element = HTMLElement.Factory(tag.Name);
                        AddElementToCurrentNode(element, token);
                        AddFormattingElement(element);
                        break;
                    }
                    case HTMLFormattingElement.NobrTag:
                    {
                        ReconstructFormatting();

                        if (IsInScope(HTMLFormattingElement.NobrTag))
                        {
                            RaiseErrorOccurred(ErrorCode.NobrInScope);
                            HeisenbergAlgorithm(tag);
                            ReconstructFormatting();
                        }

                        var element = new HTMLElement();
                        AddElementToCurrentNode(element, token);
                        AddFormattingElement(element);
                        break;
                    }
                    case HTMLAppletElement.Tag:
                    case HTMLMarqueeElement.Tag:
                    case HTMLObjectElement.Tag:
                    {
                        ReconstructFormatting();
                        var element = HTMLElement.Factory(tag.Name);
                        AddElementToCurrentNode(element, token);
                        InsertScopeMarker();
                        frameset = false;
                        break;
                    }
                    case HTMLTableElement.Tag:
                    {
                        if (doc.QuirksMode == QuirksMode.Off && IsInButtonScope(HTMLParagraphElement.Tag))
                            InBodyEndTagParagraph();

                        var element = new HTMLTableElement();
                        AddElementToCurrentNode(element, token);
                        frameset = false;
                        insert = HtmlTreeMode.InTable;
                        break;
                    }
                    case HTMLAreaElement.Tag:
                    case HTMLBRElement.Tag:
                    case HTMLEmbedElement.Tag:
                    case HTMLImageElement.Tag:
                    case HTMLKeygenElement.Tag:
                    case HTMLWbrElement.Tag:
                    {
                        InBodyStartTagBreakrow(tag);
                        break;
                    }
                    case HTMLInputElement.Tag:
                    {
                        ReconstructFormatting();
                        var element = new HTMLInputElement();
                        AddElementToCurrentNode(element, token, true);
                        CloseCurrentNode();

                        if (!tag.GetAttribute("type").Equals("hidden", StringComparison.OrdinalIgnoreCase))
                            frameset = false;
                        break;
                    }
                    case HTMLParamElement.Tag:
                    case HTMLSourceElement.Tag:
                    case HTMLTrackElement.Tag:
                    {
                        var element = HTMLElement.Factory(tag.Name);
                        AddElementToCurrentNode(element, token, true);
                        CloseCurrentNode();
                        break;
                    }
                    case HTMLHRElement.Tag:
                    {
                        if (IsInButtonScope(HTMLParagraphElement.Tag))
                            InBodyEndTagParagraph();

                        var element = new HTMLHRElement();
                        AddElementToCurrentNode(element, token, true);
                        CloseCurrentNode();
                        frameset = false;
                        break;
                    }
                    case HTMLImageElement.FalseTag:
                    {
                        RaiseErrorOccurred(ErrorCode.ImageTagNamedWrong);
                        tag.Name = HTMLImageElement.Tag;
                        goto case HTMLImageElement.Tag;
                    }
                    case HTMLIsIndexElement.Tag:
                    {
                        RaiseErrorOccurred(ErrorCode.TagInappropriate);

                        if (form == null)
                        {
                            InBody(HtmlToken.OpenTag(HTMLFormElement.Tag));

                            if (tag.GetAttribute("action") != String.Empty)
                                form.SetAttribute("action", tag.GetAttribute("action"));

                            InBody(HtmlToken.OpenTag(HTMLHRElement.Tag));
                            InBody(HtmlToken.OpenTag(HTMLLabelElement.Tag));

                            if (tag.GetAttribute("prompt") != String.Empty)
                                InsertCharacters(tag.GetAttribute("prompt"));
                            else
                                InsertCharacters("This is a searchable index. Enter search keywords:");

                            var input = HtmlToken.OpenTag(HTMLInputElement.Tag);
                            input.AddAttribute("name", HTMLIsIndexElement.Tag);

                            for (int i = 0; i < tag.Attributes.Count; i++)
                            {
                                if (tag.Attributes[i].Key == "name" || tag.Attributes[i].Key == "action" || tag.Attributes[i].Key == "prompt")
                                    continue;

                                input.AddAttribute(tag.Attributes[i].Key, tag.Attributes[i].Value);
                            }

                            InBody(input);
                            InBody(HtmlToken.CloseTag(HTMLLabelElement.Tag));
                            InBody(HtmlToken.OpenTag(HTMLHRElement.Tag));
                            InBody(HtmlToken.CloseTag(HTMLFormElement.Tag));
                        }
                        break;
                    }
                    case HTMLTextAreaElement.Tag:
                    {
                        var element = new HTMLTextAreaElement();
                        AddElementToCurrentNode(element, token);
                        tokenizer.Switch(HtmlParseMode.RCData);
                        originalInsert = insert;
                        frameset = false;
                        insert = HtmlTreeMode.Text;
                        PreventNewLine();
                        break;
                    }
                    case HTMLSemanticElement.XmpTag:
                    {
                        if (IsInButtonScope(HTMLParagraphElement.Tag))
                            InBodyEndTagParagraph();

                        ReconstructFormatting();
                        frameset = false;
                        RawtextAlgorithm(tag);
                        break;
                    }
                    case HTMLIFrameElement.Tag:
                    {
                        frameset = false;
                        RawtextAlgorithm(tag);
                        break;
                    }
                    case HTMLSelectElement.Tag:
                    {
                        ReconstructFormatting();
                        var element = new HTMLSelectElement();
                        AddElementToCurrentNode(element, token);
                        frameset = false;

                        switch (insert)
                        {
                            case HtmlTreeMode.InTable:
                            case HtmlTreeMode.InCaption:
                            case HtmlTreeMode.InRow:
                            case HtmlTreeMode.InCell:
                                insert = HtmlTreeMode.InSelectInTable;
                                break;

                            default:
                                insert = HtmlTreeMode.InSelect;
                                break;
                        }
                        break;
                    }
                    case HTMLOptGroupElement.Tag:
                    case HTMLOptionElement.Tag:
                    {
                        if (CurrentNode.NodeName == HTMLOptionElement.Tag)
                            InBodyEndTagAnythingElse(HtmlToken.CloseTag(HTMLOptionElement.Tag));

                        ReconstructFormatting();
                        var element = HTMLElement.Factory(tag.Name);
                        AddElementToCurrentNode(element, token);
                        break;
                    }
                    case "rp":
                    case "rt":
                    {
                        if (IsInScope("ruby"))
                        {
                            GenerateImpliedEndTags();

                            if (CurrentNode.NodeName != "ruby")
                                RaiseErrorOccurred(ErrorCode.TagDoesNotMatchCurrentNode);
                        }

                        var element = HTMLElement.Factory(tag.Name);
                        AddElementToCurrentNode(element, token);
                        break;
                    }
                    case HTMLNoElement.NoEmbedTag:
                    {
                        RawtextAlgorithm(tag);
                        break;
                    }
                    case HTMLNoElement.NoScriptTag:
                    {
                        if (!doc.IsScripting)
                            goto default;

                        RawtextAlgorithm(tag);
                        break;
                    }
                    case MathMLElement.RootTag:
                    {
                        var element = new MathMLElement();
                        element.NodeName = tag.Name;
                        ReconstructFormatting();

                        for (int i = 0; i < tag.Attributes.Count; i++)
                        {
                            var name = tag.Attributes[i].Key;
                            var value = tag.Attributes[i].Value;
                            element.SetAttribute(ForeignHelpers.AdjustAttributeName(MathMLHelpers.AdjustAttributeName(name)), value);
                        }

                        CurrentNode.AppendChild(element);

                        if (!tag.IsSelfClosing)
                            open.Add(element);
                        break;
                    }
                    case SVGElement.RootTag:
                    {
                        var element = new SVGElement();
                        element.NodeName = tag.Name;
                        ReconstructFormatting();

                        for (int i = 0; i < tag.Attributes.Count; i++)
                        {
                            var name = tag.Attributes[i].Key;
                            var value = tag.Attributes[i].Value;
                            element.SetAttribute(ForeignHelpers.AdjustAttributeName(MathMLHelpers.AdjustAttributeName(name)), value);
                        }

                        CurrentNode.AppendChild(element);

                        if (!tag.IsSelfClosing)
                        {
                            open.Add(element);
                            tokenizer.AcceptsCharacterData = true;
                        }
                        break;
                    }
                    case HTMLTableCaptionElement.Tag:
                    case HTMLTableColElement.ColTag:
                    case HTMLTableColElement.ColgroupTag:
                    case HTMLFrameElement.Tag:
                    case HTMLHeadElement.Tag:
                    case HTMLTableSectionElement.BodyTag:
                    case HTMLTableCellElement.NormalTag:
                    case HTMLTableSectionElement.FootTag:
                    case HTMLTableCellElement.HeadTag:
                    case HTMLTableSectionElement.HeadTag:
                    case HTMLTableRowElement.Tag:
                    {
                        RaiseErrorOccurred(ErrorCode.TagCannotStartHere);
                        break;
                    }
                    default:
                    {
                        ReconstructFormatting();
                        var element = new HTMLUnknownElement();
                        AddElementToCurrentNode(element, token);
                        break;
                    }
                }
            }
            else if (token.Type == HtmlTokenType.EndTag)
            {
                var tag = (HtmlTagToken)token;

                switch (tag.Name)
                {
                    case HTMLBodyElement.Tag:
                    {
                        InBodyEndTagBody();
                        break;
                    }
                    case HTMLHtmlElement.Tag:
                    {
                        if (InBodyEndTagBody())
                            AfterBody(token);

                        break;
                    }
                    case HTMLSemanticElement.AddressTag:
                    case HTMLSemanticElement.ArticleTag:
                    case HTMLSemanticElement.AsideTag:
                    case HTMLQuoteElement.BlockTag:
                    case HTMLButtonElement.Tag:
                    case HTMLSemanticElement.CenterTag:
                    case HTMLDetailsElement.Tag:
                    case HTMLDialogElement.Tag:
                    case HTMLDirectoryElement.Tag:
                    case HTMLDivElement.Tag:
                    case HTMLDListElement.Tag:
                    case HTMLFieldSetElement.Tag:
                    case HTMLSemanticElement.FigcaptionTag:
                    case HTMLSemanticElement.FigureTag:
                    case HTMLSemanticElement.FooterTag:
                    case HTMLSemanticElement.HeaderTag:
                    case HTMLSemanticElement.HgroupTag:
                    case HTMLSemanticElement.ListingTag:
                    case HTMLSemanticElement.MainTag:
                    case HTMLMenuElement.Tag:
                    case HTMLSemanticElement.NavTag:
                    case HTMLOListElement.Tag:
                    case HTMLPreElement.Tag:
                    case HTMLSemanticElement.SectionTag:
                    case HTMLSemanticElement.SummaryTag:
                    case HTMLUListElement.Tag:
                    {
                        InBodyEndTagBlock(tag.Name);
                        break;
                    }
                    case HTMLFormElement.Tag:
                    {
                        var node = form;
                        form = null;

                        if (node != null && IsInScope(node.NodeName))
                        {
                            GenerateImpliedEndTags();

                            if (CurrentNode != node)
                                RaiseErrorOccurred(ErrorCode.FormClosedWrong);

                            open.Remove(node);
                        }
                        else
                            RaiseErrorOccurred(ErrorCode.FormNotInScope);

                        break;
                    }
                    case HTMLParagraphElement.Tag:
                    {
                        InBodyEndTagParagraph();
                        break;
                    }
                    case HTMLLIElement.ItemTag:
                    {
                        if (IsInListItemScope(tag.Name))
                        {
                            GenerateImpliedEndTagsExceptFor(tag.Name);

                            if (CurrentNode.NodeName != tag.Name)
                                RaiseErrorOccurred(ErrorCode.TagDoesNotMatchCurrentNode);

                            ClearStackBackTo(tag.Name);
                            CloseCurrentNode();
                        }
                        else
                            RaiseErrorOccurred(ErrorCode.ListItemNotInScope);

                        break;
                    }
                    case HTMLLIElement.DefinitionTag:
                    case HTMLLIElement.DescriptionTag:
                    {
                        if (IsInScope(tag.Name))
                        {
                            GenerateImpliedEndTagsExceptFor(tag.Name);

                            if (CurrentNode.NodeName != tag.Name)
                                RaiseErrorOccurred(ErrorCode.TagDoesNotMatchCurrentNode);

                            ClearStackBackTo(tag.Name);
                            CloseCurrentNode();
                        }
                        else
                            RaiseErrorOccurred(ErrorCode.ListItemNotInScope);

                        break;
                    }
                    case HTMLHeadingElement.ChapterTag:
                    case HTMLHeadingElement.SubSubSubSubSectionTag:
                    case HTMLHeadingElement.SubSubSubSectionTag:
                    case HTMLHeadingElement.SubSubSectionTag:
                    case HTMLHeadingElement.SubSectionTag:
                    case HTMLHeadingElement.SectionTag:
                    {
                        if (IsHeadingInScope())
                        {
                            GenerateImpliedEndTags();

                            if (CurrentNode.NodeName != tag.Name)
                                RaiseErrorOccurred(ErrorCode.TagDoesNotMatchCurrentNode);

                            ClearStackBackToHeading();
                            CloseCurrentNode();
                        }
                        else
                            RaiseErrorOccurred(ErrorCode.HeadingNotInScope);

                        break;
                    }
                    case HTMLAnchorElement.Tag:
                    case HTMLFormattingElement.BTag:
                    case HTMLFormattingElement.BigTag:
                    case HTMLFormattingElement.CodeTag:
                    case HTMLFormattingElement.EmTag:
                    case HTMLFontElement.Tag:
                    case HTMLFormattingElement.ITag:
                    case HTMLFormattingElement.NobrTag:
                    case HTMLFormattingElement.STag:
                    case HTMLFormattingElement.SmallTag:
                    case HTMLFormattingElement.StrikeTag:
                    case HTMLFormattingElement.StrongTag:
                    case HTMLFormattingElement.TtTag:
                    case HTMLFormattingElement.UTag:
                    {
                        HeisenbergAlgorithm(tag);
                        break;
                    }
                    case HTMLAppletElement.Tag:
                    case HTMLMarqueeElement.Tag:
                    case HTMLObjectElement.Tag:
                    {
                        if (IsInScope(tag.Name))
                        {
                            GenerateImpliedEndTags();

                            if (CurrentNode.NodeName != tag.Name)
                                RaiseErrorOccurred(ErrorCode.TagDoesNotMatchCurrentNode);

                            ClearStackBackTo(tag.Name);
                            CloseCurrentNode();
                            ClearFormattingElements();
                        }
                        else
                            RaiseErrorOccurred(ErrorCode.ObjectNotInScope);

                        break;
                    }
                    case HTMLBRElement.Tag:
                    {
                        RaiseErrorOccurred(ErrorCode.TagCannotEndHere);
                        InBodyStartTagBreakrow(HtmlToken.OpenTag(HTMLBRElement.Tag));
                        break;
                    }
                    default:
                    {
                        InBodyEndTagAnythingElse(tag);
                        break;
                    }
                }
            }
            else if (token.Type == HtmlTokenType.EOF)
            {
                for (var i = 0; i < open.Count; i++)
                {
                    switch (open[i].NodeName)
                    {
                        case HTMLLIElement.DescriptionTag:
                        case HTMLLIElement.DefinitionTag:
                        case HTMLLIElement.ItemTag:
                        case HTMLParagraphElement.Tag:
                        case HTMLTableSectionElement.BodyTag:
                        case HTMLTableCellElement.HeadTag:
                        case HTMLTableSectionElement.FootTag:
                        case HTMLTableCellElement.NormalTag:
                        case HTMLTableSectionElement.HeadTag:
                        case HTMLTableRowElement.Tag:
                        case HTMLBodyElement.Tag:
                        case HTMLHtmlElement.Tag:
                            break;

                        default:
                            RaiseErrorOccurred(ErrorCode.BodyClosedWrong);
                            i = open.Count;
                            break;
                    }
                }

                End();
            }
        }
        /// <summary>
        /// Constucts the data set (called from a form).
        /// </summary>
        /// <param name="dataSet">The dataset to construct.</param>
        /// <param name="submitter">The given submitter.</param>
        internal override void ConstructDataSet(FormDataSet dataSet, HTMLElement submitter)
        {
            dataSet.Append(Name, Value, Type.ToString());

            if (HasAttribute(AttributeNames.DirName))
            {
                var dirname = GetAttribute(AttributeNames.DirName);

                if (String.IsNullOrEmpty(dirname))
                    return;

                dataSet.Append(dirname, Direction.ToString().ToLower(), "Direction");
            }
        }
        /// <summary>
        /// Constructs the data set (called from a form).
        /// </summary>
        /// <param name="dataSet">The dataset to construct.</param>
        /// <param name="submitter">The given submitter.</param>
        internal override void ConstructDataSet(FormDataSet dataSet, HTMLElement submitter)
        {
            var type = Type.ToEnum(InputType.Text);

            switch (type)
            {
                case InputType.Radio:
                case InputType.Checkbox:
                {
                    if (IsChecked)
                    {
                        var value = "on";

                        if (!String.IsNullOrEmpty(Value))
                            value = Value;

                        dataSet.Append(Name, value, Type.ToString());
                    }

                    break;
                }
                case InputType.Image:
                {
                    if (!String.IsNullOrEmpty(Name))
                    {
                        var name = String.Empty;

                        if (!String.IsNullOrEmpty(Value))
                            name = Value + ".";

                        var namex = name + "x";
                        var namey = name + "y";

                        //TODO get x and y of submitter and save those
                        dataSet.Append(namex, "0", Type.ToString());
                        dataSet.Append(namey, "0", Type.ToString());
                    }

                    break;
                }
                case InputType.File:
                {
                    if(_files.Count == 0)
                        dataSet.Append(Name, String.Empty, MimeTypes.Binary);

                    foreach (var file in _files)
                        dataSet.Append(Name, file, Type.ToString());

                    break;
                }
                case InputType.Text:
                case InputType.Search:
                {
                    dataSet.Append(Name, Value, Type.ToString());

                    if (HasAttribute(AttributeNames.DirName))
                    {
                        var dirname = GetAttribute(AttributeNames.DirName);

                        if (String.IsNullOrEmpty(dirname))
                            break;

                        dataSet.Append(dirname, Direction.ToString().ToLower(), "Direction");
                    }

                    break;
                }
                default:
                {
                    dataSet.Append(Name, Value, Type.ToString());
                    break;
                }
            }
        }