diff --git a/avalon.js b/avalon.js index 53928681a..7f4beb80c 100644 --- a/avalon.js +++ b/avalon.js @@ -5,7 +5,7 @@ http://weibo.com/jslouvre/ Released under the MIT license - avalon 1.3.7 2014.11.17 support IE6+ and other browsers + avalon 1.3.7.2 2014.11.19 support IE6+ and other browsers ==================================================*/ (function(DOC) { /********************************************************************* @@ -1122,9 +1122,10 @@ } }, _remove: function(cls) { - this._set((" " + this + " ").replace(" " + cls + " ", " ").trim()) + this._set((" " + this + " ").replace(" " + cls + " ", " ")) }, __set: function(cls) { + cls = cls.trim() var node = this.node if (typeof node.className === "string") { node.className = cls @@ -1639,7 +1640,8 @@ legend: [1, "
"], option: [1, ""],thead:[1,"","
"],tr:[2,""],td:[3,"
"],g:[1,'',""],_default:w? -[0,""]:[1,"X
"]};E.optgroup=E.option;E.tbody=E.tfoot=E.colgroup=E.caption=E.thead;E.th=E.td;"circle,defs,ellipse,image,line,path,polygon,polyline,rect,symbol,text,use".replace(z,function(b){E[b]=E.g});var Rc=/<([\w:]+)/,Sc=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/ig,Qb=w?/[^\d\D]/:/(<(?:script|link|style|meta|noscript))/ig,Tc=M(["","text/javascript","text/ecmascript","application/ecmascript","application/javascript"]),Uc=/<(?:tb|td|tf|th|tr|col|opt|leg|cap|area)/, -Vc=p.createElement("script");avalon.parseHTML=function(b){"string"!==typeof b&&(b+="");b=b.replace(Sc,"<$1>").trim();var c=(Rc.exec(b)||["",""])[1].toLowerCase(),d=E[c]||E._default,e=I.cloneNode(!1),f=ea,g;w||(b=b.replace(Qb,"
$1"));f.innerHTML=d[1]+b+(d[2]||"");b=f.getElementsByTagName("script");if(b.length)for(var h=0,k;k=b[h++];)Tc[k.type]&&(g=Vc.cloneNode(!1),L.forEach.call(k.attributes,function(b){b&&b.specified&&(g[b.name]=b.value,g.setAttribute(b.name,b.value))}),g.text= -k.text,k.parentNode.replaceChild(g,k));for(h=d[0];h--;f=f.lastChild);if(!w){b=f.getElementsByTagName("br");for(h=0;k=b[h++];)k.className&&"msNoScope"===k.className&&(k.parentNode.removeChild(k),h--);b=f.all;for(h=0;k=b[h++];)gb(k)&&bc(k);if("tr"===c){b=f.children;for(h=0;k=b[h++];)""==k.nodeName&&(k.parentNode.removeChild(k),h--)}}for(;c=f.firstChild;)e.appendChild(c);return e};avalon.innerHTML=function(b,c){if(!w&&!Qb.test(c)&&!Uc.test(c))try{b.innerHTML=c;return}catch(d){}var e=this.parseHTML(c); -this.clearHTML(b).appendChild(e)};avalon.clearHTML=function(b){for(b.textContent="";b.firstChild;)b.removeChild(b.firstChild);return b};var R={$watch:function(b,c){if("function"===typeof c){var d=this.$events[b];d?d.push(c):this.$events[b]=[c]}else this.$events=this.$watch.backup;return this},$unwatch:function(b,c){var d=arguments.length;if(0===d)this.$watch.backup=this.$events,this.$events={};else if(1===d)this.$events[b]=[];else for(var d=this.$events[b]||[],e=d.length;0>~--e;)if(d[e]===c)return d.splice(e, -1);return this},$fire:function(b){var c;/^(\w+)!(\S+)$/.test(b)&&(c=RegExp.$1,b=RegExp.$2);var d=this.$events,e=$.call(arguments,1),f=[b].concat(e);if("all"===c)for(var g in avalon.vmodels)e=avalon.vmodels[g],e!==this&&e.$fire.apply(e,f);else if("up"===c||"down"===c){if(d=d.expr&&Rb(d.expr)){for(g in avalon.vmodels)if(e=avalon.vmodels[g],e!==this&&e.$events.expr){var h=Rb(e.$events.expr);if(h&&("down"===c?d.contains(h):h.contains(d)))h._avalon=e}g=p.getElementsByTagName("*");var k=[];Array.prototype.forEach.call(g, -function(b){b._avalon&&(k.push(b._avalon),b._avalon="",b.removeAttribute("_avalon"))});"up"===c&&k.reverse();for(g=0;(c=k[g++])&&!1!==c.$fire.apply(c,f););}}else{f=d[b]||[];c=d.$all||[];for(g=0;d=f[g++];)V(d)&&d.apply(this,e);for(g=0;d=c[g++];)V(d)&&d.apply(this,arguments)}}},Wc=/(\w+)\[(avalonctrl)="(\S+)"\]/,Rb=p.querySelector?function(b){return p.querySelector(b)}:function(b){b=b.match(Wc);for(var c=p.getElementsByTagName(b[1]),d=0,e;e=c[d++];)if(e.getAttribute(b[2])===b[3])return e},cc=/^(duplex|on)$/, -S=[],za=0,dc=200,jb=new Date,kb,Oa={};avalon.scanCallback=function(b,c){c=c||"$all";(Oa[c]||(Oa[c]=[])).push(b)};avalon.scan=function(b,c,d){b=b||B;var e=Oa[d||"$all"]||[];c=c?[].concat(c):[];var f=0,g=!1,h,k=!1;c.cb=function(b){f+=b;k=!0;setTimeout(function(){if(0>=f&&!g)for(g=!0;h=e.shift();)h()})};lb(b,c);if(!k)for(;h=e.shift();)h()};var hc=M("AREA,BASE,BASEFONT,BR,COL,COMMAND,EMBED,HR,IMG,INPUT,LINK,META,PARAM,SOURCE,TRACK,WBR,NOSCRIPT,SCRIPT,STYLE,TEXTAREA"),tb=/ms-(\w+)-?(.*)/,ub={"if":10,repeat:90, -data:100,widget:110,each:1400,"with":1500,duplex:2E3,on:3E3},fc=M("animationend,blur,change,input,click,dblclick,focus,keydown,keypress,keyup,mousedown,mouseenter,mouseleave,mousemove,mouseout,mouseover,mouseup,scan,scroll,submit"),gc=M("value,title,alt,checked,selected,disabled,readonly,enabled");if(!"1"[0])var Pa=Da(512),Xc=/\s+(ms-[^=\s]+)(?:=("[^"]*"|'[^']*'|[^\s>]+))?/g,Yc=/^['"]/,Zc=/<\w+\b(?:(["'])[^"]*?(\1)|[^>])*>/i,$c=/&/g,sb=function(b){b=b.outerHTML;if(""],param:[1,""],col:[2,"
","
"],legend:[1,"
"],option:[1,"\u4e0d\u80fd\u5bf9\u5e94\u4e00\u4e2a\u6570\u7ec4");d=Array.isArray(d)?d.map(String):d+"";d+""!==b.oldValue&&(e.val(d), -b.oldValue=d+"")};d.bound("change",function(){if(!1!==e.data("duplex-observe")){var f=e.val(),f=Array.isArray(f)?f.map(function(b){return d.pipe(b,d,"get")}):d.pipe(f,d,"get");f+""!==b.oldValue&&c(f);d.changed.call(b,f,d)}});qa(b,function(){ya(d);d.changed.call(b,c(),d)},NaN)};X.TEXTAREA=X.INPUT;var ga=avalon.eventHooks;"onmouseenter"in B||avalon.each({mouseenter:"mouseover",mouseleave:"mouseout"},function(b,c){ga[b]={type:c,deel:function(c,e){return function(f){var g=f.relatedTarget;if(!g||g!==c&& -!(c.compareDocumentPosition(g)&16))return delete f.type,f.type=b,e.call(c,f)}}}});avalon.each({AnimationEvent:"animationend",WebKitAnimationEvent:"webkitAnimationEnd"},function(b,c){r[b]&&!ga.animationend&&(ga.animationend={type:c})});"oninput"in p.createElement("input")||(ga.input={type:"propertychange",deel:function(b,c){return function(d){if("value"===d.propertyName)return d.type="input",c.call(b,d)}}});if(void 0===p.onmousewheel){var Ub=void 0!==p.onwheel?"wheel":"DOMMouseScroll",id="wheel"=== -Ub?"deltaY":"detail";ga.mousewheel={type:Ub,deel:function(b,c){return function(d){d.wheelDeltaY=d.wheelDelta=0]*>([\S\s]*?)<\/script\s*>/gim,kd=/\s+(on[^=\s]+)(?:=("[^"]*"|'[^']*'|[^\s>]+))?/g,ld=/<\w+\b(?:(["'])[^"]*?(\1)|[^>])*>/ig,md={a:/\b(href)\=("javascript[^"]*"|'javascript[^']*')/ig,img:/\b(src)\=("javascript[^"]*"|'javascript[^']*')/ig,form:/\b(action)\=("javascript[^"]*"|'javascript[^']*')/ig}, +typeof l[d]){var m=l[d],m=m.$model||m;break}m&&(k=m[f+"Id"],"string"===typeof k&&(g=k));k=avalon.getWidgetData(e,f);b.value=[f,g,d].join();b[f+"Id"]=g;b.evaluator=y;e.msData["ms-widget-id"]=g;var n=b[f+"Options"]=avalon.mix({},h.defaults,m||{},k);e.removeAttribute("ms-widget");var q=h(e,b,c)||{};if(q.$id){if(avalon.vmodels[g]=q,mb(e,q),q.hasOwnProperty("$init")&&q.$init(function(){var b=[q].concat(c);b.cb=c.cb;avalon.scan(e,b);"function"===typeof n.onInit&&n.onInit.call(e,q,n,c)}),q.hasOwnProperty("$remove")){var p= +function(){if(!e.msRetain&&!B.contains(e))return q.$remove(),e.msData={},delete ra[q.$id],!1};r.chrome?e.addEventListener("DOMNodeRemovedFromDocument",function(){setTimeout(p)}):avalon.tick(p)}}else avalon.scan(e,c)}else c.length&&(e.vmodels=c)}};"hover,active".replace(z,function(b){C[b]=C["class"]});"with,each".replace(z,function(b){C[b]=C.repeat});C["if"]=C.data=C.text=C.html;"title,alt,src,value,css,include,href".replace(z,function(b){C[b]=C.attr});var X=C.duplex;avalon.duplexHooks={checked:{get:function(b, +c){return!c.element.oldValue}},string:{get:function(b){return b},set:Ga},"boolean":{get:function(b){return"true"===b},set:Ga},number:{get:function(b){return isFinite(b)?parseFloat(b)||0:b},set:Ga}};X.INPUT=function(b,c,d){function e(b){d.changed.call(this,b,d)}function f(){n=!0}function g(){n=!1}function h(){if(!n){var f=b.oldValue=b.value,f=d.pipe(f,d,"get");!1!==m.data("duplex-observe")&&(c(f),e.call(b,f),m.data("duplex-focus")&&avalon.nextTick(function(){b.focus()}))}}var k=b.type,l=d.bound,m= +avalon(b),n=!1;d.handler=function(){var e=d.pipe(c(),d,"set");e!==b.value&&(b.value=e)};if(d.isChecked||"radio"===b.type){var q=!r.XMLHttpRequest,h=function(){if(!1!==m.data("duplex-observe")){var f=d.pipe(b.value,d,"get");c(f);e.call(b,f)}};d.handler=function(){var e=c(),f=d.isChecked?!!e:e+""===b.value;b.oldValue=f;q?setTimeout(function(){b.defaultChecked=f;b.checked=f},100):b.checked=f};l(q?"mouseup":"click",h)}else if("checkbox"===k)h=function(){if(!1!==m.data("duplex-observe")){var f=b.checked? +"ensure":"remove",g=c();Array.isArray(g)||(v("ms-duplex\u5e94\u7528\u4e8echeckbox\u4e0a\u8981\u5bf9\u5e94\u4e00\u4e2a\u6570\u7ec4"),g=[g]);avalon.Array[f](g,d.pipe(b.value,d,"get"));e.call(b,g)}},d.handler=function(){var e=[].concat(c());b.checked=0<=e.indexOf(d.pipe(b.value,d,"get"))},l(w?"change":"click",h);else{k=b.getAttribute("data-duplex-event")||b.getAttribute("data-event")||"input";b.attributes["data-event"]&&v("data-event\u6307\u4ee4\u5df2\u7ecf\u5e9f\u5f03\uff0c\u8bf7\u6539\u7528data-duplex-event"); +var t=function(b){setTimeout(function(){h(b)})};k.replace(z,function(b){switch(b){case "input":w?(l("input",h),l("compositionstart",f),l("compositionend",g),9===p.documentMode&&(l("paste",t),l("cut",t))):l("propertychange",function(b){"value"===b.propertyName&&h()});break;default:l(b,h)}})}b.oldValue=b.value;Tb(function(){if(avalon.contains(B,b))yb.call(b);else if(!b.msRetain)return!1});ya(d);e.call(b,b.value)};var zb,ca=[],Tb=y;avalon.tick=function(b){1===ca.push(b)&&(zb=setInterval(tc,60))};try{var Va= +HTMLInputElement.prototype;Object.getOwnPropertyNames(Va);var vc=Object.getOwnPropertyDescriptor(Va,"value").set;Object.defineProperty(Va,"value",{set:uc})}catch(qd){Tb=avalon.tick}X.SELECT=function(b,c,d){var e=avalon(b);d.handler=function(){var d=c(),d=d&&d.$model||d;Array.isArray(d)?b.multiple||v("ms-duplex\u5728\u4e0d\u80fd\u5bf9\u5e94\u4e00\u4e2a\u6570\u7ec4");d= +Array.isArray(d)?d.map(String):d+"";d+""!==b.oldValue&&(e.val(d),b.oldValue=d+"")};d.bound("change",function(){if(!1!==e.data("duplex-observe")){var f=e.val(),f=Array.isArray(f)?f.map(function(b){return d.pipe(b,d,"get")}):d.pipe(f,d,"get");f+""!==b.oldValue&&c(f);d.changed.call(b,f,d)}});qa(b,function(){ya(d);d.changed.call(b,c(),d)},NaN)};X.TEXTAREA=X.INPUT;var ga=avalon.eventHooks;"onmouseenter"in B||avalon.each({mouseenter:"mouseover",mouseleave:"mouseout"},function(b,c){ga[b]={type:c,deel:function(c, +e){return function(f){var g=f.relatedTarget;if(!g||g!==c&&!(c.compareDocumentPosition(g)&16))return delete f.type,f.type=b,e.call(c,f)}}}});avalon.each({AnimationEvent:"animationend",WebKitAnimationEvent:"webkitAnimationEnd"},function(b,c){r[b]&&!ga.animationend&&(ga.animationend={type:c})});"oninput"in p.createElement("input")||(ga.input={type:"propertychange",deel:function(b,c){return function(d){if("value"===d.propertyName)return d.type="input",c.call(b,d)}}});if(void 0===p.onmousewheel){var Ub= +void 0!==p.onwheel?"wheel":"DOMMouseScroll",id="wheel"===Ub?"deltaY":"detail";ga.mousewheel={type:Ub,deel:function(b,c){return function(d){d.wheelDeltaY=d.wheelDelta=0]*>([\S\s]*?)<\/script\s*>/gim,kd=/\s+(on[^=\s]+)(?:=("[^"]*"|'[^']*'|[^\s>]+))?/g,ld=/<\w+\b(?:(["'])[^"]*?(\1)|[^>])*>/ig,md={a:/\b(href)\=("javascript[^"]*"|'javascript[^']*')/ig,img:/\b(src)\=("javascript[^"]*"|'javascript[^']*')/ig,form:/\b(action)\=("javascript[^"]*"|'javascript[^']*')/ig}, nd=/[\uD800-\uDBFF][\uDC00-\uDFFF]/g,od=/([^\#-~| |!])/g,Xa=avalon.filters={uppercase:function(b){return b.toUpperCase()},lowercase:function(b){return b.toLowerCase()},truncate:function(b,c,d){c=c||30;d=void 0===d?"...":d;return b.length>c?b.slice(0,c-d.length)+d:String(b)},camelize:oa,sanitize:function(b){return b.replace(jd,"").replace(ld,function(b,d){var e=b.toLowerCase().match(/<(\w+)\s/);e&&(e=md[e[1]])&&(b=b.replace(e,function(b,c,d){b=d.charAt(0);return c+"="+b+"javascript:void(0)"+b}));return b.replace(kd, " ").replace(/\s+/g," ")})},escape:function(b){return String(b).replace(/&/g,"&").replace(nd,function(b){var d=b.charCodeAt(0);b=b.charCodeAt(1);return"&#"+(1024*(d-55296)+(b-56320)+65536)+";"}).replace(od,function(b){return"&#"+b.charCodeAt(0)+";"}).replace(//g,">")},currency:function(b,c){return(c||"\uffe5")+avalon.filters.number(b)},number:function(b,c,d,e){b=(b+"").replace(/[^0-9+\-Ee.]/g,"");b=!isFinite(+b)?0:+b;c=!isFinite(+c)?0:Math.abs(c);e=e||",";d=d||".";var f= "",f=function(b,c){var d=Math.pow(10,c);return""+Math.round(b*d)/d},f=(c?f(b,c):""+Math.round(b)).split(".");3b&&(e="-",b=-b);for(b=""+b;b.length-e)g+=e;0===g&&-12===e&&(g=12);return b(g, d,f)}}function d(b,c){return function(d,e){var f=d["get"+b](),g=(c?"SHORT"+b:b).toUpperCase();return e[g][f]}}function e(b){var c;if(c=b.match(k)){b=new Date(0);var d=0,e=0,f=c[8]?b.setUTCFullYear:b.setFullYear,g=c[8]?b.setUTCHours:b.setHours;c[9]&&(d=parseInt(c[9]+c[10],10),e=parseInt(c[9]+c[11],10));f.call(b,parseInt(c[1],10),parseInt(c[2],10)-1,parseInt(c[3],10));d=parseInt(c[4]||0,10)-d;e=parseInt(c[5]||0,10)-e;f=parseInt(c[6]||0,10);c=Math.round(1E3*parseFloat("0."+(c[7]||0)));g.call(b,d,e,f, c)}return b}var f={yyyy:c("FullYear",4),yy:c("FullYear",2,0,!0),y:c("FullYear",1),MMMM:d("Month"),MMM:d("Month",!0),MM:c("Month",2,1),M:c("Month",1,1),dd:c("Date",2),d:c("Date",1),HH:c("Hours",2),H:c("Hours",1),hh:c("Hours",2,-12),h:c("Hours",1,-12),mm:c("Minutes",2),m:c("Minutes",1),ss:c("Seconds",2),s:c("Seconds",1),sss:c("Milliseconds",3),EEEE:d("Day"),EEE:d("Day",!0),a:function(b,c){return 12>b.getHours()?c.AMPMS[0]:c.AMPMS[1]},Z:function(c){c=-1*c.getTimezoneOffset();return c=(0<=c?"+":"")+(b(Math[0< -c?"floor":"ceil"](c/60),2)+b(Math.abs(c%60),2))}},g=/((?:[^yMdHhmsaZE']+)|(?:'(?:[^']|'')*')|(?:E+|y+|M+|d+|H+|h+|m+|s+|a|Z))(.*)/,h=/^\d+$/,k=/^(\d{4})-?(\d\d)-?(\d\d)(?:T(\d\d)(?::?(\d\d)(?::?(\d\d)(?:\.(\d+))?)?)?(Z|([+-])(\d\d):?(\d\d))?)?$/,l=/^(\d+)\D(\d+)\D(\d+)/;Xa.date=function(b,c){var d=Xa.date.locate,k="",F=[],ua,m;c=c||"mediumDate";c=d[c]||c;"string"===typeof b&&(h.test(b)?b=parseInt(b,10):(b=b.trim().replace(l,function(b,c,d,e){return(4===e.length?[e,c,d]:[c,d,e]).join("/")}),b=e(b)), -b=new Date(b));"number"===typeof b&&(b=new Date(b));if("date"===avalon.type(b)){for(;c;)(m=g.exec(c))?(F=F.concat(m.slice(1)),c=F.pop()):(F.push(c),c=null);F.forEach(function(c){ua=f[c];k+=ua?ua(b,d):c.replace(/(^'|'$)/g,"").replace(/''/g,"'")});return k}};var m={AMPMS:{"0":"\u4e0a\u5348",1:"\u4e0b\u5348"},DAY:{"0":"\u661f\u671f\u65e5",1:"\u661f\u671f\u4e00",2:"\u661f\u671f\u4e8c",3:"\u661f\u671f\u4e09",4:"\u661f\u671f\u56db",5:"\u661f\u671f\u4e94",6:"\u661f\u671f\u516d"},MONTH:{"0":"1\u6708",1:"2\u6708", -2:"3\u6708",3:"4\u6708",4:"5\u6708",5:"6\u6708",6:"7\u6708",7:"8\u6708",8:"9\u6708",9:"10\u6708",10:"11\u6708",11:"12\u6708"},SHORTDAY:{"0":"\u5468\u65e5",1:"\u5468\u4e00",2:"\u5468\u4e8c",3:"\u5468\u4e09",4:"\u5468\u56db",5:"\u5468\u4e94",6:"\u5468\u516d"},fullDate:"y\u5e74M\u6708d\u65e5EEEE",longDate:"y\u5e74M\u6708d\u65e5",medium:"yyyy-M-d ah:mm:ss",mediumDate:"yyyy-M-d",mediumTime:"ah:mm:ss","short":"yy-M-d ah:mm",shortDate:"yy-M-d",shortTime:"ah:mm"};m.SHORTMONTH=m.MONTH;Xa.date.locate=m};var s= -avalon.modules={"ready!":{exports:avalon},avalon:{exports:avalon,state:2}};new function(){function b(b){return(b||"").replace(/[?#].*/,"")}function c(b){var c;try{a.b.c()}catch(d){c=d.stack,!c&&r.opera&&(c=(String(d).match(/of linked script \S+/g)||[]).join(" "))}if(c)return c=c.split(/[@ ]/g).pop(),c="("===c[0]?c.slice(1,-1):c.replace(/\s/,""),c.replace(/(:\d+)?:\d+$/i,"");c=(b?p:J).getElementsByTagName("script");for(var e=c.length,f;f=c[--e];)if((b||f.className===G)&&"interactive"===f.readyState)return f.className= +c?"floor":"ceil"](c/60),2)+b(Math.abs(c%60),2))}},g=/((?:[^yMdHhmsaZE']+)|(?:'(?:[^']|'')*')|(?:E+|y+|M+|d+|H+|h+|m+|s+|a|Z))(.*)/,h=/^\d+$/,k=/^(\d{4})-?(\d+)-?(\d+)(?:T(\d+)(?::?(\d+)(?::?(\d+)(?:\.(\d+))?)?)?(Z|([+-])(\d+):?(\d+))?)?$/,l=/^(\d+)\D(\d+)\D(\d+)/;Xa.date=function(b,c){var d=Xa.date.locate,k="",F=[],ua,m;c=c||"mediumDate";c=d[c]||c;"string"===typeof b&&(h.test(b)?b=parseInt(b,10):(b=b.trim().replace(l,function(b,c,d,e){return(4===e.length?[e,c,d]:[c,d,e]).join("-")}),b=e(b)),b=new Date(b)); +"number"===typeof b&&(b=new Date(b));if("date"===avalon.type(b)){for(;c;)(m=g.exec(c))?(F=F.concat(m.slice(1)),c=F.pop()):(F.push(c),c=null);F.forEach(function(c){ua=f[c];k+=ua?ua(b,d):c.replace(/(^'|'$)/g,"").replace(/''/g,"'")});return k}};var m={AMPMS:{"0":"\u4e0a\u5348",1:"\u4e0b\u5348"},DAY:{"0":"\u661f\u671f\u65e5",1:"\u661f\u671f\u4e00",2:"\u661f\u671f\u4e8c",3:"\u661f\u671f\u4e09",4:"\u661f\u671f\u56db",5:"\u661f\u671f\u4e94",6:"\u661f\u671f\u516d"},MONTH:{"0":"1\u6708",1:"2\u6708",2:"3\u6708", +3:"4\u6708",4:"5\u6708",5:"6\u6708",6:"7\u6708",7:"8\u6708",8:"9\u6708",9:"10\u6708",10:"11\u6708",11:"12\u6708"},SHORTDAY:{"0":"\u5468\u65e5",1:"\u5468\u4e00",2:"\u5468\u4e8c",3:"\u5468\u4e09",4:"\u5468\u56db",5:"\u5468\u4e94",6:"\u5468\u516d"},fullDate:"y\u5e74M\u6708d\u65e5EEEE",longDate:"y\u5e74M\u6708d\u65e5",medium:"yyyy-M-d ah:mm:ss",mediumDate:"yyyy-M-d",mediumTime:"ah:mm:ss","short":"yy-M-d ah:mm",shortDate:"yy-M-d",shortTime:"ah:mm"};m.SHORTMONTH=m.MONTH;Xa.date.locate=m};var s=avalon.modules= +{"ready!":{exports:avalon},avalon:{exports:avalon,state:2}};new function(){function b(b){return(b||"").replace(/[?#].*/,"")}function c(b){var c;try{a.b.c()}catch(d){c=d.stack,!c&&r.opera&&(c=(String(d).match(/of linked script \S+/g)||[]).join(" "))}if(c)return c=c.split(/[@ ]/g).pop(),c="("===c[0]?c.slice(1,-1):c.replace(/\s/,""),c.replace(/(:\d+)?:\d+$/i,"");c=(b?p:J).getElementsByTagName("script");for(var e=c.length,f;f=c[--e];)if((b||f.className===G)&&"interactive"===f.readyState)return f.className= f.src}function d(b,c){for(var e in b)if("\u53f8\u5f92\u6b63\u7f8e"===b[e]&&2!==s[e].state&&(e===c||d(s[e].deps,c)))return!0}function e(){var b=l.length,c;a:for(;c=l[--b];){c=s[c];var d=c.deps,f;for(f in d)if(O.call(d,f)&&2!==s[f].state)continue a;2!==c.state&&(l.splice(b,1),k(c.id,c.args,c.factory),e())}}function f(c,d,e){var f=b(c.src);c.onload=c.onreadystatechange=c.onerror=null;if(d||e&&!s[f].state)setTimeout(function(){J.removeChild(c);c=null}),v("debug: \u52a0\u8f7d "+f+" \u5931\u8d25"+d+" "+ !s[f].state);else return!0}function g(c,d,e,f){if("ready!"===c||s[c]&&2===s[c].state)return c;var g;c=c.replace(/^\w+!/,function(b){g=b.slice(0,-1);return""});g=g||"js";g=U[g]||y;"object"===typeof u.shim[c]&&(f=u.shim[c]);u.paths[c]&&(c=u.paths[c]);if(/^(\w+)(\d)?:.*/.test(c))e=c;else{d=d.substr(0,d.lastIndexOf("/"));var h=c.charAt(0);if("."!==h&&"/"!==h)e=n+c;else if("./"===c.slice(0,2))e=d+c.slice(1);else if(".."===c.slice(0,2))for(e=d+"/"+c;t.test(e);)e=e.replace(t,"");else"/"===h?e=c:avalon.error("\u4e0d\u7b26\u5408\u6a21\u5757\u6807\u8bc6\u89c4\u5219: "+ c)}c=b(e);(d=g.ext)&&c.slice(0-d.length)!==d&&(e+=d);u.nocache&&(e+=(-1===e.indexOf("?")?"?":"&")+(new Date-0));return g(e,f)}function h(b,c,d){var e=p.createElement("script");e.className=G;e[w?"onload":"onreadystatechange"]=function(){if(w||/loaded|complete/i.test(e.readyState)){var g=m.pop();g&&g.delay(c);d&&d();f(e,!1,!w)&&v("debug: \u5df2\u6210\u529f\u52a0\u8f7d "+b)}};e.onerror=function(){f(e,!0)};e.src=b;J.insertBefore(e,J.firstChild);v("debug: \u6b63\u51c6\u5907\u52a0\u8f7d "+b)}function k(b, diff --git a/avalon.modern.js b/avalon.modern.js index fa26893fe..685ddfb60 100644 --- a/avalon.modern.js +++ b/avalon.modern.js @@ -5,7 +5,7 @@ http://weibo.com/jslouvre/ Released under the MIT license - avalon 1.3.7 2014.11.17 support IE10 and other latest browsers + avalon 1.3.7.2 2014.11.19 support IE10 and other latest browsers ==================================================*/ (function(DOC) { var expose = Date.now() @@ -1501,7 +1501,7 @@ if (typeof a === "string") { return } else if (node = b || c) { - var newVmodel = VMODELS[node.value] + var newVmodel = avalon.vmodels[node.value] if (!newVmodel) { return } @@ -1798,6 +1798,7 @@ for (var i = vars.length, prop; prop = vars[--i]; ) { if (scope.hasOwnProperty(prop)) { ret.push(prop + prefix + prop) + data.vars.push(prop) if (data.type === "duplex") { vars.get = name + "." + prop } @@ -1839,6 +1840,7 @@ function parseExpr(code, scopes, data) { var dataType = data.type + var isDuplex = dataType === "duplex" var filters = data.filters ? data.filters.join("") : "" var exprId = scopes.map(function(el) { return el.$id.replace(rproxy, "$1") @@ -1848,6 +1850,7 @@ names = [], args = [], prefix = "" + data.vars = [] //args 是一个对象数组, names 是将要生成的求值函数的参数 scopes = uniqSet(scopes) for (var i = 0, sn = scopes.length; i < sn; i++) { @@ -1858,9 +1861,36 @@ assigns.push.apply(assigns, addAssign(vars, scopes[i], name, data)) } } - if (!assigns.length && dataType === "duplex") { + if (!assigns.length && isDuplex) { return } + if (!isDuplex && (code.indexOf("||") > -1 || code.indexOf("&&") > -1)) { + //https://github.com/RubyLouvre/avalon/issues/583 + data.vars.forEach(function(v) { + var reg = new RegExp("\\b" + v + "(?:\\.\\w+|\\[\\w+\\])+", "ig") + code = code.replace(reg, function(_) { + var c = _.charAt(v.length) + var method = /^\s*\(/.test(RegExp.rightContext) + if (c === "." || c === "[" || method) {//比如v为aa,我们只匹配aa.bb,aa[cc],不匹配aaa.xxx + var name = "var" + String(Math.random()).replace(/^0\./, "") + if (method) {//array.size() + var array = _.split(".") + if (array.length > 2) { + var last = array.pop() + assigns.push(name + " = " + array.join(".")) + return name + "." + last + } else { + return _ + } + } + assigns.push(name + " = " + _) + return name + } else { + return _ + } + }) + }) + } //---------------args---------------- if (filters) { args.push(avalon.filters) @@ -1896,7 +1926,7 @@ code = textBuffer.join("") code += "\nreturn ret" + expose names.push("filters" + expose) - } else if (dataType === "duplex") { //双工绑定 + } else if (isDuplex) { //双工绑定 var _body = "'use strict';\nreturn function(vvv){\n\t" + prefix + ";\n\tif(!arguments.length){\n\t\treturn " + @@ -1946,9 +1976,6 @@ parseExpr(code, scopes, data) if (data.evaluator && !noregister) { data.handler = bindingExecutors[data.handlerName || data.type] - data.evaluator.toString = function() { - return data.type + " binding to eval(" + code + ")" - } //方便调试 //这里非常重要,我们通过判定视图刷新函数的element是否在DOM树决定 //将它移出订阅者列表 @@ -2419,54 +2446,54 @@ }, "duplex": function(data, vmodels) { var elem = data.element, - tagName = elem.tagName, hasCast + hasCast parseExprProxy(data.value, vmodels, data, 0, 1) - if (typeof duplexBinding[tagName] === "function") { - data.changed = getBindingCallback(elem, "data-duplex-changed", vmodels) || noop - if (data.evaluator && data.args) { - var params = [] - var casting = oneObject("string,number,boolean,checked") - if (elem.type === "radio" && data.param === "") { - data.param = "checked" + + data.changed = getBindingCallback(elem, "data-duplex-changed", vmodels) || noop + if (data.evaluator && data.args) { + var params = [] + var casting = oneObject("string,number,boolean,checked") + if (elem.type === "radio" && data.param === "") { + data.param = "checked" + } + data.param.replace(/\w+/g, function(name) { + if (/^(checkbox|radio)$/.test(elem.type) && /^(radio|checked)$/.test(name)) { + log("ms-duplex-radio已经更名为ms-duplex-checked") + name = "checked" + data.isChecked = true } - data.param.replace(/\w+/g, function(name) { - if (/^(checkbox|radio)$/.test(elem.type) && /^(radio|checked)$/.test(name)) { - log("ms-duplex-radio已经更名为ms-duplex-checked") - name = "checked" - data.isChecked = true - } - if (name === "bool") { - name = "boolean" - log("ms-duplex-bool已经更名为ms-duplex-boolean") - } else if (name === "text") { - name = "string" - log("ms-duplex-text已经更名为ms-duplex-string") - } - if (casting[name]) { - hasCast = true - } - avalon.Array.ensure(params, name) - }) - if (!hasCast) { - params.push("string") + if (name === "bool") { + name = "boolean" + log("ms-duplex-bool已经更名为ms-duplex-boolean") + } else if (name === "text") { + name = "string" + log("ms-duplex-text已经更名为ms-duplex-string") } - data.param = params.join("-") - data.bound = function(type, callback) { - elem.addEventListener(type, callback) - var old = data.rollback - data.rollback = function() { - elem.removeEventListener(type, callback) - old && old() - } + if (casting[name]) { + hasCast = true } - for (var i in avalon.vmodels) { - var v = avalon.vmodels[i] - v.$fire("avalon-ms-duplex-init", data) + avalon.Array.ensure(params, name) + }) + if (!hasCast) { + params.push("string") + } + data.param = params.join("-") + data.bound = function(type, callback) { + elem.addEventListener(type, callback) + var old = data.rollback + data.rollback = function() { + elem.removeEventListener(type, callback) + old && old() } - var cpipe = data.pipe || (data.pipe = pipe) - cpipe(null, data, "init") - duplexBinding[elem.tagName](elem, data.evaluator.apply(null, data.args), data) } + for (var i in avalon.vmodels) { + var v = avalon.vmodels[i] + v.$fire("avalon-ms-duplex-init", data) + } + var cpipe = data.pipe || (data.pipe = pipe) + cpipe(null, data, "init") + var tagName = elem.tagName + duplexBinding[tagName] && duplexBinding[tagName](elem, data.evaluator.apply(null, data.args), data) } }, "repeat": function(data, vmodels) { @@ -2637,6 +2664,7 @@ var widgetData = avalon.getWidgetData(elem, widget) data.value = [widget, id, optName].join(",") data[widget + "Id"] = id + elem.msData["ms-widget-id"] = id data.evaluator = noop var options = data[widget + "Options"] = avalon.mix({}, constructor.defaults, vmOptions || {}, widgetData) elem.removeAttribute("ms-widget") @@ -3007,6 +3035,7 @@ for (var i in EventManager) { array[i] = EventManager[i] } + avalon.mix(array, CollectionPrototype) return array } @@ -3018,6 +3047,9 @@ _fire: function(method, a, b) { notifySubscribers(this.$events[subscribers], method, a, b) }, + size: function() { //取得数组长度,这个函数可以同步视图,length不能 + return this._.length + }, _add: function(arr, pos) { var oldLength = this.length pos = typeof pos === "number" ? pos : oldLength @@ -3093,9 +3125,6 @@ contains: function(el) { //判定是否包含 return this.indexOf(el) !== -1 }, - size: function() { //取得数组长度,这个函数可以同步视图,length不能 - return this._.length - }, remove: function(el) { //移除第一个等于给定值的元素 return this.removeAt(this.indexOf(el)) }, @@ -3287,6 +3316,9 @@ proxy[k] = source[k] } eachProxyPool.splice(i, 1) + proxy.$watch(param, function(val) { + data.$repeat.set(proxy.$index, val) + }) return proxy } } @@ -3518,12 +3550,12 @@ } var DATE_FORMATS_SPLIT = /((?:[^yMdHhmsaZE']+)|(?:'(?:[^']|'')*')|(?:E+|y+|M+|d+|H+|h+|m+|s+|a|Z))(.*)/, NUMBER_STRING = /^\d+$/ - var R_ISO8601_STR = /^(\d{4})-?(\d\d)-?(\d\d)(?:T(\d\d)(?::?(\d\d)(?::?(\d\d)(?:\.(\d+))?)?)?(Z|([+-])(\d\d):?(\d\d))?)?$/ + var riso8601= /^(\d{4})-?(\d+)-?(\d+)(?:T(\d+)(?::?(\d+)(?::?(\d+)(?:\.(\d+))?)?)?(Z|([+-])(\d+):?(\d+))?)?$/ // 1 2 3 4 5 6 7 8 9 10 11 function jsonStringToDate(string) { var match - if (match = string.match(R_ISO8601_STR)) { + if (match = string.match(riso8601)) { var date = new Date(0), tzHour = 0, tzMin = 0, @@ -3558,7 +3590,7 @@ var trimDate = date.trim() date = trimDate.replace(rfixYMD, function(a, b, c, d) { var array = d.length === 4 ? [d, b, c] : [b, c, d] - return array.join("/") + return array.join("-") }) date = jsonStringToDate(date) } diff --git a/avalon.modern.min.js b/avalon.modern.min.js index fd9b458fd..c1ac79ad7 100644 --- a/avalon.modern.min.js +++ b/avalon.modern.min.js @@ -1,106 +1,106 @@ -(function(p){function v(){}function t(){avalon.config.debug&&console.log.apply(console,arguments)}function J(b,c){"string"===typeof b&&(b=b.match(w)||[]);for(var d={},e=void 0!==c?c:1,f=0,g=b.length;f=Object.keys(e).length){var S=e.set,E=e.get;l=function(b){var e=f.$events,g=d[c]; -if(arguments.length){if(ca)return;if(R(S)){var h=e[c];e[c]=[];S.call(f,b);e[c]=h}}else avalon.openComputedCollect&&da(e[c]);b=d[c]=E.call(f);if(!ea(g,b)){if(fa&&(h=T[f.$id])&&h[c])h[c].$val=b;oa(e[c]);f.$events&&P.$fire.call(f,c,b,g)}return b};k.push(function(){V[A]={evaluator:l,element:G,type:"computed::"+c,handler:v,args:[]};l();da(g[c]);delete V[A]})}else La.test(C)?(l=function(b){var e=l.child,h=d[c];if(arguments.length)!ca&&!ea(h,b)&&(e=l.child=xb(f,c,b,C),b=d[c]=e.$model,(e=pa[e.$id])&&e(), -f.$events&&P.$fire.call(f,c,b,h));else return da(g[c]),e},(l.child=K(e,0,d[c])).$events[F]=g[c]):l=function(b){var e=d[c];if(arguments.length){if(!ea(e,b)){d[c]=b;if(fa){var h=T[f.$id];h&&h[c]&&(h[c].$val=b)}oa(g[c]);f.$events&&P.$fire.call(f,c,b,e)}}else return da(g[c]),e};h[c]=l}})(e,b[e]);Ka.forEach(function(c){delete b[c];delete d[c]});Object.defineProperties(f,yb(h));for(var l in b)h[l]||(f[l]=b[l]);f.$id=ba();f.$model=d;f.$events=g;for(e in P)f[e]=P[e];Object.defineProperty(f,"hasOwnProperty", -{value:function(b){return b in f.$model},writable:!1,enumerable:!1,configurable:!0});k.forEach(function(b){b()});return f}function yb(b){var c={},d;for(d in b)c[d]={get:b[d],set:b[d],enumerable:!0,configurable:!0};return c}function xb(b,c,d,e){var f=b[c];if("array"===e){if(!Array.isArray(d)||f===d)return f;f.clear();f.pushArray(d.concat());return f}var g=b.$events[c];T[f.$id]&&(fa--,delete T[f.$id]);var h=K(d);h.$events[F]=g;pa[h.$id]=function(b){for(;b=g.shift();)(function(b){b.type&&avalon.nextTick(function(){b.rollback&& -b.rollback();u[b.type](b,b.vmodels)})})(b);delete pa[h.$id]};return h}function s(b){for(var c in b)if(Ma.call(b,c)){var d=b[c];if("function"===typeof s.plugins[c])s.plugins[c](d);else"object"===typeof s[c]?avalon.mix(s[c],d):s[c]=d}return this}function Na(b){return b.replace(/([a-z\d])([A-Z]+)/g,"$1-$2").toLowerCase()}function ga(b){return 0>b.indexOf("-")&&0>b.indexOf("_")?b:b.replace(/[-_][^-_]/g,function(b){return b.charAt(1).toUpperCase()})}function ha(b){try{b="true"===b?!0:"false"===b?!1:"null"=== -b?null:+b+""===b?+b:zb.test(b)?JSON.parse(b):b}catch(c){}return b}function Oa(b,c){if(0>=b.offsetWidth){var d=getComputedStyle(b,null);if(Ab.test(d.display)){var e={node:b},f;for(f in Pa)e[f]=d[f],b.style[f]=Pa[f];c.push(e)}(d=b.parentNode)&&1===d.nodeType&&Oa(d,c)}}function qa(b){V[A]=b;avalon.openComputedCollect=!0;var c=b.evaluator;if(c)try{var d=Bb.test(b.type)?b:c.apply(0,b.args);b.handler(d,b.element,b)}catch(e){t("warning:exception throwed in [registerSubscriber] "+e),delete b.evaluator,c= -b.element,3===c.nodeType&&(d=c.parentNode,s.commentInterpolate?d.replaceChild(p.createComment(b.value),c):c.data=L+b.value+M)}avalon.openComputedCollect=!1;delete V[A]}function da(b){var c=V[A];b&&(c&&avalon.Array.ensure(b,c)&&c.element)&&Qa(c,b)}function Qa(b,c){b.$uuid=b.$uuid||ba();c.$uuid=c.$uuid||ba();var d={data:b,list:c,toString:function(){return b.$uuid+" "+c.$uuid}};Q[d]||(Q[d]=1,Q.push(d))}function Ra(){for(var b=ra,c=ra+Cb;b=Object.keys(e).length){var P=e.set,E=e.get;n=function(b){var e=f.$events,g=d[c]; +if(arguments.length){if(da)return;if(S(P)){var h=e[c];e[c]=[];P.call(f,b);e[c]=h}}else avalon.openComputedCollect&&ea(e[c]);b=d[c]=E.call(f);if(!fa(g,b)){if(ga&&(h=T[f.$id])&&h[c])h[c].$val=b;oa(e[c]);f.$events&&Q.$fire.call(f,c,b,g)}return b};k.push(function(){W[B]={evaluator:n,element:G,type:"computed::"+c,handler:v,args:[]};n();ea(g[c]);delete W[B]})}else La.test(l)?(n=function(b){var e=n.child,h=d[c];if(arguments.length)!da&&!fa(h,b)&&(e=n.child=xb(f,c,b,l),b=d[c]=e.$model,(e=pa[e.$id])&&e(), +f.$events&&Q.$fire.call(f,c,b,h));else return ea(g[c]),e},(n.child=K(e,0,d[c])).$events[F]=g[c]):n=function(b){var e=d[c];if(arguments.length){if(!fa(e,b)){d[c]=b;if(ga){var h=T[f.$id];h&&h[c]&&(h[c].$val=b)}oa(g[c]);f.$events&&Q.$fire.call(f,c,b,e)}}else return ea(g[c]),e};h[c]=n}})(e,b[e]);Ka.forEach(function(c){delete b[c];delete d[c]});Object.defineProperties(f,yb(h));for(var l in b)h[l]||(f[l]=b[l]);f.$id=ca();f.$model=d;f.$events=g;for(e in Q)f[e]=Q[e];Object.defineProperty(f,"hasOwnProperty", +{value:function(b){return b in f.$model},writable:!1,enumerable:!1,configurable:!0});k.forEach(function(b){b()});return f}function yb(b){var c={},d;for(d in b)c[d]={get:b[d],set:b[d],enumerable:!0,configurable:!0};return c}function xb(b,c,d,e){var f=b[c];if("array"===e){if(!Array.isArray(d)||f===d)return f;f.clear();f.pushArray(d.concat());return f}var g=b.$events[c];T[f.$id]&&(ga--,delete T[f.$id]);var h=K(d);h.$events[F]=g;pa[h.$id]=function(b){for(;b=g.shift();)(function(b){b.type&&avalon.nextTick(function(){b.rollback&& +b.rollback();y[b.type](b,b.vmodels)})})(b);delete pa[h.$id]};return h}function s(b){for(var c in b)if(Ma.call(b,c)){var d=b[c];if("function"===typeof s.plugins[c])s.plugins[c](d);else"object"===typeof s[c]?avalon.mix(s[c],d):s[c]=d}return this}function Na(b){return b.replace(/([a-z\d])([A-Z]+)/g,"$1-$2").toLowerCase()}function ha(b){return 0>b.indexOf("-")&&0>b.indexOf("_")?b:b.replace(/[-_][^-_]/g,function(b){return b.charAt(1).toUpperCase()})}function ia(b){try{b="true"===b?!0:"false"===b?!1:"null"=== +b?null:+b+""===b?+b:zb.test(b)?JSON.parse(b):b}catch(c){}return b}function Oa(b,c){if(0>=b.offsetWidth){var d=getComputedStyle(b,null);if(Ab.test(d.display)){var e={node:b},f;for(f in Pa)e[f]=d[f],b.style[f]=Pa[f];c.push(e)}(d=b.parentNode)&&1===d.nodeType&&Oa(d,c)}}function qa(b){W[B]=b;avalon.openComputedCollect=!0;var c=b.evaluator;if(c)try{var d=Bb.test(b.type)?b:c.apply(0,b.args);b.handler(d,b.element,b)}catch(e){u("warning:exception throwed in [registerSubscriber] "+e),delete b.evaluator,c= +b.element,3===c.nodeType&&(d=c.parentNode,s.commentInterpolate?d.replaceChild(p.createComment(b.value),c):c.data=L+b.value+M)}avalon.openComputedCollect=!1;delete W[B]}function ea(b){var c=W[B];b&&(c&&avalon.Array.ensure(b,c)&&c.element)&&Qa(c,b)}function Qa(b,c){b.$uuid=b.$uuid||ca();c.$uuid=c.$uuid||ca();var d={data:b,list:c,toString:function(){return b.$uuid+" "+c.$uuid}};R[d]||(R[d]=1,R.push(d))}function Ra(){for(var b=ra,c=ra+Cb;bb&&delete c[d.shift()];return c[e]=f}var d=[];return c}function eb(b,c,d){var e=d.type,f=d.filters?d.filters.join(""):"",g=c.map(function(b){return b.$id.replace(Lb, -"$1")})+b+e+f,h=Mb(b).concat(),k=[],l=[],m=[],n="";c=cb(c);for(var q=0,n=c.length;qs.maxRepeatSize&&Z.pop()}b.length=0}function $(){z?(r["ready!"].state=2,z.checkDeps()):lb.forEach(function(b){b(avalon)});$=v}var A=Date.now(),F="$"+A,x=Function("return this")(),Wb=x.require,Xb=x.define,ca=!1,w=/[^, ]+/g,La=/^(?:object|array)$/, -mb=/^\[object SVG\w*Element\]$/,Yb=/^\[object (Window|DOMWindow|global)\]$/,Aa=Object.prototype,Ma=Aa.hasOwnProperty,Ba=Aa.toString,N=Array.prototype,ia=N.slice,V={},G=p.head,D=p.documentElement,H=p.createDocumentFragment(),la=p.createElement("div"),nb={};"Boolean Number String Function Array Date RegExp Object Error".replace(w,function(b){nb["[object "+b+"]"]=b.toLowerCase()});x.avalon=function(b){return new avalon.init(b)};avalon.init=function(b){this[0]=this.element=b};avalon.fn=avalon.prototype= -avalon.init.prototype;avalon.isFunction=R;avalon.type=function(b){return null==b?String(b):"object"===typeof b||"function"===typeof b?nb[Ba.call(b)]||"object":typeof b};avalon.isWindow=function(b){return Yb.test(Ba.call(b))};avalon.isPlainObject=function(b){return!!b&&"object"===typeof b&&Object.getPrototypeOf(b)===Aa};avalon.mix=avalon.fn.mix=function(){var b,c,d,e,f,g=arguments[0]||{},h=1,k=arguments.length,l=!1;"boolean"===typeof g&&(l=g,g=arguments[1]||{},h++);"object"!==typeof g&&"function"!== -avalon.type(g)&&(g={});h===k&&(g=this,h--);for(;h';if(!mb.test(ob.firstChild)){var Ca=function(b,c){if(b&&b.childNodes)for(var d=b.childNodes,e=0,f;f=d[e++];)if(f.tagName){var g=p.createElementNS("http://www.w3.org/2000/svg", -f.tagName.toLowerCase());N.forEach.call(f.attributes,function(b){g.setAttribute(b.name,b.value)});Ca(f,g);c.appendChild(g)}};Object.defineProperties(SVGElement.prototype,{outerHTML:{enumerable:!0,configurable:!0,get:function(){return(new XMLSerializer).serializeToString(this)},set:function(b){var c=this.tagName.toLowerCase(),d=this.parentNode;b=avalon.parseHTML(b);"svg"===c?d.insertBefore(b,this):(c=p.createDocumentFragment(),Ca(b,c),d.insertBefore(c,this));d.removeChild(this)}},innerHTML:{enumerable:!0, -configurable:!0,get:function(){var b=RegExp("$","i");return this.outerHTML.replace(RegExp("<"+this.nodeName+'\\b(?:(["\'])[^"]*?(\\1)|[^>])*>',"i"),"").replace(b,"")},set:function(b){avalon.clearHTML&&(avalon.clearHTML(this),b=avalon.parseHTML(b),Ca(b,this))}}})}}var ka=avalon.vmodels={};avalon.define=function(b,c){var d=b.$id||b;d||t("warning: \u5fc5\u987b\u6307\u5b9a$id");ka[d]&&t("warning: "+d+" \u5df2\u7ecf\u5b58\u5728\u4e8eavalon.vmodels\u4e2d");if("object"===typeof b)var e= -K(b);else e={$watch:v},c(e),e=K(e),ca=!0,c(e),ca=!1;e.$id=d;return ka[d]=e};var Ka="$id,$watch,$unwatch,$fire,$events,$model,$skipArray".match(w),ea=Object.is||function(b,c){return 0===b&&0===c?1/b===1/c:b!==b?c!==c:b===c},T={},fa=0,pa={},L,M,W,pb,bb,qb=/[-.*+?^${}()|[\]\/\\]/g,z=v,O={loader:function(b){x.define=b?z.define:Xb;x.require=b?z:Wb},interpolate:function(b){L=b[0];M=b[1];L===M?avalon.error("openTag!==closeTag",SyntaxError):"\x3c!--,--\x3e"===b+""?s.commentInterpolate=!0:(b=L+"test"+M,la.innerHTML= -b,la.innerHTML!==b&&0<=la.innerHTML.indexOf("<")&&avalon.error("\u6b64\u5b9a\u754c\u7b26\u4e0d\u5408\u6cd5",SyntaxError),la.innerHTML="");b=(L+"").replace(qb,"\\$&");var c=(M+"").replace(qb,"\\$&");W=RegExp(b+"(.*?)"+c);pb=RegExp(b+"(.*?)"+c,"g");bb=RegExp(b+".*?"+c+"|\\sms-")}};s.debug=!0;s.plugins=O;s.plugins.interpolate(["{{","}}"]);s.paths={};s.shim={};s.maxRepeatSize=100;avalon.config=s;"add,remove".replace(w,function(b){avalon.fn[b+"Class"]=function(c){var d=this[0];c&&("string"===typeof c&& -d&&1===d.nodeType)&&c.replace(/\S+/g,function(c){d.classList[b](c)});return this}});avalon.fn.mix({hasClass:function(b){var c=this[0]||{};return 1===c.nodeType&&c.classList.contains(b)},toggleClass:function(b,c){for(var d,e=0,f=b.split(/\s+/),g="boolean"===typeof c;d=f[e++];)this[(g?c:!this.hasClass(d))?"addClass":"removeClass"](d);return this},attr:function(b,c){return 2===arguments.length?(this[0].setAttribute(b,c),this):this[0].getAttribute(b)},data:function(b,c){b="data-"+Na(b||"");switch(arguments.length){case 2:return this.attr(b, -c),this;case 1:var d=this.attr(b);return ha(d);case 0:var e={};N.forEach.call(this[0].attributes,function(c){c&&(b=c.name,b.indexOf("data-")||(b=ga(b.slice(5)),e[b]=ha(c.value)))});return e}},removeData:function(b){b="data-"+Na(b);this[0].removeAttribute(b);return this},css:function(b,c){if(avalon.isPlainObject(b))for(var d in b)avalon.css(this,d,b[d]);else var e=avalon.css(this,b,c);return void 0!==e?e:this},position:function(){var b,c,d=this[0],e={top:0,left:0};if(d)return"fixed"===this.css("position")? -c=d.getBoundingClientRect():(b=this.offsetParent(),c=this.offset(),"HTML"!==b[0].tagName&&(e=b.offset()),e.top+=avalon.css(b[0],"borderTopWidth",!0),e.left+=avalon.css(b[0],"borderLeftWidth",!0)),{top:c.top-e.top-avalon.css(d,"marginTop",!0),left:c.left-e.left-avalon.css(d,"marginLeft",!0)}},offsetParent:function(){for(var b=this[0].offsetParent||D;b&&"HTML"!==b.tagName&&"static"===avalon.css(b,"position");)b=b.offsetParent;return avalon(b||D)},bind:function(b,c,d){if(this[0])return avalon.bind(this[0], -b,c,d)},unbind:function(b,c,d){this[0]&&avalon.unbind(this[0],b,c,d);return this},val:function(b){var c=this[0];if(c&&1===c.nodeType){var d=0===arguments.length,e=d?":get":":set",f=Zb,g;g=c.tagName.toLowerCase();g="input"===g&&/checkbox|radio/.test(c.type)?"checked":g;if(e=f[g+e])var h=e(c,b);else{if(d)return(c.value||"").replace(/\r/g,"");c.value=b}}return d?h:this}});D.dataset&&(avalon.fn.data=function(b,c){var d=this[0].dataset;switch(arguments.length){case 2:return d[b]=c,this;case 1:return c= -d[b],ha(c);case 0:var e={};for(b in d)e[b]=ha(d[b]);return e}});var zb=/(?:\{[\s\S]*\}|\[[\s\S]*\])$/;avalon.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(b,c){avalon.fn[b]=function(d){var e=this[0]||{},f=e.window&&e.document?e:9===e.nodeType?e.defaultView:!1,g="scrollTop"===b;if(arguments.length)f?f.scrollTo(!g?d:avalon(f).scrollLeft(),g?d:avalon(f).scrollTop()):e[b]=d;else return f?f[c]:e[b]}});var y=avalon.cssHooks={},rb=["","-webkit-","-moz-","-ms-"],Da={"float":"cssFloat"}; -avalon.cssNumber=J("columnCount,order,fillOpacity,fontWeight,lineHeight,opacity,orphans,widows,zIndex,zoom");avalon.cssName=function(b,c,d){if(Da[b])return Da[b];c=c||D.style;for(var e=0,f=rb.length;el&&(e=e-avalon.css(c,"border"+d[0]+"Width",!0)-avalon.css(c,"border"+d[1]+"Width",!0));-4===l&&(e=e-avalon.css(c,"padding"+d[0],!0)-avalon.css(c,"padding"+d[1],!0));return e};y[c+"&get"]=function(b){var d=[];Oa(b,d);for(var e=y[c+":get"](b),f=0,m;m=d[f++];){b=m.node;for(var n in m)"string"===typeof m[n]&&(b.style[n]=m[n])}return e};avalon.fn[c]=function(g){var h=this[0]; -if(0===arguments.length){if(h.setTimeout)return h["inner"+b]||h.document.documentElement[d];if(9===h.nodeType){var k=h.documentElement;return Math.max(h.body[e],k[e],h.body[f],k[f],k[d])}return y[c+"&get"](h)}return this.css(c,g)};avalon.fn["inner"+b]=function(){return y[c+":get"](this[0],void 0,-2)};avalon.fn["outer"+b]=function(b){return y[c+":get"](this[0],void 0,!0===b?2:0)}});avalon.fn.offset=function(){var b=this[0],c={left:0,top:0};if(!b||!b.tagName||!b.ownerDocument)return c;var d=b.ownerDocument, -e=d.documentElement,d=d.defaultView;if(!e.contains(b))return c;void 0!==b.getBoundingClientRect&&(c=b.getBoundingClientRect());return{top:c.top+d.pageYOffset-e.clientTop,left:c.left+d.pageXOffset-e.clientLeft}};var Zb={"select:get":function(b,c){for(var d,e=b.options,f=b.selectedIndex,g="select-one"===b.type||0>f,h=g?null:[],k=g?f+1:e.length,l=0>f?k:g?f:0;l]*)\/>/ig,bc=J(["","text/javascript","text/ecmascript","application/ecmascript","application/javascript"]),cc=p.createElement("script");avalon.parseHTML=function(b){"string"!==typeof b&&(b+="");b=b.replace(ac,"<$1>").trim(); -var c=($b.exec(b)||["",""])[1].toLowerCase(),c=B[c]||B._default,d=H.cloneNode(!1);c.innerHTML=b;b=c.getElementsByTagName("script");if(b.length)for(var e=0,f;f=b[e++];)if(bc[f.type]){var g=cc.cloneNode(!1);N.forEach.call(f.attributes,function(b){g.setAttribute(b.name,b.value)});g.text=f.text;f.parentNode.replaceChild(g,f)}for(;b=c.firstChild;)d.appendChild(b);return d};avalon.innerHTML=function(b,c){var d=this.parseHTML(c);this.clearHTML(b).appendChild(d)};avalon.clearHTML=function(b){for(b.textContent= -"";b.firstChild;)b.removeChild(b.firstChild);return b};var P={$watch:function(b,c){if("function"===typeof c){var d=this.$events[b];d?d.push(c):this.$events[b]=[c]}else this.$events=this.$watch.backup;return this},$unwatch:function(b,c){var d=arguments.length;if(0===d)this.$watch.backup=this.$events,this.$events={};else if(1===d)this.$events[b]=[];else for(var d=this.$events[b]||[],e=d.length;0>~--e;)if(d[e]===c)return d.splice(e,1);return this},$fire:function(b){var c;/^(\w+)!(\S+)$/.test(b)&&(c= -RegExp.$1,b=RegExp.$2);var d=this.$events,e=ia.call(arguments,1),f=[b].concat(e);if("all"===c)for(var g in avalon.vmodels)e=avalon.vmodels[g],e!==this&&e.$fire.apply(e,f);else if("up"===c||"down"===c){if(d=d.expr&&p.querySelector(d.expr)){for(g in avalon.vmodels)if(e=avalon.vmodels[g],e!==this&&e.$events.expr){var h=p.querySelector(e.$events.expr);if(h&&("down"===c?d.contains(h):h.contains(d)))h._avalon=e}g=p.getElementsByTagName("*");var k=[];Array.prototype.forEach.call(g,function(b){b._avalon&& -(k.push(b._avalon),b._avalon="",b.removeAttribute("_avalon"))});"up"===c&&k.reverse();for(g=0;(c=k[g++])&&!1!==c.$fire.apply(c,f););}}else{f=d[b]||[];c=d.$all||[];for(g=0;d=f[g++];)R(d)&&d.apply(this,e);for(g=0;d=c[g++];)R(d)&&d.apply(this,arguments)}}},Bb=/^(duplex|on)$/,Q=[],ra=0,Cb=200,Sa=Date.now(),Ta,Ea={};avalon.scanCallback=function(b,c){c=c||"$all";(Ea[c]||(Ea[c]=[])).push(b)};avalon.scan=function(b,c,d){b=b||D;var e=Ea[d||"$all"]||[];c=c?[].concat(c):[];var f=0,g=!1,h,k=!1;c.cb=function(b){f+= -b;k=!0;setTimeout(function(){if(0>=f&&!g)for(g=!0;h=e.shift();)h()})};Ua(b,c);if(!k)for(;h=e.shift();)h()};var Gb=J("AREA,BASE,BASEFONT,BR,COL,COMMAND,EMBED,HR,IMG,INPUT,LINK,META,PARAM,SOURCE,TRACK,WBR,NOSCRIPT,NOSCRIPT,SCRIPT,STYLE,TEXTAREA"),Db=/ms-(\w+)-?(.*)/,ab={"if":10,repeat:90,data:100,widget:110,each:1400,"with":1500,duplex:2E3,on:3E3},Eb=J("animationend,blur,change,input,click,dblclick,focus,keydown,keypress,keyup,mousedown,mouseenter,mouseleave,mousemove,mouseout,mouseover,mouseup,scan,scroll,submit"), -Fb=J("value,title,alt,checked,selected,disabled,readonly,enabled"),Ib=/\|\s*(\w+)\s*(\([^)]*\))?/g,Hb=/\|\|/g,Jb=/U2hvcnRDaXJjdWl0/g,dc=/\/\*[\w\W]*?\*\/|\/\/[^\n]*\n|\/\/[^\n]*$|"(?:[^"\\]|\\[\w\W])*"|'(?:[^'\\]|\\[\w\W])*'|[\s\t\n]*\.[\s\t\n]*[$\w\.]+/g,ec=/[^\w$]+/g,fc=RegExp(""+("\\b"+"break,case,catch,continue,debugger,default,delete,do,else,false,finally,for,function,if,in,instanceof,new,null,return,switch,this,throw,true,try,typeof,var,void,while,with,abstract,boolean,byte,char,class,const,double,enum,export,extends,final,float,goto,implements,import,int,interface,long,native,package,private,protected,public,short,static,super,synchronized,throws,transient,volatile,arguments,let,yield,undefined".replace(/,/g, -"\\b|\\b")+"\\b"),"g"),gc=/\b\d[^,]*/g,hc=/^,+|,+$/g,Fa=db(512),Mb=function(b){var c=","+b.trim();if(Fa[c])return Fa[c];b=b.replace(dc,"").replace(ec,",").replace(fc,"").replace(gc,"").replace(hc,"").split(/^$|,+/);return Fa(c,cb(b))},wa=db(128),Nb=/\w\[.*\]|\w\.\w/,Lb=/(\$proxy\$[a-z]+)\d+$/;avalon.parseExprProxy=I;G.insertAdjacentHTML("afterBegin",'');var sa=G.firstChild,aa=function(b,c,d){if(b=b.getAttribute(c)){c= -0;for(var e;e=d[c++];)if(e.hasOwnProperty(b)&&"function"===typeof e[b])return e[b]}},Ga=avalon.templateCache={},Ha={};"autofocus,autoplay,async,checked,controls,declare,disabled,defer,defaultChecked,defaultSelectedcontentEditable,isMap,loop,multiple,noHref,noResize,noShade,open,readOnly,selected".replace(w,function(b){Ha[b.toLowerCase()]=b});var xa=avalon.bindingExecutors={attr:function(b,c,d){var e=d.type,f=d.param;if("css"===e)avalon(c).css(f,b);else if("attr"===e){if(Ha[f]&&(e=Ha[f],"boolean"=== -typeof c[e]))return c[e]=!!b;if(!1===b||null===b||void 0===b)return c.removeAttribute(f);(mb.test(c)?0:f in c.cloneNode(!1))?c[f]=b:c.setAttribute(f,b)}else if("include"===e&&b){var g=d.vmodels,h=d.includeRendered,k=d.includeLoaded,l=d.includeReplaced?c.parentNode:c,m=function(b){k&&(b=k.apply(l,[b].concat(g)));for(h&&ja(l,function(){h.call(l)},NaN);;){var c=d.startInclude.nextSibling;if(c&&c!==d.endInclude)l.removeChild(c);else break}b=avalon.parseHTML(b);c=avalon.slice(b.childNodes);l.insertBefore(b, -d.endInclude);ta(c,g);g.cb(-1)};if("src"===d.param)if(Ga[b])avalon.nextTick(function(){m(Ga[b])});else{var n=new x.XMLHttpRequest;n.onload=function(){var c=n.status;if(200<=c&&300>c||304===c)m(Ga[b]=n.responseText)};n.open("GET",b,!0);n.withCredentials=!0;n.setRequestHeader("X-Requested-With","XMLHttpRequest");n.send(null)}else{var q=b&&1==b.nodeType?b:p.getElementById(b);avalon.nextTick(function(){m(q.value||q.innerText||q.innerHTML)})}}else c[e]=b,x.chrome&&"EMBED"===c.tagName&&(f=c.parentNode, -e=document.createComment("ms-src"),f.replaceChild(e,c),f.replaceChild(c,e))},"class":function(b,c,d){var e=avalon(c),f=d.type;if("class"===f&&d.oldStyle)e.toggleClass(d.oldStyle,!!b);else switch(d.toggleClass=d._evaluator?!!d._evaluator.apply(c,d._args):!0,d.newClass=d.immobileClass||b,d.oldClass&&d.newClass!==d.oldClass&&e.removeClass(d.oldClass),d.oldClass=d.newClass,f){case "class":e.toggleClass(d.newClass,d.toggleClass);break;case "hover":case "active":if(!d.hasBindEvent){b="mouseenter";var g= -"mouseleave";"active"===f&&(c.tabIndex=c.tabIndex||-1,b="mousedown",g="mouseup",e.bind("mouseleave",function(){d.toggleClass&&e.removeClass(d.newClass)}));e.bind(b,function(){d.toggleClass&&e.addClass(d.newClass)});e.bind(g,function(){d.toggleClass&&e.removeClass(d.newClass)});d.hasBindEvent=!0}}},data:function(b,c,d){d="data-"+d.param;b&&"object"===typeof b?c[d]=b:c.setAttribute(d,String(b))},repeat:function(b,c,d){if(b){var e=this.element.parentNode,f=this.proxies,g=H.cloneNode(!1);if("del"===b|| -"move"===b)var h=za(this,c);var k=this.group;switch(b){case "add":for(var l=d,m=this.$repeat.length-1,k=[],h=0,n=l.length;h\u4e0a\u8981\u6c42\u5bf9\u5e94\u4e00\u4e2a\u6570\u7ec4"):b.multiple&&t("ms-duplex\u5728\u4e0d\u80fd\u5bf9\u5e94\u4e00\u4e2a\u6570\u7ec4");d=Array.isArray(d)?d.map(String):d+"";d+""!==b.oldValue&&(e.val(d),b.oldValue=d+"")};d.bound("change",function(){if(!1!==e.data("duplex-observe")){var f=e.val(),f=Array.isArray(f)?f.map(function(b){return d.pipe(b, +d,"get")}):d.pipe(f,d,"get");f+""!==b.oldValue&&c(f);d.changed.call(b,f,d)}});ka(b,function(){qa(d);d.changed.call(b,c(),d)},NaN)};U.TEXTAREA=U.INPUT;var na=avalon.eventHooks;"onmouseenter"in D||avalon.each({mouseenter:"mouseover",mouseleave:"mouseout"},function(b,c){na[b]={type:c,deel:function(c,e){return function(f){var g=f.relatedTarget;if(!g||g!==c&&!(c.compareDocumentPosition(g)&16))return delete f.type,f.type=b,e.call(c,f)}}}});avalon.each({AnimationEvent:"animationend",WebKitAnimationEvent:"webkitAnimationEnd"}, +function(b,c){x[b]&&!na.animationend&&(na.animationend={type:c})});void 0===p.onmousewheel&&(na.mousewheel={type:"wheel",deel:function(b,c){return function(d){d.wheelDeltaY=d.wheelDelta=0b?Math.max(d+b,0):Math.min(b,d);var d=Ia.apply(this.$model,arguments),e=[],f;this._stopFireLength=!0;d.length&&(e=this._del(b,d.length), +f=!0);2]*>([\S\s]*?)<\/script\s*>/gim,jc=/\s+(on[^=\s]+)(?:=("[^"]*"|'[^']*'|[^\s>]+))?/g,kc=/<\w+\b(?:(["'])[^"]*?(\1)|[^>])*>/ig,lc={a:/\b(href)\=("javascript[^"]*"|'javascript[^']*')/ig,img:/\b(src)\=("javascript[^"]*"|'javascript[^']*')/ig, +form:/\b(action)\=("javascript[^"]*"|'javascript[^']*')/ig},mc=/[\uD800-\uDBFF][\uDC00-\uDFFF]/g,nc=/([^\#-~| |!])/g,Ja=avalon.filters={uppercase:function(b){return b.toUpperCase()},lowercase:function(b){return b.toLowerCase()},truncate:function(b,c,d){c=c||30;d=void 0===d?"...":d;return b.length>c?b.slice(0,c-d.length)+d:String(b)},sanitize:x.toStaticHTML?toStaticHTML.bind(x):function(b){return b.replace(ic,"").replace(kc,function(b,d){var e=b.toLowerCase().match(/<(\w+)\s/);e&&(e=lc[e[1]])&&(b= +b.replace(e,function(b,c,d){b=d.charAt(0);return c+"="+b+"javascript:void(0)"+b}));return b.replace(jc," ").replace(/\s+/g," ")})},camelize:ha,escape:function(b){return String(b).replace(/&/g,"&").replace(mc,function(b){var d=b.charCodeAt(0);b=b.charCodeAt(1);return"&#"+(1024*(d-55296)+(b-56320)+65536)+";"}).replace(nc,function(b){return"&#"+b.charCodeAt(0)+";"}).replace(//g,">")},currency:function(b,c){return(c||"\uffe5")+avalon.filters.number(b)},number:function(b,c, +d,e){b=(b+"").replace(/[^0-9+\-Ee.]/g,"");b=!isFinite(+b)?0:+b;c=!isFinite(+c)?0:Math.abs(c);e=e||",";d=d||".";var f="",f=function(b,c){var d=Math.pow(10,c);return""+Math.round(b*d)/d},f=(c?f(b,c):""+Math.round(b)).split(".");3b&&(e="-",b=-b);for(b=""+b;b.length-e)g+=e;0===g&&-12===e&&(g=12);return b(g,d,f)}}function d(b,c){return function(d,e){var f=d["get"+b](),g=(c?"SHORT"+b:b).toUpperCase();return e[g][f]}}function e(b){var c;if(c=b.match(k)){b=new Date(0);var d=0,e=0,f=c[8]?b.setUTCFullYear:b.setFullYear,g=c[8]?b.setUTCHours:b.setHours;c[9]&&(d=parseInt(c[9]+c[10],10),e=parseInt(c[9]+c[11],10));f.call(b,parseInt(c[1],10),parseInt(c[2],10)-1,parseInt(c[3],10));d=parseInt(c[4]|| +0,10)-d;e=parseInt(c[5]||0,10)-e;f=parseInt(c[6]||0,10);c=Math.round(1E3*parseFloat("0."+(c[7]||0)));g.call(b,d,e,f,c)}return b}var f={yyyy:c("FullYear",4),yy:c("FullYear",2,0,!0),y:c("FullYear",1),MMMM:d("Month"),MMM:d("Month",!0),MM:c("Month",2,1),M:c("Month",1,1),dd:c("Date",2),d:c("Date",1),HH:c("Hours",2),H:c("Hours",1),hh:c("Hours",2,-12),h:c("Hours",1,-12),mm:c("Minutes",2),m:c("Minutes",1),ss:c("Seconds",2),s:c("Seconds",1),sss:c("Milliseconds",3),EEEE:d("Day"),EEE:d("Day",!0),a:function(b, +c){return 12>b.getHours()?c.AMPMS[0]:c.AMPMS[1]},Z:function(c){c=-1*c.getTimezoneOffset();return c=(0<=c?"+":"")+(b(Math[0]*)\/>/ig var tagHooks = { - col: [2, "", "
"], g: [1, '', ''], //IE6-8在用innerHTML生成节点时,不能直接创建no-scope元素与HTML5的新标签 _default: [0, "", ""] //div可以不用闭合 @@ -978,14 +977,13 @@ t.innerHTML = wrap[1] + html + wrap[2] var wrapper = t.content if (wrap[0]) { - console.log(wrapper) -// var fragment = wrapper.cloneNode(false), firstChild -// for (var i = wrap[0]; i--; wrapper = wrapper.lastChild) { -// } -// while (firstChild = wrapper.firstChild) { // 将wrapper上的节点转移到文档碎片上! -// fragment.appendChild(firstChild) -// } -// return fragment + var fragment = wrapper.cloneNode(false), firstChild + for (var i = wrap[0]; i--; wrapper = wrapper.lastChild) { + } + while (firstChild = wrapper.firstChild) { // 将wrapper上的节点转移到文档碎片上! + fragment.appendChild(firstChild) + } + return fragment } return wrapper } @@ -1211,30 +1209,58 @@ /********************************************************************* * 扫描系统 * **********************************************************************/ - avalon.scan = function(elem, vmodel) { + var scanObject = {} + avalon.scanCallback = function(fn, group) { + group = group || "$all" + var array = scanObject[group] || (scanObject[group] = []) + array.push(fn) + } + avalon.scan = function(elem, vmodel, group) { elem = elem || root + group = group || "$all" + var array = scanObject[group] || [] var vmodels = vmodel ? [].concat(vmodel) : [] + var scanIndex = 0; + var scanAll = false + var fn + var dirty = false + function cb(i) { + scanIndex += i + dirty = true + setTimeout(function() { + if (scanIndex <= 0 && !scanAll) { + scanAll = true + while (fn = array.shift()) { + fn() + } + } + }) + } + vmodels.cb = cb scanTag(elem, vmodels) + //html, include, widget + if (!dirty) { + while (fn = array.shift()) { + fn() + } + } } //http://www.w3.org/TR/html5/syntax.html#void-elements var stopScan = oneObject("area,base,basefont,br,col,command,embed,hr,img,input,link,meta,param,source,track,wbr,noscript,noscript,script,style,textarea".toUpperCase()) - /*确保元素的内容被完全扫描渲染完毕才调用回调*/ - function checkScan(elem, callback) { - var innerHTML = NaN, - id = setInterval(function() { - var currHTML = elem.innerHTML - if (currHTML === innerHTML) { - clearInterval(id) - callback() - } else { - innerHTML = currHTML - } - }, 15) + function checkScan(elem, callback, innerHTML) { + var id = setTimeout(function() { + var currHTML = elem.innerHTML + clearTimeout(id) + if (currHTML === innerHTML) { + callback() + } else { + checkScan(elem, callback, currHTML) + } + }) } - function scanTag(elem, vmodels, node) { //扫描顺序 ms-skip(0) --> ms-important(1) --> ms-controller(2) --> ms-if(10) --> ms-repeat(100) //--> ms-if-loop(110) --> ms-attr(970) ...--> ms-each(1400)-->ms-with(1500)--〉ms-duplex(2000)垫后 @@ -1244,20 +1270,29 @@ if (typeof a === "string") { return } else if (node = b || c) { - var newVmodel = VMODELS[node.value] + var newVmodel = avalon.vmodels[node.value] if (!newVmodel) { return } //ms-important不包含父VM,ms-controller相反 + var cb = vmodels.cb vmodels = node === b ? [newVmodel] : [newVmodel].concat(vmodels) + vmodels.cb = cb elem.removeAttribute(node.name) //removeAttributeNode不会刷新[ms-controller]样式规则 elem.classList.remove(node.name) + createSignalTower(elem, newVmodel) elem.setAttribute("avalonctrl", node.value) newVmodel.$events.expr = elem.tagName + '[avalonctrl="' + node.value + '"]' } scanAttr(elem, vmodels) //扫描特性节点 } + function createSignalTower(elem, vmodel) { + var id = elem.getAttribute("avalonctrl") || vmodel.$id + elem.setAttribute("avalonctrl", id) + vmodel.$events.expr = elem.tagName + '[avalonctrl="' + id + '"]' + } + function scanNodeList(parent, vmodels) { var node = parent.firstChild while (node) { @@ -1266,6 +1301,7 @@ node = nextNode } } + function scanNodeArray(nodes, vmodels) { for (var i = 0, node; node = nodes[i++]; ) { scanNode(node, node.nodeType, vmodels) @@ -1280,6 +1316,7 @@ scanText(node, vmodels) //扫描注释节点 } } + function scanText(textNode, vmodels) { var bindings = [] if (textNode.nodeType === 8) { @@ -1329,6 +1366,7 @@ var priorityMap = { "if": 10, "repeat": 90, + "data": 100, "widget": 110, "each": 1400, "with": 1500, @@ -1401,6 +1439,8 @@ } function executeBindings(bindings, vmodels) { + if (bindings.length) + vmodels.cb(bindings.length) for (var i = 0, data; data = bindings[i++]; ) { data.vmodels = vmodels bindingHandlers[data.type](data, vmodels) @@ -1476,48 +1516,53 @@ **********************************************************************/ var keywords = // 关键字 - "break,case,catch,continue,debugger,default,delete,do,else,false" - + ",finally,for,function,if,in,instanceof,new,null,return,switch,this" - + ",throw,true,try,typeof,var,void,while,with" + "break,case,catch,continue,debugger,default,delete,do,else,false" + + ",finally,for,function,if,in,instanceof,new,null,return,switch,this" + + ",throw,true,try,typeof,var,void,while,with" // 保留字 - + ",abstract,boolean,byte,char,class,const,double,enum,export,extends" - + ",final,float,goto,implements,import,int,interface,long,native" - + ",package,private,protected,public,short,static,super,synchronized" - + ",throws,transient,volatile" + + ",abstract,boolean,byte,char,class,const,double,enum,export,extends" + + ",final,float,goto,implements,import,int,interface,long,native" + + ",package,private,protected,public,short,static,super,synchronized" + + ",throws,transient,volatile" // ECMA 5 - use strict + ",arguments,let,yield" + ",undefined" - var robjectProperty = /([\w\.\_$])\s*\[['"]([^'"]+)['"]\]/ - //处理注释及字符串 - var rstringComment = /\/\*[\w\W]*?\*\/|\/\/[^\n]*\n|\/\/[^\n]*$|"(?:[^"\\]|\\[\w\W])*"|'(?:[^'\\]|\\[\w\W])*'/g - //处理加减乘除小括号等运算符 - var roperator = /[^\w\.$]+/g - //处理数字 - var rnumber = /\b\d[^,]*/g - //处理最前面或最后面逗号 - var rcommaOfFirstOrLast = /^,+|,+$/g - //处理位于中间的逗号 - var rcommaInMiddle = /,+/ - //去掉所有关键字保留字 + var rrexpstr = /\/\*[\w\W]*?\*\/|\/\/[^\n]*\n|\/\/[^\n]*$|"(?:[^"\\]|\\[\w\W])*"|'(?:[^'\\]|\\[\w\W])*'|[\s\t\n]*\.[\s\t\n]*[$\w\.]+/g + var rsplit = /[^\w$]+/g var rkeywords = new RegExp(["\\b" + keywords.replace(/,/g, '\\b|\\b') + "\\b"].join('|'), 'g') + var rnumber = /\b\d[^,]*/g + var rcomma = /^,+|,+$/g var cacheVars = createCache(512) - var getVariables = function(str) { - var key = "," + str.trim() + var getVariables = function(code) { + var key = "," + code.trim() if (cacheVars[key]) { return cacheVars[key] } - while (robjectProperty.test(str)) { - str = str.replace(robjectProperty, function(match, obj, prop) { - return obj + '.' + prop; - }) + var match = code + .replace(rrexpstr, "") + .replace(rsplit, ",") + .replace(rkeywords, "") + .replace(rnumber, "") + .replace(rcomma, "") + .split(/^$|,+/) + return cacheVars(key, uniqSet(match)) + } + /*添加赋值语句*/ + function addAssign(vars, scope, name, data) { + var ret = [], + prefix = " = " + name + "." + for (var i = vars.length, prop; prop = vars[--i]; ) { + if (scope.hasOwnProperty(prop)) { + ret.push(prop + prefix + prop) + data.vars.push(prop) + if (data.type === "duplex") { + vars.get = name + "." + prop + } + vars.splice(i, 1) + } } - var vars = str.replace(rstringComment, "") - .replace(roperator, ",") - .replace(rkeywords, ",") - .replace(rnumber, ",") - .replace(rcommaOfFirstOrLast, "") - .split(rcommaInMiddle) - return cacheVars(key, uniqSet(vars)) + return ret + } function uniqSet(array) { @@ -1545,62 +1590,11 @@ } }() - function addDeps(scope, prop, data) { - var obj = scope.$accessors - if (obj) { - var arr = obj[prop] || (obj[prop] = []) - avalon.Array.ensure(arr, data) - } - } - function inObject(obj, array) { - if (!obj.hasOwnProperty(array[0])) { - return 0 - } - for (var i = 1, el; el = array[i++]; ) { - if (!obj.hasOwnProperty(el)) { - return (obj && typeof obj === "object") ? 1 : 0 - } else { - obj = obj[el] - } - } - return 2 - } - /*添加赋值语句*/ - function addAssign(vars, scope, name, data) { - var ret = [], - prefix = " =" + name + "." - - for (var i = vars.length, path; path = vars[--i]; ) { - var arr = path.split(".") - var flag = inObject(scope, arr) - if (flag) { - var prop = arr.shift() - addDeps(scope, prop, data) - ret.push(prop + prefix + prop) - if (data.type === "duplex") { - vars.get = name + "." + prop - } - var subscope = scope - do {//处理子对象 - subscope = subscope[prop] - if (subscope && typeof subscope === "object") { - prop = arr.shift() - addDeps(subscope, prop, data) - } else { - break - } - } while (arr.length); - if (flag > 0) - vars.splice(i, 1) - } - } - return ret - } - /*创建具有一定容量的缓存体*/ function createCache(maxLength) { var keys = [] + function cache(key, value) { if (keys.push(key) > maxLength) { delete cache[keys.shift()] @@ -1609,33 +1603,64 @@ } return cache; } - var cacheExprs = createCache(256) + var cacheExprs = createCache(128) //根据一段文本与一堆VM,转换为对应的求值函数及匹配的VM(解释器模式) var rduplex = /\w\[.*\]|\w\.\w/ var rproxy = /(\$proxy\$[a-z]+)\d+$/ function parseExpr(code, scopes, data) { var dataType = data.type + var isDuplex = dataType === "duplex" var filters = data.filters ? data.filters.join("") : "" var exprId = scopes.map(function(el) { return el.$id.replace(rproxy, "$1") }) + code + dataType + filters - var vars = getVariables(code).concat() - var assigns = [] //收集赋值表达式 - var names = [] - var args = [] //新生成的求值函数的传参 包括所有VM与avalon.filters对象 - if (vars.length) { - scopes.forEach(function(scope, i) { + var vars = getVariables(code).concat(), + assigns = [], + names = [], + args = [], + prefix = "" + data.vars = [] + //args 是一个对象数组, names 是将要生成的求值函数的参数 + scopes = uniqSet(scopes) + for (var i = 0, sn = scopes.length; i < sn; i++) { + if (vars.length) { var name = "vm" + expose + "_" + i names.push(name) - args.push(scope) - assigns.push.apply(assigns, addAssign(vars, scope, name, data)) - }) + args.push(scopes[i]) + assigns.push.apply(assigns, addAssign(vars, scopes[i], name, data)) + } } - - if (!assigns.length && dataType === "duplex") { + if (!assigns.length && isDuplex) { return } + if (!isDuplex && (code.indexOf("||") > -1 || code.indexOf("&&") > -1)) { + //https://github.com/RubyLouvre/avalon/issues/583 + data.vars.forEach(function(v) { + var reg = new RegExp("\\b" + v + "(?:\\.\\w+|\\[\\w+\\])+", "ig") + code = code.replace(reg, function(_) { + var c = _.charAt(v.length) + var method = /^\s*\(/.test(RegExp.rightContext) + if (c === "." || c === "[" || method) {//比如v为aa,我们只匹配aa.bb,aa[cc],不匹配aaa.xxx + var name = "var" + String(Math.random()).replace(/^0\./, "") + if (method) {//array.size() + var array = _.split(".") + if (array.length > 2) { + var last = array.pop() + assigns.push(name + " = " + array.join(".")) + return name + "." + last + } else { + return _ + } + } + assigns.push(name + " = " + _) + return name + } else { + return _ + } + }) + }) + } //---------------args---------------- if (filters) { args.push(avalon.filters) @@ -1671,7 +1696,7 @@ code = textBuffer.join("") code += "\nreturn ret" + expose names.push("filters" + expose) - } else if (dataType === "duplex") { //双工绑定 + } else if (isDuplex) { //双工绑定 var _body = "'use strict';\nreturn function(vvv){\n\t" + prefix + ";\n\tif(!arguments.length){\n\t\treturn " + @@ -1706,25 +1731,21 @@ } catch (e) { log("debug: parse error," + e.message) } finally { - textBuffer = names = null //释放内存 + vars = textBuffer = names = null //释放内存 } } /*parseExpr的智能引用代理*/ - function parseExprProxy(code, scopes, data, tokens) { + function parseExprProxy(code, scopes, data, tokens, noregister) { + scopes.cb(-1) if (Array.isArray(tokens)) { code = tokens.map(function(el) { return el.expr ? "(" + el.value + ")" : JSON.stringify(el.value) }).join(" + ") } - parseExpr(code, scopes, data) - - if (data.evaluator) { + if (data.evaluator && !noregister) { data.handler = bindingExecutors[data.handlerName || data.type] - data.evaluator.toString = function() { - return data.type + " binding to eval(" + code + ")" - } //方便调试 //这里非常重要,我们通过判定视图刷新函数的element是否在DOM树决定 //将它移出订阅者列表 @@ -2295,58 +2316,74 @@ var args = data.value.match(rword) var elem = data.element var widget = args[0] - if (args[1] === "$" || !args[1]) { - args[1] = widget + setTimeout("1") + var id = args[1] + if (!id || id === "$") {//没有定义或为$时,取组件名+随机数 + id = widget + setTimeout("1") } - data.value = args.join(",") + var optName = args[2] || widget//没有定义,取组件名 + vmodels.cb(-1) var constructor = avalon.ui[widget] if (typeof constructor === "function") { //ms-widget="tabs,tabsAAA,optname" vmodels = elem.vmodels || vmodels - var optName = args[2] || widget //尝试获得配置项的名字,没有则取widget的名字 for (var i = 0, v; v = vmodels[i++]; ) { if (v.hasOwnProperty(optName) && typeof v[optName] === "object") { - var nearestVM = v + var vmOptions = v[optName] + vmOptions = vmOptions.$model || vmOptions break } } - if (nearestVM) { - var vmOptions = nearestVM[optName] - vmOptions = vmOptions.$model || vmOptions - var id = vmOptions[widget + "Id"] - if (typeof id === "string") { - args[1] = id + if (vmOptions) { + var wid = vmOptions[widget + "Id"] + if (typeof wid === "string") { + id = wid } } - var widgetData = avalon.getWidgetData(elem, args[0]) //抽取data-tooltip-text、data-tooltip-attr属性,组成一个配置对象 - data[widget + "Id"] = args[1] - data[widget + "Options"] = avalon.mix({}, constructor.defaults, vmOptions || {}, widgetData) + //抽取data-tooltip-text、data-tooltip-attr属性,组成一个配置对象 + var widgetData = avalon.getWidgetData(elem, widget) + data.value = [widget, id, optName].join(",") + data[widget + "Id"] = id + data.evaluator = noop + elem.msData["ms-widget-id"] = id + var options = data[widget + "Options"] = avalon.mix({}, constructor.defaults, vmOptions || {}, widgetData) elem.removeAttribute("ms-widget") var vmodel = constructor(elem, data, vmodels) || {} //防止组件不返回VM - data.evaluator = noop - elem.msData["ms-widget-id"] = vmodel.$id || "" - if (vmodel.hasOwnProperty("$init")) { - vmodel.$init() - } - if (vmodel.hasOwnProperty("$remove")) { - function offTree() { - if (!elem.msRetain && !root.contains(elem)) { - vmodel.$remove() - elem.msData = {} - delete VMODELS[vmodel.$id] - return false - } + if (vmodel.$id) { + avalon.vmodels[id] = vmodel + createSignalTower(elem, vmodel) + if (vmodel.hasOwnProperty("$init")) { + vmodel.$init(function() { + var nv = [vmodel].concat(vmodels) + nv.cb = vmodels.cb + avalon.scan(elem, nv) + if (typeof options.onInit === "function") { + options.onInit.call(elem, vmodel, options, vmodels) + } + }) } - if (window.chrome) { - elem.addEventListener("DOMNodeRemovedFromDocument", offTree) - } else { - avalon.tick(offTree) + if (vmodel.hasOwnProperty("$remove")) { + function offTree() { + if (!elem.msRetain && !root.contains(elem)) { + vmodel.$remove() + elem.msData = {} + delete avalon.vmodels[vmodel.$id] + return false + } + } + if (window.chrome) { + elem.addEventListener("DOMNodeRemovedFromDocument", function() { + setTimeout(offTree) + }) + } else { + avalon.tick(offTree) + } } + } else { + avalon.scan(elem, vmodels) } } else if (vmodels.length) { //如果该组件还没有加载,那么保存当前的vmodels elem.vmodels = vmodels } } - } //============================ class preperty binding ======================= @@ -2367,11 +2404,10 @@ //============================= model binding ======================= var duplexBinding = bindingHandlers.duplex //将模型中的字段与input, textarea的value值关联在一起 - var duplexBinding = bindingHandlers.duplex + function fixNull(val) { return val == null ? "" : val } - avalon.duplexHooks = { checked: { get: function(val, data) { @@ -2379,7 +2415,7 @@ } }, string: { - get: function(val) {//同步到VM + get: function(val) { //同步到VM return val }, set: fixNull @@ -2391,21 +2427,15 @@ set: fixNull }, number: { - get: function(val, data) { - delete data.error.number - if (isFinite(val)) { - return parseFloat(val) || 0 - } else { - data.error.number = true - return val - } + get: function(val) { + return isFinite(val) ? parseFloat(val) || 0 : val }, set: fixNull } } - function pipe(val, data, action) { - data.param.replace(rword, function(name) { + function pipe(val, data, action, e) { + data.param.replace(/\w+/g, function(name) { var hook = avalon.duplexHooks[name] if (hook && typeof hook[action] === "function") { val = hook[action](val, data) @@ -2414,6 +2444,7 @@ return val } + //如果一个input标签添加了model绑定。那么它对应的字段将与元素的value连结在一起 //字段变,value就变;value变,字段也跟着变。默认是绑定input事件, duplexBinding.INPUT = function(element, evaluator, data) { @@ -2435,7 +2466,7 @@ if (composing)//处理中文输入法在minlengh下引发的BUG return var val = element.oldValue = element.value //防止递归调用形成死循环 - var lastValue = pipe(val, data, "get") + var lastValue = data.pipe(val, data, "get") if ($elem.data("duplex-observe") !== false) { evaluator(lastValue) callback.call(element, lastValue) @@ -2449,7 +2480,7 @@ //当model变化时,它就会改变value的值 data.handler = function() { - var val = pipe(evaluator(), data, "set") + var val = data.pipe(evaluator(), data, "set") if (val !== element.value) { element.value = val } @@ -2457,7 +2488,7 @@ if (data.isChecked || element.type === "radio") { updateVModel = function() { if ($elem.data("duplex-observe") !== false) { - var lastValue = pipe(element.value, data, "get") + var lastValue = data.pipe(element.value, data, "get") evaluator(lastValue) callback.call(element, lastValue) } @@ -2477,25 +2508,29 @@ log("ms-duplex应用于checkbox上要对应一个数组") array = [array] } - avalon.Array[method](array, pipe(element.value, data, "get")) + avalon.Array[method](array, data.pipe(element.value, data, "get")) callback.call(element, array) } } data.handler = function() { var array = [].concat(evaluator()) //强制转换为数组 - element.checked = array.indexOf(pipe(element.value, data, "get")) >= 0 + element.checked = array.indexOf(data.pipe(element.value, data, "get")) >= 0 } bound("change", updateVModel) } else { - var event = element.attributes["data-duplex-event"] || {} - event = event.value - if (event === "change") { - bound("change", updateVModel) - } else { - bound("input", updateVModel) - bound("compositionstart", compositionStart) - bound("compositionend", compositionEnd) - } + var events = element.getAttribute("data-duplex-event") || "input" + events.replace(rword, function(name) { + switch (name) { + case "input": + bound("input", updateVModel) + bound("compositionstart", compositionStart) + bound("compositionend", compositionEnd) + break + default: + bound(name, updateVModel) + break + } + }) } element.oldValue = element.value launch(function() { @@ -2508,6 +2543,7 @@ registerSubscriber(data) callback.call(element, element.value) } + var TimerID, ribbon = [], launch = noop @@ -2519,15 +2555,18 @@ } el.dispatchEvent(event) } - function onTree() { //disabled状态下改动不触发inout事件 - if (!this.disabled && this.oldValue !== this.value) { - W3CFire(this, "input") + + function onTree(value) { //disabled状态下改动不触发inout事件 + var newValue = arguments.length ? value : this.value + if (!this.disabled && this.oldValue !== newValue) { + var type = this.getAttribute("data-duplex-event") || "input" + type = type.match(rword).shift() + W3CFire(this, type) } } - avalon.tick = function(fn) { if (ribbon.push(fn) === 1) { - TimerID = requestAnimationFrame(ticker) + TimerID = setInterval(ticker, 60) } } function ticker() { @@ -2537,22 +2576,18 @@ ribbon.splice(n, 1) } } - cancelAnimationFrame(TimerID) - TimerID = null - if (ribbon.length) { - TimerID = requestAnimationFrame(ticker) + if (!ribbon.length) { + clearInterval(TimerID) } } - function newSetter(newValue) { - oldSetter.call(this, newValue) - if (newValue !== this.oldValue) { - W3CFire(this, "input") - } + function newSetter(value) { + onSetter.call(this, value) + onTree.call(this, value) } try { var inputProto = HTMLInputElement.prototype - var oldSetter = Object.getOwnPropertyDescriptor(inputProto, "value").set //屏蔽chrome, safari,opera + var onSetter = Object.getOwnPropertyDescriptor(inputProto, "value").set //屏蔽chrome, safari,opera Object.defineProperty(inputProto, "value", { set: newSetter, configurable: true @@ -2560,7 +2595,6 @@ } catch (e) { launch = avalon.tick } - duplexBinding.SELECT = function(element, evaluator, data) { var $elem = avalon(element) function updateVModel() { @@ -2568,10 +2602,10 @@ var val = $elem.val() //字符串或字符串数组 if (Array.isArray(val)) { val = val.map(function(v) { - return pipe(v, data, "get") + return data.pipe(v, data, "get") }) } else { - val = pipe(val, data, "get") + val = data.pipe(val, data, "get") } if (val + "" !== element.oldValue) { evaluator(val) @@ -2599,34 +2633,28 @@ } } data.bound("change", updateVModel) - var innerHTML = NaN - var id = setInterval(function() { - var currHTML = element.innerHTML - if (currHTML === innerHTML) { - clearInterval(id) - //先等到select里的option元素被扫描后,才根据model设置selected属性 - registerSubscriber(data) - } else { - innerHTML = currHTML - } - }, 20) + checkScan(element, function() { + registerSubscriber(data) + data.changed.call(element, evaluator(), data) + }, NaN) } duplexBinding.TEXTAREA = duplexBinding.INPUT //========================= event binding ==================== var eventHooks = avalon.eventHooks //针对firefox, chrome的mouseenter, mouseleave(chrome30+)的补丁已去掉 //针对IE9+, w3c的animationend补丁已经去掉 - if (document.onmousewheel === void 0) { + if (DOC.onmousewheel === void 0) { /* IE6-11 chrome mousewheel wheelDetla 下 -120 上 120 firefox DOMMouseScroll detail 下3 上-3 firefox wheel detlaY 下3 上-3 IE9-11 wheel deltaY 下40 上-40 chrome wheel deltaY 下100 上-100 */ eventHooks.mousewheel = { - type: "DOMMouseScroll", + type: "wheel", deel: function(elem, fn) { return function(e) { - e.wheelDelta = e.detail > 0 ? -120 : 120 + e.wheelDeltaY = e.wheelDelta = e.deltaY > 0 ? -120 : 120 + e.wheelDeltaX = 0 Object.defineProperty(e, "type", { value: "mousewheel" }) diff --git a/examples/avalon.shim.js b/examples/avalon.shim.js index 0e443fd06..db45c9aac 100644 --- a/examples/avalon.shim.js +++ b/examples/avalon.shim.js @@ -1122,9 +1122,10 @@ } }, _remove: function(cls) { - this._set((" " + this + " ").replace(" " + cls + " ", " ").trim()) + this._set((" " + this + " ").replace(" " + cls + " ", " ")) }, __set: function(cls) { + cls = cls.trim() var node = this.node if (typeof node.className === "string") { node.className = cls @@ -1639,7 +1640,8 @@ legend: [1, "
"], option: [1, "