/// <summary>
        /// Transform each form element to a HtmlFormTag.
        /// </summary>
        /// <param name="htmlDoc"> The HTML DOM Document to process.</param>
        public static HtmlFormTagCollection TransformFormElements(IHTMLDocument2 htmlDoc, Uri currentUri)
        {
            // For each form, add in temp FormTags Collection
            FormConverter converter = new FormConverter();

            HtmlFormTagCollection formCollection = new HtmlFormTagCollection(htmlDoc.forms.length);

            try
            {
                foreach ( HTMLFormElementClass formElement in htmlDoc.forms )
                {
                    System.Windows.Forms.Application.DoEvents();

                    // Convert to HTML Form Tag
                    HtmlFormTag form = converter.ConvertToHtmlFormTag(formElement, currentUri);

                    if ( !formCollection.ContainsKey(form.Name) )
                    {
                        formCollection.Add(form.Name, form);
                    }
                }
            }
            catch (Exception ex)
            {
                System.Windows.Forms.MessageBox.Show(ex.ToString());
                Microsoft.ApplicationBlocks.ExceptionManagement.ExceptionManager.Publish(ex);
            }

            return formCollection;
        }
        /// <summary>
        /// Creates a new FormsEditor.
        /// </summary>
        /// <param name="forms"> Form collection to load.</param>
        /// <param name="sessionData"> ResponseBuffer data.</param>
        /// <param name="parserSettings"> Parser Settings.</param>
        /// <param name="inspectorConfiguration"> The inspector configuration.</param>
        public FormsEditor(HtmlFormTagCollection forms, ResponseBuffer sessionData, HtmlParserProperties parserSettings, InspectorConfiguration inspectorConfiguration)
            : this()
        {
            this.SessionData = sessionData;
            this.InspectorConfig = inspectorConfiguration;

            // set parser settings
            _parserSettings = parserSettings;

            // Load tree
            LoadFormTree(forms);
        }
 internal HtmlFormTagCollectionEnumerator(HtmlFormTagCollection enumerable)
 {
     innerEnumerator = enumerable.InnerHash.GetEnumerator();
 }
        public HtmlFormTagCollection Clone()
        {
            HtmlFormTagCollection clone = new HtmlFormTagCollection();
            clone.innerHash = (Hashtable) innerHash.Clone();

            return clone;
        }
        public static HtmlFormTagCollection Synchronized(HtmlFormTagCollection nonSync)
        {
            HtmlFormTagCollection sync = new HtmlFormTagCollection();
            sync.innerHash = Hashtable.Synchronized(nonSync.innerHash);

            return sync;
        }
        /// <summary>
        /// Validates that the forms has an action attribute available.
        /// </summary>
        /// <param name="forms"> The HtmlFormTagCollection to validate.</param>
        /// <returns> Returns a string with the form that needs to be checked.</returns>
        private string ValidateFormsReport(HtmlFormTagCollection forms)
        {
            StringBuilder report = new StringBuilder();
            // print validate forms report for correction
            // check each form for correctness
            foreach (DictionaryEntry de in forms)
            {
                HtmlFormTag form = (HtmlFormTag)de.Value;

                if ( form.Action.Length == 0 )
                {
                    report.AppendFormat("Form {0} has no Action attribute. Please add value in Editor.",form.Name);
                }
            }

            return report.ToString();
        }
        /// <summary>
        /// Validates that the forms has an action attribute available.
        /// </summary>
        /// <param name="forms"> The HtmlFormTagCollection to validate.</param>
        /// <param name="currentUri"> The current uri of the request.</param>
        /// <returns> Returns true if forms are valid, else false.</returns>
        private bool ValidateForms(HtmlFormTagCollection forms, Uri currentUri)
        {
            bool retVal = true;

            // check each form for correctness
            foreach (DictionaryEntry de in forms)
            {
                HtmlFormTag form = (HtmlFormTag)de.Value;

                if ( form.Action.Length == 0 )
                {
                    form.Action = currentUri.Authority + currentUri.AbsolutePath;
                    break;
                }
            }

            return retVal;
        }
 /// <summary>
 /// Loads the form editor.
 /// </summary>
 /// <param name="sender"> The sender object.</param>
 /// <param name="e"> The LoadFormsEditorEventArgs.</param>
 private void LoadFormsEditor(object sender, LoadFormsEditorEventArgs e)
 {
     // Add as a pending call if is still loading.
     if ( InspectorState == GBInspectorState.Complete )
     {
         DisplayForms(e.FormCollection, false);
         formCollection = null;
     }
     else
     {
         formCollection = e.FormCollection;
     }
 }
        /// <summary>
        /// Matches the post data to a form in a form collection.
        /// </summary>
        /// <param name="formCollection"> The form collection.</param>
        /// <param name="data"> The post data string.</param>
        /// <returns> A HtmlFormTag.</returns>
        public HtmlFormTag MatchPostDataToForm(HtmlFormTagCollection formCollection, string data)
        {
            FormConverter converter = new FormConverter();
            PostDataCollection postDataItems = converter.GetPostDataCollection(data);

            int matchByFieldName = 0;

            HtmlFormTagCollection formMatchByCount =  new HtmlFormTagCollection();

            #region First Match By Count
            foreach (DictionaryEntry de in formCollection)
            {
                HtmlFormTag form = (HtmlFormTag)de.Value;

                // if match count is unique then use that form
                if ( postDataItems.Count == form.Count )
                {
                    formMatchByCount.Add(form.Name, form);
                }
            }
            #endregion

            HtmlFormTag foundFormTag = null;
            if ( formMatchByCount.Count == 0 )
            {
                #region Then Match by Field Names, select the one with the matching more fields

                int weight = 0;
                string currentForm = string.Empty;
                Hashtable formKeysFound = new Hashtable(formCollection.Count);

                foreach ( DictionaryEntry de in formCollection )
                {
                    HtmlFormTag form = (HtmlFormTag)de.Value;
                    ArrayList keysToMaintain = new ArrayList();

                    // if match by field name is unique then use that form
                    for (int i=0;i<postDataItems.Count;i++ )
                    {
                        string name = postDataItems.Keys[i];

                        // all values has to be found, else exit
                        if ( form.ContainsKey(name) )
                        {
                            keysToMaintain.Add(name);
                            matchByFieldName++;
                        }
                    }

                    // form keys to maintain
                    formKeysFound.Add(form.Name, keysToMaintain);

                    // Example: 31 Forms Items, but match only 29 equals 2
                    if ( matchByFieldName > 0 )
                    {
                        if ( (matchByFieldName - form.Count) < weight )
                        {
                            weight = matchByFieldName - form.Count;
                            currentForm = form.Name;
                        }
                        matchByFieldName = 0;
                    }
                }

                // select form and remove not needed items
                foundFormTag = formCollection[currentForm];

                if ( foundFormTag != null )
                {
                    ArrayList itemKeys = (ArrayList)formKeysFound[currentForm];

                    // remove other fields from FormTag
                    HtmlFormTag clone = foundFormTag.CloneTag();
                    foundFormTag.Clear();

                    for (int j=0;j<itemKeys.Count;j++)
                    {
                        string itemName = (string)itemKeys[j];
                        foundFormTag.Add(itemName, clone[itemName]);
                    }
                }
                #endregion
            }
            else
            {
                #region Then Match by Field Names
                foreach ( DictionaryEntry de in formMatchByCount )
                {
                    HtmlFormTag form = (HtmlFormTag)de.Value;
                    Hashtable formKeysFound = new Hashtable(formCollection.Count);
                    ArrayList keysToMaintain = new ArrayList();

                    // if match by field name is unique then use that form
                    for (int i=0;i<postDataItems.Count;i++ )
                    {
                        string name = postDataItems.Keys[i];

                        // all values has to be found, else exit
                        if ( form.ContainsKey(name) )
                        {
                            keysToMaintain.Add(name);
                            matchByFieldName++;
                        }
                        else
                        {
                            matchByFieldName = -1;
                            break;
                        }
                    }

                    // form keys to maintain
                    formKeysFound.Add(form.Name, keysToMaintain);

                    if ( matchByFieldName != -1 )
                    {
                        // found, return first occurence no matter what
                        foundFormTag = form;

                        ArrayList itemKeys = (ArrayList)formKeysFound[foundFormTag.Name];

                        // remove other fields from FormTag
                        HtmlFormTag clone = foundFormTag.CloneTag();
                        foundFormTag.Clear();

                        for (int j=0;j<itemKeys.Count;j++)
                        {
                            string itemName = (string)itemKeys[j];
                            foundFormTag.Add(itemName, clone[itemName]);
                        }
                    }
                }
                #endregion
            }

            return foundFormTag;
        }
        private void mnuCreateFormFromQueryString_Click(object sender, System.EventArgs e)
        {
            if ( _currentRequestUri.Query.Length > 0 )
            {
                HtmlFormTag formTag = CreateFormFromQueryString(_currentRequestUri);

                base.WebRequest.Form.ReadHtmlFormTag(formTag);
                HtmlFormTagCollection collection = new HtmlFormTagCollection();
                collection.Add(formTag.Name, formTag);
                LoadFormTree(collection);
            }
            else
            {
                MessageBox.Show("No query string found.", AppLocation.ApplicationName, MessageBoxButtons.OK, MessageBoxIcon.Information);
            }
        }
        /// <summary>
        /// Loads the request.
        /// </summary>
        /// <param name="index"> The current request index.</param>
        /// <param name="scripting"> The scripting application.</param>
        /// <param name="request"> The current web request.</param>
        public override void LoadRequest(int index, ScriptingApplication scripting ,Ecyware.GreenBlue.Engine.Scripting.WebRequest request)
        {
            base.LoadRequest (index, scripting, request);

            try
            {
                //_httpRequestType = request.RequestType;
                _currentRequestUri = new Uri(request.Url);

                if ( request.Form.Elements.Length > 0 )
                {
                    HtmlFormTagCollection forms = new HtmlFormTagCollection(1);
                    _form = request.Form.WriteHtmlFormTag();
                    forms.Add(request.Form.Name, _form);

                    // Load tree
                    LoadFormTree(forms);
                }
                else
                {
                    DisplayNoDataMessage();
                }
            }
            catch ( Exception ex )
            {
                MessageBox.Show(ex.ToString(), AppLocation.ApplicationName, MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }
        /// <summary>
        /// Loads the forms into the form tree.
        /// </summary>
        /// <param name="forms"></param>
        public void LoadFormTree(HtmlFormTagCollection forms)
        {
            formEditor.Clear();

            foreach (DictionaryEntry de in forms)
            {
                HtmlFormTag form = (HtmlFormTag)de.Value;

                StringBuilder label = new StringBuilder();
                // add Form node
                label.Append("<form name=");
                label.Append((string)de.Key);
                label.Append(" method=");
                label.Append(form.Method);
                label.Append(" action=");
                label.Append(form.Action);

                if ( form.OnSubmit != null )
                {
                    if ( form.OnSubmit.Length > 0 )
                    {
                        label.Append(" onsubmit=");
                        label.Append(form.OnSubmit);
                    }
                }
                label.Append(">");

                FormEditorNode formNode = formEditor.AddFormNode(label.ToString(),form);

                for (int i=0;i<form.Count;i++)
                {
                    FormEditorNode child = new FormEditorNode();
                    HtmlTagBaseList controlArray = (HtmlTagBaseList)((DictionaryEntry)form[i]).Value;

                    foreach (HtmlTagBase tag in controlArray)
                    {
                        if (tag is HtmlALinkTag)
                        {
                            HtmlALinkTag a=(HtmlALinkTag)tag;
                            AddALinkNode(formNode, a);
                        }

                        if (tag is HtmlInputTag)
                        {
                            HtmlInputTag input=(HtmlInputTag)tag;
                            AddInputNode(formNode,input);

                        }

                        if (tag is HtmlButtonTag)
                        {
                            HtmlButtonTag button = (HtmlButtonTag)tag;
                            AddButtonNode(formNode,button);
                        }

                        if (tag is HtmlSelectTag)
                        {
                            HtmlSelectTag select = (HtmlSelectTag)tag;
                            AddSelectNode(formNode,select);
                        }

                        if (tag is HtmlTextAreaTag)
                        {
                            HtmlTextAreaTag textarea=(HtmlTextAreaTag)tag;
                            AddTextAreaNode(formNode,textarea);
                        }
                    }
                }
            }

            formEditor.ExpandAll();
        }
        /// <summary>
        /// Gets the form tag collection.
        /// </summary>
        /// <returns> A HtmlFormTagCollection.</returns>
        public HtmlFormTagCollection GetFormCollection()
        {
            HtmlFormTagCollection forms = new HtmlFormTagCollection();
            foreach (DictionaryEntry de in this)
            {
                UnitTestItem uti = (UnitTestItem)de.Value;
                forms.Add(uti.Form.Name,uti.Form);
            }

            return forms;
        }
        // Fires when the browser ActiveX control finishes loading a document
        private void OnComplete(IHTMLDocument2 htmlDoc)
        {
            // Adds some event handlers to the DOM Document
            AddEventsToDoc(htmlDoc);

            formCollection = HtmlDomTransformation.TransformFormElements(htmlDoc, new Uri(htmlDoc.location.toString()));
            // FIX: This might be no longer neccesary because
            // it injects code into the document.
            //SetFormOnSubmit(htmlDoc);

            // check if it is NewWindow
            if ( isNewWindow )
            {
                RequestGetEventArgs args = new RequestGetEventArgs();
                args.Url = (string)web.LocationURL;
                args.InspectorRequestAction = InspectorAction.WebBrowserGet;
                this.StartEvent(this, args);

                isNewWindow = false;
            }

            // raise load links event
            if ( LoadLinksEvent != null )
            {
                LoadLinksEventArgs args = new LoadLinksEventArgs();
                args.Frames = HtmlDomTransformation.TransformFrameElements(htmlDoc);
                args.Anchors = HtmlDomTransformation.TransformAnchorElements(htmlDoc);
                args.Links = HtmlDomTransformation.TransformLinksElements(htmlDoc);
                LoadLinksEvent.BeginInvoke(this, args, new AsyncCallback(FireAndForget), null);
            }

            // raise load forms event
            if ( LoadFormsEditorEvent != null )
            {
                // Transform form elements to HTML DOM Document.
                LoadFormsEditorEvent.BeginInvoke(this, new LoadFormsEditorEventArgs(postData, formCollection), new AsyncCallback(FireAndForget),null);
            }

            // reset
            inspectorState = InspectorAction.Idle;
        }
 public HtmlFormTagCollection(HtmlFormTagCollection original)
 {
     innerHash = new Hashtable (original.innerHash);
 }
        /// <summary>
        /// Display the form collection in editor.
        /// </summary>
        /// <param name="forms"></param>
        /// <param name="showCreateMessage"></param>
        private void DisplayForms(HtmlFormTagCollection forms, bool showCreateMessage)
        {
            if ( forms.Count > 0 )
            {
                // Validate Forms
                if ( ValidateForms(forms, (Uri)this.CurrentResponseBuffer.ResponseHeaderCollection["Response Uri"]))
                {
                    // Create new FormEditor Window and apply events
                    formeditor = new FormsEditor(forms, this.CurrentResponseBuffer, this.SnifferProperties, this.InspectorConfig);
                    formeditor.RequestPostEvent += new Ecyware.GreenBlue.GreenBlueMain.FormsEditor.RequestPostEventHandler(formeditor_RequestPostEvent);
                    formeditor.ApplyMenuSettingsEvent += new ApplyMenuSettingsEventHandler(formeditor_ApplyMenuSettingsEvent);
                    formeditor.PluginMenus = this.mnSessionMenus;

                    Uri url = (Uri)CurrentResponseBuffer.ResponseHeaderCollection["Response Uri"];
                    RemoveAndAddDocument(formeditor, "Forms Editor", false);

                    if ( showCreateMessage )
                    {
                        string message = "A Forms Editor Tree has been created.";
                        ChangeStatusBarEventArgs args = new ChangeStatusBarEventArgs(0,message,null);
                        ChangeStatusBarPanelEvent(this,args);
                    }
                }
                else
                {
                    string message = ValidateFormsReport(forms);

                    ChangeStatusBarEventArgs args = new ChangeStatusBarEventArgs(0,message,null);
                    ChangeStatusBarPanelEvent(this,args);
                }
            }
            else
            {
                if ( showCreateMessage )
                {
                    string message = "This page has no forms.";
                    ChangeStatusBarEventArgs args = new ChangeStatusBarEventArgs(0,message,null);
                    ChangeStatusBarPanelEvent(this,args);
                }
            }
        }
 /// <summary>
 /// Creates a new LoadFormsEditorEventArgs.
 /// </summary>
 /// <param name="postData"> Post data in bytes.</param>
 /// <param name="forms"> Form collection.</param>
 public LoadFormsEditorEventArgs(byte[] postData, HtmlFormTagCollection forms)
 {
     this.PostData = postData;
     this.FormCollection = forms;
 }
        /// <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;
        }