JavaScriptMinifier C#压缩Javascript
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('\n');
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 '\n':
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 '\n':
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 <= '\n') 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 != '\n')) 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 <= '\n') 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 <= '\n') 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 == '\n' || c == EOF ? c : (c == '\r' ? '\n' : ' ');
} 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
}
JavaScriptMinifier C#压缩Javascript的更多相关文章
- node.js 使用 UglifyJS2 高效率压缩 javascript 文件
UglifyJS2 这个工具使用很长时间了,但之前都是在 gulp 自动构建 时用到了 UglifyJS 算法进行压缩. 最近玩了一下 UglifyJS2 ,做了一个 在线压缩javascript工具 ...
- 使用Ant命令压缩JavaScript文件
压缩JavaScript文件可以减少代码尺寸,保护源代码,节省网络带宽,加快页面打开速度,甚至优化JS代码.Yahoo有一个压缩JS的工具叫做YUI compressor, Google也有一个工具叫 ...
- YUI Compressor 压缩 JavaScript 原理-《转载》
YUI Compressor 压缩 JavaScript 的内容包括: 移除注释 移除额外的空格 细微优化 标识符替换(Identifier Replacement) YUI Compressor包括 ...
- 压缩javascript文件方法
写在前面的话:正式部署前端的时候,javascript文件一般需要压缩,并生成相应的sourcemap文件,对于一些小型的项目开发,这里提供一个简单的办法. ======正文开始====== 1.下载 ...
- gzip压缩JavaScript
为了提高客户端的体验效果,RIA开发逐渐兴起.这样会项目中会充斥的大量的JavaScript代码,与此同时会消耗客户端浏览器性能.对于 Ext 实现的 one page one application ...
- Grunt 使用(二)uglify插件压缩javascript代码
本文在配置grunt基本环境的基础下,讲解如何使用grunt-contrib-uglify进行javascript压缩 本文只介绍了grunt-contrib-uglify插件的一种压缩方式适用于大部 ...
- 使用jsmin压缩javascript脚本
官方地址:http://www.crockford.com/javascript/jsmin.html 点击页下方的”zip file containing an MS-DOS.exe file“下载 ...
- 使用Google Closure Compiler高级压缩Javascript代码
背景 前端开发中,特别是移动端,Javascript代码压缩已经成为上线必备条件. 如今主流的Js代码压缩工具主要有: 1)Uglify http://lisperator.net/uglifyjs/ ...
- 使用Google Closure Compiler高级压缩Javascript代码注意的几个地方
介绍 GCC(Google Closure Compiler)是由谷歌发布的Js代码压缩编译工具.它可以做到分析Js的代码,移除不需要的代码(dead code),并且去重写它,最后再进行压缩. 三种 ...
随机推荐
- 02-自定义CALayer
*:first-child { margin-top: 0 !important; } body > *:last-child { margin-bottom: 0 !important; } ...
- 百度校招面试经历及总结(已发offer)
听说发面经可以攒rp,希望早点给我确定的offer通知,也希望看到这个面经的小伙伴能顺利拿到心仪的offer~ 职位:机器学习-数据挖掘工程师 9.15 上午11点 一面 1.介绍项目 2.考研意向, ...
- 好文EF
http://www.cnblogs.com/zhaopei/p/5721789.html#autoid-0-0 http://www.cnblogs.com/zhaopei/p/5746414.ht ...
- 如何绕过CDN找源站ip?
这是一个总结帖,查了一下关于这个问题的国内外大大小小的网站,对其中说的一些方法总结归纳形成,里面具体发现ip的方法不是原创,所有参考的原贴都也贴在了后面,大家可以自行看看原贴. 首先,先要明确一个概念 ...
- MSP430F149学习之路——捕获/比较模式
1.捕获模式 #include <msp430x14x.h> unsigned ,last1=; unsigned ,j=; void mian(void) { WDTCTL = WDTP ...
- EF CRUD 操作
1.Add 操作 public bool Add(EFDataModels.User model) { try { int result=0; using (DBEntities db = new D ...
- MySql 日期函数
在 MySql 中经常会用到日期,关于常用的日期函数,做了以下的总结: 1 . now() 作用; 获取当前的日期 除此之外,获取当前日期的函数还有: current_timestamp(); cur ...
- LA3902 Network
给出一棵树,对于每一个叶子节点要使得在它的k距离内至少一个节点被打了标记,(叶节点不能打标记,非叶结点也不必满足这个条件),现在已经有一个节点s被打了标记,问至少还要打几个标记(这表达能力也是捉急.. ...
- vba 快速定位当前EXCEL最后一栏
工作的需要,有时会对EXCEL数据进行处理,比如格式化,有数据的单元格画横线. 最初,傻傻的,直接用个循环从第1行,一直往后找,判断是否为空,真傻. Function FindLastCell() D ...
- C#使用Cookie方法
//写入 protected void Button1_Click(object sender, EventArgs e) { HttpCookie cookie=new HttpCookie(&qu ...