WEB开发网
开发学院网页设计JavaScript JS代码的格式化和压缩 阅读

JS代码的格式化和压缩

 2006-05-23 19:52:47 来源:WEB开发网   
核心提示:曾经为看别人写的杂乱代码而头痛吗?曾经为看BWindow代码而烦恼吗?曾经为减小JS体积和JS的可读性之间的矛盾而左右徘徊吗?最好的办法是有个代码格式化和代码压缩的程序,今天总算有了,它是纯JS编写的,当然也就是开源的了.不好意思,做个广告先:),老早就想写这个代码了,今天总算利用这个周末把它写完了,由于写的仓促,还有

曾经为看别人写的杂乱代码而头痛吗?曾经为看BWindow代码而烦恼吗?曾经为减小JS体积和JS的可读性之间的矛盾而左右徘徊吗?最好的办法是有个代码格式化和代码压缩的程序,今天总算有了,它是纯JS编写的,当然也就是开源的了.不好意思,做个广告先:),老早就想写这个代码了,今天总算利用这个周末把它写完了,由于写的仓促,还有些小BUG,请经常注意更新!


<HTML><HEAD><TITLE>Format</TITLE>
<META content="MSHTML 6.00.2800.1528" name=GENERATOR>
<META content="" name=Author>
<META content="" name=KeyWords>
<META content="" name=Description></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();

   if(document.getElementById('cboOperate').selectedIndex==1){
     xx.isCompress=true;
   }else{
     xx.style = parseInt(document.getElementById('cboStyle').value);
   }
   document.getElementById("display").value = xx.format();
   alert("共花:" + (new Date().getTime()-a.getTime()) + "ms");
}
//-->
</SCRIPT>
<TEXTAREA id=code rows=12 cols=100>
/*
这个是一个类
*/


function   xx  (num,str){//说明
var a = num;this.aa = a;
this.bb = function(){alert(str);}
this.cc = function(){for(var i=0;i<10;i++){document.title=i;}}};

xx.prototype.dd= function(){alert("d  d     kd");}

var a = new xx(100,"hello"),b=new xx(0,"ttyp");
if(1>2)  {  alert();
 }
 else {
 alert(" hell ");
 }

a.bb();
b.dd();
alert(a.aa);

</TEXTAREA> <BR>
<select id="cboOperate" >
   <option value="0">格式化</option>
   <option value="1">压缩</option>
</select>
<select id="cboStyle">
   <option value="0">经典</option>
   <option value="1">微软</option>
</select>
<INPUT onclick=go() type=button value=go><br>
<textarea id=display rows=12 cols=100>
</textarea>
</BODY></HTML>

Tags:JS 代码 格式化

编辑录入:爽爽 [复制链接] [打 印]
赞助商链接