木子屋 Dnawo's BLOG

JavaScript在线压缩/格式化工具

👤 dnawo 📅 2008-06-19 👁 4808 👍 0 💬 0 🔄 ttyp
HTML
<html><head><title>JavaScript在线压缩/格式化</title>
<meta http-equiv=Content-Type content="text/html; charset=gb2312">
<style type="text/css">
	html{overflow:hidden;}
	textarea{width:100%;height:250px;}
</style>
</head>
<body>
<script language=JavaScript>
<!--
/*
=========================================================================================
**    类名:CLASS_FORMATER
**    功能:JS格式化  
**    示例:  
    ---------------------------------------------------------------------------------------------------  
  
            var xx        = new CLASS_FORMATER(code);            

            document.getElementById("display").innerHTML = xx.format(); 
  
    ---------------------------------------------------------------------------------------------------  
**    作者:ttyp  
**    邮件:ttyp@21cn.com  
**    日期:2006-5-21  
**    版本:0.1
**    =========================================================================================
**/

function CLASS_FORMAT(code) {
	//哈希表类
	function Hashtable() {
		this._hash=new Object();
		this.add=function (key,value) {
			if(typeof(key)!="undefined") {
				if(this.contains(key)==false) {
					this._hash[key]=typeof(value)=="undefined"?null:value;
					return true;
				}else {
					return false;
				}
			}else {
				return false;
			}
		}
		this.remove=function (key) {
			delete this._hash[key];
		}
		this.count=function () {
			var i=0;
			for(var k in this._hash) {
				i++;
			}return i;
		}
		this.items=function (key) {
			return this._hash[key];
		}
		this.contains=function (key) {
			return typeof(this._hash[key])!="undefined";
		}
		this.clear=function () {
			for(var k in this._hash) {
				delete this._hash[k];
			}
		}
	}
	this._caseSensitive=true;
	//字符串转换为哈希表
	this.str2hashtable=function (key,cs) {
		var _key=key.split(/,/g);
		var _hash=new Hashtable();
		var _cs=true;
		if(typeof(cs)=="undefined"||cs==null) {
			_cs=this._caseSensitive;
		}else {
			_cs=cs;
		}
		for(var i in _key) {
			if(_cs) {
				_hash.add(_key[i]);
			}else {
				_hash.add((_key[i]+"").toLowerCase());
			}
		}
		return _hash;
	}
	//获得需要转换的代码
	this._codetxt=code;
	if(typeof(syntax)=="undefined") {
		syntax="";
	}
	this._deleteComment=false;
	//是否大小写敏感
	this._caseSensitive=true;
	//可以后面加块语句的关键字
	this._blockElement=this.str2hashtable("switch,if,while,try,finally");
	//是函数申明
	this._function=this.str2hashtable("function");
	//本行括号内分号不做换行
	this._isFor="for";
	this._choiceElement=this.str2hashtable("else,catch");
	this._beginBlock="{";
	this._endBlock="}";
	this._singleEyeElement=this.str2hashtable("var,new,return,else,delete,in,case");
	//得到分割字符
	this._wordDelimiters="  ,.?!;:\\/<>() {}[]\"'\r\n\t=+-|*%@#$^&";
	//引用字符
	this._quotation=this.str2hashtable("\",'");
	//行注释字符
	this._lineComment="//";
	//转义字符
	this._escape="\\";
	//多行引用开始
	this._commentOn="/*";
	//多行引用结束
	this._commentOff="*/";
	//行结束词
	this._rowEnd=";";
	this._in="in";
	this.isCompress=false;
	this.style=0;
	this._tabNum=0;
	this.format=function () {
		var codeArr=new Array();
		var word_index=0;
		var htmlTxt=new Array();
		if(this.isCompress) {
			this._deleteComment=true;
		}
		//得到分割字符数组(分词)
		for(var i=0;i<this._codetxt.length;i++) {
			if(this._wordDelimiters.indexOf(this._codetxt.charAt(i))==-1) {
				//找不到关键字
				if(codeArr[word_index]==null||typeof(codeArr[word_index])=='undefined') {
					codeArr[word_index]="";
				}
				codeArr[word_index]+=this._codetxt.charAt(i);
			}else {
				if(typeof(codeArr[word_index])!='undefined'&&codeArr[word_index].length>0)
				word_index++;
				codeArr[word_index++]=this._codetxt.charAt(i);
			}
		}
		var quote_opened=false;
		//引用标记
		var slash_star_comment_opened=false;
		//多行注释标记
		var slash_slash_comment_opened=false;
		//单行注释标记
		var line_num=1;
		//行号
		var quote_char="";
		//引用标记类型
		var function_opened=false;
		var bracket_open=false;
		var for_open=false;
		//按分割字,分块显示
		for(var i=0;i<=word_index;i++) {
			//处理空行(由于转义带来)
			if(typeof(codeArr[i])=="undefined"||codeArr[i].length==0) {
				continue;
			}else if(codeArr[i]==" "||codeArr[i]=="\t") {
				if(slash_slash_comment_opened||slash_star_comment_opened) {
					if(!this._deleteComment) {
						htmlTxt[htmlTxt.length]=codeArr[i];
					}
				}
				if(quote_opened) {
					htmlTxt[htmlTxt.length]=codeArr[i];
				}
			}else if(codeArr[i]=="\n") {
				//处理换行
			}else if(codeArr[i]=="\r") {
				slash_slash_comment_opened=false;
				quote_opened=false;
				line_num++;
				if(!this.isCompress) {
					htmlTxt[htmlTxt.length]="\r\n"+this.getIdent();
				}
				//处理function里的参数标记
			}else if(!slash_slash_comment_opened&&!slash_star_comment_opened&&!quote_opened&&this.isFunction(codeArr[i])) {
				htmlTxt[htmlTxt.length]=codeArr[i]+" ";
				function_opened=true;
			}else if(!slash_slash_comment_opened&&!slash_star_comment_opened&&!quote_opened&&codeArr[i]==this._isFor) {
				htmlTxt[htmlTxt.length]=codeArr[i];
				for_open=true;
			}else if(!slash_slash_comment_opened&&!slash_star_comment_opened&&!quote_opened&&codeArr[i]=="(") {
				bracket_open=true;
				htmlTxt[htmlTxt.length]=codeArr[i];
			}else if(!slash_slash_comment_opened&&!slash_star_comment_opened&&!quote_opened&&codeArr[i]==")") {
				bracket_open=false;
				htmlTxt[htmlTxt.length]=codeArr[i];
			}else if(!slash_slash_comment_opened&&!slash_star_comment_opened&&!quote_opened&&codeArr[i]==this._rowEnd) {
				if(!this.isCompress) {
					if(!for_open) {
						if(i<word_index&&(codeArr[i+1]!="\r"&&codeArr[i+1]!="\n")) {
							htmlTxt[htmlTxt.length]=codeArr[i]+"\n"+this.getIdent();
						}else {
							htmlTxt[htmlTxt.length]=codeArr[i]+this.getIdent();
						}
					}else {
						htmlTxt[htmlTxt.length]=codeArr[i];
					}
				}else {
					htmlTxt[htmlTxt.length]=codeArr[i];
				}
			}else if(!slash_slash_comment_opened&&!slash_star_comment_opened&&!quote_opened&&codeArr[i]==this._beginBlock) {
				for_open=false;
				if(!this.isCompress) {
					switch(this.style) {
						case 0:
						this._tabNum++;
						htmlTxt[htmlTxt.length]=codeArr[i]+"\n"+this.getIdent();
						break;
						case 1:
						htmlTxt[htmlTxt.length]="\n"+this.getIdent();
						this._tabNum++;
						htmlTxt[htmlTxt.length]=codeArr[i]+"\n"+this.getIdent();
						break;
						default:
						this._tabNum++;
						htmlTxt[htmlTxt.length]=codeArr[i];
						break;
					}
				}else {
					htmlTxt[htmlTxt.length]=codeArr[i];
				}
			}else if(!slash_slash_comment_opened&&!slash_star_comment_opened&&!quote_opened&&codeArr[i]==this._endBlock) {
				if(!this.isCompress) {
					this._tabNum--;
					if(i<word_index&&codeArr[i+1]!=this._rowEnd) {
						htmlTxt[htmlTxt.length]="\n"+this.getIdent()+codeArr[i];
					}else {
						htmlTxt[htmlTxt.length]="\n"+this.getIdent()+codeArr[i];
					}
				}else {
					if(i<word_index&&codeArr[i+1]!=this._rowEnd) {
						htmlTxt[htmlTxt.length]=codeArr[i]+this._rowEnd;
					}else {
						htmlTxt[htmlTxt.length]=codeArr[i];
					}
				}
				//处理关键字
			}else if(!slash_slash_comment_opened&&!slash_star_comment_opened&&!quote_opened&&this.isBlockElement(codeArr[i])) {
				htmlTxt[htmlTxt.length]=codeArr[i];
				//处理内置对象(后面加一个空格)
			}else if(!slash_slash_comment_opened&&!slash_star_comment_opened&&!quote_opened&&this.isSingleEyeElement(codeArr[i])) {
				if(codeArr[i]==this._in) {
					htmlTxt[htmlTxt.length]=" ";
				}
				htmlTxt[htmlTxt.length]=codeArr[i]+" ";
				//处理双引号(引号前不能为转义字符)
			}else if(!slash_star_comment_opened&&!slash_slash_comment_opened&&this._quotation.contains(codeArr[i])) {
				if(quote_opened) {
					//是相应的引号
					if(quote_char==codeArr[i]) {
						htmlTxt[htmlTxt.length]=codeArr[i];
						quote_opened=false;
						quote_char="";
					}else {
						htmlTxt[htmlTxt.length]=codeArr[i];
					}
				}else {
					htmlTxt[htmlTxt.length]=codeArr[i];
					quote_opened=true;
					quote_char=codeArr[i];
				}
				//处理转义字符
			}else if(codeArr[i]==this._escape) {
				htmlTxt[htmlTxt.length]=codeArr[i];
				if(i<word_index-1) {
					if(codeArr[i+1].charCodeAt(0)>=32&&codeArr[i+1].charCodeAt(0)<=127) {
						htmlTxt[htmlTxt.length]=codeArr[i+1].substr(0,1);
						htmlTxt[htmlTxt.length]=codeArr[i+1].substr(1);
						i=i+1;
					}
				}
				//处理多行注释的开始
			}else if(!slash_slash_comment_opened&&!slash_star_comment_opened&&!quote_opened&&this.isStartWith(this._commentOn,codeArr,i)) {
				slash_star_comment_opened=true;
				if(!this._deleteComment) {
					htmlTxt[htmlTxt.length]=this._commentOn;
				}
				i=i+this.getSkipLength(this._commentOn);
				//处理单行注释
			}else if(!slash_slash_comment_opened&&!slash_star_comment_opened&&!quote_opened&&this.isStartWith(this._lineComment,codeArr,i)) {
				slash_slash_comment_opened=true;
				if(!this._deleteComment) {
					htmlTxt[htmlTxt.length]=this._lineComment;
				}
				i=i+this.getSkipLength(this._lineComment);
				//处理忽略词
			}else if(!slash_slash_comment_opened&&!slash_star_comment_opened&&!quote_opened&&this.isStartWith(this._ignore,codeArr,i)) {
				slash_slash_comment_opened=true;
				htmlTxt[htmlTxt.length]=this._ignore;
				i=i+this.getSkipLength(this._ignore);
				//处理多行注释结束
			}else if(!quote_opened&&!slash_slash_comment_opened&&this.isStartWith(this._commentOff,codeArr,i)) {
				if(slash_star_comment_opened) {
					slash_star_comment_opened=false;
					if(!this._deleteComment) {
						htmlTxt[htmlTxt.length]=this._commentOff;
					}
					i=i+this.getSkipLength(this._commentOff);
				}
			}else {
				//不是在字符串中
				if(!quote_opened) {
					//如果不是在注释重
					if(!slash_slash_comment_opened&&!slash_star_comment_opened) {
						htmlTxt[htmlTxt.length]=codeArr[i];
						//注释中
					}else {
						if(!this._deleteComment) {
							htmlTxt[htmlTxt.length]=codeArr[i];
						}
					}
				}else {
					htmlTxt[htmlTxt.length]=codeArr[i];
				}
			}
		}
		return htmlTxt.join("");
	}
	this.isStartWith=function (str,code,index) {
		if(typeof(str)!="undefined"&&str.length>0) {
			var cc=new Array();
			for(var i=index;i<index+str.length;i++) {
				cc[cc.length]=code[i];
			}
			var c=cc.join("");
			if(this._caseSensitive) {
				if(str.length>=code[index].length&&c.indexOf(str)==0) {
					return true;
				}
			}else {
				if(str.length>=code[index].length&&c.toLowerCase().indexOf(str.toLowerCase())==0) {
					return true;
				}
			}
			return false;
		}else {
			return false;
		}
	}
	this.isFunction=function (val) {
		return this._function.contains(this._caseSensitive?val:val.toLowerCase());
	}
	this.isBlockElement=function (val) {
		return this._blockElement.contains(this._caseSensitive?val:val.toLowerCase());
	}
	this.isChoiceElement=function (val) {
		return this._choiceElement.contains(this._caseSensitive?val:val.toLowerCase());
	}
	this.isSingleEyeElement=function (val) {
		return this._singleEyeElement.contains(this._caseSensitive?val:val.toLowerCase());
	}
	this.isNextElement=function (from,word) {
		for(var i=from;i<word.length;i++) {
			if(word[i]!=" "&&word[i]!="\t"&&word[i]!="\r"&&word[i]!="\n") {
				return this.isChoiceElement(word[i]);
			}
		}
		return false;
	}
	this.getSkipLength=function (val) {
		var count=0;
		for(var i=0;i<val.length;i++) {
			if(this._wordDelimiters.indexOf(val.charAt(i))>=0) {
				count++;
			}
		}
		if(count>0) {
			count=count-1;
		}
		return count;
	}
	this.getIdent=function () {		//添加字符缩进
		var n=[];
		for(var i=0;i<this._tabNum;i++) {
			n[n.length]="\t";				//缩进字符
		}
		return n.join("");
	}
}

