1 Jx().$package(function(J){
  2     var EventParser=J.Class({
  3         init: function() {
  4             var _this= this;
  5             this.op= [
  6                 {
  7                     ".": function(word,target) {
  8                         return target.className==word;
  9                     },
 10                     "+": function(word,target) {
 11                         return target.getAttribute(word);
 12                     },
 13                     "#": function(word,target) {
 14                         return target.id==word;
 15                     },
 16                     ".~": function(word,target) {
 17                         return $D.hasClass(target,word);
 18                     }
 19                 },
 20                 {
 21                     ">": function(word,e) {
 22                         var p,wordP,wordS,s;
 23                         s= word.split(">");
 24                         wordP= s[0];
 25                         wordS= s[1];
 26                         //通配符支持
 27                         if( (wordS=="*"?true:_this.match(wordS,e)) && 
 28                             (p= _this.operate(_this.detectAncestor, wordP, e)())) {//检测符合特征的祖先节点
 29                             return _this.packEvent(e, p);
 30                         }
 31                         return false;
 32                     }
 33                 },
 34                 {
 35                     "!": function(word,e) {
 36                         word= word.substr(1);
 37                         return !_this.match(word,e);
 38                     }
 39                 },
 40                 {
 41                     "&&": function(word,e) {
 42                         var wordL,wordR,s;
 43                         s= word.split("&&");
 44                         wordL= s[0];
 45                         wordR= s.slice(1).join("");
 46                         if(_this.match(wordL,e)) {
 47                             if(wordR.indexOf("&&")==-1) {
 48                                 return _this.match(wordR,e);
 49                             }else {
 50                                 return arguments.callee(wordR,e);
 51                             }
 52                         }
 53                         return false;
 54                     }
 55                 }
 56             ];
 57             //优先级从下往上递减,对应于this.op
 58             this.op2Level= [
 59                 [".","#","+",".~"],//第一级操作符
 60                 ">",//第二级操作符
 61                 "!",//第三级操作符
 62                 "&&"//第四级操作符
 63             ];
 64         },
 65         //寻找符合特征的祖先节点
 66         detectAncestor: function(word, e, func) {
 67             //if over 5...sorry.
 68             //I think you should never touch the limit.
 69             var max=5;
 70             var target= e.target;
 71             return function () {
 72                 if(func(word,target)) {
 73                     return target;
 74                 }else if(max>0) {
 75                     max--;
 76                     if(target.parentNode) {
 77                         target= target.parentNode;
 78                     }else {
 79                         max= 0;
 80                     }
 81                     return arguments.callee();
 82                 }
 83                 return null;
 84             }
 85         },
 86         //用于对target跟特征的匹配
 87         //因为e.target并不总是我们期待的target
 88         detect: function(word, e, func) {
 89             var target= e.target;
 90             if(target.nodeType!=1) {//ipad下总是发生
 91                 target= target.parentNode;
 92                 if(func(word,target)) {
 93                     return this.packEvent(e,target);
 94                 }
 95             }else {
 96                 return func(word,target);
 97             }
 98             return false;
 99         },
100         packEvent: function(e, target) {
101             return [true,
102                     {
103                         target: target,
104                         oTarget: e.target,
105                         stopPropagation: function(){
106                            e.stopPropagation();
107                         },
108                         preventDefault: function(){
109                             e.preventDefault();
110                         },
111                         pageX: e.pageX,
112                         pageY: e.pageY
113                     }
114             ];
115         },
116         operate: function(func,word,e) {
117             var p,
118                 i=3;//("..#").length=3 由长至短检查是否有对应的第一级操作符
119             while(i>0) {
120                 if(p= this.op[0][word.substr(0,i)]) {
121                     var result= null;
122                     if(result= func(word.substr(i),e,p)) {
123                         return result;
124                     }
125                 }
126                 i--;
127             }
128             return false;
129         },
130         //按照层级进行匹配
131         match: function(word,e) {
132             var p;
133             //level > 0
134             for(var len=this.op2Level.length;len>0;len--) { //这里稍耗性能
135                 var sig= this.op2Level[len];
136                 if(word.indexOf(sig) != -1 ) {
137                     return this.op[len][sig](word,e,p);
138                 }
139             }
140             //level 0
141             return this.operate(this.detect,word,e);
142         },
143         //拆解并列条件(并列条件以","号分隔)
144         router: function(story/* .aa,.~bb,#cc,.aa>.dd */,e/* event */,p) {
145             var words= story.split(",");
146             var result;
147             for(p= words.length-1;p>=0;p--) {
148                 if(result= this.match(words[p],e)) {
149                     return result;
150                 }
151             }
152             return false;
153         },
154         //总入口
155         parse: function(story,func,e) {
156             var result= this.router(story,e);
157             if(result.length==2) {
158                 func(result[1]);
159             }else if(result){
160                 func(e);
161             }
162         }
163     });
164     J.event.eventParser= new EventParser();
165 });
166