From: Argiris K. <be...@us...> - 2005-11-24 19:23:15
|
Update of /cvsroot/magicajax/magicajax/Core In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv3953/Core Modified Files: MagicAjaxModule.cs Util.cs Log Message: Fixed the IE problem about script execution order of document.write. If browser is IE, the 'defer' attribute is added to script tags, excluding the external script file tags. Index: Util.cs =================================================================== RCS file: /cvsroot/magicajax/magicajax/Core/Util.cs,v retrieving revision 1.8 retrieving revision 1.9 diff -C2 -d -r1.8 -r1.9 *** Util.cs 24 Nov 2005 13:13:04 -0000 1.8 --- Util.cs 24 Nov 2005 19:23:05 -0000 1.9 *************** *** 5,8 **** --- 5,9 ---- using System.Security.Cryptography; using System.Text; + using System.Text.RegularExpressions; namespace MagicAjax *************** *** 13,16 **** --- 14,64 ---- internal class Util { + public const string ScriptPattern = "<script.[^>]*>"; + + /// <summary> + /// Add 'defer' attribute to script tags excluding external script files. + /// </summary> + /// <remarks> + /// IE has a weird bug and when document.write is called, it + /// executes the scripts of the html BEFORE the external script files. + /// So add 'defer' attribute to the scripts so that external script files + /// are executed first. + /// </remarks> + /// <param name="html"></param> + /// <returns></returns> + public static string AddDeferToScriptTags (string html) + { + StringBuilder sb = new StringBuilder(html); + MatchCollection scriptMatches = Regex.Matches(html, ScriptPattern, RegexOptions.IgnoreCase); + + int diff = 0; + for (int i=0; i < scriptMatches.Count; i++) + { + Match match = scriptMatches[i]; + string tag = match.Value.ToLower(); + + if (tag.IndexOf(" src=") == -1) + { + // It's script block, add 'defer' attribute + tag = tag.Insert(tag.Length - 1, " defer"); + } + else if (tag.IndexOf(" defer") != -1) + { + // It's an external script file with a 'defer' attribute. + // Disable 'defer' by replacing it + tag = tag.Replace(" defer", " nodefer"); + } + + if ( tag.Length != match.Value.Length ) + { + int sbIndex = match.Index + diff; + sb.Replace(match.Value, tag, sbIndex, match.Value.Length); + diff += tag.Length - match.Value.Length; + } + } + + return sb.ToString(); + } + /// <summary> /// Create a base64 encoded MD5 sum string of an input string Index: MagicAjaxModule.cs =================================================================== RCS file: /cvsroot/magicajax/magicajax/Core/MagicAjaxModule.cs,v retrieving revision 1.32 retrieving revision 1.33 diff -C2 -d -r1.32 -r1.33 *** MagicAjaxModule.cs 24 Nov 2005 14:03:31 -0000 1.32 --- MagicAjaxModule.cs 24 Nov 2005 19:23:05 -0000 1.33 *************** *** 122,126 **** #else // src-request to "AjaxCallObject.js.aspx" will be handled by Application_BeginRequest, which returns the embedded AjaxCallObject.js script ! includeScript = String.Format("<script type=\"text/javascript\" src=\"{0}\"></script>", "AjaxCallObject.js.aspx"); #endif } --- 122,126 ---- #else // src-request to "AjaxCallObject.js.aspx" will be handled by Application_BeginRequest, which returns the embedded AjaxCallObject.js script ! includeScript = String.Format("<script language='javascript' type=\"text/javascript\" src=\"{0}\"></script>", "AjaxCallObject.js.aspx"); #endif } *************** *** 630,633 **** --- 630,642 ---- { string html = _filter.GetHtmlPage(); + if (_request.Browser != null && _request.Browser.Browser == "IE") + { + // IE has a weird bug and when document.write is called, it + // executes the scripts of the html BEFORE the external script files. + // So add 'defer' attribute to the scripts so that external script files + // are executed first. + html = Util.AddDeferToScriptTags(html); + + } AjaxCallHelper.WriteSetHtmlOfPageScript(html); } |