/// <summary>
        /// Transform anchor tags to HtmlAnchorTag.
        /// </summary>
        /// <param name="htmlDoc"> The HTML DOM Document to process.</param>
        /// <returns> A HtmlTagBaseList.</returns>
        public static HtmlTagBaseList TransformAnchorElements(IHTMLDocument2 htmlDoc)
        {
            HtmlTagBaseList list = new HtmlTagBaseList();

            foreach ( object obj in htmlDoc.links )
            {
                if ( obj is IHTMLAnchorElement )
                {
                    IHTMLAnchorElement a = (IHTMLAnchorElement)obj;
                    HtmlAnchorTag anchorTag = new HtmlAnchorTag();
                    anchorTag.HRef = a.href;
                    anchorTag.Host = a.host;
                    anchorTag.Hostname = a.hostname;
                    anchorTag.MimeType = a.mimeType;
                    anchorTag.Pathname = a.pathname;
                    anchorTag.Protocol = a.protocol;
                    anchorTag.Query = a.search;
                    list.Add(anchorTag);
                }
            //				else
            //				{
            //					System.Windows.Forms.MessageBox.Show(((mshtml.IHTMLElement)obj).outerHTML);
            //				}
            }

            return list;
        }
        /// <summary>
        /// Initializes a new instance of the <see cref="HtmlTagBaseList"/> class
        /// that contains elements copied from the specified collection and
        /// that has the same initial capacity as the number of elements copied.
        /// </summary>
        /// <param name="collection">The <see cref="HtmlTagBaseList"/> 
        /// whose elements are copied to the new collection.</param>
        /// <exception cref="ArgumentNullException">
        /// <paramref name="collection"/> is a null reference.</exception>        
        /// <remarks>Please refer to <see cref="ArrayList(ICollection)"/> for details.</remarks>    
        public HtmlTagBaseList(HtmlTagBaseList collection)
        {
            if (collection == null)
                throw new ArgumentNullException("collection");

            this._array = new HtmlTagBase[collection.Count];
            AddRange(collection);
        }
        public HtmlTagListXml(string key, HtmlTagBaseList list)
        {
            this.Name = key;

            foreach ( HtmlTagBase tag in list )
            {
                _tags.Add(tag);
            }
        }
        /// <summary>
        /// Creates a shallow copy of the <see cref="HtmlTagBaseList"/>.
        /// </summary>
        /// <returns>A shallow copy of the <see cref="HtmlTagBaseList"/>.</returns>
        /// <remarks>Please refer to <see cref="ArrayList.Clone"/> for details.</remarks>
        public virtual object Clone()
        {
            HtmlTagBaseList collection = new HtmlTagBaseList(this._count);

            Array.Copy(this._array, 0, collection._array, 0, this._count);
            collection._count = this._count;
            collection._version = this._version;

            return collection;
        }
        /// <overloads>
        /// Adds a range of elements to the end of the <see cref="HtmlTagBaseList"/>.
        /// </overloads>
        /// <summary>
        /// Adds the elements of another collection to the end of the <see cref="HtmlTagBaseList"/>.
        /// </summary>
        /// <param name="collection">The <see cref="HtmlTagBaseList"/> whose elements 
        /// should be added to the end of the current collection.</param>
        /// <exception cref="ArgumentNullException">
        /// <paramref name="collection"/> is a null reference.</exception>    
        /// <exception cref="NotSupportedException">
        /// <para>The <see cref="HtmlTagBaseList"/> is read-only.</para>
        /// <para>-or-</para>
        /// <para>The <b>HtmlTagBaseList</b> has a fixed size.</para></exception>    
        /// <remarks>Please refer to <see cref="ArrayList.AddRange"/> for details.</remarks>
        public virtual void AddRange(HtmlTagBaseList collection)
        {
            if (collection == null)
                throw new ArgumentNullException("collection");

            if (collection.Count == 0) return;
            if (this._count + collection.Count > this._array.Length)
                EnsureCapacity(this._count + collection.Count);

            ++this._version;
            Array.Copy(collection._array, 0, this._array, this._count, collection.Count);
            this._count += collection.Count;
        }
        /// <summary>
        /// Returns a synchronized (thread-safe) wrapper 
        /// for the specified <see cref="HtmlTagBaseList"/>.
        /// </summary>
        /// <param name="collection">The <see cref="HtmlTagBaseList"/> to synchronize.</param>    
        /// <returns>
        /// A synchronized (thread-safe) wrapper around <paramref name="collection"/>.
        /// </returns>
        /// <exception cref="ArgumentNullException">
        /// <paramref name="collection"/> is a null reference.</exception>    
        /// <remarks>Please refer to <see cref="ArrayList.Synchronized"/> for details.</remarks>
        public static HtmlTagBaseList Synchronized(HtmlTagBaseList collection)
        {
            if (collection == null)
                throw new ArgumentNullException("collection");

            return new SyncList(collection);
        }
        /// <summary>
        /// Returns a read-only wrapper for the specified <see cref="HtmlTagBaseList"/>.
        /// </summary>
        /// <param name="collection">The <see cref="HtmlTagBaseList"/> to wrap.</param>    
        /// <returns>A read-only wrapper around <paramref name="collection"/>.</returns>
        /// <exception cref="ArgumentNullException">
        /// <paramref name="collection"/> is a null reference.</exception>    
        /// <remarks>Please refer to <see cref="ArrayList.ReadOnly"/> for details.</remarks>
        public static HtmlTagBaseList ReadOnly(HtmlTagBaseList collection)
        {
            if (collection == null)
                throw new ArgumentNullException("collection");

            return new ReadOnlyList(collection);
        }
        /// <summary>
        /// Loads the forms into a HtmlFormTagCollection.
        /// </summary>
        /// <param name="html"> The parsed HTML content.</param>
        /// <returns> Returns a HtmlFormTagCollection with the forms contained in the HTML.</returns>
        public HtmlFormTagCollection LoadForm(string html)
        {
            HtmlFormTagCollection forms;
            try
            {
                forms = new HtmlFormTagCollection();
                XPathDocument doc;

                if ( HasForms(html) )
                {
                    doc = this.DocumentCache;

                    XPathNavigator nav = doc.CreateNavigator();
                    #region "Set namespaces"
                    if ( this.NamespaceCache == null)
                    {
                        //create prefix<->namespace mappings (if any)
                        XmlNamespaceManager nsMgr = new XmlNamespaceManager(nav.NameTable);

                        // resolve namespaces before loading document
                        Hashtable values = ResolveNamespaces(new XmlTextReader(new StringReader(html)));

                        foreach (DictionaryEntry de in values)
                        {
                            nsMgr.AddNamespace((string)de.Key,(string)de.Value);
                        }

                        this.NamespaceCache = nsMgr;
                    }
                    #endregion
                    int i=0;
                    XPathExpression expr = nav.Compile("//form");
                    expr.SetContext(this.NamespaceCache);
                    // select all form elements
                    XPathNodeIterator nodes = nav.Select(expr);

                    #region Build Form Tag
                    while (nodes.MoveNext())
                    {
                        HtmlFormTag f = new HtmlFormTag();

                        f.FormIndex = i;
                        f.Id=nodes.Current.GetAttribute("id",nodes.Current.NamespaceURI);
                        f.Style=nodes.Current.GetAttribute("style",nodes.Current.NamespaceURI);
                        f.Enctype=nodes.Current.GetAttribute("enctype",nodes.Current.NamespaceURI);
                        f.Class=nodes.Current.GetAttribute("class",nodes.Current.NamespaceURI);
                        f.Name=nodes.Current.GetAttribute("name",nodes.Current.NamespaceURI);
                        f.Action=nodes.Current.GetAttribute("action",nodes.Current.NamespaceURI);
                        f.Method=nodes.Current.GetAttribute("method",nodes.Current.NamespaceURI);
                        f.Id=nodes.Current.GetAttribute("id",nodes.Current.NamespaceURI);
                        f.OnSubmit=nodes.Current.GetAttribute("onsubmit",nodes.Current.NamespaceURI);

                        if (f.Action.Length == 0 )
                        {
                            // add dummy action
                            f.Action = "dummyAction";
                        }

                        if ( f.Method.Length==0 )
                        {
                            f.Method="get";
                        }

                        if ( f.Id!=String.Empty )
                        {
                            f.Name = f.Id;
                        }
                        if ( forms.ContainsKey(f.Name) )
                        {
                            forms.Add("_" + f.Name,f);
                        }
                        else
                        {
                            if ( f.Name!=String.Empty )
                            {
                                forms.Add(f.Name,f);
                            }
                            if (f.Id==String.Empty && f.Name == String.Empty )
                            {
                                f.Id = "Form " + i;
                                f.Name = "Form " + i;
                                forms.Add(f.Name,f);
                            }
                        }

                        #region " Loop thru descendants from Form"
                        // Select descendants, childs
                        XPathNodeIterator items = nodes.Current.SelectDescendants(XPathNodeType.Element,true);

                        int autoId = 0;

                        while ( items.MoveNext() )
                        {

                            // if exists, add to same HtmlTagBaseList type
                            // else create new
                            string name = items.Current.GetAttribute("name",items.Current.NamespaceURI);
                            string id = items.Current.GetAttribute("id",items.Current.NamespaceURI);
                            string onclick = items.Current.GetAttribute("onclick",items.Current.NamespaceURI);

                            if ( onclick == String.Empty )
                            {
                                onclick = items.Current.GetAttribute("onClick",items.Current.NamespaceURI);
                            }

                            // prioritize name use
                            // else use id
                            if ( name == String.Empty )
                            {
                                name = id;
                                // if no id, generate one
                                if ( name == String.Empty )
                                {
                                    id = autoId.ToString();
                                    name = id;
                                }
                            }

                            switch ( items.Current.Name )
                            {
                                case "div":
                                    if ( onclick != String.Empty )
                                    {
                                        AddCommonTag(f,onclick,id,name);
                                    }
                                    break;
                                case "span":
                                    if ( onclick != String.Empty )
                                    {
                                        AddCommonTag(f,onclick,id,name);
                                    }
                                    break;
                                case "a":
                                    HtmlALinkTag a = CreateLinkTag(items.Current);
                                    if ( f.ContainsKey(name) )
                                    {
                                        // just add the value
                                        HtmlTagBaseList array = ((HtmlTagBaseList)f[name]);
                                        array.Add(a);
                                    }
                                    else
                                    {
                                        HtmlTagBaseList list = new HtmlTagBaseList();
                                        list.Add(a);
                                        f.Add("a" + autoId.ToString(),list);
                                    }
                                    break;
                                case "input":
                                    // if exists, add to same HtmlTagBaseList type
                                    // else create new
                                    // verify by name and type
                                    HtmlInputTag input = FillInputTag(items.Current);
                                    input.Name = name;

                                    if ( f.ContainsKey(name) )
                                    {
                                        // just add the value
                                        HtmlTagBaseList array = ((HtmlTagBaseList)f[name]);
                                        array.Add(input);
                                    }
                                    else
                                    {
                                        HtmlTagBaseList list = new HtmlTagBaseList();
                                        //HtmlInputTag input = FillInputTag(items.Current);
                                        list.Add(input);
                                        f.Add(input.Name,list);
                                    }
                                    break;
                                case "button":
                                    // if exists, add to same HtmlTagBaseList type
                                    // else create new
                                    // verify by name
                                    HtmlButtonTag button = FillButtonTag(items.Current);
                                    button.Name = name;

                                    if ( f.ContainsKey(name) )
                                    {
                                        // just add the value
                                        HtmlTagBaseList array = ((HtmlTagBaseList)f[name]);
                                        //HtmlButtonTag button = FillButtonTag(items.Current);
                                        array.Add(button);
                                    }
                                    else
                                    {
                                        HtmlTagBaseList buttonList = new HtmlTagBaseList();
                                        buttonList.Add(button);
                                        f.Add(button.Name,buttonList);
                                    }

                                    break;
                                case "select":
                                    // if exists, add to same HtmlTagBaseList type
                                    // else create new
                                    // verify by name
                                    HtmlSelectTag select = CreateSelectTag(items.Current);
                                    select.Name = name;

                                    if ( f.ContainsKey(name) )
                                    {
                                        HtmlTagBaseList array = ((HtmlTagBaseList)f[name]);
                                        array.Add(select);
                                    }
                                    else
                                    {
                                        HtmlTagBaseList selectList = new HtmlTagBaseList();
                                        //HtmlSelectTag select = FillSelectTag(items.Current);
                                        selectList.Add(select);
                                        f.Add(select.Name,selectList);
                                    }
                                    break;
                                case "textarea":
                                    // if exists, add to same HtmlTagBaseList type
                                    // else create new
                                    // verify by name
                                    HtmlTextAreaTag textarea = FillTextAreaTag(items.Current);
                                    textarea.Name = name;

                                    if ( f.ContainsKey(name) )
                                    {
                                        HtmlTagBaseList array = ((HtmlTagBaseList)f[name]);
                                        //HtmlTextAreaTag textarea = FillTextAreaTag(items.Current);
                                        array.Add(textarea);
                                    }
                                    else
                                    {
                                        HtmlTagBaseList textAreaList = new HtmlTagBaseList();
                                        textAreaList.Add(textarea);
                                        f.Add(textarea.Name,textAreaList);
                                    }
                                    break;
                            }

                            // increase
                            autoId++;
                        }
                        i++;
                        #endregion
                    }
                    #endregion
                }
            }
            catch
            {
                throw;
            }

            return forms;
        }
 // Adds an entry to the collection.
 public void Add( String key, HtmlTagBaseList value )
 {
     this.BaseAdd( key, value );
 }
 internal ReadOnlyList(HtmlTagBaseList collection)
     : base(Tag.Default)
 {
     this._collection = collection;
 }
        /// <summary>
        /// Creates a form from a query string.
        /// </summary>
        /// <param name="url"> The complete url.</param>
        /// <returns> A HtmlFormTag.</returns>
        private HtmlFormTag CreateFormFromQueryString(Uri url)
        {
            string action = url.Scheme + "://" + url.Host + url.AbsolutePath;
            FormConverter converter = new FormConverter();
            PostDataCollection postData = converter.GetPostDataCollection(url.Query.TrimStart('?'));

            HtmlFormTag formTag = new HtmlFormTag();
            formTag.Action = action;
            formTag.Name = "docform";
            formTag.Method = base.WebRequest.RequestType.ToString();

            foreach ( string key in postData.Keys )
            {
                ArrayList items = postData[key];

                HtmlTagBaseList list = new HtmlTagBaseList();
                formTag.Add(key, list);
                foreach ( string value in items )
                {
                    HtmlInputTag hiddenField = new HtmlInputTag();
                    hiddenField.Type = HtmlInputType.Hidden;
                    hiddenField.Name = key;
                    hiddenField.Value = value.Trim().TrimEnd('\0');
                    list.Add(hiddenField);
                }
            }

            return formTag;
        }
 // Adds an entry to the collection.
 public void Add( String key, HtmlTagBaseList value )
 {
     innerCollection.Add( key, value );
 }
        /// <summary>
        /// Transform link tags to HtmlAnchorTag.
        /// </summary>
        /// <param name="htmlDoc"> The HTML DOM Document to process.</param>
        /// <returns> A HtmlTagBaseList.</returns>
        public static HtmlTagBaseList TransformLinksElements(IHTMLDocument2 htmlDoc)
        {
            HtmlTagBaseList list = new HtmlTagBaseList();
            IHTMLElementCollection coll = (IHTMLElementCollection)htmlDoc.all.tags("link");

            foreach ( object obj in coll )
            {
                if ( obj is IHTMLLinkElement )
                {
                    IHTMLLinkElement link = (IHTMLLinkElement)obj;
                    HtmlLinkTag linkTag = new HtmlLinkTag();
                    linkTag.HRef = link.href;
                    linkTag.MimeType = link.type;
                    list.Add(linkTag);
                }
            //				else
            //				{
            //					System.Windows.Forms.MessageBox.Show(((mshtml.IHTMLElement)obj).outerHTML);
            //				}
            }

            return list;
        }
        /// <summary>
        /// Transform frame elements to HtmlLinkTag array.
        /// </summary>
        /// <param name="htmlDoc"> The HTML DOM Document to process.</param>
        /// <returns> A HtmlTagBaseList.</returns>
        public static HtmlTagBaseList TransformFrameElements(IHTMLDocument2 htmlDoc)
        {
            HtmlTagBaseList list = new HtmlTagBaseList();

            IHTMLElementCollection coll = (IHTMLElementCollection)htmlDoc.all.tags("frame");
            foreach ( object obj in coll )
            {
                if ( obj is IHTMLFrameBase )
                {
                    IHTMLFrameBase a = (IHTMLFrameBase)obj;

                    HtmlLinkTag frame = new HtmlLinkTag();
                    frame.HRef = a.src;
                    list.Add(frame);
                }
            }

            return list;
        }
        /// <summary>
        /// Writes the HtmlFormTagXml to a HtmlFormTag.
        /// </summary>
        /// <returns>A new cloned HtmlFormTag.</returns>
        public HtmlFormTag WriteHtmlFormTag()
        {
            HtmlFormTag form = new HtmlFormTag();
            form.Action = this.Action;
            form.Enctype = this.Enctype;
            form.FormIndex = this.FormIndex;
            form.Method = this.Method;
            form.Name = this.Name;
            form.OnSubmit = this.OnSubmit;

            foreach ( HtmlTagListXml listXml in Elements )
            {
                HtmlTagBaseList list = new HtmlTagBaseList();

                list.AddRange(listXml.Tags);
                form.Add(listXml.Name, list);
            }

            return form;
        }
 internal Enumerator(HtmlTagBaseList collection)
 {
     this._collection = collection;
     this._version = collection._version;
     this._index = -1;
 }
 public override void AddRange(HtmlTagBaseList collection)
 {
     throw new NotSupportedException("Read-only collections cannot be modified.");
 }
 internal SyncList(HtmlTagBaseList collection)
     : base(Tag.Default)
 {
     this._root = collection.SyncRoot;
     this._collection = collection;
 }
 public override void AddRange(HtmlTagBaseList collection)
 {
     lock (this._root) this._collection.AddRange(collection);
 }
        /// <summary>
        /// Converts a HTMLFormElementClass to a GB HtmlFormTag.
        /// </summary>
        /// <param name="formElement"> The HTMLFormElementClass to convert.</param>
        /// <param name="currentUri"> The current uri.</param>
        /// <returns> A HtmlFormTag.</returns>
        public HtmlFormTag ConvertToHtmlFormTag(HTMLFormElementClass formElement, Uri currentUri)
        {
            IHTMLElement el = (IHTMLElement)formElement.elements;
            ArrayList elements = new ArrayList();
            // Converts the element tag to an array list
            elements = ParseTags(elements,(IHTMLElementCollection)el.children);

            HtmlFormTag formTag = new HtmlFormTag();

            #region Set Form Properties
            if ( formElement.action == null )
            {
                formTag.Action = currentUri.Scheme + "://" + currentUri.Authority + currentUri.AbsolutePath;
            }
            else
            {
                formTag.Action = formElement.action;
            }

            formTag.Class = formElement.className;

            if ( formElement.method == null )
            {
                formTag.Method = "GET";
            } else {
                formTag.Method = formElement.method;
            }
            if ( formElement.encoding == null )
            {
                formTag.Enctype = "";
            }
            else
            {
                formTag.Enctype = formElement.encoding;
            }

            // formTag.FormIndex = formElement.
            formTag.Id = formElement.id;

            if ( formElement.name != null )
            {
                formTag.Name = formElement.name;
            }
            else
            {
                if ( formElement.id != null )
                {
                    formTag.Name = formElement.id;
                }
                else
                {
                    formTag.Name = formElement.uniqueID;
                    formTag.Id = formElement.uniqueID;
                }
            }
            formTag.OnSubmit = string.Empty;
            formTag.Style = string.Empty;
            formTag.Title = formElement.title;
            #endregion
            #region Add Tags
            foreach (object obj in elements)
            {
                // The last check is the most significant type

                #region Button Element
                if (obj is mshtml.HTMLInputButtonElementClass)
                {
                    HtmlButtonTag button = CreateHtmlButtonTag((HTMLInputButtonElementClass)obj);

                    if ( formTag.ContainsKey(button.Name) )
                    {
                        // just add the value
                        HtmlTagBaseList array = ((HtmlTagBaseList)formTag[button.Name]);
                        array.Add(button);
                    }
                    else
                    {
                        HtmlTagBaseList list = new HtmlTagBaseList();
                        list.Add(button);
                        formTag.Add(button.Name,list);
                    }
                    continue;
                }
                #endregion

                #region Select Element
                if (obj is mshtml.HTMLSelectElementClass)
                {
                    HtmlSelectTag select = CreateHtmlSelectTag((HTMLSelectElementClass)obj);

                    if ( formTag.ContainsKey(select.Name) )
                    {
                        // just add the value
                        HtmlTagBaseList array = ((HtmlTagBaseList)formTag[select.Name]);
                        array.Add(select);
                    }
                    else
                    {
                        HtmlTagBaseList list = new HtmlTagBaseList();
                        list.Add(select);
                        formTag.Add(select.Name,list);
                    }
                    continue;
                }
                #endregion

                #region Textarea Element
                if (obj is mshtml.HTMLTextAreaElementClass)
                {
                    HtmlTextAreaTag textarea=CreateHtmlTextAreaTag((HTMLTextAreaElementClass)obj);
                    if ( formTag.ContainsKey(textarea.Name) )
                    {
                        // just add the value
                        HtmlTagBaseList array = ((HtmlTagBaseList)formTag[textarea.Name]);
                        array.Add(textarea);
                    }
                    else
                    {
                        HtmlTagBaseList list = new HtmlTagBaseList();
                        list.Add(textarea);
                        formTag.Add(textarea.Name,list);
                    }
                    continue;
                }
                #endregion

                #region Input Element
                if (obj is mshtml.HTMLInputElementClass)
                {
                    HtmlInputTag input = CreateHtmlInputTag((HTMLInputElementClass)obj);
                    if ( formTag.ContainsKey(input.Name) )
                    {
                        // just add the value
                        HtmlTagBaseList array = ((HtmlTagBaseList)formTag[input.Name]);
                        array.Add(input);
                    }
                    else
                    {
                        HtmlTagBaseList list = new HtmlTagBaseList();
                        list.Add(input);
                        formTag.Add(input.Name,list);
                    }
                    continue;
                }
                #endregion

            }
            #endregion

            return formTag;
        }
        /// <summary>
        /// Adds a common tag.
        /// </summary>
        /// <param name="form"> The HtmlFormTag.</param>
        /// <param name="click"> The click event source code.</param>
        /// <param name="id"> The element id.</param>
        /// <param name="name"> The element name.</param>
        private void AddCommonTag(HtmlFormTag form,string click,string id, string name)
        {
            //add
            HtmlTagBase tag = new HtmlTagBase();
            tag.Id = id;
            tag.OnClick = click;

            if ( form.ContainsKey(name) )
            {
                // just add the value
                HtmlTagBaseList array = ((HtmlTagBaseList)form[name]);
                array.Add(tag);
            }
            else
            {
                HtmlTagBaseList list = new HtmlTagBaseList();
                list.Add(tag);
                form.Add(tag.Id,list);
            }
        }