From: Argiris K. <be...@us...> - 2005-12-12 05:31:29
|
Update of /cvsroot/magicajax/magicajax/Core In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv13113/Core Modified Files: MagicAjax NET 2.0.csproj MagicAjax.csproj MagicAjaxModule.cs Util.cs Log Message: -The values of form elements are not taken into account for the fingerprint, thus html to update an already updated by the user form element is not sent to client any more. Index: Util.cs =================================================================== RCS file: /cvsroot/magicajax/magicajax/Core/Util.cs,v retrieving revision 1.14 retrieving revision 1.15 diff -C2 -d -r1.14 -r1.15 *** Util.cs 5 Dec 2005 18:44:31 -0000 1.14 --- Util.cs 12 Dec 2005 05:31:17 -0000 1.15 *************** *** 36,39 **** --- 36,40 ---- { public const string ScriptPattern = "<script.[^>]*>"; + public const string FormElementPattern = @"<(?<tag>input|textarea|select)\s+(?<attribute>(?<attrname>[-\w]+)=((""|')(?<attrvalue>.*?)(""|')\s*|(?<attrvalue>[-\w]+)\s*))*.*?(/>|>(?<inner>.*?)</\k'tag'>)"; /// <summary> *************** *** 77,81 **** /// <summary> ! /// Create a base64 encoded MD5 sum string of an input string /// </summary> /// <param name="str"></param> --- 78,82 ---- /// <summary> ! /// Create a fingerprint string of an input html /// </summary> /// <param name="str"></param> *************** *** 83,86 **** --- 84,89 ---- public static string GetFingerprint(string input) { + input = GetHtmlWithClearedFormValues(input); + MagicAjax.Configuration.OutputCompareMode compareMode = MagicAjaxContext.Current.Configuration.CompareMode; switch (compareMode) *************** *** 100,103 **** --- 103,222 ---- /// <summary> + /// Parses all form input controls from the html, and clears their values. + /// The return html is used to get a fingerprint that is not dependent on the + /// actual value of a form input control. + /// </summary> + /// <param name="html"></param> + /// <returns></returns> + public static string GetHtmlWithClearedFormValues (string html) + { + StringBuilder strbuild = new StringBuilder(html); + RegexOptions options = RegexOptions.Singleline | RegexOptions.IgnoreCase | RegexOptions.Compiled | RegexOptions.ExplicitCapture; + Regex regEx = new System.Text.RegularExpressions.Regex(Util.FormElementPattern, options); + MatchCollection matches = regEx.Matches(html); + int diff = 0; + for (int i=0; i<matches.Count; i++) + { + Match match = matches[i]; + CaptureCollection attributes = match.Groups["attribute"].Captures; + CaptureCollection attrnames = match.Groups["attrname"].Captures; + CaptureCollection attrvalues = match.Groups["attrvalue"].Captures; + + Hashtable attrCaptures = new Hashtable(attributes.Count); + Hashtable attrNameValues = new Hashtable(attributes.Count); + + for (int j=0; j < attributes.Count; j++) + { + string attrname = attrnames[j].Value.ToLower(); + attrNameValues.Add (attrname, attrvalues[j].Value); + attrCaptures.Add (attrname, attributes[j]); + } + + // If the form element has the MagicAjax 'ExcludeFromPost' attribute + // set to 'true', ignore it. We will need its value for the fingerprint. + if ( attrNameValues.ContainsKey("excludefrompost") + && (attrNameValues["excludefrompost"] as String).ToLower() == "true") + continue; + + string tag = match.Groups["tag"].Value.ToLower(); + string name = (string)attrNameValues["name"]; + + if ( name == null ) + continue; + + switch (tag) + { + #region <input> tags + + case "input": + string type = (string)attrNameValues["type"]; + if (type != null) + { + switch (type) + { + case "text": + case "password": + if (attrNameValues.ContainsKey("value")) + { + Capture attr = attrCaptures["value"] as Capture; + int sbIndex = attr.Index - diff; + strbuild.Remove (sbIndex, attr.Length); + diff += attr.Length; + } + break; + case "checkbox": + case "radio": + if (attrNameValues.ContainsKey("checked")) + { + Capture attr = attrCaptures["checked"] as Capture; + int sbIndex = attr.Index - diff; + strbuild.Remove (sbIndex, attr.Length); + diff += attr.Length; + } + break; + } + } + break; + + #endregion + + #region <textarea> tags + + case "textarea": + Group inner = match.Groups["inner"]; + if (inner.Success) + { + int sbIndex = inner.Index - diff; + strbuild.Remove (sbIndex, inner.Length); + diff += inner.Length; + } + break; + + #endregion + + #region <select> tags + + case "select": + Group selInner = match.Groups["inner"]; + Regex regExOpt = new System.Text.RegularExpressions.Regex(@"<option.*?(?<selected>selected=(""|'|)selected(""|'|)(\s+|(?=>))).*?>", options); + + //now remove the 'selected' attributes within this <select> tag + MatchCollection matchesSelected = regExOpt.Matches(selInner.Value); + for (int j = 0; j < matchesSelected.Count; j++) + { + Group selected = matchesSelected[j].Groups["selected"]; + int sbIndex = selInner.Index + selected.Index - diff; + strbuild.Remove (sbIndex, selected.Length); + diff += selected.Length; + } + break; + #endregion + } + } + + return strbuild.ToString(); + } + + /// <summary> /// Resolves relative url's (starting with "~"). /// Use this when Control.ResolveUrl() is not available. Index: MagicAjax.csproj =================================================================== RCS file: /cvsroot/magicajax/magicajax/Core/MagicAjax.csproj,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -d -r1.5 -r1.6 *** MagicAjax.csproj 23 Nov 2005 15:12:48 -0000 1.5 --- MagicAjax.csproj 12 Dec 2005 05:31:17 -0000 1.6 *************** *** 159,167 **** /> <File - RelPath = "Interfaces\IFormDataLoadedEventHandler.cs" - SubType = "Code" - BuildAction = "Compile" - /> - <File RelPath = "Interfaces\IPreWriteScriptEventHandler.cs" SubType = "Code" --- 159,162 ---- Index: MagicAjax NET 2.0.csproj =================================================================== RCS file: /cvsroot/magicajax/magicajax/Core/MagicAjax NET 2.0.csproj,v retrieving revision 1.8 retrieving revision 1.9 diff -C2 -d -r1.8 -r1.9 *** MagicAjax NET 2.0.csproj 23 Nov 2005 15:12:48 -0000 1.8 --- MagicAjax NET 2.0.csproj 12 Dec 2005 05:31:17 -0000 1.9 *************** *** 109,115 **** </Compile> <Compile Include="Interfaces\IAjaxCallEventHandler.cs" /> - <Compile Include="Interfaces\IFormDataLoadedEventHandler.cs"> - <SubType>Code</SubType> - </Compile> <Compile Include="Interfaces\IPreWriteScriptEventHandler.cs"> <SubType>Code</SubType> --- 109,112 ---- Index: MagicAjaxModule.cs =================================================================== RCS file: /cvsroot/magicajax/magicajax/Core/MagicAjaxModule.cs,v retrieving revision 1.41 retrieving revision 1.42 diff -C2 -d -r1.41 -r1.42 *** MagicAjaxModule.cs 11 Dec 2005 21:07:22 -0000 1.41 --- MagicAjaxModule.cs 12 Dec 2005 05:31:17 -0000 1.42 *************** *** 669,682 **** Util.CallPrivateMethod (page, typeof(Page), "SetIntrinsics", HttpContext.Current); ! ReadOnlyArrayList postDataChangedControls; ! postDataChangedControls = new ReadOnlyArrayList(LoadFormDataOnChildren(page)); ! RaiseFormDataLoadedEvent (page, postDataChangedControls); foreach (IPostBackDataHandler handler in postDataChangedControls) handler.RaisePostDataChangedEvent(); - RaiseAjaxCallEvent (page); - if (_magicAjaxContext.AjaxCallType == AjaxCallType.Control) { --- 669,680 ---- Util.CallPrivateMethod (page, typeof(Page), "SetIntrinsics", HttpContext.Current); ! ArrayList postDataChangedControls; ! postDataChangedControls = LoadFormDataOnChildren(page); ! RaiseAjaxCallEvent (page); foreach (IPostBackDataHandler handler in postDataChangedControls) handler.RaisePostDataChangedEvent(); if (_magicAjaxContext.AjaxCallType == AjaxCallType.Control) { *************** *** 694,715 **** /// <summary> - /// Raises PostDataLoaded event on the supplied control and its children. - /// </summary> - /// <remarks> - /// This is a recursive method. It goes through the control collection tree - /// and raises the PostDataLoaded event on all the controls that implement the - /// IFormDataLoadedEventHandler interface. - /// </remarks> - /// <param name="control"></param> - protected void RaiseFormDataLoadedEvent(Control control, ReadOnlyArrayList changedControls) - { - if (control is IFormDataLoadedEventHandler) - ((IFormDataLoadedEventHandler) control).RaiseFormDataLoadedEvent (changedControls); - - for (int i=0; i < control.Controls.Count; i++) - RaiseFormDataLoadedEvent (control.Controls[i], changedControls); - } - - /// <summary> /// Raises AjaxCall event on the supplied control and its children. /// </summary> --- 692,695 ---- |