function doformat(o) {
	var htmltxt="";
	if(o==null) {
		alert("domNode is null!");
		return ;
	}
	var _codetxt="";
	if(typeof(o)=="object") {
		switch(o.tagName) {
			case "TEXTAREA":
			case "INPUT":
			_codetxt=o.value;
			break;
			case "DIV":
			case "SPAN":
			_codetxt=o.innerText;
			break;
			default:
			_codetxt=o.innerHTML;
			break;
		}
	}else {
		_codetxt=o;
	}
	var _syn=new CLASS_FORMAT(_codetxt);
	htmltxt=_syn.format();
	return htmltxt;
}

function go()
{
	var code=document.getElementById("code").value;
	var xx=new CLASS_FORMAT(code);	
	var a=new Date();
	var code1;		//格式化之后对code 继续格式化

	if(document.getElementById('cboOperate').selectedIndex==1) {
		xx.isCompress=true;
	}else {
		xx.style=parseInt(document.getElementById('cboStyle').value);
	}
	code1=xx.format();
	code1=code1.replace(/\s*\n/g,'\n');		//去掉行尾的空白符号
	code1=code1.replace(/\n\n/g,'\n');			//去掉联系的两个空行
	code1=code1.replace(/\)\{/g,') {');			//在){之间加一个空格
	document.getElementById("display").value=code1;
	alert("格式化完成,共花:"+(new Date().getTime()-a.getTime())+"ms");
}
//-->
</script>
<textarea id="code">
/*
源代码写在这里
*/
</textarea>
<select id="cboOperate" 
onchange="if(this.selectedIndex==1)document.getElementById('cboStyle').disabled=true;
else document.getElementById('cboStyle').disabled=false;"><option value="0" selected>格式化</option><option value="1">压缩</option></select> 
<select id="cboStyle"><option value="0" selected>经典</option><option value="1">微软</option></select>
<input onclick="go()" type="button" value="go" />
  
<textarea id="display"></textarea>
</body>
</html>

评论(0)

暂无评论。

计算题
评论需审核通过后显示
← 上一篇 ActionScript的接口和类示例 下一篇 → IE中的条件注释