<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>JS格式化工具JS代碼轉換爲格式排版格式或壓縮格式</title>
<script type="text/javascript">
< !--
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>
</head>
<body>
<div style=" padding:10px;">
<h2 style="text-align:center; padding:5px;">
JS格式化工具—排版格式,JS壓縮
</h2>
<TEXTAREA style="width:98%; height:240px;" name="code" id=code></TEXTAREA>
<SELECT name="cboOperate" id=cboOperate οnchange="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 name="cboStyle" id=cboStyle>
<OPTION value=0 selected>經典</OPTION>
<OPTION value=1>微軟</OPTION>
</SELECT>
<INPUT οnclick=go() type=button value=轉換>
<TEXTAREA style="width:98%; height:240px;" name="display" id=display></TEXTAREA>
</div>
</body>
</html>