JavaScript Minifier C葃圧縮Javascript

10364 ワード

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Text;
using System.IO;

/// <summary>
///      JavaScript      。
/// </summary>
public sealed class JavaScriptMinifier
{
    #region     

    private const int EOF = -1;

    private readonly StringBuilder _JsBuilder;
    private readonly TextReader _JsReader;
    private int _TheA = Convert.ToInt32('
'); private int _TheB; private int _TheLookahead = EOF; #endregion #region /// <summary> /// <see cref="JavaScriptMinifier"/> 。 /// </summary> /// <param name="jsReader"> JavaScript <see cref="TextReader"/>。</param> private JavaScriptMinifier(TextReader jsReader) { if (jsReader == null) throw new ArgumentNullException("jsReader"); this._JsReader = jsReader; this._JsBuilder = new StringBuilder(); } #endregion #region /// <summary> /// JavaScript 。 /// </summary> /// <param name="js"> JavaScript <see cref="StringBuilder"/>。</param> /// <returns> JavaScript <see cref="StringBuilder"/>。</returns> public static StringBuilder Minify(StringBuilder js) { return Minify(new StringReader(js.ToString())); } /// <summary> /// JavaScript 。 /// </summary> /// <param name="jsCode"> JavaScript 。</param> /// <returns> JavaScript <see cref="StringBuilder"/>。</returns> public static StringBuilder Minify(string jsCode) { return Minify(new StringReader(jsCode)); } /// <summary> /// JavaScript 。 /// </summary> /// <param name="jsReader"> JavaScript <see cref="TextReader"/>。</param> /// <returns> JavaScript <see cref="StringBuilder"/>。</returns> public static StringBuilder Minify(TextReader jsReader) { JavaScriptMinifier jsmin = new JavaScriptMinifier(jsReader); jsmin._Jsmin(); return jsmin._JsBuilder; } #endregion #region private void _Jsmin() { this._Action(3); while (this._TheA != EOF) { switch ((Char)this._TheA) { case ' ': if (_IsAlphanum(this._TheB)) this._Action(1); else this._Action(2); break; case '
': switch ((Char)this._TheB) { case '{': case '[': case '(': case '+': case '-': this._Action(1); break; case ' ': this._Action(3); break; default: if (_IsAlphanum(this._TheB)) this._Action(1); else this._Action(2); break; } break; default: switch ((Char)this._TheB) { case ' ': if (_IsAlphanum(this._TheA)) { this._Action(1); break; } this._Action(3); break; case '
': switch ((Char)this._TheA) { case '}': case ']': case ')': case '+': case '-': case '"': case '\'': this._Action(1); break; default: if (_IsAlphanum(this._TheA)) this._Action(1); else this._Action(3); break; } break; default: this._Action(1); break; } break; } } } private void _Action(int d) { if (d <= 1) this._Put(this._TheA); if (d <= 2) { this._TheA = this._TheB; if (this._TheA == '\'' || this._TheA == '"') { for (; ; ) { this._Put(this._TheA); this._TheA = this._Get(); if (this._TheA == this._TheB) break; if (this._TheA <= '
') throw new Exception(string.Format("Error: JSMIN unterminated string literal: {0}", this._TheA)); if (this._TheA != '\\') continue; this._Put(this._TheA); this._TheA = this._Get(); } } } if (d > 3) return; this._TheB = this._Next(); if (this._TheB != '/' || ((((((((((((this._TheA != '(' && this._TheA != ',') && this._TheA != '=') && this._TheA != '[') && this._TheA != '!') && this._TheA != ':') && this._TheA != '&') && this._TheA != '|') && this._TheA != '?') && this._TheA != '{') && this._TheA != '}') && this._TheA != ';') && this._TheA != '
')) return; this._Put(this._TheA); this._Put(this._TheB); for (; ; ) { this._TheA = this._Get(); if (this._TheA == '/') break; if (this._TheA == '\\') { this._Put(this._TheA); this._TheA = this._Get(); } else if (this._TheA <= '
') throw new Exception(string.Format("Error: JSMIN unterminated Regular Expression literal : {0}.", this._TheA)); this._Put(this._TheA); } this._TheB = this._Next(); } private int _Next() { int c = this._Get(); const int s = (int)'*'; if (c == '/') { switch ((Char)this._Peek()) { case '/': for (; ; ) { c = this._Get(); if (c <= '
') return c; } case '*': this._Get(); for (; ; ) { switch (this._Get()) { case s: if (this._Peek() == '/') { this._Get(); return Convert.ToInt32(' '); } break; case EOF: throw new Exception("Error: JSMIN Unterminated comment."); } } default: return c; } } return c; } private int _Peek() { this._TheLookahead = this._Get(); return this._TheLookahead; } private int _Get() { int c = this._TheLookahead; this._TheLookahead = EOF; if (c == EOF) c = this._JsReader.Read(); return c >= ' ' || c == '
' || c == EOF ? c : (c == '\r' ? '
' : ' '); } private void _Put(int c) { this._JsBuilder.Append((char)c); } private static bool _IsAlphanum(int c) { return ((c >= 'a' && c <= 'z') || (c >= '0' && c <= '9') || (c >= 'A' && c <= 'Z') || c == '_' || c == '$' || c == '\\' || c > 126); } #endregion }
 JavaScript Minifier