/**////<summary> /// Hashtable to store the captured special elements. ///</summary> private Hashtable htCaptureFields;
/**////<summary> /// Hashtable to store pre-compiled regular expressions for special elements. ///</summary> private Hashtable htRegSpecialElement;
/**////<summary> /// The total number of special elements captured. ///</summary> privateint specialItemCount;
/**////<summary> /// If <code>true</code> comments will be removed. /// Default value is <code>true</code>. ///</summary> publicbool RemoveComments ...{ set ...{ removeComments = value; } }
/**////<summary> /// If <code>true</code> lines will be trimmed and multiple blank /// new lines will be removed. /// Default value is <code>true</code>. ///</summary> publicbool TrimLines ...{ set ...{ removeAndTrimBlankLines = value; } }
/**////<summary> /// If <code>true</code> all CRLF characters will be removed. /// Default value is <code>true</code>. ///</summary> publicbool RemoveCRLF ...{ set ...{ removeCarriageReturns = value; } }
/**////<summary> /// If <code>true</code> some additional compression will be done. /// Default value is <code>true</code>. ///</summary> publicbool RemoveEverthingElse ...{ set ...{ removeEverthingElse = value; } } #endregion
protectedvoid Page_Load(object sender, EventArgs e) ...{ /**//* initialize members */
//return a javascript file contains compressed vesion of javascript Response.Write(Compress(Script)); }
/**////<summary> /// Compresses the given String. ///</summary> ///<param name="toBeCompressed">The String to be compressed.</param> publicstring Compress(string toBeCompressed) ...{ /**//*clean the hasthable*/ htCaptureFields.Clear(); htRegSpecialElement.Clear(); specialItemCount =0;
/**//* mark special elements */ MarkQuotesAndRegExps(ref toBeCompressed);
if (removeComments) ...{ /**//* remove line comments */ RemoveLineComments(ref toBeCompressed); /**//* remove C Style comments */ RemoveCStyleComments(ref toBeCompressed); }
if (removeAndTrimBlankLines) ...{ /**//* trim left */ TrimLinesLeft(ref toBeCompressed); /**//* trim right */ TrimLinesRight(ref toBeCompressed); }
supporting functions#region supporting functions /**////<summary> /// Replaces the stored special elements back to their places. ///</summary> ///<param name="input">The input String to process.</param> privatevoid RestoreQuotesAndRegExps(ref String input) ...{ int captureCount = htCaptureFields.Count; for (int i =0; i < captureCount; i++) ...{ input = ((Regex)htRegSpecialElement[i]).Replace(input, (String)htCaptureFields[i]); } }
/**////<summary> /// Quotes and regular expressions should be untouched and unprocessed at all times. /// So we mark and store them beforehand in a private Hashtable for later use. ///</summary> ///<param name="input">The input String to process. It should be a single line.</param> privatevoid MarkQuotesAndRegExps(ref String input) ...{ MatchCollection matches = regSpecialElement.Matches(input);
int count = matches.Count; Match currentMatch;
/**//* store strings and regular expressions */ for (int i =0; i < count; i++) ...{ currentMatch = matches[i]; htCaptureFields.Add(specialItemCount, currentMatch.Value); /**//* we added one more special item to our Hashtable */ specialItemCount++; }
/**//* replace strings and regular expressions */ for (int i =0; i < count; i++) ...{ /**//* * compile and add the Regex to the hashtable * so that it executes faster at the Restore phase. * * A trade off between Regex compilation speed and * memory. */ htRegSpecialElement.Add(i, new Regex("____SPECIAL_ELEMENT____"+ (i) +"____", RegexOptions.ECMAScript | RegexOptions.Compiled));
/**////<summary> /// Replaces any duplicate space-tab combinations with a single space. ///</summary> ///<param name="input">The input String to replace.</param> privatevoid ReplaceDuplicateWhiteSpace(ref String input) ...{ input = regWhiteSpaceExceptCRLF.Replace(input, ""); }
/**////<summary> /// Trims all the trailing whitespace characters in a line with "". ///</summary> ///<param name="input">The input String to replace.</param> privatevoid TrimLinesLeft(ref String input) ...{ input = regSpaceLeft.Replace(input, ""); }
/**////<summary> /// Trims all whitespace after the end of the line, and the proceeding CRLF characters /// with a single CRLF. ///</summary> ///<param name="input">The input String to replace.</param> privatevoid TrimLinesRight(ref String input) ...{ input = regSpaceRight.Replace(input, ""); }
/**////<summary> /// Replaces any whitespace before and after "{" characters with "". ///</summary> ///<param name="input">The input String to replace.</param> privatevoid ReplaceLeftCurlyBrace(ref String input) ...{ input = regLeftCurlyBrace.Replace(input, "{"); }
/**////<summary> /// Replaces any whitespace before and after "}" characters with "". ///</summary> ///<param name="input">The input String to replace.</param> privatevoid ReplaceRightCurlyBrace(ref String input) ...{ input = regRightCurlyBrace.Replace(input, "}"); }
/**////<summary> /// Replaces any whitespace before and after "," characters with "". ///</summary> ///<param name="input">The input String to replace.</param> privatevoid ReplaceComma(ref String input) ...{ input = regComma.Replace(input, ","); }
/**////<summary> /// Replaces any whitespace before and after ";" characters with "". ///</summary> ///<param name="input">The input String to replace.</param> privatevoid ReplaceSemiColumn(ref String input) ...{ input = regSemiColumn.Replace(input, ";"); }
/**////<summary> /// Replaces all CRLF characters in the input to "". ///</summary> ///<param name="input">The input String to replace.</param> privatevoid ReplaceNewLine(ref String input) ...{ input = regNewLine.Replace(input, ""); }
#endregion
/**////<summary> /// Get the script and return as a string. The parameter of this page can be: /// 1. Javascript file location parameter "file=" (eg. "Compress.aspx?file=/path/to/script.js") /// 2. Encoded Javascript code with parameter "code=" (eg. "Compress.aspx?code=%20F...") /// NOTE: In the second form the code is the pure javascript code between tags. ///</summary> privatestring Script ...{ get ...{ if (Request.QueryString["file"] !=null) ...{ string fileName = Request.QueryString["file"]; /**//* * Localization is always an issue if you are non-English. * System.Text.Encoding class helps sort out this problem. */ string sourcePath = MapPath(fileName); Encoding locale = System.Text.Encoding.GetEncoding(CODEPAGE); StreamReader sr =new StreamReader(sourcePath, locale); String strCompress = sr.ReadToEnd(); sr.Close(); return strCompress; } elseif (Request.QueryString["code"] !=null) ...{ string strCode = Request.QueryString["code"];//todo: parse return strCode; } else...{ returnnull; } } }