").append(w.parseHTML(e)).find(i):e)}).complete(r&&function(e,t){u.each(r,s||[e.responseText,t,e])})}return this};w.each(["ajaxStart","ajaxStop","ajaxComplete","ajaxError","ajaxSuccess","ajaxSend"],function(e,t){w.fn[t]=function(e){return this.on(t,e)}});w.extend({active:0,lastModified:{},etag:{},ajaxSettings:{url:gn,type:"GET",isLocal:xn.test(mn[1]),global:true,processData:true,async:true,contentType:"application/x-www-form-urlencoded; charset=UTF-8",accepts:{"*":On,text:"text/plain",html:"text/html",xml:"application/xml, text/xml",json:"application/json, text/javascript"},contents:{xml:/xml/,html:/html/,json:/json/},responseFields:{xml:"responseXML",text:"responseText",json:"responseJSON"},converters:{"* text":String,"text html":true,"text json":w.parseJSON,"text xml":w.parseXML},flatOptions:{url:true,context:true}},ajaxSetup:function(e,t){return t?Pn(Pn(e,w.ajaxSettings),t):Pn(w.ajaxSettings,e)},ajaxPrefilter:_n(Ln),ajaxTransport:_n(An),ajax:function(e,n){function N(e,n,r,i){var l,g,y,E,S,T=n;if(b===2){return}b=2;if(u){clearTimeout(u)}f=t;o=i||"";x.readyState=e>0?4:0;l=e>=200&&e<300||e===304;if(r){E=Hn(c,x,r)}E=Bn(c,E,x,l);if(l){if(c.ifModified){S=x.getResponseHeader("Last-Modified");if(S){w.lastModified[s]=S}S=x.getResponseHeader("etag");if(S){w.etag[s]=S}}if(e===204||c.type==="HEAD"){T="nocontent"}else if(e===304){T="notmodified"}else{T=E.state;g=E.data;y=E.error;l=!y}}else{y=T;if(e||!T){T="error";if(e<0){e=0}}}x.status=e;x.statusText=(n||T)+"";if(l){d.resolveWith(h,[g,T,x])}else{d.rejectWith(h,[x,T,y])}x.statusCode(m);m=t;if(a){p.trigger(l?"ajaxSuccess":"ajaxError",[x,c,l?g:y])}v.fireWith(h,[x,T]);if(a){p.trigger("ajaxComplete",[x,c]);if(!--w.active){w.event.trigger("ajaxStop")}}}if(typeof e==="object"){n=e;e=t}n=n||{};var r,i,s,o,u,a,f,l,c=w.ajaxSetup({},n),h=c.context||c,p=c.context&&(h.nodeType||h.jquery)?w(h):w.event,d=w.Deferred(),v=w.Callbacks("once memory"),m=c.statusCode||{},g={},y={},b=0,E="canceled",x={readyState:0,getResponseHeader:function(e){var t;if(b===2){if(!l){l={};while(t=Sn.exec(o)){l[t[1].toLowerCase()]=t[2]}}t=l[e.toLowerCase()]}return t==null?null:t},getAllResponseHeaders:function(){return b===2?o:null},setRequestHeader:function(e,t){var n=e.toLowerCase();if(!b){e=y[n]=y[n]||e;g[e]=t}return this},overrideMimeType:function(e){if(!b){c.mimeType=e}return this},statusCode:function(e){var t;if(e){if(b<2){for(t in e){m[t]=[m[t],e[t]]}}else{x.always(e[x.status])}}return this},abort:function(e){var t=e||E;if(f){f.abort(t)}N(0,t);return this}};d.promise(x).complete=v.add;x.success=x.done;x.error=x.fail;c.url=((e||c.url||gn)+"").replace(wn,"").replace(Nn,mn[1]+"//");c.type=n.method||n.type||c.method||c.type;c.dataTypes=w.trim(c.dataType||"*").toLowerCase().match(S)||[""];if(c.crossDomain==null){r=Cn.exec(c.url.toLowerCase());c.crossDomain=!!(r&&(r[1]!==mn[1]||r[2]!==mn[2]||(r[3]||(r[1]==="http:"?"80":"443"))!==(mn[3]||(mn[1]==="http:"?"80":"443"))))}if(c.data&&c.processData&&typeof c.data!=="string"){c.data=w.param(c.data,c.traditional)}Dn(Ln,c,n,x);if(b===2){return x}a=c.global;if(a&&w.active++===0){w.event.trigger("ajaxStart")}c.type=c.type.toUpperCase();c.hasContent=!Tn.test(c.type);s=c.url;if(!c.hasContent){if(c.data){s=c.url+=(bn.test(s)?"&":"?")+c.data;delete c.data}if(c.cache===false){c.url=En.test(s)?s.replace(En,"$1_="+yn++):s+(bn.test(s)?"&":"?")+"_="+yn++}}if(c.ifModified){if(w.lastModified[s]){x.setRequestHeader("If-Modified-Since",w.lastModified[s])}if(w.etag[s]){x.setRequestHeader("If-None-Match",w.etag[s])}}if(c.data&&c.hasContent&&c.contentType!==false||n.contentType){x.setRequestHeader("Content-Type",c.contentType)}x.setRequestHeader("Accept",c.dataTypes[0]&&c.accepts[c.dataTypes[0]]?c.accepts[c.dataTypes[0]]+(c.dataTypes[0]!=="*"?", "+On+"; q=0.01":""):c.accepts["*"]);for(i in c.headers){x.setRequestHeader(i,c.headers[i])}if(c.beforeSend&&(c.beforeSend.call(h,x,c)===false||b===2)){return x.abort()}E="abort";for(i in{success:1,error:1,complete:1}){x[i](c[i])}f=Dn(An,c,n,x);if(!f){N(-1,"No Transport")}else{x.readyState=1;if(a){p.trigger("ajaxSend",[x,c])}if(c.async&&c.timeout>0){u=setTimeout(function(){x.abort("timeout")},c.timeout)}try{b=1;f.send(g,N)}catch(T){if(b<2){N(-1,T)}else{throw T}}}return x},getJSON:function(e,t,n){return w.get(e,t,n,"json")},getScript:function(e,n){return w.get(e,t,n,"script")}});w.each(["get","post"],function(e,n){w[n]=function(e,r,i,s){if(w.isFunction(r)){s=s||i;i=r;r=t}return w.ajax({url:e,type:n,dataType:s,data:r,success:i})}});w.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/(?:java|ecma)script/},converters:{"text script":function(e){w.globalEval(e);return e}}});w.ajaxPrefilter("script",function(e){if(e.cache===t){e.cache=false}if(e.crossDomain){e.type="GET";e.global=false}});w.ajaxTransport("script",function(e){if(e.crossDomain){var n,r=o.head||w("head")[0]||o.documentElement;return{send:function(t,i){n=o.createElement("script");n.async=true;if(e.scriptCharset){n.charset=e.scriptCharset}n.src=e.url;n.onload=n.onreadystatechange=function(e,t){if(t||!n.readyState||/loaded|complete/.test(n.readyState)){n.onload=n.onreadystatechange=null;if(n.parentNode){n.parentNode.removeChild(n)}n=null;if(!t){i(200,"success")}}};r.insertBefore(n,r.firstChild)},abort:function(){if(n){n.onload(t,true)}}}}});var jn=[],Fn=/(=)\?(?=&|$)|\?\?/;w.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var e=jn.pop()||w.expando+"_"+yn++;this[e]=true;return e}});w.ajaxPrefilter("json jsonp",function(n,r,i){var s,o,u,a=n.jsonp!==false&&(Fn.test(n.url)?"url":typeof n.data==="string"&&!(n.contentType||"").indexOf("application/x-www-form-urlencoded")&&Fn.test(n.data)&&"data");if(a||n.dataTypes[0]==="jsonp"){s=n.jsonpCallback=w.isFunction(n.jsonpCallback)?n.jsonpCallback():n.jsonpCallback;if(a){n[a]=n[a].replace(Fn,"$1"+s)}else if(n.jsonp!==false){n.url+=(bn.test(n.url)?"&":"?")+n.jsonp+"="+s}n.converters["script json"]=function(){if(!u){w.error(s+" was not called")}return u[0]};n.dataTypes[0]="json";o=e[s];e[s]=function(){u=arguments};i.always(function(){e[s]=o;if(n[s]){n.jsonpCallback=r.jsonpCallback;jn.push(s)}if(u&&w.isFunction(o)){o(u[0])}u=o=t});return"script"}});var In,qn,Rn=0,Un=e.ActiveXObject&&function(){var e;for(e in In){In[e](t,true)}};w.ajaxSettings.xhr=e.ActiveXObject?function(){return!this.isLocal&&zn()||Wn()}:zn;qn=w.ajaxSettings.xhr();w.support.cors=!!qn&&"withCredentials"in qn;qn=w.support.ajax=!!qn;if(qn){w.ajaxTransport(function(n){if(!n.crossDomain||w.support.cors){var r;return{send:function(i,s){var o,u,a=n.xhr();if(n.username){a.open(n.type,n.url,n.async,n.username,n.password)}else{a.open(n.type,n.url,n.async)}if(n.xhrFields){for(u in n.xhrFields){a[u]=n.xhrFields[u]}}if(n.mimeType&&a.overrideMimeType){a.overrideMimeType(n.mimeType)}if(!n.crossDomain&&!i["X-Requested-With"]){i["X-Requested-With"]="XMLHttpRequest"}try{for(u in i){a.setRequestHeader(u,i[u])}}catch(f){}a.send(n.hasContent&&n.data||null);r=function(e,i){var u,f,l,c;try{if(r&&(i||a.readyState===4)){r=t;if(o){a.onreadystatechange=w.noop;if(Un){delete In[o]}}if(i){if(a.readyState!==4){a.abort()}}else{c={};u=a.status;f=a.getAllResponseHeaders();if(typeof a.responseText==="string"){c.text=a.responseText}try{l=a.statusText}catch(h){l=""}if(!u&&n.isLocal&&!n.crossDomain){u=c.text?200:404}else if(u===1223){u=204}}}}catch(p){if(!i){s(-1,p)}}if(c){s(u,l,c,f)}};if(!n.async){r()}else if(a.readyState===4){setTimeout(r)}else{o=++Rn;if(Un){if(!In){In={};w(e).unload(Un)}In[o]=r}a.onreadystatechange=r}},abort:function(){if(r){r(t,true)}}}}})}var Xn,Vn,$n=/^(?:toggle|show|hide)$/,Jn=new RegExp("^(?:([+-])=|)("+E+")([a-z%]*)$","i"),Kn=/queueHooks$/,Qn=[nr],Gn={"*":[function(e,t){var n=this.createTween(e,t),r=n.cur(),i=Jn.exec(t),s=i&&i[3]||(w.cssNumber[e]?"":"px"),o=(w.cssNumber[e]||s!=="px"&&+r)&&Jn.exec(w.css(n.elem,e)),u=1,a=20;if(o&&o[3]!==s){s=s||o[3];i=i||[];o=+r||1;do{u=u||".5";o=o/u;w.style(n.elem,e,o+s)}while(u!==(u=n.cur()/r)&&u!==1&&--a)}if(i){o=n.start=+o||+r||0;n.unit=s;n.end=i[1]?o+(i[1]+1)*i[2]:+i[2]}return n}]};w.Animation=w.extend(er,{tweener:function(e,t){if(w.isFunction(e)){t=e;e=["*"]}else{e=e.split(" ")}var n,r=0,i=e.length;for(;r
-1,f={},l={},c,h;if(a){l=i.position();c=l.top;h=l.left}else{c=parseFloat(o)||0;h=parseFloat(u)||0}if(w.isFunction(t)){t=t.call(e,n,s)}if(t.top!=null){f.top=t.top-s.top+c}if(t.left!=null){f.left=t.left-s.left+h}if("using"in t){t.using.call(e,f)}else{i.css(f)}}};w.fn.extend({position:function(){if(!this[0]){return}var e,t,n={top:0,left:0},r=this[0];if(w.css(r,"position")==="fixed"){t=r.getBoundingClientRect()}else{e=this.offsetParent();t=this.offset();if(!w.nodeName(e[0],"html")){n=e.offset()}n.top+=w.css(e[0],"borderTopWidth",true);n.left+=w.css(e[0],"borderLeftWidth",true)}return{top:t.top-n.top-w.css(r,"marginTop",true),left:t.left-n.left-w.css(r,"marginLeft",true)}},offsetParent:function(){return this.map(function(){var e=this.offsetParent||u;while(e&&!w.nodeName(e,"html")&&w.css(e,"position")==="static"){e=e.offsetParent}return e||u})}});w.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(e,n){var r=/Y/.test(n);w.fn[e]=function(i){return w.access(this,function(e,i,s){var o=sr(e);if(s===t){return o?n in o?o[n]:o.document.documentElement[i]:e[i]}if(o){o.scrollTo(!r?s:w(o).scrollLeft(),r?s:w(o).scrollTop())}else{e[i]=s}},e,i,arguments.length,null)}});w.each({Height:"height",Width:"width"},function(e,n){w.each({padding:"inner"+e,content:n,"":"outer"+e},function(r,i){w.fn[i]=function(i,s){var o=arguments.length&&(r||typeof i!=="boolean"),u=r||(i===true||s===true?"margin":"border");return w.access(this,function(n,r,i){var s;if(w.isWindow(n)){return n.document.documentElement["client"+e]}if(n.nodeType===9){s=n.documentElement;return Math.max(n.body["scroll"+e],s["scroll"+e],n.body["offset"+e],s["offset"+e],s["client"+e])}return i===t?w.css(n,r,u):w.style(n,r,i,u)},n,o?i:t,o,null)}})});w.fn.size=function(){return this.length};w.fn.andSelf=w.fn.addBack;if(typeof module==="object"&&module&&typeof module.exports==="object"){module.exports=w}else{e.jQuery=e.$=w;if(typeof define==="function"&&define.amd){define("jquery",[],function(){return w})}}})(window);(function(e,t,n){"use strict";function O(e,t){if(t&&t.onError){if(t.onError(e)===false){return}}this.name="JsRender Error";this.message=e||"JsRender error"}function M(e,t){var n;e=e||{};for(n in t){e[n]=t[n]}return e}function _(e,t,n){if(!it.rTag||e){a=e?e.charAt(0):a;f=e?e.charAt(1):f;l=t?t.charAt(0):l;c=t?t.charAt(1):c;h=n||h;e="\\"+a+"(\\"+h+")?\\"+f;t="\\"+l+"\\"+c;o="(?:(?:(\\w+(?=[\\/\\s\\"+l+"]))|(?:(\\w+)?(:)|(>)|!--((?:[^-]|-(?!-))*)--|(\\*)))"+"\\s*((?:[^\\"+l+"]|\\"+l+"(?!\\"+c+"))*?)";it.rTag=o+")";o=new RegExp(e+o+"(\\/)?|(?:\\/(\\w+)))"+t,"g");u=new RegExp("<.*>|([^\\\\]|^)[{}]|"+e+".*"+t)}return[a,f,l,c,h]}function D(e,t){if(!t){t=e;e=n}var r,i,s,o,u=this,a=!t||t==="root";if(e){o=u.type===t?u:n;if(!o){r=u.views;if(u._.useKey){for(i in r){if(o=r[i].get(e,t)){break}}}else for(i=0,s=r.length;!o&&i0){try{h=n.nodeType>0?n:!u.test(n)&&t&&t(e.document).find(n)[0]}catch(i){}if(h){n=h.getAttribute(C);r=r||n;n=et[n];if(!n){r=r||"_"+x++;h.setAttribute(C,r);n=et[r]=z(r,h.innerHTML,s,o,a,f)}}return n}}var c,h;i=i||"";c=l(i);f=f||(i.markup?i:{});f.tmplName=r;if(s){f._parentTmpl=s}if(!c&&i.markup&&(c=l(i.markup))){if(c.fn&&(c.debug!==i.debug||c.allowCode!==i.allowCode)){c=c.markup}}if(c!==n){if(r&&!s){k[r]=function(){return i.render.apply(i,arguments)}}if(c.fn||i.fn){if(c.fn){if(r&&r!==c.tmplName){i=Y(f,c)}else{i=c}}}else{i=W(c,f);K(c.replace(g,"\\$&"),i)}R(f);return i}}function W(e,t){var n,r=st.wrapMap||{},s=M({markup:e,tmpls:[],links:{},tags:{},bnds:[],_is:"template",render:V},t);if(!t.htmlTag){n=w.exec(e);s.htmlTag=n?n[1].toLowerCase():""}n=r[s.htmlTag];if(n&&n!==r.div){s.markup=i.trim(s.markup)}return s}function X(e,t){function r(s,o,u){var a,f,l,c;if(s&&""+s!==s&&!s.nodeType&&!s.markup){for(l in s){r(l,s[l],o)}return A}if(o===n){o=s;s=n}if(s&&""+s!==s){u=o;o=s;s=n}c=u?u[i]=u[i]||{}:r;f=t.compile;if(a=it.onBeforeStoreItem){f=a(c,s,o,f)||f}if(!s){o=f(n,o)}else if(o===null){delete c[s]}else{c[s]=f?o=f(s,o,u,e,t):o}if(f&&o){o._is=e}if(a=it.onStoreItem){a(c,s,o,f)}return o}var i=e+"s";A[i]=r;L[e]=t}function V(e,t,r,s,o,u){var a,f,l,c,h,p,d,v,m,g,y,b,w,E=this,S=!E.attr||E.attr==="html",x="";if(s===true){d=true;s=0}if(E.tag){v=E;E=E.tag;g=E._;b=E.tagName;w=v.tmpl;t=Y(t,E.ctx);m=v.content;if(v.props.link===false){t=t||{};t.link=false}r=r||v.view;e=e===n?r:e}else{w=E.jquery&&(E[0]||$('Unknown template: "'+E.selector+'"'))||E}if(w){if(!r&&e&&e._is==="view"){r=e}if(r){m=m||r.content;u=u||r._.onRender;if(e===r){e=r.data;o=true}t=Y(t,r.ctx)}if(!r||r.data===n){(t=t||{}).root=e}if(!w.fn){w=et[w]||et(w)}if(w){u=(t&&t.link)!==false&&S&&u;y=u;if(u===true){y=n;u=r._.onRender}t=w.helpers?Y(w.helpers,t):t;if(i.isArray(e)&&!o){c=d?r:s!==n&&r||q(t,"array",r,e,w,s,m,u);for(a=0,f=e.length;a":u+o}if(_){L="prm"+i;_="try{var "+L+"=["+a+"][0];}catch(e){"+L+'="";}\n';a=L}}else{if(S){w=W(x,D);w.tmplName=b+"/"+o;Q(S,w);y.push(w)}if(!C){E=o;N=M;M=""}T=e[i+1];T=T&&T[0]==="else"}f+=",args:["+a+"]}";if(k&&g||u&&o!==">"){A=new Function("data,view,j,u"," // "+b+" "+O+" "+o+"\n"+_+"return {"+f+";");A.paths=g;A._ctxs=o;if(r){return A}d=1}M+=k?"\n"+(g?"":_)+(r?"return ":"ret+=")+(d?(d=0,p=true,'c("'+u+'",view,'+(g?(m[O-1]=A,O):"{"+f)+");"):o===">"?(c=true,"h("+a+");"):(h=true,"(v="+a+")!="+(r?"=":"")+'u?v:"";')):(l=true,"{view:view,tmpl:"+(S?y.length:"0")+","+f+",");if(E&&!T){M="["+M.slice(0,-1)+"]";if(r||g){M=new Function("data,view,j,u"," // "+b+" "+O+" "+E+"\nreturn "+M+";");if(g){(m[O-1]=M).paths=g}M._ctxs=o;if(r){return M}}M=N+'\nret+=t("'+E+'",view,this,'+(O||M)+");";g=0;E=0}}}}M="// "+b+"\nvar j=j||"+(t?"jQuery.":"js")+"views"+(h?",v":"")+(l?",t=j._tag":"")+(p?",c=j._cnvt":"")+(c?",h=j.converters.html":"")+(r?";\n":',ret="";\n')+(st.tryCatch?"try{\n":"")+(D.debug?"debugger;":"")+M+(r?"\n":"\nreturn ret;\n")+(st.tryCatch?"\n}catch(e){return j._err(e);}":"");try{M=new Function("data,view,j,u",M)}catch(H){J("Compiled template code:\n\n"+M,H)}if(n){n.fn=M}return M}function G(e,t,n){function r(r,d,b,w,E,S,x,T,N,C,k,L,A,O,M,_,D,P,H,B){function F(e,n,r,u,a,f,l,c){if(r){if(t){if(i==="linkTo"){s=t._jsvto=t._jsvto||[];s.push(E)}if(!i||o){t.push(E.slice(n.length))}}if(r!=="."){var h=(u?'view.hlp("'+u+'")':a?"view":"data")+(c?(f?"."+f:u?"":a?"":"."+r)+(l||""):(c=u?"":a?f||"":r,""));h=h+(c?"."+c:"");return n+(h.slice(0,9)==="view.data"?h.slice(5):h)}}return e}var j;S=S||"";b=b||d||L;E=E||N;C=C||D||"";if(x){J(e)}else{if(t&&_&&!y&&!g){if(!i||o||s){j=v[m];if(B.length-1>H-j){j=B.slice(j,H+1);_=f+":"+j+l;_=u[_]=u[_]||K(a+_+c,n,true);if(!_.paths){G(j,_.paths=[],n)}(s||t).push({_jsvOb:_})}}}return y?(y=!A,y?r:'"'):g?(g=!O,g?r:'"'):(b?(m++,v[m]=H++,b):"")+(P?m?"":i?(i=o=s=false,"\b"):",":T?(m&&J(e),i=E,o=w,"\b"+E+":"):E?E.split("^").join(".").replace(p,F)+(C?(h[++m]=true,E.charAt(0)!=="."&&(v[m]=H),C):S):S?S:M?(h[m--]=false,M)+(C?(h[++m]=true,C):""):k?(h[m]||J(e),","):d?"":(y=A,g=O,'"'))}}var i,s,o,u=n.links,h={},v={0:-1},m=0,g=false,y=false;return(e+" ").replace(/\)\^/g,").").replace(d,r)}function Y(e,t){return e&&e!==t?t?M(M({},t),e):e:t&&M({},t)}function Z(e){return N[e]||(N[e]=""+e.charCodeAt(0)+";")}function ut(e){var t=this,r=t.tagCtx,s=!arguments.length,o="",u=s||0;if(!t.rendering.done){if(s){o=n}else if(e!==n){e=t.prep?t.prep(e):e;o+=r.render(e);u+=i.isArray(e)?e.length:1}if(t.rendering.done=u){t.selected=r.index}}return o}if(t&&t.views||e.jsviews){return}var r="v1.0.0-beta",i,s,o,u,a="{",f="{",l="}",c="}",h="^",p=/^(!*?)(?:null|true|false|\d[\d.]*|([\w$]+|\.|~([\w$]+)|#(view|([\w$]+))?)([\w$.^]*?)(?:[.[^]([\w$]+)\]?)?)$/g,d=/(\()(?=\s*\()|(?:([([])\s*)?(?:(\^?)(!*?[#~]?[\w$.^]+)?\s*((\+\+|--)|\+|-|&&|\|\||===|!==|==|!=|<=|>=|[<>%*:?\/]|(=))\s*|(!*?[#~]?[\w$.^]+)([([])?)|(,\s*)|(\(?)\\?(?:(')|("))|(?:\s*(([)\]])(?=\s*\.|\s*\^|\s*$)|[)\]])([([]?))|(\s+)/g,v=/[ \t]*(\r\n|\n|\r)/g,m=/\\(['"])/g,g=/['"\\]/g,y=/\x08(~)?([^\x08]+)\x08/g,b=/^if\s/,w=/<(\w+)[>\s]/,E=/[\x00`><"'&]/g,S=E,x=0,T=0,N={"&":"&","<":"<",">":">","\0":"","'":"'",'"':""","`":"`"},C="data-jsv-tmpl",k={},L={template:{compile:z},tag:{compile:U},helper:{},converter:{}},A={jsviews:r,render:k,settings:{delimiters:_,debugMode:true,tryCatch:true},sub:{View:q,Error:O,tmplFn:K,parse:G,extend:M,error:$,syntaxError:J},_cnvt:j,_tag:I,_err:function(e){return st.debugMode?"Error: "+(e.message||e)+". ":""}};(O.prototype=new Error).constructor=O;P.depends=function(){return[this.get("item"),"index"]};H.depends=function(){return["index"]};for(s in L){X(s,L[s])}var et=A.templates,tt=A.converters,nt=A.helpers,rt=A.tags,it=A.sub,st=A.settings,ot="Error: #index in nested view: use #getIndex()";if(t){i=t;i.fn.render=V}else{i=e.jsviews={};i.isArray=Array&&Array.isArray||function(e){return Object.prototype.toString.call(e)==="[object Array]"}}i.render=k;i.views=A;i.templates=et=A.templates;rt({"else":function(){},"if":{render:function(e){var t=this,n=t.rendering.done||!e&&(arguments.length||!t.tagCtx.index)?"":(t.rendering.done=true,t.selected=t.tagCtx.index,t.tagCtx.render());return n},onUpdate:function(e,t,n){var r,i,s;for(r=0;(i=this.tagCtxs[r])&&i.args.length;r++){i=i.args[0];s=!i!==!n[r].args[0];if(!!i||s){return s}}return false},flow:true},"for":{render:ut,onArrayChange:function(e,t){var n,r=this,i=t.change;if(this.tagCtxs[1]&&(i==="insert"&&e.target.length===t.items.length||i==="remove"&&!e.target.length||i==="refresh"&&!t.oldItems.length!==!e.target.length)){this.refresh()}else{for(n in r._.arrVws){n=r._.arrVws[n];if(n.data===e.target){n._.onArrayChange.apply(n,arguments)}}}e.done=true},flow:true},props:{prep:function(e){var t,n=[];for(t in e){n.push({key:t,prop:e[t]})}return n},render:ut,flow:true},include:{flow:true},"*":{render:function(e){return e},flow:true}});tt({html:function(e){return e!=n?String(e).replace(S,Z):""},attr:function(e){return e!=n?String(e).replace(E,Z):e===null?e:""},url:function(e){return e!=n?encodeURI(String(e)):e===null?e:""}});_()})(this,this.jQuery);(function(e,t,n){"use strict";function x(e){return l(e)?new N(e):new T(e)}function T(e){this._data=e;return this}function N(e){this._data=e;return this}function C(e){return l(e)?[e]:e}function k(e,t){e=l(e)?e:[e];var n,r,i=t,s=i,o=e.length,u=[];for(n=0;n1){f=f[u.shift()]}a._setProperty(f,u.join("."),t,r)}}return a},_setProperty:function(e,t,n,r){var i,s,o=t?e[t]:e;if(y(o)){if(o.set){s=o;i=o.set===true?o:o.set;o=o.call(e)}}if(o!==n||r&&o!=n){if(!(o instanceof Date)||o>n||o-1&&e<=n.length){t=l(t)?t:[t];if(t.length){this._insert(e,t)}}return this},_insert:function(e,t){var n=this._data,r=n.length;f.apply(n,[e,0].concat(t));this._trigger({change:"insert",index:e,items:t},r)},remove:function(e,t){var r,i=this._data;if(e===n){e=i.length-1}e=p(e);t=t?p(t):t===0?0:1;if(t>-1&&e>-1){r=i.slice(e,e+t);t=r.length;if(t){this._remove(e,t,r)}}return this},_remove:function(e,t,n){var r=this._data,i=r.length;r.splice(e,t);this._trigger({change:"remove",index:e,items:n},i)},move:function(e,t,n){n=n?p(n):n===0?0:1;e=p(e);t=p(t);if(n>0&&e>-1&&t>-1&&e!==t){var r=this._data.slice(e,e+n);n=r.length;if(n){this._move(e,t,n,r)}}return this},_move:function(e,t,n,r){var i=this._data,s=i.length;i.splice(e,n);i.splice.apply(i,[t,0].concat(r));this._trigger({change:"move",oldIndex:e,index:t,items:r},s)},refresh:function(e){var t=this._data.slice(0);this._refresh(t,e);return this},_refresh:function(e,t){var n=this._data,r=n.length;f.apply(n,[0,n.length].concat(t));this._trigger({change:"refresh",oldItems:e},r)},_trigger:function(e,n){var r=this._data,i=r.length,s=t([r]);s.triggerHandler(v,e);if(i!==n){s.triggerHandler(d,{change:"set",path:"length",value:i,oldValue:n})}}};o[d]=o[v]={remove:function(e){if((e=e.data)&&(e.off=1,e=e.cb)){i=m[s=e._bnd]}},teardown:function(e){if(i){delete i[t.data(this,"obId")];L(i,s)}}}})(this,this.jQuery||this.jsviews);(function(e,t,n){"use strict";function ht(e){var n=this.linkedElem;if(n){pt({target:n[0],stopImmediatePropagation:t.noop},e)}}function pt(e,r){var i,s,o,u,a,f,l,c,h,p,d,v,m,g,y,b,E,S,T=e.target,d=T._jsvBnd,N=/&(\d+)\+?/g;if(d){while(p=N.exec(d)){if(p=rt[p[1]]){if(E=p.to){u=p.linkCtx;h=u.view;b=u.tag;c=t(T);g=h.hlp(M);y=h.hlp(_);o=wt(T);i=R[o];if(r===n){r=w(o)?o(T):i?c[i]():c.attr(o)}f=E[1];E=E[0];if(f){if(w(f)){a=f}else{a=h.getRsc("converters",f)}}if(a){r=a.call(b,r)}m=h.linkCtx;h.linkCtx=u;S={change:"change",oldValue:u._val,value:r};if((!g||!(s=g.call(u,e,S)===false))&&(!b||!b.onBeforeChange||!(s=b.onBeforeChange(e,S)===false))&&r!==n){l=E[0];if(r!==n&&l){l=l._jsvOb?l._ob:l;if(b){b._.chging=true}x(l).setProperty(E[2]||E[1],r);if(y){y.call(u,e,S)}if(b){if(b.onAfterChange){b.onAfterChange(e,S)}delete b._.chging}}}h.linkCtx=m;if(s){e.stopImmediatePropagation()}}}}}}function dt(e,r,i){var s,o,u,a=this,f=a.data,l=a.elem,c=a.convert,h=l.parentNode,p=h,d=a.view,m=d.ctx,g=d.linkCtx,y=d.hlp(M);d.linkCtx=a;if(h&&(!y||!(r&&y.call(a,e,r)===false))&&!(r&&e.data.prop!=="*"&&e.data.prop!==r.path)){if(r){a.eventArgs=r}if(r||a._initVal){delete a._initVal;o=i.call(d.tmpl,f,d,v);s=vt(o,a,u,a.attr||wt(l,true,c!==n));if(u=a.tag){if(r&&u.onUpdate&&u.onUpdate(e,r,o)===false||s==="none"){u.tagCtxs=o=o[0]?o:[o];u.tagCtx=o[0];if(s==="html"){u.onBeforeLink&&u.onBeforeLink()}It(u,u.tagCtx);xt(a,f,l);d.linkCtx=g;return}if(u._.chging){return}o=u.tagName.slice(-1)===":"?v._cnvt(u.tagName.slice(0,-1),d,o):v._tag(u,d,d.tmpl,o,true)}else if(i._ctxs){c=c===""?"true":c;o=c?v._cnvt(c,d,o):v._tag(i._ctxs,d,d.tmpl,o,true);u=d._.tag;s=a.attr||s}if(mt(o,a,s,u)&&r&&(y=d.hlp(_))){y.call(a,e,r)}}if(u){u.contents=Ht;u.nodes=Bt;u.childTags=jt;u.currentCtxs=Ft;u.update=ht;u.refresh=Rt;It(u,u.tagCtx)}if((u=a.tag)&&u.tagName.slice(-1)!==":"){a._hdlr.array=u.onArrayChange?function(e,t){a.tag.onArrayChange(e,t)}:t.noop}xt(a,f,l);d.linkCtx=g}}function vt(e,r,i,s){var o,u,a,f,l=i&&i.parentElem||r.elem;if(e!==n){f=t(l);s=i&&i.attr||s;if(w(e)){X(r.expr+": missing parens")}if(s==="visible"){s="css-display"}if(a=/^css-/.test(s)&&s.slice(4)){o=t.style(l,a);if(+e===e){o=parseInt(o)}o=t.style(l,a)}else if(s!=="link"){if(s==="value"){if(l.type===H){o=f.prop(s=P)}}else if(s===B){if(l.value===""+e){o=f.prop(P)}else{return s}}if(o===n){u=R[s];o=u?f[u]():f.attr(s)}}r._val=o}return s}function mt(e,r,i,s){var o,u,a,f,l,c,h,p=e!==n,d=r.data,v=s&&s.parentElem||r.elem,m=t(v),g=r.view,y=r._val,b=g.ctx,w=g.linkCtx,E=s||i==="html";if(s){s.parentElem=s.parentElem||r.expr||s._elCnt?v:v.parentNode;a=s._prv;f=s._nxt}if(!p){if(i==="html"&&s&&s.onBeforeLink){s.onBeforeLink()}return}if(/^css-/.test(i)){if(i==="css-display"){e=e?yt(v):"none"}if(E=E||y!==e){t.style(v,i.slice(4),e)}}else if(i!=="link"){if(i===P){h=1;e=e&&e!=="false"}else if(i===B){if(v.value===""+e){e=true;h=1;i=P}else{xt(r,d,v);return}}else if(i==="selected"||i==="disabled"||i==="multiple"||i==="readlonly"){e=e&&e!=="false"?i:null}if(o=R[i]){if(i==="html"){g.linkCtx=r;g.ctx=r.ctx;if(s&&s._.inline){c=s.nodes(true);if(s._elCnt){if(a&&a!==f){Jt(a,f,v,s._tgId,"^",true)}a=a?a.previousSibling:f?f.previousSibling:v.lastChild}t(c).remove();if(s&&s.onBeforeLink){s.onBeforeLink()}l=g.link(g.data,v,a,f,e,s&&{tag:s._tgId,lazyLink:s.tagCtx.props.lazyLink})}else{if(p){m.empty()}if(s&&s.onBeforeLink){s.onBeforeLink()}if(p){l=g.link(d,v,a,f,e,s&&{tag:s._tgId})}}g.linkCtx=w;g.ctx=b}else if(E=E||y!==e){if(i==="text"&&v.children&&!v.children[0]){if(v.textContent!==n){v.textContent=e}else{v.innerText=e===null?"":e}}else{m[o](e)}}}else if(E=E||y!==e){m[h?"prop":"attr"](i,e===n&&!h?null:e)}r._val=e}return l||E}function gt(e,t){var n=this,r=n.hlp(M),i=n.hlp(_);if(!r||r.call(this,e,t)!==false){if(t){var s=t.change,o=t.index,u=t.items;switch(s){case"insert":n.addViews(o,u);break;case"remove":n.removeViews(o,u.length);break;case"move":n.refresh();break;case"refresh":n.refresh();break}}if(i){i.call(this,e,t)}}}function yt(t){var n,r,i=e.getComputedStyle,s=(t.currentStyle||i.call(e,t,"")).display;if(s==="none"&&!(s=tt[r=t.nodeName])){n=d.createElement(r);d.body.appendChild(n);s=(i?i.call(e,n,""):n.currentStyle).display;tt[r]=s;d.body.removeChild(n)}return s}function bt(e){var r,i,s=e.data,o=e._.bnd;if(!e._.useKey&&o){if(i=e._.bndArr){t([i[1]]).off(L,i[0]);e._.bndArr=n}if(o!==!!o&&o._.inline){if(s){o._.arrVws[e._.id]=e}else{delete o._.arrVws[e._.id]}}else if(s){r=function(t){if(!(t.data&&t.data.off)){gt.apply(e,arguments)}};t([s]).on(L,r);e._.bndArr=[r,s]}}}function wt(e,t,n){var r=e.nodeName.toLowerCase(),i=g.merge[r];return i?t?r==="input"&&e.type===B?B:i.to:i.from:t?n?"text":"html":""}function Et(e,r,i,s,o,u,a){var f,l,c,h,p,d=e.parentElem,v=e._prv,m=e._nxt,g=e._elCnt;if(v&&v.parentNode!==d){X("Missing parentNode")}if(a){h=e.nodes();if(g&&v&&v!==m){Jt(v,m,d,e._.id,"_",true)}e.removeViews(n,n,true);l=m;if(g){v=v?v.previousSibling:m?m.previousSibling:d.lastChild}t(h).remove();for(p in e._.bnds){zt(p)}}else{if(r){c=s[r-1];if(!c){return false}v=c._nxt}if(g){l=v;v=l?l.previousSibling:d.lastChild}else{l=v.nextSibling}}f=i.render(o,u,e,a||r,e._.useKey&&a,true);e.link(o,d,v,l,f,c)}function St(e,t,r){var i,s,o,u;if(r){o="^`";s=t._.tag||{_:{inline:true,bnd:r},tagCtx:{view:t},flow:true};i=s._tgId;if(!i){rt[i=it++]=s;s._tgId=""+i}}else{o="_`";nt[i=t._.id]=t}return"#"+i+o+(e===n?"":e)+"/"+i+o}function xt(e,t,r){var i,s,o,u=e.convertBack,a=e.tag,f=[],l=e._bndId||""+it++,c=e._hdlr;delete e._bndId;if(a){o=a.linkedElem,f=a.depends||f;f=w(f)?a.depends(a):f}if(!e._depends||""+e._depends!==""+f){if(e._depends){x._apply(t,e._depends,c,true)}i=x._apply(t,e.fn.paths,f,c,e._ctxCb);i.elem=r;i.linkCtx=e;i._tgId=l;r._jsvBnd=r._jsvBnd||"";r._jsvBnd+="&"+l;if(o){i.to=[[],u];s=o.length;while(s--){o[s]._jsvBnd=r._jsvBnd+"+"}}e._depends=f;e.view._.bnds[l]=l;rt[l]=i;if(a){if(a.onAfterBind){a.onAfterBind(i)}if(!a.flow&&!a._.inline){r.setAttribute(N,(r.getAttribute(N)||"")+"#"+l+"^/"+l+"^");a._tgId=""+l}}if(o||u!==n){qt(i,u)}}}function Tt(e,t,n,r,i,s){return Nt(this,e,t,n,r,i,s)}function Nt(e,r,i,u,a,f,l){if(e&&r){r=r.jquery?r:t(r);if(!s){s=d.body;t(s).on(O,pt)}var c,h,p,v,m,g,y,b,w,E=St,S=u&&u.target==="replace",x=r.length;while(x--){y=r[x];if(""+e===e){m=o(y);b=m.ctx;m.ctx=u;kt(e,y,o(y),i);m.ctx=b}else{a=a||o(y);if(e.markup!==n){if(a.link===false){u=u||{};u.link=E=false}if(S){g=y.parentNode}p=e.render(i,u,a,n,n,E);if(g){f=y.previousSibling;l=y.nextSibling;t.cleanData([y],true);g.removeChild(y);y=g}else{f=l=n;t(y).empty()}}else if(e!==true){break}if(y._dfr&&!l){v=Mt(y._dfr,true,ut);for(c=0,h=v.length;c' in:\n"+a)}}Et=wt;pt=Xt.shift();wt=G[pt];c=c?""+c+">":"";if(Et){zt+=Tt;Tt="";if(!wt){m=c+F+"@"+zt+j+(h||"");zt=Vt.shift()}else{zt+="-"}}}if(wt){if(o){Tt+=o}else{t=c||d||""}if(w){t+=w;if(Tt){t+=" "+N+'="'+Tt+'"';Tt=""}}}else{t=o?t+m+s+F+o+j+u+w:m||e}if(w){Xt.unshift(pt);pt=w.slice(1);if(Xt[0]&&Xt[0]===Y[pt]){X("Parent of must be ")}dt=et[pt];if((wt=G[pt])&&!Et){Vt.unshift(zt);zt=""}Et=wt;if(zt&&wt){zt+="+"}}return t}function h(e,t){var s,o,u,a,f,l,c,h=[];if(e){if(e._tkns.charAt(0)==="@"){t=L.previousSibling;L.parentNode.removeChild(L);L=null}T=e.length;while(T--){M=e[T];u=M.ch;if(s=M.path){x=s.length-1;while(o=s.charAt(x--)){if(o==="+"){if(s.charAt(x)==="-"){x--;t=t.previousSibling}else{t=t.parentNode}}else{t=t.lastChild}}}if(u==="^"){if(w=rt[f=M.id]){c=t&&(!L||L.parentNode!==t);if(!L||c){w.parentElem=t}if(M.elCnt&&c){t._dfr=(M.open?"#":"/")+f+u+(t._dfr||"")}h.push([c?null:L,M])}}else if(A=nt[f=M.id]){if(!A.link){A.parentElem=t||L&&L.parentNode||r;y(A,i);A._.onRender=St;A._.onArrayChange=gt;bt(A)}a=A.parentElem;if(M.open){A._elCnt=M.elCnt;if(t){t._dfr="#"+f+u+(t._dfr||"")}else{if(!A._prv){a._dfr=At(a._dfr,"#"+f+u)}A._prv=L}}else{if(t&&(!L||L.parentNode!==t)){t._dfr="/"+f+u+(t._dfr||"");A._nxt=n}else if(L){if(!A._nxt){a._dfr=At(a._dfr,"/"+f+u)}A._nxt=L}b=A.linkCtx;if(l=A.ctx&&A.ctx.onAfterCreate||$t){l.call(b,A)}}}}T=h.length;while(T--){Wt.push(h[T])}}return!e||e.elCnt}function v(e){var t,n;if(e){T=e.length;for(x=0;x' in:\n"+a)}K.appendChild(mt);xt=Z[xt]||Z.div;ut=xt[0];vt.innerHTML=xt[1]+a+xt[2];while(ut--){vt=vt.lastChild}K.removeChild(mt);at=d.createDocumentFragment();while(ft=vt.firstChild){at.appendChild(ft)}r.insertBefore(at,u)}if(Lt){setTimeout(m,0)}else{m()}return Lt&&Lt.promise()}function kt(e,t,r,i,s,o){var f,h,p,d,v,g,y,b,w,E,S;if(s){E=rt[s];E=E.linkCtx?E.linkCtx.tag:E;w=E.linkCtx||{data:i,elem:E._elCnt?E.parentElem:t,view:r,ctx:r.ctx,attr:"html",fn:E._.bnd,tag:E,_bndId:s};Lt(w,w.fn)}else if(e&&t){f=r.tmpl;e=Pt(e,wt(t));u.lastIndex=0;while(h=u.exec(e)){S=u.lastIndex;p=s?"html":h[1];y=h[3];v=h[10];d=n;w={data:i,elem:E&&E._elCnt?E.parentElem:t,view:r,ctx:o||r.ctx,attr:p,_initVal:!h[2]};if(h[6]){if(!p&&(d=/:([\w$]*)$/.exec(v))){d=d[1];if(d!==n){g=-d.length-1;y=y.slice(0,g-1)+l;v=v.slice(0,g)}}if(d===null){d=n}w.convert=h[5]||""}w.expr=p+y;b=f.links[y];if(!b){f.links[y]=b=m.tmplFn(a+y+c,f,true,d);m.parse(v,b.paths=[],f)}w.fn=b;if(!p&&d!==n){w.convertBack=d}Lt(w,b);u.lastIndex=S}}}function Lt(e,t){function n(n,r){dt.call(e,n,r,t)}e._ctxCb=Vt(e.view);e._hdlr=n;n(true)}function At(e,t){var n;return e?(n=e.indexOf(t),n+1?e.slice(0,n)+e.slice(n+t.length):e):""}function Ot(e){return e&&(""+e===e?e:e.tagName==="SCRIPT"?e.type.slice(3):e.nodeType===1&&e.getAttribute(N)||"")}function Mt(e,t,n){function r(e,t,n,r,s,u){o.push({elCnt:i,id:r,ch:s,open:t,close:n,path:u,token:e})}var i,s,o=[];if(s=t?e:Ot(e)){o.elCnt=!e.type;i=s.charAt(0)==="@"||!e.type;o._tkns=s;s.replace(n||ct,r);return o}}function _t(e,t){if(e){if(e.type==="jsv"){e.parentNode.removeChild(e)}else if(t&&e.getAttribute(C)===""){e.removeAttribute(C)}}}function Dt(e,t){var n=e;while(t&&n&&n.nodeType!==1){n=n.previousSibling}if(n){if(n.nodeType!==1){n=d.createElement("SCRIPT");n.type="jsv";e.parentNode.insertBefore(n,e)}else if(!Ot(n)&&!n.getAttribute(C)){n.setAttribute(C,"")}}return n}function Pt(e,n){e=t.trim(e).replace(J,"\\$&");return e.slice(-1)!==l?e=f+":"+e+(n?":":"")+l:e}function Ht(e,r){if(e!==!!e){r=e;e=n}var i,s=t(this.nodes());if(s[0]){i=r?s.filter(r):s;s=e&&r?i.add(s.find(r)):i}return s}function Bt(e,t,n){var r,i=this,s=i._elCnt,o=!t&&s,u=[];t=t||i._prv;n=n||i._nxt;r=o?t===i._nxt?i.parentElem.lastSibling:t:i._.inline===false?t||i.linkCtx.elem.firstChild:t&&t.nextSibling;while(r&&(!n||r!==n)){if(e||s||r.tagName!=="SCRIPT"){u.push(r)}r=r.nextSibling}return u}function jt(e,t){if(e!==!!e){t=e;e=n}var r=this,i=r.link?r:r.tagCtx.view,s=r._prv,o=r._elCnt,u=[];if(s){i.link(n,r.parentElem,o?s.previousSibling:s,r._nxt,n,{get:{tags:u,deep:e,name:t,id:o&&r._tgId}})}return u}function Ft(){var e=this.tagCtx.view;return this._.bnd.call(e.tmpl,e.data,e,v)}function It(e,t){var r,i,s,o,u,a,f,l,c,h,p=t.view,d=e.linkCtx=e.linkCtx||{tag:e,data:p.data,view:p,ctx:p.ctx};if(e.onAfterLink){e.onAfterLink(t,d)}i=e.targetTag?e.targetTag.linkedElem:e.linkedElem;if(!e._.chging&&i&&(s=i[0])){o=s.type===B;r=d.convert;u=r?w(r)?r(t.args[0]):v._cnvt(r,p,t):t.args[0];if(s!==d.elem){c=i.length;while(c--){s=i[c];h=s._jsvLnkdEl;if(e._.inline&&(!h||h!==e&&h.targetTag!==e)){s._jsvLnkdEl=e;s._jsvBnd=d.elem?d.elem._jsvBnd:e._prv._jsvBnd;a=s._jsvBnd.slice(1).split("&");l=a.length;while(l--){qt(rt[a[l]],d.convertBack)}}if(o){s[P]=u===s.value}}}if(!o&&s.value!==n&&u!==n){if(s.type===H){s[P]=u&&u!=="false"}else{s.value=u}}}}function qt(e,t){var n,r,i,s,o=e.linkCtx,u=o.data,a=o.fn.paths;if(e){if(n=a._jsvto){a=n}r=a.length;while(r&&""+(i=a[--r])!==i){}if(i&&(!o.tag||o.tag.tagCtx.args.length)){i=a[r]=i.split("^").join(".");e.to=i.charAt(0)==="."?[[s=a[r-1],i.slice(1)],t]:[o._ctxCb(a[0])||[u,a[0]],t];if(n&&s){e.to[0][0]=o._ctxCb(s,u)}}else{e.to=[[],t]}}}function Rt(e){var t,r,i=this,s=i.linkCtx,o=i.tagCtx.view;if(i.disposed){X("Removed tag")}if(e===n){e=v._tag(i,o,o.tmpl,i.currentCtxs?i.currentCtxs():i.tagCtxs,true)}if(e+""===e){r=i._.inline?"html":s.attr||wt(i.parentElem,true);t=mt(e,s,r,i)}It(i,i.tagCtx);return t||i}function Ut(e){var t,r,i,s,o,u,a,f=[],l=e.length,c=l;while(c--){f.push(e[c])}c=l;while(c--){s=f[c];if(s.parentNode){if(a=s._jsvBnd){a=a.slice(1).split("&");s._jsvBnd="";r=a.length;while(r--){zt(a[r],s._jsvLnkdEl)}}if(o=Mt(Ot(s)+(s._dfr||""),true,at)){for(t=0,i=o.length;t',F='',
- openScript = ' - data-linked tag, close marker
- // TODO add validation to track whether we are in attribute context (not yet hit preceding ending with a >) or element content of current 'parentTag'
- // and according disallow inserting script markers in attribute context. Similar for elCnt too, so no "" or " ...{{/if}}..."
- preceding = id
- ? (preceding + endOfElCnt + spaceBefore + openScript + id + closeScript + spaceAfter + tag)
- : endOfElCnt || all;
- }
- if (tag) {
- // If there are ids (markers since the last tag), move them to the defer string
- tagStack.unshift(parentTag);
- parentTag = tag.slice(1);
- if (tagStack[0] && tagStack[0] === badParent[parentTag]) {
- // Missing
- // TODO: replace this by smart insertion of tags
- error('Parent of must be ');
- }
- isVoid = voidElems[parentTag];
- if ((elCnt = elContent[parentTag]) && !prevElCnt) {
- deferStack.unshift(defer);
- defer = "";
- }
- prevElCnt = elCnt;
-//TODO Consider providing validation which throws if you place as child of , etc. - since if not caught,
-//this can cause errors subsequently which are difficult to debug.
-// if (elContent[tagStack[0]]>2 && !elCnt) {
-// error(parentTag + " in " + tagStack[0]);
-// }
- if (defer && elCnt) {
- defer += "+"; // Will be used for stepping back through deferred tokens
- }
- }
- return preceding;
- }
-
- function processViewInfos(vwInfos, targetParent) {
- // If targetParent, we are processing viewInfos (which may include navigation through '+-' paths) and hooking up to the right parentElem etc.
- // (and elem may also be defined - the next node)
- // If no targetParent, then we are processing viewInfos on newly inserted content
- var deferPath, deferChar, bindChar, parentElem, id, onAftCr, deep,
- addedBindEls = [];
-
- // In elCnt context (element-only content model), prevNode is the first node after the open, nextNode is the first node after the close.
- // If both are null/undefined, then open and close are at end of parent content, so the view is empty, and its placeholder is the
- // 'lastChild' of the parentNode. If there is a prevNode, then it is either the first node in the view, or the view is empty and
- // its placeholder is the 'previousSibling' of the prevNode, which is also the nextNode.
- if (vwInfos) {
- //targetParent = targetParent || targetElem && targetElem.previousSibling;
- //targetParent = targetElem ? targetElem.previousSibling : targetParent;
- if (vwInfos._tkns.charAt(0) === "@") {
- // We are processing newly inserted content. This is a special script element that was created in convertMarkers() to process deferred bindings,
- // and inserted following the target parent element - because no element tags (outside elCnt) were encountered to carry those binding tokens.
- // We will step back from the preceding sibling of this element, looking at targetParent elements until we find the one that the current binding
- // token belongs to. Set elem to null (the special script element), and remove it from the DOM.
- targetParent = elem.previousSibling;
- elem.parentNode.removeChild(elem);
- elem = null;
- }
- len = vwInfos.length;
- while (len--) {
- vwInfo = vwInfos[len];
- //if (prevIds.indexOf(vwInfo.token) < 0) { // This token is a newly created view or tag binding
- bindChar = vwInfo.ch;
- if (deferPath = vwInfo.path) {
- // We have a 'deferred path'
- j = deferPath.length - 1;
- while (deferChar = deferPath.charAt(j--)) {
- // Use the "+" and"-" characters to navigate the path back to the original parent node where the deferred bindings ocurred
- if (deferChar === "+") {
- if (deferPath.charAt(j) === "-") {
- j--;
- targetParent = targetParent.previousSibling;
- } else {
- targetParent = targetParent.parentNode;
- }
- } else {
- targetParent = targetParent.lastChild;
- }
- // Note: Can use previousSibling and lastChild, not previousElementSibling and lastElementChild,
- // since we have removed white space within elCnt. Hence support IE < 9
- }
- }
- if (bindChar === "^") {
- if (tag = bindingStore[id = vwInfo.id]) {
- // The binding may have been deleted, for example in a different handler to an array collectionChange event
- // This is a tag binding
- deep = targetParent && (!elem || elem.parentNode !== targetParent); // We are stepping back looking for the right targetParent,
- // or we are linking existing content and this element is in elCnt, not an immediate child of the targetParent.
- if (!elem || deep) {
- tag.parentElem = targetParent;
- }
- if (vwInfo.elCnt && deep) {
- // With element only content, if there is no following element, or if the binding is deeper than the following element
- // then we need to set the open or close token as a deferred binding annotation on the parent
- targetParent._dfr = (vwInfo.open ? "#" : "/") + id + bindChar + (targetParent._dfr || "");
- }
- // This is an open or close marker for a data-linked tag {^{...}}. Add it to bindEls.
- addedBindEls.push([deep ? null : elem, vwInfo]);
- }
- } else if (view = viewStore[id = vwInfo.id]) {
- // The view may have been deleted, for example in a different handler to an array collectionChange event
- if (!view.link) {
- // If view is not already extended for JsViews, extend and initialize the view object created in JsRender, as a JsViews view
- view.parentElem = targetParent || elem && elem.parentNode || parentNode;
- $extend(view, LinkedView);
- view._.onRender = addBindingMarkers;
- view._.onArrayChange = arrayChangeHandler;
- setArrayChangeLink(view);
- }
- parentElem = view.parentElem;
- if (vwInfo.open) {
- // This is an 'open view' node (preceding script marker node,
- // or if elCnt, the first element in the view, with a data-jsv annotation) for binding
- view._elCnt = vwInfo.elCnt;
- if (targetParent) {
- targetParent._dfr = "#" + id + bindChar + (targetParent._dfr || "");
- } else {
- // No targetParent, so there is a ._nxt elem (and this is processing tokens on the elem)
- if (!view._prv) {
- parentElem._dfr = removeSubStr(parentElem._dfr, "#" + id + bindChar);
- }
- view._prv = elem;
- }
- } else {
- // This is a 'close view' marker node for binding
- if (targetParent && (!elem || elem.parentNode !== targetParent)) {
- // There is no ._nxt so add token to _dfr. It is deferred.
- targetParent._dfr = "/" + id + bindChar + (targetParent._dfr || "");
- view._nxt = undefined;
- } else if (elem) {
- // This view did not have a ._nxt, but has one now, so token may be in _dfr, and must be removed. (No longer deferred)
- if (!view._nxt) {
- parentElem._dfr = removeSubStr(parentElem._dfr, "/" + id + bindChar);
- }
- view._nxt = elem;
- }
- linkCtx = view.linkCtx;
- if (onAftCr = view.ctx && view.ctx.onAfterCreate || onAfterCreate) {
- onAftCr.call(linkCtx, view);
- }
- }
- //}
- }
- }
- len = addedBindEls.length;
- while (len--) {
- // These were added in reverse order to addedBindEls. We push them in BindEls in the correct order.
- bindEls.push(addedBindEls[len]);
- }
- }
- return !vwInfos || vwInfos.elCnt;
- }
-
- function getViewInfos(vwInfos) {
- // Used by view.childTags() and tag.childTags()
- // Similar to processViewInfos in how it steps through bindings to find tags. Only finds data-linked tags.
- var level, parentTag;
-
- if (vwInfos) {
- len = vwInfos.length;
- for (j = 0; j < len; j++) {
- vwInfo = vwInfos[j];
- if (get.id) {
- get.id = get.id !== vwInfo.id && get.id;
- } else {
- // This is an open marker for a data-linked tag {^{...}}, within the content of the tag whose id is get.id. Add it to bindEls.
- parentTag = tag = bindingStore[vwInfo.id].linkCtx.tag;
- if (!tag.flow) {
- if (!deep) {
- level = 1;
- while (parentTag = parentTag.parent) {
- level++;
- }
- tagDepth = tagDepth || level; // The level of the first tag encountered.
- }
- if ((deep || level === tagDepth) && (!tagName || tag.tagName === tagName)) {
- // Filter on top-level or tagName as appropriate
- tags.push(tag);
- }
- }
- }
- }
- }
- }
-
- function dataLink() {
- //================ Data-link and fixup of data-jsv annotations ================
- elems = qsa ? parentNode.querySelectorAll(linkViewsSel) : $(linkViewsSel, parentNode).get();
- l = elems.length;
-
- // The prevNode will be in the returned query, since we called markPrevOrNextNode() on it.
- // But it may have contained nodes that satisfy the selector also.
- if (prevNode && prevNode.innerHTML) {
- // Find the last contained node of prevNode, to use as the prevNode - so we only link subsequent elems in the query
- prevNodes = qsa ? prevNode.querySelectorAll(linkViewsSel) : $(linkViewsSel, prevNode).get();
- prevNode = prevNodes.length ? prevNodes[prevNodes.length - 1] : prevNode;
- }
-
- tagDepth = 0;
- for (i = 0; i < l; i++) {
- elem = elems[i];
- if (prevNode && !found) {
- // If prevNode is set, not false, skip linking. If this element is the prevNode, set to false so subsequent elements will link.
- found = (elem === prevNode);
- } else if (nextNode && elem === nextNode) {
- // If nextNode is set then break when we get to nextNode
- break;
- } else if (elem.parentNode
- // elem has not been removed from DOM
- && processInfos(viewInfos(elem, undefined, tags && rOpenTagMarkers))
- // If a link() call, processViewInfos() adds bindings to bindEls, and returns true for non-script nodes, for adding data-link bindings
- // If a childTags() call, getViewInfos returns array of tag bindings.
- && !get && elem.getAttribute($viewsLinkAttr)) {
- bindEls.push([elem]); // A data-linked element so add to bindEls too
- }
- }
-
- // Remove temporary marker script nodes they were added by markPrevOrNextNode
- unmarkPrevOrNextNode(prevNode, elCnt);
- unmarkPrevOrNextNode(nextNode, elCnt);
-
- if (get) {
- lazyLink && lazyLink.resolve();
- return;
- }
-
- if (elCnt && defer + ids) {
- // There are some views with elCnt, for which the open or close did not precede any HTML tag - so they have not been processed yet
- elem = nextNode;
- if (defer) {
- if (nextNode) {
- processViewInfos(viewInfos(defer + "+", true), nextNode);
- } else {
- processViewInfos(viewInfos(defer, true), parentNode);
- }
- }
- processViewInfos(viewInfos(ids, true), parentNode);
- // If there were any tokens on nextNode which have now been associated with inserted HTML tags, remove them from nextNode
- if (nextNode) {
- tokens = nextNode.getAttribute(jsvAttrStr);
- if (l = tokens.indexOf(prevIds) + 1) {
- tokens = tokens.slice(l + prevIds.length - 1);
- }
- nextNode.setAttribute(jsvAttrStr, ids + tokens);
- }
- }
-
- //================ Bind the data-linked elements and tags ================
- l = bindEls.length;
- for (i = 0; i < l; i++) {
- elem = bindEls[i];
- linkInfo = elem[1];
- elem = elem[0];
- if (linkInfo) {
- tag = bindingStore[linkInfo.id];
- if (linkCtx = tag.linkCtx) {
- // The tag may have been stored temporarily on the bindingStore - or may have already been replaced by the actual binding
- tag = linkCtx.tag;
- tag.linkCtx = linkCtx;
- }
- if (linkInfo.open) {
- // This is an 'open linked tag' binding annotation for a data-linked tag {^{...}}
- if (elem) {
- tag.parentElem = elem.parentNode;
- tag._prv = elem;
- }
- tag._elCnt = linkInfo.elCnt;
- if (tag && (!tag.onBeforeLink || tag.onBeforeLink() !== false) && !tag._.bound) {
- // By default we data-link depth-last ("on the way in"), which is better for perf. But if a tag needs nested tags to be linked (refreshed)
- // first, before linking its content, then make onBeforeLink() return false. In that case we data-link depth-first ("on the way out"), so nested tags will have already refreshed.
- tag._.bound = true;
- view = tag.tagCtx.view;
- addDataBinding(undefined, tag._prv, view, view.data||outerData, linkInfo.id);
- }
-
- tag._.linking = true;
- } else {
- tag._nxt = elem;
- if (tag._.linking) {
- // This is a 'close linked tag' binding annotation
- // Add data binding
- tagCtx = tag.tagCtx;
- view = tagCtx.view;
- tag.contents = getContents;
- tag.nodes = getNodes;
- tag.childTags = getChildTags;
- tag.currentCtxs = getCurrentCtxs;
- tag.update = updateTag;
- tag.refresh = refreshTag;
- delete tag._.linking;
- if (!tag._.bound) {
- tag._.bound = true;
- addDataBinding(undefined, tag._prv, view, view.data||outerData, linkInfo.id);
- }
- callAfterLink(tag, tagCtx);
- }
- }
- } else {
- view = $view(elem);
- // Add data binding for a data-linked element (with data-link attribute)
- addDataBinding(elem.getAttribute($viewsLinkAttr), elem, view, view.data||outerData, undefined, context);
- }
- }
- lazyLink && lazyLink.resolve();
- }
- //==== /end of nested functions ====
-
- var linkCtx, tag, i, l, j, len, elems, elem, view, vwInfos, vwInfo, linkInfo, prevNodes, token, prevView, nextView, node, tags, deep, tagName, tagCtx, cvt,
- tagDepth, get, depth, fragment, copiedNode, firstTag, parentTag, isVoid, wrapper, div, tokens, elCnt, prevElCnt, htmlTag, ids, prevIds, found, lazyLink, linkedElem,
- noDomLevel0 = $viewsSettings.noDomLevel0,
- self = this,
- thisId = self._.id + "_",
- defer = "",
- // The marker ids for which no tag was encountered (empty views or final closing markers) which we carry over to container tag
- bindEls = [],
- tagStack = [],
- deferStack = [],
- onAfterCreate = self.hlp(onAfterCreateStr),
- processInfos = processViewInfos;
-
- if (refresh) {
- lazyLink = refresh.lazyLink && $.Deferred();
- if (refresh.tmpl) {
- // refresh is the prevView, passed in from addViews()
- prevView = "/" + refresh._.id + "_";
- } else {
- get = refresh.get;
- if (refresh.tag) {
- thisId = refresh.tag + "^";
- refresh = true;
- }
- }
- refresh = refresh === true;
- }
-
- if (get) {
- processInfos = getViewInfos;
- tags = get.tags;
- deep = get.deep;
- tagName = get.name;
- }
-
- parentNode = parentNode
- ? ("" + parentNode === parentNode
- ? $(parentNode)[0] // It is a string, so treat as selector
- : parentNode.jquery
- ? parentNode[0] // A jQuery object - take first element.
- : parentNode)
- : (self.parentElem // view.link()
- || document.body); // link(null, data) to link the whole document
-
- parentTag = parentNode.tagName.toLowerCase();
- elCnt = !!elContent[parentTag];
-
- prevNode = prevNode && markPrevOrNextNode(prevNode, elCnt);
- nextNode = nextNode && markPrevOrNextNode(nextNode, elCnt) || null;
-
- if (html !== undefined) {
- //================ Insert html into DOM using documentFragments (and wrapping HTML appropriately). ================
- // Also convert markers to DOM annotations, based on content model.
- // Corresponds to nextNode ? $(nextNode).before(html) : $(parentNode).html(html);
- // but allows insertion to wrap correctly even with inserted script nodes. jQuery version will fail e.g. under tbody or select.
- // This version should also be slightly faster
- div = document.createElement("div");
- wrapper = div;
- prevIds = ids = "";
- htmlTag = parentNode.namespaceURI === "http://www.w3.org/2000/svg" ? "svg_ns" : (firstTag = rFirstElem.exec(html)) && firstTag[1] || "";
- if (noDomLevel0 && firstTag && firstTag[2]) {
- error("Unsupported: " + firstTag[2]); // For security reasons, don't allow insertion of elements with onFoo attributes.
- }
- if (elCnt) {
- // Now look for following view, and find its tokens, or if not found, get the parentNode._dfr tokens
- node = nextNode;
- while (node && !(nextView = viewInfos(node))) {
- node = node.nextSibling;
- }
- if (tokens = nextView ? nextView._tkns : parentNode._dfr) {
- token = prevView || "";
- if (refresh || !prevView) {
- token += "#" + thisId;
- }
- j = tokens.indexOf(token);
- if (j + 1) {
- j += token.length;
- // Transfer the initial tokens to inserted nodes, by setting them as the ids variable, picked up in convertMarkers
- prevIds = ids = tokens.slice(0, j);
- tokens = tokens.slice(j);
- if (nextView) {
- node.setAttribute(jsvAttrStr, tokens);
- } else {
- parentNode._dfr = tokens;
- }
- }
- }
- }
-
- //================ Convert the markers to DOM annotations, based on content model. ================
-// oldElCnt = elCnt;
- isVoid = undefined;
- html = ("" + html).replace(rConvertMarkers, convertMarkers);
-// if (!!oldElCnt !== !!elCnt) {
-// error("Parse: " + html); // Parse error. Content not well-formed?
-// }
- if (validate && tagStack.length) {
- syntaxError("Mismatched '<" + parentTag + "...>' in:\n" + html); // Unmatched tag
- }
- // Append wrapper element to doc fragment
- safeFragment.appendChild(div);
-
- // Go to html and back, then peel off extra wrappers
- // Corresponds to jQuery $(nextNode).before(html) or $(parentNode).html(html);
- // but supports svg elements, and other features missing from jQuery version (and this version should also be slightly faster)
- htmlTag = wrapMap[htmlTag] || wrapMap.div;
- depth = htmlTag[0];
- wrapper.innerHTML = htmlTag[1] + html + htmlTag[2];
- while (depth--) {
- wrapper = wrapper.lastChild;
- }
- safeFragment.removeChild(div);
- fragment = document.createDocumentFragment();
- while (copiedNode = wrapper.firstChild) {
- fragment.appendChild(copiedNode);
- }
- // Insert into the DOM
- parentNode.insertBefore(fragment, nextNode);
- }
-
- if (lazyLink) {
- setTimeout(dataLink, 0);
- } else {
- dataLink();
- }
-
- return lazyLink && lazyLink.promise();
- }
-
- function addDataBinding(linkMarkup, node, currentView, data, boundTagId, context) {
- // Add data binding for data-linked elements or {^{...}} data-linked tags
- var tmpl, tokens, attr, convertBack, params, trimLen, tagExpr, linkFn, linkCtx, tag, rTagIndex;
-
- if (boundTagId) {
- // {^{...}} data-linked tag. So only one linkTag in linkMarkup
- tag = bindingStore[boundTagId];
- tag = tag.linkCtx ? tag.linkCtx.tag : tag;
-
- linkCtx = tag.linkCtx || {
- data: data, // source
- elem: tag._elCnt ? tag.parentElem : node, // target
- view: currentView,
- ctx: currentView.ctx,
- attr: "html", // Script marker nodes are associated with {^{ and always target HTML.
- fn: tag._.bnd,
- tag: tag,
- // Pass the boundTagId in the linkCtx, so that it can be picked up in observeAndBind
- _bndId: boundTagId
- };
- bindDataLinkTarget(linkCtx, linkCtx.fn);
- } else if (linkMarkup && node) {
- // Compiled linkFn expressions could be stored in the tmpl.links array of the template
- // TODO - consider also caching globally so that if {{:foo}} or data-link="foo" occurs in different places,
- // the compiled template for this is cached and only compiled once...
- //links = currentView.links || currentView.tmpl.links;
-
- tmpl = currentView.tmpl;
-
-// if (!(linkTags = links[linkMarkup])) {
- // This is the first time this view template has been linked, so we compile the data-link expressions, and store them on the template.
-
- linkMarkup = normalizeLinkTag(linkMarkup, defaultAttr(node));
- rTag.lastIndex = 0;
- while (tokens = rTag.exec(linkMarkup)) { // TODO require } to be followed by whitespace or $, and remove the \}(!\}) option.
- // Iterate over the data-link expressions, for different target attrs,
- // (only one if there is a boundTagId - the case of data-linked tag {^{...}})
- // e.g. )|!--((?:[^-]|-(?!-))*)--|(\*)))\s*((?:[^}]|}(?!}))*?))})
- return this;
- })();
-
- //===============
- // Public helpers
- //===============
-
- $viewsSub.viewInfos = viewInfos;
- // Expose viewInfos() as public helper method
-
- //====================================
- // Additional members for linked views
- //====================================
-
- function transferViewTokens(prevNode, nextNode, parentElem, id, viewOrTagChar, refresh) {
- // Transfer tokens on prevNode of viewToRemove/viewToRefresh to nextNode or parentElem._dfr
- var i, l, vwInfos, vwInfo, viewOrTag, viewId, tokens,
- precedingLength = 0,
- emptyView = prevNode === nextNode;
-
- if (prevNode) {
- // prevNode is either the first node in the viewOrTag, or has been replaced by the vwInfos tokens string
- vwInfos = viewInfos(prevNode) || [];
- for (i = 0, l = vwInfos.length; i < l; i++) {
- // Step through views or tags on the prevNode
- vwInfo = vwInfos[i];
- viewId = vwInfo.id;
- if (viewId === id && vwInfo.ch === viewOrTagChar) {
- if (refresh) {
- // This is viewOrTagToRefresh, this is the last viewOrTag to process...
- l = 0;
- } else {
- // This is viewOrTagToRemove, so we are done...
- break;
- }
- }
- if (!emptyView) {
- viewOrTag = vwInfo.ch === "_"
- ? viewStore[viewId]
- : bindingStore[viewId].linkCtx.tag;
- if (vwInfo.open) {
- // A "#m" token
- viewOrTag._prv = nextNode;
- } else if (vwInfo.close) {
- // A "/m" token
- viewOrTag._nxt = nextNode;
- }
- }
- precedingLength += viewId.length + 2;
- }
-
- if (precedingLength) {
- prevNode.setAttribute(jsvAttrStr, prevNode.getAttribute(jsvAttrStr).slice(precedingLength));
- }
- tokens = nextNode ? nextNode.getAttribute(jsvAttrStr) : parentElem._dfr;
- if (l = tokens.indexOf("/" + id + viewOrTagChar) + 1) {
- tokens = vwInfos._tkns.slice(0, precedingLength) + tokens.slice(l + (refresh ? -1 : id.length + 1));
- }
- if (tokens) {
- if (nextNode) {
- // If viewOrTagToRemove was an empty viewOrTag, we will remove both #n and /n
- // (and any intervening tokens) from the nextNode (=== prevNode)
- // If viewOrTagToRemove was not empty, we will take tokens preceding #n from prevNode,
- // and concatenate with tokens following /n on nextNode
- nextNode.setAttribute(jsvAttrStr, tokens);
- } else {
- parentElem._dfr = tokens;
- }
- }
- } else {
- // !prevNode, so there may be a deferred nodes token on the parentElem. Remove it.
- parentElem._dfr = removeSubStr(parentElem._dfr, "#" + id + viewOrTagChar);
- if (!refresh && !nextNode) {
- // If this viewOrTag is being removed, and there was no .nxt, remove closing token from deferred tokens
- parentElem._dfr = removeSubStr(parentElem._dfr, "/" + id + viewOrTagChar);
- }
- }
- }
-
- LinkedView = {
- // Note: a linked view will also, after linking have nodes[], _prv (prevNode), _nxt (nextNode) ...
- addViews: function(index, dataItems, tmpl) {
- // if view is not an array view, do nothing
- var i, viewsCount,
- self = this,
- itemsCount = dataItems.length,
- views = self.views;
-
- if (!self._.useKey && itemsCount && (tmpl = self.tmpl)) {
- // view is of type "array"
- // Use passed-in template if provided, since self added view may use a different template than the original one used to render the array.
- viewsCount = views.length + itemsCount;
-
- if (renderAndLink(self, index, tmpl, views, dataItems, self.ctx) !== false) {
- for (i = index + itemsCount; i < viewsCount; i++) {
- $observable(views[i]).setProperty("index", i);
- // This is fixing up index, but not key, and not index on child views. From child views, use view.getIndex()
- }
- }
- }
- return self;
- },
-
- removeViews: function(index, itemsCount, keepNodes) {
- // view.removeViews() removes all the child views
- // view.removeViews(index) removes the child view with specified index or key
- // view.removeViews(index, count) removes the specified nummber of child views, starting with the specified index
- function removeView(index) {
- var id, bindId, parentElem, prevNode, nextNode, nodesToRemove,
- viewToRemove = views[index];
-
- if (viewToRemove && viewToRemove.link) {
- id = viewToRemove._.id;
- if (!keepNodes) {
- // Remove the HTML nodes from the DOM, unless they have already been removed, including nodes of child views
- nodesToRemove = viewToRemove.nodes();
- }
-
- // Remove child views, without removing nodes
- viewToRemove.removeViews(undefined, undefined, true);
-
- viewToRemove.data = undefined; // Set data to undefined: used as a flag that this view is being removed
- prevNode = viewToRemove._prv;
- nextNode = viewToRemove._nxt;
- parentElem = viewToRemove.parentElem;
- // If prevNode and nextNode are the same, the view is empty
- if (!keepNodes) {
- // Remove the HTML nodes from the DOM, unless they have already been removed, including nodes of child views
- if (viewToRemove._elCnt) {
- // if keepNodes is false (and transferring of tokens has not already been done at a higher level)
- // then transfer tokens from prevNode which is being removed, to nextNode.
- transferViewTokens(prevNode, nextNode, parentElem, id, "_");
- }
- $(nodesToRemove).remove();
- }
- if (!viewToRemove._elCnt) {
- prevNode.parentNode && parentElem.removeChild(prevNode);
- nextNode.parentNode && parentElem.removeChild(nextNode);
- }
- setArrayChangeLink(viewToRemove);
- for (bindId in viewToRemove._.bnds) {
- removeViewBinding(bindId);
- }
- delete viewStore[id];
- }
- }
-
- var current, view, viewsCount,
- self = this,
- isArray = !self._.useKey,
- views = self.views;
-
- if (isArray) {
- viewsCount = views.length;
- }
- if (index === undefined) {
- // Remove all child views
- if (isArray) {
- // views and data are arrays
- current = viewsCount;
- while (current--) {
- removeView(current);
- }
- self.views = [];
- } else {
- // views and data are objects
- for (view in views) {
- // Remove by key
- removeView(view);
- }
- self.views = {};
- }
- } else {
- if (itemsCount === undefined) {
- if (isArray) {
- // The parentView is data array view.
- // Set itemsCount to 1, to remove this item
- itemsCount = 1;
- } else {
- // Remove child view with key 'index'
- removeView(index);
- delete views[index];
- }
- }
- if (isArray && itemsCount) {
- current = index + itemsCount;
- // Remove indexed items (parentView is data array view);
- while (current-- > index) {
- removeView(current);
- }
- views.splice(index, itemsCount);
- if (viewsCount = views.length) {
- // Fixup index on following view items...
- while (index < viewsCount) {
- $observable(views[index]).setProperty("index", index++);
- }
- }
- }
- }
- return this;
- },
-
- refresh: function(context) {
- var self = this,
- parent = self.parent;
-
- if (parent) {
- renderAndLink(self, self.index, self.tmpl, parent.views, self.data, context, true);
- setArrayChangeLink(self);
- }
- return self;
- },
-
- nodes: getNodes,
- contents: getContents,
- childTags: getChildTags,
- link: viewLink
- };
-
- //=========================
- // Extend $.views.settings
- //=========================
-
- $viewsSettings.merge = {
- input: {
- from: inputAttrib, to: "value"
- },
- textarea: valueBinding,
- select: valueBinding,
- optgroup: {
- to: "label"
- }
- };
-
- if ($viewsSettings.debugMode) {
- // In debug mode create global for accessing views, etc
- validate = !$viewsSettings.noValidate;
- global._jsv = {
- views: viewStore,
- bindings: bindingStore
- };
- }
-
- //========================
- // JsViews-specific converters
- //========================
-
- $converters.merge = function(val) {
- // Special converter used in data-linking to space-separated lists, such as className:
- // Currently only supports toggle semantics - and has no effect if toggle string is not specified
- // data-link="class{merge:boolExpr toggle=className}"
- var regularExpression,
- currentValue = this.linkCtx._val || "",
- toggle = this.tagCtx.props.toggle;
-
- if (toggle) {
- // We are toggling the class specified by the toggle property,
- // and the boolean val binding is driving the insert/remove toggle
-
- regularExpression = toggle.replace(/[\\^$.|?*+()[{]/g, "\\$&");
- // Escape any regular expression special characters (metacharacters) within the toggle string
- regularExpression = "(\\s(?=" + regularExpression + "$)|(\\s))?(" + regularExpression + "(\\s|$))"
-
- currentValue = currentValue.replace(new RegExp(regularExpression), "$2")
- val = currentValue + (val ? (currentValue && " ") + toggle : "")
- }
- return val;
- };
-
- //========================
- // JsViews-specific tags
- //========================
-
- $views.tags("on", {
- attr: "none",
- onAfterLink: function(tagCtx, linkCtx) {
- var self = this,
- elem = $(linkCtx.elem),
- args = tagCtx.args,
- data = tagCtx.props.data,
- handler = args.pop(),
- selector = args[1] || null,
- contextOb = tagCtx.props.context;
-
- data = data !== undefined ? data : null;
- handler = handler.fn && contextOb ? handler.fn : handler; //??VERIFY
- elem.on(args[0], selector, data, function(ev) {
- handler.call(contextOb || self.leaf, ev);
- });
- },
- onAfterBind: function(binding) {
- this.leaf = binding.leaf;
- },
- flow: true
- });
-
- //========================
- // Extend jQuery namespace
- //========================
-
- $extend($, {
-
- //=======================
- // jQuery $.view() plugin
- //=======================
-
- view: $views.view = $view = function(node, inner, type) {
- // $.view() returns top view
- // $.view(node) returns view that contains node
- // $.view(selector) returns view that contains first selected element
- // $.view(nodeOrSelector, type) returns nearest containing view of given type
- // $.view(nodeOrSelector, "root") returns root containing view (child of top view)
- // $.view(nodeOrSelector, true, type) returns nearest inner (contained) view of given type
-
- if (inner !== !!inner) {
- // inner not boolean, so this is view(nodeOrSelector, type)
- type = inner;
- inner = undefined;
- }
- var view, vwInfos, i, j, k, l, elem, elems,
- level = 0,
- body = document.body;
-
- if (node && node !== body && topView._.useKey > 1) {
- // Perf optimization for common cases
-
- node = "" + node === node
- ? $(node)[0]
- : node.jquery
- ? node[0]
- : node;
-
- if (node) {
- if (inner) {
- // Treat supplied node as a container element and return the first view encountered.
- elems = qsa ? node.querySelectorAll(bindElsSel) : $(bindElsSel, node).get();
- l = elems.length;
- for (i = 0; i < l; i++) {
- elem = elems[i];
- vwInfos = viewInfos(elem, undefined, rOpenViewMarkers);
-
- for (j = 0, k = vwInfos.length; j < k; j++) {
- view = vwInfos[j];
- if (view = viewStore[view.id]) {
- view = view && type ? view.get(true, type) : view;
- if (view) {
- return view;
- }
- }
- }
- }
- } else {
- while (node) {
- // Move back through siblings and up through parents to find preceding node which is a _prv (prevNode)
- // script marker node for a non-element-content view, or a _prv (first node) for an elCnt view
- if (vwInfos = viewInfos(node, undefined, rViewMarkers)) {
- l = vwInfos.length;
- while (l--) {
- view = vwInfos[l];
- if (view.open) {
- if (level < 1) {
- view = viewStore[view.id];
- return view && type ? view.get(type) : view || topView;
- }
- level--;
- } else {
- // level starts at zero. If we hit a view.close, then we move level to 1, and we don't return a view until
- // we are back at level zero (or a parent view with level < 0)
- level++;
- }
- }
- }
- node = node.previousSibling || node.parentNode;
- }
- }
- }
- }
- return inner ? undefined : topView;
- },
-
- link: $views.link = $link,
- unlink: $views.unlink = $unlink,
-
- //=====================
- // override $.cleanData
- //=====================
- cleanData: function(elems) {
- if (elems.length) {
- // Remove JsViews bindings. Also, remove from the DOM any corresponding script marker nodes
- clean(elems);
- // (elems HTMLCollection no longer includes removed script marker nodes)
- oldCleanData.call($, elems);
- }
- }
- });
-
- //===============================
- // Extend jQuery instance plugins
- //===============================
-
- $extend($.fn, {
- link: function(expr, from, context, parentView, prevNode, nextNode) {
- return $link(expr, this, from, context, parentView, prevNode, nextNode);
- },
- unlink: function(expr) {
- return $unlink(expr, this);
- },
- view: function(type) {
- return $view(this[0], type);
- }
- });
-
- //===============
- // Extend topView
- //===============
-
- $extend(topView, {tmpl: {links: {}, tags: {}}});
- $extend(topView, LinkedView);
- topView._.onRender = addBindingMarkers;
-
-//TODO
-// Tests for {{props}} tag.
-// add tests for "on" binding.
-// Tests for different attr settings on tags
-// tests of onAfterBind extensibility
-})(this, this.jQuery);