/Minifier/Minifier.cs

http://jasc.codeplex.com · C# · 320 lines · 173 code · 36 blank · 111 comment · 14 complexity · 76e5151e9c9b8a1bf228d0be79026e42 MD5 · raw file

  1. // Minifier.cs
  2. //
  3. // Copyright 2010 Microsoft Corporation
  4. //
  5. // Licensed under the Apache License, Version 2.0 (the "License");
  6. // you may not use this file except in compliance with the License.
  7. // You may obtain a copy of the License at
  8. //
  9. // http://www.apache.org/licenses/LICENSE-2.0
  10. //
  11. // Unless required by applicable law or agreed to in writing, software
  12. // distributed under the License is distributed on an "AS IS" BASIS,
  13. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14. // See the License for the specific language governing permissions and
  15. // limitations under the License.
  16. using System;
  17. using System.Collections.Generic;
  18. using System.Globalization;
  19. using System.IO;
  20. using System.Text;
  21. namespace Microsoft.Ajax.Utilities
  22. {
  23. /// <summary>
  24. /// Summary description for MainClass.
  25. /// </summary>
  26. public class Minifier
  27. {
  28. #region Properties
  29. /// <summary>
  30. /// Warning level threshold for reporting errors.
  31. /// Default value is zero: syntax/run-time errors.
  32. /// </summary>
  33. public int WarningLevel
  34. {
  35. get; set;
  36. }
  37. /// <summary>
  38. /// File name to use in error reporting.
  39. /// Default value is null: use Minify... method name.
  40. /// </summary>
  41. public string FileName
  42. {
  43. get; set;
  44. }
  45. /// <summary>
  46. /// Collection of ContextError objects found during minification process
  47. /// </summary>
  48. public ICollection<ContextError> ErrorList { get { return m_errorList; } }
  49. private List<ContextError> m_errorList; // = null;
  50. /// <summary>
  51. /// Collection of any error strings found during the crunch process.
  52. /// Deprecated; do not use this collection. Use the ErrorList collection instead.
  53. /// </summary>
  54. [Obsolete("This property is deprecated; use ErrorList instead")]
  55. [System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)]
  56. public ICollection<string> Errors
  57. {
  58. get
  59. {
  60. var errorList = new List<string>(ErrorList.Count);
  61. foreach (var error in ErrorList)
  62. {
  63. errorList.Add(error.ToString());
  64. }
  65. return errorList;
  66. }
  67. }
  68. #endregion
  69. #region JavaScript methods
  70. /// <summary>
  71. /// MinifyJavaScript JS string passed to it using default code minification settings.
  72. /// The ErrorList property will be set with any errors found during the minification process.
  73. /// </summary>
  74. /// <param name="source">source Javascript</param>
  75. /// <returns>minified Javascript</returns>
  76. public string MinifyJavaScript(string source)
  77. {
  78. // just pass in default settings
  79. return MinifyJavaScript(source, new CodeSettings());
  80. }
  81. /// <summary>
  82. /// Crunched JS string passed to it, returning crunched string.
  83. /// The ErrorList property will be set with any errors found during the minification process.
  84. /// </summary>
  85. /// <param name="source">source Javascript</param>
  86. /// <param name="codeSettings">code minification settings</param>
  87. /// <returns>minified Javascript</returns>
  88. public string MinifyJavaScript(string source, CodeSettings codeSettings)
  89. {
  90. // default is an empty string
  91. string crunched = string.Empty;
  92. // reset the errors builder
  93. m_errorList = new List<ContextError>();
  94. // create the parser from the source string.
  95. // pass null for the assumed globals array
  96. JSParser parser = new JSParser(source);
  97. // file context is a property on the parser
  98. parser.FileContext = FileName;
  99. // hook the engine error event
  100. parser.CompilerError += OnJavaScriptError;
  101. try
  102. {
  103. // parse the input
  104. Block scriptBlock = parser.Parse(codeSettings);
  105. if (scriptBlock != null)
  106. {
  107. // we'll return the crunched code
  108. crunched = scriptBlock.ToCode();
  109. }
  110. }
  111. catch (Exception e)
  112. {
  113. m_errorList.Add(new ContextError(
  114. true,
  115. 0,
  116. null,
  117. null,
  118. null,
  119. this.FileName,
  120. 0,
  121. 0,
  122. 0,
  123. 0,
  124. e.Message));
  125. }
  126. return crunched;
  127. }
  128. #endregion
  129. #region CSS methods
  130. /// <summary>
  131. /// MinifyJavaScript CSS string passed to it using default code minification settings.
  132. /// The ErrorList property will be set with any errors found during the minification process.
  133. /// </summary>
  134. /// <param name="source">source Javascript</param>
  135. /// <returns>minified Javascript</returns>
  136. public string MinifyStyleSheet(string source)
  137. {
  138. // just pass in default settings
  139. return MinifyStyleSheet(source, new CssSettings());
  140. }
  141. /// <summary>
  142. /// Minifies the CSS stylesheet passes to it using the given settings, returning the minified results
  143. /// The ErrorList property will be set with any errors found during the minification process.
  144. /// </summary>
  145. /// <param name="source">CSS Source</param>
  146. /// <param name="settings">CSS minification settings</param>
  147. /// <returns>Minified StyleSheet</returns>
  148. public string MinifyStyleSheet(string source, CssSettings settings)
  149. {
  150. // initialize some values, including the error list (which shoudl start off empty)
  151. string minifiedResults = string.Empty;
  152. m_errorList = new List<ContextError>();
  153. // create the parser object and if we specified some settings,
  154. // use it to set the Parser's settings object
  155. CssParser parser = new CssParser();
  156. parser.FileContext = FileName;
  157. if (settings != null)
  158. {
  159. parser.Settings = settings;
  160. }
  161. // hook the error handler
  162. parser.CssError += new EventHandler<CssErrorEventArgs>(OnCssError);
  163. // try parsing the source and return the results
  164. try
  165. {
  166. minifiedResults = parser.Parse(source);
  167. }
  168. catch (Exception e)
  169. {
  170. m_errorList.Add(new ContextError(
  171. true,
  172. 0,
  173. null,
  174. null,
  175. null,
  176. this.FileName,
  177. 0,
  178. 0,
  179. 0,
  180. 0,
  181. e.Message));
  182. }
  183. return minifiedResults;
  184. }
  185. #endregion
  186. #region Error-handling Members
  187. private void OnCssError(object sender, CssErrorEventArgs e)
  188. {
  189. ContextError error = e.Error;
  190. if (error.Severity <= WarningLevel)
  191. {
  192. m_errorList.Add(error);
  193. }
  194. }
  195. private void OnJavaScriptError(object sender, JScriptExceptionEventArgs e)
  196. {
  197. ContextError error = e.Error;
  198. if (error.Severity <= WarningLevel)
  199. {
  200. m_errorList.Add(error);
  201. }
  202. }
  203. #endregion
  204. #region deprecated methods
  205. /// <summary>
  206. /// This method is deprecated. The list of known global names has been moved to the CodeSettings
  207. /// object. If codeSettings.KnownGlobalNames is null and the globalNames parameter is not, this
  208. /// API will populate the codeSettings object. Otherwise the globalNames parameter will be ignored.
  209. /// </summary>
  210. /// <param name="source"></param>
  211. /// <param name="codeSettings"></param>
  212. /// <param name="globalNames"></param>
  213. /// <returns></returns>
  214. [Obsolete("This method is deprecated; use the CodeSettings object to pass known global names")]
  215. [System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)]
  216. public string MinifyJavaScript(string source, CodeSettings codeSettings, params string[] globalNames)
  217. {
  218. if (codeSettings != null && codeSettings.KnownGlobalNames == null && globalNames != null)
  219. {
  220. codeSettings.SetKnownGlobalNames(globalNames);
  221. }
  222. return MinifyJavaScript(source, codeSettings);
  223. }
  224. /// <summary>
  225. /// This method is deprecated. The list of known global names has been moved to the CodeSettings object.
  226. /// </summary>
  227. /// <param name="source">source Javascript</param>
  228. /// <param name="globalNames">array of known global object names</param>
  229. /// <returns>minified Javascript</returns>
  230. [Obsolete("This method is deprecated; use the CodeSettings object to pass known global names")]
  231. [System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)]
  232. public string MinifyJavaScript(string source, params string[] globalNames)
  233. {
  234. // just pass in default settings
  235. CodeSettings codeSettings = new CodeSettings();
  236. if (globalNames != null)
  237. {
  238. codeSettings.SetKnownGlobalNames(globalNames);
  239. }
  240. return MinifyJavaScript(source, codeSettings);
  241. }
  242. #endregion
  243. }
  244. #region deprecated class
  245. /// <summary>
  246. /// This class is deprecated; it will be removed in future versions.
  247. /// Please use Microsoft.Ajax.Utilities.Minifier instead.
  248. /// </summary>
  249. [Obsolete("This class is deprecated; use Microsoft.Ajax.Utilities.Minifier instead")]
  250. [System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)]
  251. public class ScriptCruncher : Minifier
  252. {
  253. /// <summary>
  254. /// Crunched JS string passed to it using default code settings, returning crunched string.
  255. /// This API is deprecated and will be removed in future versions. Please use
  256. /// Microsoft.Ajax.Utilities.Minifier.MinifyJavaScript instead.
  257. /// </summary>
  258. /// <param name="source">source Javascript</param>
  259. /// <returns>crunched Javascript</returns>
  260. [Obsolete("This API is deprecated; use Microsoft.Ajax.Utilties.Minifier.MinifyJavaScript instead")]
  261. [System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)]
  262. public string Crunch(string source)
  263. {
  264. // just pass in default settings
  265. return MinifyJavaScript(source, new CodeSettings());
  266. }
  267. /// <summary>
  268. /// Crunched JS string passed to it, returning crunched string.
  269. /// This API is deprecated and will be removed in future versions. Please use
  270. /// Microsoft.Ajax.Utilities.Minifier.MinifyJavaScript instead.
  271. /// </summary>
  272. /// <param name="source">source Javascript</param>
  273. /// <param name="codeSettings">code minification settings</param>
  274. /// <returns>crunched Javascript</returns>
  275. [Obsolete("This API is deprecated; use Microsoft.Ajax.Utilties.Minifier.MinifyJavaScript instead")]
  276. [System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)]
  277. public string Crunch(string source, CodeSettings codeSettings)
  278. {
  279. // just pass in default settings
  280. return MinifyJavaScript(source, codeSettings);
  281. }
  282. }
  283. #endregion
  284. }