knockoutjs-rails 1.2.1 → 1.03

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -20,7 +20,7 @@ Add the following directive to your Javascript manifest file (application.js):
20
20
 
21
21
  ## Versioning
22
22
 
23
- knockoutjs-rails 1.2.1 == Knockout.js 1.2.1
23
+ knockoutjs-rails 1.03 == Knockout.js 1.03
24
24
 
25
25
  Every attempt is made to mirror the currently shipping Knockout.js version number wherever possible.
26
26
  The major and minor version numbers will always represent the Knockout.js version, but the patch level
@@ -1,5 +1,5 @@
1
1
  module Knockoutjs
2
2
  module Rails
3
- VERSION = "1.2.1"
3
+ VERSION = "1.03"
4
4
  end
5
5
  end
@@ -1,76 +1,1298 @@
1
- // Knockout JavaScript library v1.2.1
2
- // (c) Steven Sanderson - http://knockoutjs.com/
3
- // License: MIT (http://www.opensource.org/licenses/mit-license.php)
4
-
5
- (function(window,undefined){
6
- function c(e){throw e;}var m=void 0,o=null,p=window.ko={};p.b=function(e,d){for(var b=e.split("."),a=window,f=0;f<b.length-1;f++)a=a[b[f]];a[b[b.length-1]]=d};p.i=function(e,d,b){e[d]=b};
7
- p.a=new function(){function e(a,b){if(a.tagName!="INPUT"||!a.type)return!1;if(b.toLowerCase()!="click")return!1;var d=a.type.toLowerCase();return d=="checkbox"||d=="radio"}var d=/^(\s|\u00A0)+|(\s|\u00A0)+$/g,b=/MSIE 6/i.test(navigator.userAgent),a=/MSIE 7/i.test(navigator.userAgent),f={},h={};f[/Firefox\/2/i.test(navigator.userAgent)?"KeyboardEvent":"UIEvents"]=["keyup","keydown","keypress"];f.MouseEvents=["click","dblclick","mousedown","mouseup","mousemove","mouseover","mouseout","mouseenter","mouseleave"];
8
- for(var g in f){var i=f[g];if(i.length)for(var k=0,j=i.length;k<j;k++)h[i[k]]=g}return{ca:["authenticity_token",/^__RequestVerificationToken(_.*)?$/],g:function(a,b){for(var d=0,e=a.length;d<e;d++)b(a[d])},h:function(a,b){if(typeof a.indexOf=="function")return a.indexOf(b);for(var d=0,e=a.length;d<e;d++)if(a[d]===b)return d;return-1},xa:function(a,b,d){for(var e=0,f=a.length;e<f;e++)if(b.call(d,a[e]))return a[e];return o},N:function(a,b){var d=p.a.h(a,b);d>=0&&a.splice(d,1)},L:function(a){for(var a=
9
- a||[],b=[],d=0,e=a.length;d<e;d++)p.a.h(b,a[d])<0&&b.push(a[d]);return b},M:function(a,b){for(var a=a||[],d=[],e=0,f=a.length;e<f;e++)d.push(b(a[e]));return d},K:function(a,b){for(var a=a||[],d=[],e=0,f=a.length;e<f;e++)b(a[e])&&d.push(a[e]);return d},u:function(a,b){for(var d=0,e=b.length;d<e;d++)a.push(b[d])},Q:function(a){for(;a.firstChild;)p.removeNode(a.firstChild)},Xa:function(a,b){p.a.Q(a);b&&p.a.g(b,function(b){a.appendChild(b)})},ka:function(a,b){var d=a.nodeType?[a]:a;if(d.length>0){for(var e=
10
- d[0],f=e.parentNode,h=0,g=b.length;h<g;h++)f.insertBefore(b[h],e);h=0;for(g=d.length;h<g;h++)p.removeNode(d[h])}},ma:function(a,b){navigator.userAgent.indexOf("MSIE 6")>=0?a.setAttribute("selected",b):a.selected=b},da:function(a,b){if(!a||a.nodeType!=1)return[];var d=[];a.getAttribute(b)!==o&&d.push(a);for(var e=a.getElementsByTagName("*"),f=0,h=e.length;f<h;f++)e[f].getAttribute(b)!==o&&d.push(e[f]);return d},k:function(a){return(a||"").replace(d,"")},ab:function(a,b){for(var d=[],e=(a||"").split(b),
11
- f=0,h=e.length;f<h;f++){var g=p.a.k(e[f]);g!==""&&d.push(g)}return d},Za:function(a,b){a=a||"";if(b.length>a.length)return!1;return a.substring(0,b.length)===b},Ha:function(a,b){if(b===m)return(new Function("return "+a))();return(new Function("sc","with(sc) { return ("+a+") }"))(b)},Fa:function(a,b){if(b.compareDocumentPosition)return(b.compareDocumentPosition(a)&16)==16;for(;a!=o;){if(a==b)return!0;a=a.parentNode}return!1},P:function(a){return p.a.Fa(a,document)},t:function(a,b,d){if(typeof jQuery!=
12
- "undefined"){if(e(a,b))var f=d,d=function(a,b){var d=this.checked;if(b)this.checked=b.Aa!==!0;f.call(this,a);this.checked=d};jQuery(a).bind(b,d)}else typeof a.addEventListener=="function"?a.addEventListener(b,d,!1):typeof a.attachEvent!="undefined"?a.attachEvent("on"+b,function(b){d.call(a,b)}):c(Error("Browser doesn't support addEventListener or attachEvent"))},qa:function(a,b){(!a||!a.nodeType)&&c(Error("element must be a DOM node when calling triggerEvent"));if(typeof jQuery!="undefined"){var d=
13
- [];e(a,b)&&d.push({Aa:a.checked});jQuery(a).trigger(b,d)}else if(typeof document.createEvent=="function")typeof a.dispatchEvent=="function"?(d=document.createEvent(h[b]||"HTMLEvents"),d.initEvent(b,!0,!0,window,0,0,0,0,0,!1,!1,!1,!1,0,a),a.dispatchEvent(d)):c(Error("The supplied element doesn't support dispatchEvent"));else if(typeof a.fireEvent!="undefined"){if(b=="click"&&a.tagName=="INPUT"&&(a.type.toLowerCase()=="checkbox"||a.type.toLowerCase()=="radio"))a.checked=a.checked!==!0;a.fireEvent("on"+
14
- b)}else c(Error("Browser doesn't support triggering events"))},d:function(a){return p.C(a)?a():a},Ea:function(a,b){return p.a.h((a.className||"").split(/\s+/),b)>=0},pa:function(a,b,d){var e=p.a.Ea(a,b);if(d&&!e)a.className=(a.className||"")+" "+b;else if(e&&!d){for(var d=(a.className||"").split(/\s+/),e="",f=0;f<d.length;f++)d[f]!=b&&(e+=d[f]+" ");a.className=p.a.k(e)}},Ua:function(a,b){for(var a=p.a.d(a),b=p.a.d(b),d=[],e=a;e<=b;e++)d.push(e);return d},U:function(a){for(var b=[],d=0,e=a.length;d<
15
- e;d++)b.push(a[d]);return b},S:b,Ma:a,ea:function(a,b){for(var d=p.a.U(a.getElementsByTagName("INPUT")).concat(p.a.U(a.getElementsByTagName("TEXTAREA"))),e=typeof b=="string"?function(a){return a.name===b}:function(a){return b.test(a.name)},f=[],h=d.length-1;h>=0;h--)e(d[h])&&f.push(d[h]);return f},F:function(a){if(typeof a=="string"&&(a=p.a.k(a))){if(window.JSON&&window.JSON.parse)return window.JSON.parse(a);return(new Function("return "+a))()}return o},Y:function(a){(typeof JSON=="undefined"||typeof JSON.stringify==
16
- "undefined")&&c(Error("Cannot find JSON.stringify(). Some browsers (e.g., IE < 8) don't support it natively, but you can overcome this by adding a script reference to json2.js, downloadable from http://www.json.org/json2.js"));return JSON.stringify(p.a.d(a))},Ta:function(a,b,d){var d=d||{},e=d.params||{},f=d.includeFields||this.ca,h=a;if(typeof a=="object"&&a.tagName=="FORM")for(var h=a.action,g=f.length-1;g>=0;g--)for(var i=p.a.ea(a,f[g]),k=i.length-1;k>=0;k--)e[i[k].name]=i[k].value;var b=p.a.d(b),
17
- j=document.createElement("FORM");j.style.display="none";j.action=h;j.method="post";for(var u in b)a=document.createElement("INPUT"),a.name=u,a.value=p.a.Y(p.a.d(b[u])),j.appendChild(a);for(u in e)a=document.createElement("INPUT"),a.name=u,a.value=e[u],j.appendChild(a);document.body.appendChild(j);d.submitter?d.submitter(j):j.submit();setTimeout(function(){j.parentNode.removeChild(j)},0)}}};p.b("ko.utils",p.a);p.b("ko.utils.arrayForEach",p.a.g);p.b("ko.utils.arrayFirst",p.a.xa);
18
- p.b("ko.utils.arrayFilter",p.a.K);p.b("ko.utils.arrayGetDistinctValues",p.a.L);p.b("ko.utils.arrayIndexOf",p.a.h);p.b("ko.utils.arrayMap",p.a.M);p.b("ko.utils.arrayPushAll",p.a.u);p.b("ko.utils.arrayRemoveItem",p.a.N);p.b("ko.utils.fieldsIncludedWithJsonPost",p.a.ca);p.b("ko.utils.getElementsHavingAttribute",p.a.da);p.b("ko.utils.getFormFields",p.a.ea);p.b("ko.utils.postJson",p.a.Ta);p.b("ko.utils.parseJson",p.a.F);p.b("ko.utils.registerEventHandler",p.a.t);p.b("ko.utils.stringifyJson",p.a.Y);
19
- p.b("ko.utils.range",p.a.Ua);p.b("ko.utils.toggleDomNodeCssClass",p.a.pa);p.b("ko.utils.triggerEvent",p.a.qa);p.b("ko.utils.unwrapObservable",p.a.d);Function.prototype.bind||(Function.prototype.bind=function(e){var d=this,b=Array.prototype.slice.call(arguments),e=b.shift();return function(){return d.apply(e,b.concat(Array.prototype.slice.call(arguments)))}});
20
- p.a.e=new function(){var e=0,d="__ko__"+(new Date).getTime(),b={};return{get:function(a,b){var d=p.a.e.getAll(a,!1);return d===m?m:d[b]},set:function(a,b,d){d===m&&p.a.e.getAll(a,!1)===m||(p.a.e.getAll(a,!0)[b]=d)},getAll:function(a,f){var h=a[d];if(!h){if(!f)return;h=a[d]="ko"+e++;b[h]={}}return b[h]},clear:function(a){var e=a[d];e&&(delete b[e],a[d]=o)}}};
21
- p.a.p=new function(){function e(a,d){var e=p.a.e.get(a,b);e===m&&d&&(e=[],p.a.e.set(a,b,e));return e}function d(a){var b=e(a,!1);if(b)for(var b=b.slice(0),d=0;d<b.length;d++)b[d](a);p.a.e.clear(a);typeof jQuery=="function"&&typeof jQuery.cleanData=="function"&&jQuery.cleanData([a])}var b="__ko_domNodeDisposal__"+(new Date).getTime();return{ba:function(a,b){typeof b!="function"&&c(Error("Callback must be a function"));e(a,!0).push(b)},ja:function(a,d){var h=e(a,!1);h&&(p.a.N(h,d),h.length==0&&p.a.e.set(a,
22
- b,m))},v:function(a){if(!(a.nodeType!=1&&a.nodeType!=9)){d(a);var b=[];p.a.u(b,a.getElementsByTagName("*"));for(var a=0,e=b.length;a<e;a++)d(b[a])}},removeNode:function(a){p.v(a);a.parentNode&&a.parentNode.removeChild(a)}}};p.v=p.a.p.v;p.removeNode=p.a.p.removeNode;p.b("ko.cleanNode",p.v);p.b("ko.removeNode",p.removeNode);p.b("ko.utils.domNodeDisposal",p.a.p);p.b("ko.utils.domNodeDisposal.addDisposeCallback",p.a.p.ba);p.b("ko.utils.domNodeDisposal.removeDisposeCallback",p.a.p.ja);
23
- p.a.Sa=function(e){if(typeof jQuery!="undefined")e=jQuery.clean([e]);else{var d=p.a.k(e).toLowerCase(),b=document.createElement("div"),d=d.match(/^<(thead|tbody|tfoot)/)&&[1,"<table>","</table>"]||!d.indexOf("<tr")&&[2,"<table><tbody>","</tbody></table>"]||(!d.indexOf("<td")||!d.indexOf("<th"))&&[3,"<table><tbody><tr>","</tr></tbody></table>"]||[0,"",""];for(b.innerHTML=d[1]+e+d[2];d[0]--;)b=b.lastChild;e=p.a.U(b.childNodes)}return e};
24
- p.a.Ya=function(e,d){p.a.Q(e);if(d!==o&&d!==m)if(typeof d!="string"&&(d=d.toString()),typeof jQuery!="undefined")jQuery(e).html(d);else for(var b=p.a.Sa(d),a=0;a<b.length;a++)e.appendChild(b[a])};
25
- p.l=function(){function e(){return((1+Math.random())*4294967296|0).toString(16).substring(1)}function d(a,b){if(a)if(a.nodeType==8){var e=p.l.ha(a.nodeValue);e!=o&&b.push({Da:a,Pa:e})}else if(a.nodeType==1)for(var e=0,g=a.childNodes,i=g.length;e<i;e++)d(g[e],b)}var b={};return{V:function(a){typeof a!="function"&&c(Error("You can only pass a function to ko.memoization.memoize()"));var d=e()+e();b[d]=a;return"<\!--[ko_memo:"+d+"]--\>"},ra:function(a,d){var e=b[a];e===m&&c(Error("Couldn't find any memo with ID "+
26
- a+". Perhaps it's already been unmemoized."));try{return e.apply(o,d||[]),!0}finally{delete b[a]}},sa:function(a,b){var e=[];d(a,e);for(var g=0,i=e.length;g<i;g++){var k=e[g].Da,j=[k];b&&p.a.u(j,b);p.l.ra(e[g].Pa,j);k.nodeValue="";k.parentNode&&k.parentNode.removeChild(k)}},ha:function(a){return(a=a.match(/^\[ko_memo\:(.*?)\]$/))?a[1]:o}}}();p.b("ko.memoization",p.l);p.b("ko.memoization.memoize",p.l.V);p.b("ko.memoization.unmemoize",p.l.ra);p.b("ko.memoization.parseMemoText",p.l.ha);
27
- p.b("ko.memoization.unmemoizeDomNodeAndDescendants",p.l.sa);p.$a=function(e,d){this.za=e;this.n=function(){this.La=!0;d()}.bind(this);p.i(this,"dispose",this.n)};p.Z=function(){var e=[];this.$=function(d,b){var a=b?d.bind(b):d,f=new p.$a(a,function(){p.a.N(e,f)});e.push(f);return f};this.z=function(d){p.a.g(e.slice(0),function(b){b&&b.La!==!0&&b.za(d)})};this.Ja=function(){return e.length};p.i(this,"subscribe",this.$);p.i(this,"notifySubscribers",this.z);p.i(this,"getSubscriptionsCount",this.Ja)};
28
- p.ga=function(e){return typeof e.$=="function"&&typeof e.z=="function"};p.b("ko.subscribable",p.Z);p.b("ko.isSubscribable",p.ga);p.A=function(){var e=[];return{ya:function(){e.push([])},end:function(){return e.pop()},ia:function(d){p.ga(d)||c("Only subscribable things can act as dependencies");e.length>0&&e[e.length-1].push(d)}}}();var x={undefined:!0,"boolean":!0,number:!0,string:!0};function y(e,d){return e===o||typeof e in x?e===d:!1}
29
- p.s=function(e){function d(){if(arguments.length>0){if(!d.equalityComparer||!d.equalityComparer(b,arguments[0]))b=arguments[0],d.z(b);return this}else return p.A.ia(d),b}var b=e;d.o=p.s;d.H=function(){d.z(b)};d.equalityComparer=y;p.Z.call(d);p.i(d,"valueHasMutated",d.H);return d};p.C=function(e){if(e===o||e===m||e.o===m)return!1;if(e.o===p.s)return!0;return p.C(e.o)};p.D=function(e){if(typeof e=="function"&&e.o===p.s)return!0;if(typeof e=="function"&&e.o===p.j&&e.Ka)return!0;return!1};
30
- p.b("ko.observable",p.s);p.b("ko.isObservable",p.C);p.b("ko.isWriteableObservable",p.D);
31
- p.Ra=function(e){arguments.length==0&&(e=[]);e!==o&&e!==m&&!("length"in e)&&c(Error("The argument passed when initializing an observable array must be an array, or null, or undefined."));var d=new p.s(e);p.a.g(["pop","push","reverse","shift","sort","splice","unshift"],function(b){d[b]=function(){var a=d(),a=a[b].apply(a,arguments);d.H();return a}});p.a.g(["slice"],function(b){d[b]=function(){var a=d();return a[b].apply(a,arguments)}});d.remove=function(b){for(var a=d(),e=[],h=[],g=typeof b=="function"?
32
- b:function(a){return a===b},i=0,k=a.length;i<k;i++){var j=a[i];g(j)?h.push(j):e.push(j)}d(e);return h};d.Va=function(b){if(b===m){var a=d();d([]);return a}if(!b)return[];return d.remove(function(a){return p.a.h(b,a)>=0})};d.O=function(b){for(var a=d(),e=typeof b=="function"?b:function(a){return a===b},h=a.length-1;h>=0;h--)e(a[h])&&(a[h]._destroy=!0);d.H()};d.Ca=function(b){if(b===m)return d.O(function(){return!0});if(!b)return[];return d.O(function(a){return p.a.h(b,a)>=0})};d.indexOf=function(b){var a=
33
- d();return p.a.h(a,b)};d.replace=function(b,a){var e=d.indexOf(b);e>=0&&(d()[e]=a,d.H())};p.i(d,"remove",d.remove);p.i(d,"removeAll",d.Va);p.i(d,"destroy",d.O);p.i(d,"destroyAll",d.Ca);p.i(d,"indexOf",d.indexOf);return d};p.b("ko.observableArray",p.Ra);
34
- p.j=function(e,d,b){function a(){p.a.g(n,function(a){a.n()});n=[]}function f(b){a();p.a.g(b,function(a){n.push(a.$(h))})}function h(){if(k&&typeof b.disposeWhen=="function"&&b.disposeWhen())g.n();else{try{p.A.ya(),i=b.owner?b.read.call(b.owner):b.read()}finally{var a=p.a.L(p.A.end());f(a)}g.z(i);k=!0}}function g(){if(arguments.length>0)if(typeof b.write==="function"){var a=arguments[0];b.owner?b.write.call(b.owner,a):b.write(a)}else c("Cannot write a value to a dependentObservable unless you specify a 'write' option. If you wish to read the current value, don't pass any parameters.");
35
- else return k||h(),p.A.ia(g),i}var i,k=!1;e&&typeof e=="object"?b=e:(b=b||{},b.read=e||b.read,b.owner=d||b.owner);typeof b.read!="function"&&c("Pass a function that returns the value of the dependentObservable");var j=typeof b.disposeWhenNodeIsRemoved=="object"?b.disposeWhenNodeIsRemoved:o,l=o;if(j){l=function(){g.n()};p.a.p.ba(j,l);var q=b.disposeWhen;b.disposeWhen=function(){return!p.a.P(j)||typeof q=="function"&&q()}}var n=[];g.o=p.j;g.Ia=function(){return n.length};g.Ka=typeof b.write==="function";
36
- g.n=function(){j&&p.a.p.ja(j,l);a()};p.Z.call(g);b.deferEvaluation!==!0&&h();p.i(g,"dispose",g.n);p.i(g,"getDependenciesCount",g.Ia);return g};p.j.o=p.s;p.b("ko.dependentObservable",p.j);
37
- (function(){function e(a,f,h){h=h||new b;a=f(a);if(!(typeof a=="object"&&a!==o&&a!==m))return a;var g=a instanceof Array?[]:{};h.save(a,g);d(a,function(b){var d=f(a[b]);switch(typeof d){case "boolean":case "number":case "string":case "function":g[b]=d;break;case "object":case "undefined":var j=h.get(d);g[b]=j!==m?j:e(d,f,h)}});return g}function d(a,b){if(a instanceof Array)for(var d=0;d<a.length;d++)b(d);else for(d in a)b(d)}function b(){var a=[],b=[];this.save=function(d,e){var i=p.a.h(a,d);i>=0?
38
- b[i]=e:(a.push(d),b.push(e))};this.get=function(d){d=p.a.h(a,d);return d>=0?b[d]:m}}p.oa=function(a){arguments.length==0&&c(Error("When calling ko.toJS, pass the object you want to convert."));return e(a,function(a){for(var b=0;p.C(a)&&b<10;b++)a=a();return a})};p.toJSON=function(a){a=p.oa(a);return p.a.Y(a)}})();p.b("ko.toJS",p.oa);p.b("ko.toJSON",p.toJSON);
39
- p.f={m:function(e){if(e.tagName=="OPTION"){if(e.__ko__hasDomDataOptionValue__===!0)return p.a.e.get(e,p.c.options.W);return e.getAttribute("value")}else return e.tagName=="SELECT"?e.selectedIndex>=0?p.f.m(e.options[e.selectedIndex]):m:e.value},I:function(e,d){if(e.tagName=="OPTION")switch(typeof d){case "string":case "number":p.a.e.set(e,p.c.options.W,m);"__ko__hasDomDataOptionValue__"in e&&delete e.__ko__hasDomDataOptionValue__;e.value=d;break;default:p.a.e.set(e,p.c.options.W,d),e.__ko__hasDomDataOptionValue__=
40
- !0,e.value=""}else if(e.tagName=="SELECT")for(var b=e.options.length-1;b>=0;b--){if(p.f.m(e.options[b])==d){e.selectedIndex=b;break}}else{if(d===o||d===m)d="";e.value=d}}};p.b("ko.selectExtensions",p.f);p.b("ko.selectExtensions.readValue",p.f.m);p.b("ko.selectExtensions.writeValue",p.f.I);
41
- p.r=function(){function e(a,b){return a.replace(d,function(a,d){return b[d]})}var d=/\[ko_token_(\d+)\]/g,b=/^[\_$a-z][\_$a-z0-9]*(\[.*?\])*(\.[\_$a-z][\_$a-z0-9]*(\[.*?\])*)*$/i,a=["true","false"];return{F:function(a){a=p.a.k(a);if(a.length<3)return{};for(var b=[],d=o,i,k=a.charAt(0)=="{"?1:0;k<a.length;k++){var j=a.charAt(k);if(d===o)switch(j){case '"':case "'":case "/":d=k;i=j;break;case "{":d=k;i="}";break;case "[":d=k,i="]"}else if(j==i){j=a.substring(d,k+1);b.push(j);var l="[ko_token_"+(b.length-
42
- 1)+"]",a=a.substring(0,d)+l+a.substring(k+1);k-=j.length-l.length;d=o}}d={};a=a.split(",");i=0;for(k=a.length;i<k;i++){var l=a[i],q=l.indexOf(":");q>0&&q<l.length-1&&(j=p.a.k(l.substring(0,q)),l=p.a.k(l.substring(q+1)),j.charAt(0)=="{"&&(j=j.substring(1)),l.charAt(l.length-1)=="}"&&(l=l.substring(0,l.length-1)),j=p.a.k(e(j,b)),l=p.a.k(e(l,b)),d[j]=l)}return d},R:function(d){var e=p.r.F(d),g=[],i;for(i in e){var k=e[i],j;j=k;j=p.a.h(a,p.a.k(j).toLowerCase())>=0?!1:j.match(b)!==o;j&&(g.length>0&&g.push(", "),
43
- g.push(i+" : function(__ko_value) { "+k+" = __ko_value; }"))}g.length>0&&(d=d+", '_ko_property_writers' : { "+g.join("")+" } ");return d}}}();p.b("ko.jsonExpressionRewriting",p.r);p.b("ko.jsonExpressionRewriting.parseJson",p.r.F);p.b("ko.jsonExpressionRewriting.insertPropertyAccessorsIntoJson",p.r.R);p.c={};
44
- p.J=function(e,d,b,a){function f(a){return function(){return i[a]}}function h(){return i}var g=!0,a=a||"data-bind",i;new p.j(function(){var k;if(!(k=typeof d=="function"?d():d)){var j=e.getAttribute(a);try{var l=" { "+p.r.R(j)+" } ";k=p.a.Ha(l,b===o?window:b)}catch(q){c(Error("Unable to parse binding attribute.\nMessage: "+q+";\nAttribute value: "+j))}}i=k;if(g)for(var n in i)p.c[n]&&typeof p.c[n].init=="function"&&(0,p.c[n].init)(e,f(n),h,b);for(n in i)p.c[n]&&typeof p.c[n].update=="function"&&(0,p.c[n].update)(e,
45
- f(n),h,b)},o,{disposeWhenNodeIsRemoved:e});g=!1};p.ua=function(e,d){d&&d.nodeType==m&&c(Error("ko.applyBindings: first parameter should be your view model; second parameter should be a DOM node (note: this is a breaking change since KO version 1.05)"));var d=d||window.document.body,b=p.a.da(d,"data-bind");p.a.g(b,function(a){p.J(a,o,e)})};p.b("ko.bindingHandlers",p.c);p.b("ko.applyBindings",p.ua);p.b("ko.applyBindingsToNode",p.J);
46
- p.a.g(["click"],function(e){p.c[e]={init:function(d,b,a,f){return p.c.event.init.call(this,d,function(){var a={};a[e]=b();return a},a,f)}}});p.c.event={init:function(e,d,b,a){var f=d()||{},h;for(h in f)(function(){var f=h;typeof f=="string"&&p.a.t(e,f,function(e){var h,j=d()[f];if(j){var l=b();try{h=j.apply(a,arguments)}finally{if(h!==!0)e.preventDefault?e.preventDefault():e.returnValue=!1}if(l[f+"Bubble"]===!1)e.cancelBubble=!0,e.stopPropagation&&e.stopPropagation()}})})()}};
47
- p.c.submit={init:function(e,d,b,a){typeof d()!="function"&&c(Error("The value for a submit binding must be a function to invoke on submit"));p.a.t(e,"submit",function(b){var h,g=d();try{h=g.call(a,e)}finally{if(h!==!0)b.preventDefault?b.preventDefault():b.returnValue=!1}})}};p.c.visible={update:function(e,d){var b=p.a.d(d()),a=e.style.display!="none";if(b&&!a)e.style.display="";else if(!b&&a)e.style.display="none"}};
48
- p.c.enable={update:function(e,d){var b=p.a.d(d());if(b&&e.disabled)e.removeAttribute("disabled");else if(!b&&!e.disabled)e.disabled=!0}};p.c.disable={update:function(e,d){p.c.enable.update(e,function(){return!p.a.d(d())})}};
49
- p.c.value={init:function(e,d,b){var a=["change"],f=b().valueUpdate;f&&(typeof f=="string"&&(f=[f]),p.a.u(a,f),a=p.a.L(a));p.a.g(a,function(a){var f=!1;p.a.Za(a,"after")&&(f=!0,a=a.substring(5));var i=f?function(a){setTimeout(a,0)}:function(a){a()};p.a.t(e,a,function(){i(function(){var a=d(),f=p.f.m(e);p.D(a)?a(f):(a=b(),a._ko_property_writers&&a._ko_property_writers.value&&a._ko_property_writers.value(f))})})})},update:function(e,d){var b=p.a.d(d()),a=p.f.m(e),f=b!=a;b===0&&a!==0&&a!=="0"&&(f=!0);
50
- f&&(a=function(){p.f.I(e,b)},a(),e.tagName=="SELECT"&&setTimeout(a,0));e.tagName=="SELECT"&&(a=p.f.m(e),a!==b&&p.a.qa(e,"change"))}};
51
- p.c.options={update:function(e,d,b){e.tagName!="SELECT"&&c(Error("options binding applies only to SELECT elements"));var a=p.a.M(p.a.K(e.childNodes,function(a){return a.tagName&&a.tagName=="OPTION"&&a.selected}),function(a){return p.f.m(a)||a.innerText||a.textContent}),f=e.scrollTop,h=p.a.d(d());p.a.Q(e);if(h){var g=b();typeof h.length!="number"&&(h=[h]);if(g.optionsCaption){var i=document.createElement("OPTION");i.innerHTML=g.optionsCaption;p.f.I(i,m);e.appendChild(i)}b=0;for(d=h.length;b<d;b++){var i=
52
- document.createElement("OPTION"),k=typeof g.optionsValue=="string"?h[b][g.optionsValue]:h[b],k=p.a.d(k);p.f.I(i,k);var j=g.optionsText;optionText=typeof j=="function"?j(h[b]):typeof j=="string"?h[b][j]:k;if(optionText===o||optionText===m)optionText="";optionText=p.a.d(optionText).toString();typeof i.innerText=="string"?i.innerText=optionText:i.textContent=optionText;e.appendChild(i)}h=e.getElementsByTagName("OPTION");b=g=0;for(d=h.length;b<d;b++)p.a.h(a,p.f.m(h[b]))>=0&&(p.a.ma(h[b],!0),g++);if(f)e.scrollTop=
53
- f}}};p.c.options.W="__ko.bindingHandlers.options.optionValueDomData__";
54
- p.c.selectedOptions={fa:function(e){for(var d=[],e=e.childNodes,b=0,a=e.length;b<a;b++){var f=e[b];f.tagName=="OPTION"&&f.selected&&d.push(p.f.m(f))}return d},init:function(e,d,b){p.a.t(e,"change",function(){var a=d();p.D(a)?a(p.c.selectedOptions.fa(this)):(a=b(),a._ko_property_writers&&a._ko_property_writers.value&&a._ko_property_writers.value(p.c.selectedOptions.fa(this)))})},update:function(e,d){e.tagName!="SELECT"&&c(Error("values binding applies only to SELECT elements"));var b=p.a.d(d());if(b&&
55
- typeof b.length=="number")for(var a=e.childNodes,f=0,h=a.length;f<h;f++){var g=a[f];g.tagName=="OPTION"&&p.a.ma(g,p.a.h(b,p.f.m(g))>=0)}}};p.c.text={update:function(e,d){var b=p.a.d(d());if(b===o||b===m)b="";typeof e.innerText=="string"?e.innerText=b:e.textContent=b}};p.c.html={update:function(e,d){var b=p.a.d(d());p.a.Ya(e,b)}};p.c.css={update:function(e,d){var b=p.a.d(d()||{}),a;for(a in b)if(typeof a=="string"){var f=p.a.d(b[a]);p.a.pa(e,a,f)}}};
56
- p.c.style={update:function(e,d){var b=p.a.d(d()||{}),a;for(a in b)if(typeof a=="string"){var f=p.a.d(b[a]);e.style[a]=f||""}}};p.c.uniqueName={init:function(e,d){if(d())e.name="ko_unique_"+ ++p.c.uniqueName.Ba,p.a.S&&e.mergeAttributes(document.createElement("<input name='"+e.name+"'/>"),!1)}};p.c.uniqueName.Ba=0;
57
- p.c.checked={init:function(e,d,b){p.a.t(e,"click",function(){var a;if(e.type=="checkbox")a=e.checked;else if(e.type=="radio"&&e.checked)a=e.value;else return;var f=d();e.type=="checkbox"&&p.a.d(f)instanceof Array?(a=p.a.h(p.a.d(f),e.value),e.checked&&a<0?f.push(e.value):!e.checked&&a>=0&&f.splice(a,1)):p.D(f)?f()!==a&&f(a):(f=b(),f._ko_property_writers&&f._ko_property_writers.checked&&f._ko_property_writers.checked(a))});e.type=="radio"&&!e.name&&p.c.uniqueName.init(e,function(){return!0})},update:function(e,
58
- d){var b=p.a.d(d());if(e.type=="checkbox")e.checked=b instanceof Array?p.a.h(b,e.value)>=0:b,b&&p.a.S&&e.mergeAttributes(document.createElement("<input type='checkbox' checked='checked' />"),!1);else if(e.type=="radio")e.checked=e.value==b,e.value==b&&(p.a.S||p.a.Ma)&&e.mergeAttributes(document.createElement("<input type='radio' checked='checked' />"),!1)}};
59
- p.c.attr={update:function(e,d){var b=p.a.d(d())||{},a;for(a in b)if(typeof a=="string"){var f=p.a.d(b[a]);f===!1||f===o||f===m?e.removeAttribute(a):e.setAttribute(a,f.toString())}}};
60
- p.aa=function(){this.renderTemplate=function(){c("Override renderTemplate in your ko.templateEngine subclass")};this.isTemplateRewritten=function(){c("Override isTemplateRewritten in your ko.templateEngine subclass")};this.rewriteTemplate=function(){c("Override rewriteTemplate in your ko.templateEngine subclass")};this.createJavaScriptEvaluatorBlock=function(){c("Override createJavaScriptEvaluatorBlock in your ko.templateEngine subclass")}};p.b("ko.templateEngine",p.aa);
61
- p.G=function(){var e=/(<[a-z]+\d*(\s+(?!data-bind=)[a-z0-9\-]+(=(\"[^\"]*\"|\'[^\']*\'))?)*\s+)data-bind=(["'])([\s\S]*?)\5/gi;return{Ga:function(d,b){b.isTemplateRewritten(d)||b.rewriteTemplate(d,function(a){return p.G.Qa(a,b)})},Qa:function(d,b){return d.replace(e,function(a,d,e,g,i,k,j){a=p.r.R(j);return b.createJavaScriptEvaluatorBlock("ko.templateRewriting.applyMemoizedBindingsToNextSibling(function() { return (function() { return { "+a+" } })() })")+d})},
62
- va:function(d){return p.l.V(function(b,a){b.nextSibling&&p.J(b.nextSibling,d,a)})}}}();p.b("ko.templateRewriting",p.G);p.b("ko.templateRewriting.applyMemoizedBindingsToNextSibling",p.G.va);
63
- (function(){function e(b,a,e,h,g){var i=p.a.d(h),g=g||{},k=g.templateEngine||d;p.G.Ga(e,k);e=k.renderTemplate(e,i,g);(typeof e.length!="number"||e.length>0&&typeof e[0].nodeType!="number")&&c("Template engine must return an array of DOM nodes");e&&p.a.g(e,function(a){p.l.sa(a,[h])});switch(a){case "replaceChildren":p.a.Xa(b,e);break;case "replaceNode":p.a.ka(b,e);break;case "ignoreTargetNode":break;default:c(Error("Unknown renderMode: "+a))}g.afterRender&&g.afterRender(e,h);return e}var d;p.na=function(b){b!=
64
- m&&!(b instanceof p.aa)&&c("templateEngine must inherit from ko.templateEngine");d=b};p.X=function(b,a,f,h,g){f=f||{};(f.templateEngine||d)==m&&c("Set a template engine before calling renderTemplate");g=g||"replaceChildren";if(h){var i=h.nodeType?h:h.length>0?h[0]:o;return new p.j(function(){var d=typeof b=="function"?b(a):b,d=e(h,g,d,a,f);g=="replaceNode"&&(h=d,i=h.nodeType?h:h.length>0?h[0]:o)},o,{disposeWhen:function(){return!i||!p.a.P(i)},disposeWhenNodeIsRemoved:i&&g=="replaceNode"?i.parentNode:
65
- i})}else return p.l.V(function(d){p.X(b,a,f,d,"replaceNode")})};p.Wa=function(b,a,d,h){return new p.j(function(){var g=p.a.d(a)||[];typeof g.length=="undefined"&&(g=[g]);g=p.a.K(g,function(a){return d.includeDestroyed||!a._destroy});p.a.la(h,g,function(a){var g=typeof b=="function"?b(a):b;return e(o,"ignoreTargetNode",g,a,d)},d)},o,{disposeWhenNodeIsRemoved:h})};p.c.template={update:function(b,a,d,e){a=p.a.d(a());d=typeof a=="string"?a:a.name;if(typeof a.foreach!="undefined")e=p.Wa(d,a.foreach||[],
66
- {templateOptions:a.templateOptions,afterAdd:a.afterAdd,beforeRemove:a.beforeRemove,includeDestroyed:a.includeDestroyed,afterRender:a.afterRender},b);else var g=a.data,e=p.X(d,typeof g=="undefined"?e:g,{templateOptions:a.templateOptions,afterRender:a.afterRender},b);(a=p.a.e.get(b,"__ko__templateSubscriptionDomDataKey__"))&&typeof a.n=="function"&&a.n();p.a.e.set(b,"__ko__templateSubscriptionDomDataKey__",e)}}})();p.b("ko.setTemplateEngine",p.na);p.b("ko.renderTemplate",p.X);
67
- p.a.w=function(e,d,b){if(b===m)return p.a.w(e,d,1)||p.a.w(e,d,10)||p.a.w(e,d,Number.MAX_VALUE);else{for(var e=e||[],d=d||[],a=e,f=d,h=[],g=0;g<=f.length;g++)h[g]=[];for(var g=0,i=Math.min(a.length,b);g<=i;g++)h[0][g]=g;g=1;for(i=Math.min(f.length,b);g<=i;g++)h[g][0]=g;for(var i=a.length,k,j=f.length,g=1;g<=i;g++){var l=Math.min(j,g+b);for(k=Math.max(1,g-b);k<=l;k++)h[k][g]=a[g-1]===f[k-1]?h[k-1][g-1]:Math.min(h[k-1][g]===m?Number.MAX_VALUE:h[k-1][g]+1,h[k][g-1]===m?Number.MAX_VALUE:h[k][g-1]+1)}b=
68
- e.length;a=d.length;f=[];g=h[a][b];if(g===m)h=o;else{for(;b>0||a>0;){i=h[a][b];k=a>0?h[a-1][b]:g+1;j=b>0?h[a][b-1]:g+1;l=a>0&&b>0?h[a-1][b-1]:g+1;if(k===m||k<i-1)k=g+1;if(j===m||j<i-1)j=g+1;l<i-1&&(l=g+1);k<=j&&k<l?(f.push({status:"added",value:d[a-1]}),a--):(j<k&&j<l?f.push({status:"deleted",value:e[b-1]}):(f.push({status:"retained",value:e[b-1]}),a--),b--)}h=f.reverse()}return h}};p.b("ko.utils.compareArrays",p.a.w);
69
- (function(){function e(d,b,a){var e=[],d=p.j(function(){var d=b(a)||[];e.length>0&&p.a.ka(e,d);e.splice(0,e.length);p.a.u(e,d)},o,{disposeWhenNodeIsRemoved:d,disposeWhen:function(){return e.length==0||!p.a.P(e[0])}});return{Oa:e,j:d}}p.a.la=function(d,b,a,f){for(var b=b||[],f=f||{},h=p.a.e.get(d,"setDomNodeChildrenFromArrayMapping_lastMappingResult")===m,g=p.a.e.get(d,"setDomNodeChildrenFromArrayMapping_lastMappingResult")||[],i=p.a.M(g,function(a){return a.wa}),k=p.a.w(i,b),b=[],j=0,l=[],i=[],q=
70
- o,n=0,v=k.length;n<v;n++)switch(k[n].status){case "retained":var r=g[j];b.push(r);r.B.length>0&&(q=r.B[r.B.length-1]);j++;break;case "deleted":g[j].j.n();p.a.g(g[j].B,function(a){l.push({element:a,index:n,value:k[n].value});q=a});j++;break;case "added":var s=e(d,a,k[n].value),r=s.Oa;b.push({wa:k[n].value,B:r,j:s.j});for(var s=0,w=r.length;s<w;s++){var t=r[s];i.push({element:t,index:n,value:k[n].value});q==o?d.firstChild?d.insertBefore(t,d.firstChild):d.appendChild(t):q.nextSibling?d.insertBefore(t,
71
- q.nextSibling):d.appendChild(t);q=t}}p.a.g(l,function(a){p.v(a.element)});a=!1;if(!h){if(f.afterAdd)for(n=0;n<i.length;n++)f.afterAdd(i[n].element,i[n].index,i[n].value);if(f.beforeRemove){for(n=0;n<l.length;n++)f.beforeRemove(l[n].element,l[n].index,l[n].value);a=!0}}a||p.a.g(l,function(a){a.element.parentNode&&a.element.parentNode.removeChild(a.element)});p.a.e.set(d,"setDomNodeChildrenFromArrayMapping_lastMappingResult",b)}})();p.b("ko.utils.setDomNodeChildrenFromArrayMapping",p.a.la);
72
- p.T=function(){this.q=function(){if(typeof jQuery=="undefined"||!jQuery.tmpl)return 0;if(jQuery.tmpl.tag){if(jQuery.tmpl.tag.tmpl&&jQuery.tmpl.tag.tmpl.open&&jQuery.tmpl.tag.tmpl.open.toString().indexOf("__")>=0)return 3;return 2}return 1}();this.getTemplateNode=function(d){var b=document.getElementById(d);b==o&&c(Error("Cannot find template with ID="+d));return b};var e=RegExp("__ko_apos__","g");this.renderTemplate=function(d,b,a){a=a||{};this.q==0&&c(Error("jquery.tmpl not detected.\nTo use KO's default template engine, reference jQuery and jquery.tmpl. See Knockout installation documentation for more details."));
73
- if(this.q==1)return d='<script type="text/html">'+this.getTemplateNode(d).text+"<\/script>",b=jQuery.tmpl(d,b)[0].text.replace(e,"'"),jQuery.clean([b],document);if(!(d in jQuery.template)){var f=this.getTemplateNode(d).text;jQuery.template(d,f)}b=[b];b=jQuery.tmpl(d,b,a.templateOptions);b.appendTo(document.createElement("div"));jQuery.fragments={};return b};this.isTemplateRewritten=function(d){if(d in jQuery.template)return!0;return this.getTemplateNode(d).Na===!0};this.rewriteTemplate=function(d,
74
- b){var a=this.getTemplateNode(d),e=b(a.text);this.q==1&&(e=p.a.k(e),e=e.replace(/([\s\S]*?)(\${[\s\S]*?}|{{[\=a-z][\s\S]*?}}|$)/g,function(a,b,d){return b.replace(/\'/g,"__ko_apos__")+d}));a.text=e;a.Na=!0};this.createJavaScriptEvaluatorBlock=function(d){if(this.q==1)return"{{= "+d+"}}";return"{{ko_code ((function() { return "+d+" })()) }}"};this.ta=function(d,b){document.write("<script type='text/html' id='"+d+"'>"+b+"<\/script>")};p.i(this,"addTemplate",this.ta);this.q>1&&(jQuery.tmpl.tag.ko_code=
75
- {open:(this.q<3?"_":"__")+".push($1 || '');"})};p.T.prototype=new p.aa;p.na(new p.T);p.b("ko.jqueryTmplTemplateEngine",p.T);
76
- })(window);
1
+ // Knockout JavaScript library v1.03
2
+ // (c) 2010 Steven Sanderson - http://knockoutjs.com/
3
+ // License: Ms-Pl (http://www.opensource.org/licenses/ms-pl.html)
4
+
5
+ var ko = window.ko = {};
6
+ /// <reference path="namespace.js" />
7
+
8
+ ko.utils = new (function () {
9
+ var stringTrimRegex = /^(\s|\u00A0)+|(\s|\u00A0)+$/g;
10
+
11
+ return {
12
+ arrayForEach: function (array, action) {
13
+ for (var i = 0, j = array.length; i < j; i++)
14
+ action(array[i]);
15
+ },
16
+
17
+ arrayIndexOf: function (array, item) {
18
+ if (typeof array.indexOf == "function")
19
+ return array.indexOf(item);
20
+ for (var i = 0, j = array.length; i < j; i++)
21
+ if (array[i] == item)
22
+ return i;
23
+ return -1;
24
+ },
25
+
26
+ arrayFirst: function (array, predicate, predicateOwner) {
27
+ for (var i = 0, j = array.length; i < j; i++)
28
+ if (predicate.call(predicateOwner, array[i]))
29
+ return array[i];
30
+ return null;
31
+ },
32
+
33
+ arrayRemoveItem: function (array, itemToRemove) {
34
+ var index = ko.utils.arrayIndexOf(array, itemToRemove);
35
+ if (index >= 0)
36
+ array.splice(index, 1);
37
+ },
38
+
39
+ arrayGetDistinctValues: function (array) {
40
+ array = array || [];
41
+ var result = [];
42
+ for (var i = 0, j = array.length; i < j; i++) {
43
+ if (ko.utils.arrayIndexOf(result, array[i]) < 0)
44
+ result.push(array[i]);
45
+ }
46
+ return result;
47
+ },
48
+
49
+ arrayMap: function (array, mapping) {
50
+ array = array || [];
51
+ var result = [];
52
+ for (var i = 0, j = array.length; i < j; i++)
53
+ result.push(mapping(array[i]));
54
+ return result;
55
+ },
56
+
57
+ arrayFilter: function (array, predicate) {
58
+ array = array || [];
59
+ var result = [];
60
+ for (var i = 0, j = array.length; i < j; i++)
61
+ if (predicate(array[i]))
62
+ result.push(array[i]);
63
+ return result;
64
+ },
65
+
66
+ emptyDomNode: function (domNode) {
67
+ while (domNode.firstChild) {
68
+ ko.utils.domData.cleanNodeAndDescendants(domNode.firstChild);
69
+ domNode.removeChild(domNode.firstChild);
70
+ }
71
+ },
72
+
73
+ setDomNodeChildren: function (domNode, childNodes) {
74
+ ko.utils.emptyDomNode(domNode);
75
+ if (childNodes) {
76
+ ko.utils.arrayForEach(childNodes, function (childNode) {
77
+ domNode.appendChild(childNode);
78
+ });
79
+ }
80
+ },
81
+
82
+ replaceDomNodes: function (nodeToReplaceOrNodeArray, newNodesArray) {
83
+ var nodesToReplaceArray = nodeToReplaceOrNodeArray.nodeType ? [nodeToReplaceOrNodeArray] : nodeToReplaceOrNodeArray;
84
+ if (nodesToReplaceArray.length > 0) {
85
+ var insertionPoint = nodesToReplaceArray[0];
86
+ var parent = insertionPoint.parentNode;
87
+ for (var i = 0, j = newNodesArray.length; i < j; i++)
88
+ parent.insertBefore(newNodesArray[i], insertionPoint);
89
+ for (var i = 0, j = nodesToReplaceArray.length; i < j; i++) {
90
+ ko.utils.domData.cleanNodeAndDescendants(nodesToReplaceArray[i]);
91
+ parent.removeChild(nodesToReplaceArray[i]);
92
+ }
93
+ }
94
+ },
95
+
96
+ setOptionNodeSelectionState: function (optionNode, isSelected) {
97
+ // IE6 sometimes throws "unknown error" if you try to write to .selected directly, whereas Firefox struggles with setAttribute. Pick one based on browser.
98
+ if (navigator.userAgent.indexOf("MSIE 6") >= 0)
99
+ optionNode.setAttribute("selected", isSelected);
100
+ else
101
+ optionNode.selected = isSelected;
102
+ },
103
+
104
+ getElementsHavingAttribute: function (rootNode, attributeName) {
105
+ if ((!rootNode) || (rootNode.nodeType != 1)) return [];
106
+ var results = [];
107
+ if (rootNode.getAttribute(attributeName) !== null)
108
+ results.push(rootNode);
109
+ var descendants = rootNode.getElementsByTagName("*");
110
+ for (var i = 0, j = descendants.length; i < j; i++)
111
+ if (descendants[i].getAttribute(attributeName) !== null)
112
+ results.push(descendants[i]);
113
+ return results;
114
+ },
115
+
116
+ stringTrim: function (string) {
117
+ return (string || "").replace(stringTrimRegex, "");
118
+ },
119
+
120
+ stringTokenize: function (string, delimiter) {
121
+ var result = [];
122
+ var tokens = (string || "").split(delimiter);
123
+ for (var i = 0, j = tokens.length; i < j; i++) {
124
+ var trimmed = ko.utils.stringTrim(tokens[i]);
125
+ if (trimmed !== "")
126
+ result.push(trimmed);
127
+ }
128
+ return result;
129
+ },
130
+
131
+ evalWithinScope: function (expression, scope) {
132
+ if (scope === undefined)
133
+ return (new Function("return " + expression))();
134
+ with (scope) { return eval("(" + expression + ")"); }
135
+ },
136
+
137
+ domNodeIsContainedBy: function (node, containedByNode) {
138
+ if (containedByNode.compareDocumentPosition)
139
+ return (containedByNode.compareDocumentPosition(node) & 16) == 16;
140
+ while (node != null) {
141
+ if (node == containedByNode)
142
+ return true;
143
+ node = node.parentNode;
144
+ }
145
+ return false;
146
+ },
147
+
148
+ domNodeIsAttachedToDocument: function (node) {
149
+ return ko.utils.domNodeIsContainedBy(node, document);
150
+ },
151
+
152
+ registerEventHandler: function (element, eventType, handler) {
153
+ if (typeof jQuery != "undefined")
154
+ jQuery(element).bind(eventType, handler);
155
+ else if (typeof element.addEventListener == "function")
156
+ element.addEventListener(eventType, handler, false);
157
+ else if (typeof element.attachEvent != "undefined")
158
+ element.attachEvent("on" + eventType, function (event) {
159
+ handler.call(element, event);
160
+ });
161
+ else
162
+ throw new Error("Browser doesn't support addEventListener or attachEvent");
163
+ },
164
+
165
+ triggerEvent: function (element, eventType) {
166
+ if (!(element && element.nodeType))
167
+ throw new Error("element must be a DOM node when calling triggerEvent");
168
+
169
+ if (typeof element.fireEvent != "undefined") {
170
+ // Unlike other browsers, IE doesn't change the checked state of checkboxes/radiobuttons when you trigger their "click" event
171
+ // so to make it consistent, we'll do it manually here
172
+ if (eventType == "click") {
173
+ if ((element.tagName == "INPUT") && ((element.type.toLowerCase() == "checkbox") || (element.type.toLowerCase() == "radio")))
174
+ element.checked = element.checked !== true;
175
+ }
176
+ element.fireEvent("on" + eventType);
177
+ } else if (typeof document.createEvent == "function") {
178
+ if (typeof element.dispatchEvent == "function") {
179
+ var eventCategory = (eventType == "click" ? "MouseEvents" : "HTMLEvents"); // Might need to account for other event names at some point
180
+ var event = document.createEvent(eventCategory);
181
+ event.initEvent(eventType, true, true, window, 0, 0, 0, 0, 0, false, false, false, false, 0, element);
182
+ element.dispatchEvent(event);
183
+ }
184
+ else
185
+ throw new Error("The supplied element doesn't support dispatchEvent");
186
+ }
187
+ else
188
+ throw new Error("Browser doesn't support triggering events");
189
+ },
190
+
191
+ unwrapObservable: function (value) {
192
+ return ko.isObservable(value) ? value() : value;
193
+ },
194
+
195
+ domNodeHasCssClass: function (node, className) {
196
+ var currentClassNames = (node.className || "").split(/\s+/);
197
+ return ko.utils.arrayIndexOf(currentClassNames, className) >= 0;
198
+ },
199
+
200
+ toggleDomNodeCssClass: function (node, className, shouldHaveClass) {
201
+ var hasClass = ko.utils.domNodeHasCssClass(node, className);
202
+ if (shouldHaveClass && !hasClass) {
203
+ node.className = (node.className || "") + " " + className;
204
+ } else if (hasClass && !shouldHaveClass) {
205
+ var currentClassNames = (node.className || "").split(/\s+/);
206
+ var newClassName = "";
207
+ for (var i = 0; i < currentClassNames.length; i++)
208
+ if (currentClassNames[i] != className)
209
+ newClassName += currentClassNames[i] + " ";
210
+ node.className = ko.utils.stringTrim(newClassName);
211
+ }
212
+ },
213
+
214
+ range: function (min, max) {
215
+ min = ko.utils.unwrapObservable(min);
216
+ max = ko.utils.unwrapObservable(max);
217
+ var result = [];
218
+ for (var i = min; i <= max; i++)
219
+ result.push(i);
220
+ return result;
221
+ },
222
+
223
+ stringifyJson: function (data) {
224
+ if ((typeof JSON == "undefined") || (typeof JSON.stringify == "undefined"))
225
+ throw new Error("Cannot find JSON.stringify(). Some browsers (e.g., IE < 8) don't support it natively, but you can overcome this by adding a script reference to json2.js, downloadable from http://www.json.org/json2.js");
226
+ return JSON.stringify(ko.utils.unwrapObservable(data));
227
+ },
228
+
229
+ postJson: function (url, data) {
230
+ data = ko.utils.unwrapObservable(data);
231
+ var form = document.createElement("FORM");
232
+ form.style.display = "none";
233
+ form.action = url;
234
+ form.method = "post";
235
+ for (var key in data) {
236
+ var input = document.createElement("INPUT");
237
+ input.name = key;
238
+ input.value = ko.utils.stringifyJson(ko.utils.unwrapObservable(data[key]));
239
+ form.appendChild(input);
240
+ }
241
+ document.body.appendChild(form);
242
+ form.submit();
243
+ setTimeout(function () { form.parentNode.removeChild(form); }, 0);
244
+ },
245
+
246
+ domData: {
247
+ uniqueId: 0,
248
+ dataStoreKeyExpandoPropertyName: "__ko__" + (new Date).getTime(),
249
+ dataStore: {},
250
+ get: function (node, key) {
251
+ var allDataForNode = ko.utils.domData.getAll(node, false);
252
+ return allDataForNode === undefined ? undefined : allDataForNode[key];
253
+ },
254
+ set: function (node, key, value) {
255
+ var allDataForNode = ko.utils.domData.getAll(node, true);
256
+ allDataForNode[key] = value;
257
+ },
258
+ getAll: function (node, createIfNotFound) {
259
+ var dataStoreKey = node[ko.utils.domData.dataStoreKeyExpandoPropertyName];
260
+ if (!dataStoreKey) {
261
+ if (!createIfNotFound)
262
+ return undefined;
263
+ dataStoreKey = node[ko.utils.domData.dataStoreKeyExpandoPropertyName] = "ko" + ko.utils.domData.uniqueId++;
264
+ ko.utils.domData[dataStoreKey] = {};
265
+ }
266
+ return ko.utils.domData[dataStoreKey];
267
+ },
268
+ cleanNode: function (node) {
269
+ var dataStoreKey = node[ko.utils.domData.dataStoreKeyExpandoPropertyName];
270
+ if (dataStoreKey) {
271
+ delete ko.utils.domData[dataStoreKey];
272
+ node[ko.utils.domData.dataStoreKeyExpandoPropertyName] = null;
273
+ }
274
+ },
275
+ cleanNodeAndDescendants: function (node) {
276
+ if ((node.nodeType != 1) && (node.nodeType != 9))
277
+ return;
278
+ ko.utils.domData.cleanNode(node);
279
+ var descendants = node.getElementsByTagName("*");
280
+ for (var i = 0, j = descendants.length; i < j; i++)
281
+ ko.utils.domData.cleanNode(descendants[i]);
282
+ }
283
+ }
284
+ }
285
+ })();
286
+
287
+ if (!Function.prototype.bind) {
288
+ // Function.prototype.bind is a standard part of ECMAScript 5th Edition (December 2009, http://www.ecma-international.org/publications/files/ECMA-ST/ECMA-262.pdf)
289
+ // In case the browser doesn't implement it natively, provide a JavaScript implementation. This implementation is based on the one in prototype.js
290
+ Function.prototype.bind = function (object) {
291
+ var originalFunction = this, args = Array.prototype.slice.call(arguments), object = args.shift();
292
+ return function () {
293
+ return originalFunction.apply(object, args.concat(Array.prototype.slice.call(arguments)));
294
+ };
295
+ };
296
+ }/// <reference path="utils.js" />
297
+
298
+ ko.memoization = (function () {
299
+ var memos = {};
300
+
301
+ function randomMax8HexChars() {
302
+ return (((1 + Math.random()) * 0x100000000) | 0).toString(16).substring(1);
303
+ }
304
+ function generateRandomId() {
305
+ return randomMax8HexChars() + randomMax8HexChars();
306
+ }
307
+ function findMemoNodes(rootNode, appendToArray) {
308
+ if (!rootNode)
309
+ return;
310
+ if (rootNode.nodeType == 8) {
311
+ var memoId = ko.memoization.parseMemoText(rootNode.nodeValue);
312
+ if (memoId != null)
313
+ appendToArray.push({ domNode: rootNode, memoId: memoId });
314
+ } else if (rootNode.nodeType == 1) {
315
+ for (var i = 0, childNodes = rootNode.childNodes, j = childNodes.length; i < j; i++)
316
+ findMemoNodes(childNodes[i], appendToArray);
317
+ }
318
+ }
319
+
320
+ return {
321
+ memoize: function (callback) {
322
+ if (typeof callback != "function")
323
+ throw new Error("You can only pass a function to ko.memoization.memoize()");
324
+ var memoId = generateRandomId();
325
+ memos[memoId] = callback;
326
+ return "<!--[ko_memo:" + memoId + "]-->";
327
+ },
328
+
329
+ unmemoize: function (memoId, callbackParams) {
330
+ var callback = memos[memoId];
331
+ if (callback === undefined)
332
+ throw new Error("Couldn't find any memo with ID " + memoId + ". Perhaps it's already been unmemoized.");
333
+ try {
334
+ callback.apply(null, callbackParams || []);
335
+ return true;
336
+ }
337
+ finally { delete memos[memoId]; }
338
+ },
339
+
340
+ unmemoizeDomNodeAndDescendants: function (domNode) {
341
+ var memos = [];
342
+ findMemoNodes(domNode, memos);
343
+ for (var i = 0, j = memos.length; i < j; i++) {
344
+ var node = memos[i].domNode;
345
+ ko.memoization.unmemoize(memos[i].memoId, [node]);
346
+ node.nodeValue = ""; // Neuter this node so we don't try to unmemoize it again
347
+ if (node.parentNode)
348
+ node.parentNode.removeChild(node); // If possible, erase it totally (not always possible - someone else might just hold a reference to it then call unmemoizeDomNodeAndDescendants again)
349
+ }
350
+ },
351
+
352
+ parseMemoText: function (memoText) {
353
+ var match = memoText.match(/^\[ko_memo\:(.*?)\]$/);
354
+ return match ? match[1] : null;
355
+ }
356
+ };
357
+ })();/// <reference path="../utils.js" />
358
+
359
+ ko.subscription = function (callback, disposeCallback) {
360
+ this.callback = callback;
361
+ this.dispose = disposeCallback;
362
+ };
363
+
364
+ ko.subscribable = function () {
365
+ var _subscriptions = [];
366
+
367
+ this.subscribe = function (callback, callbackTarget) {
368
+ var boundCallback = callbackTarget ? function () { callback.call(callbackTarget) } : callback;
369
+
370
+ var subscription = new ko.subscription(boundCallback, function () {
371
+ ko.utils.arrayRemoveItem(_subscriptions, subscription);
372
+ });
373
+ _subscriptions.push(subscription);
374
+ return subscription;
375
+ };
376
+
377
+ this.notifySubscribers = function (valueToNotify) {
378
+ ko.utils.arrayForEach(_subscriptions.slice(0), function (subscription) {
379
+ if (subscription)
380
+ subscription.callback(valueToNotify);
381
+ });
382
+ };
383
+
384
+ this.getSubscriptionsCount = function () {
385
+ return _subscriptions.length;
386
+ };
387
+ }
388
+
389
+ ko.isSubscribable = function (instance) {
390
+ return typeof instance.subscribe == "function" && typeof instance.notifySubscribers == "function";
391
+ };/// <reference path="subscribable.js" />
392
+
393
+ ko.dependencyDetection = (function () {
394
+ var _detectedDependencies = [];
395
+
396
+ return {
397
+ begin: function () {
398
+ _detectedDependencies.push([]);
399
+ },
400
+
401
+ end: function () {
402
+ return _detectedDependencies.pop();
403
+ },
404
+
405
+ registerDependency: function (subscribable) {
406
+ if (!ko.isSubscribable(subscribable))
407
+ throw "Only subscribable things can act as dependencies";
408
+ if (_detectedDependencies.length > 0) {
409
+ _detectedDependencies[_detectedDependencies.length - 1].push(subscribable);
410
+ }
411
+ }
412
+ };
413
+ })();/// <reference path="dependencyDetection.js" />
414
+
415
+ ko.observable = function (initialValue) {
416
+ var _latestValue = initialValue;
417
+
418
+ function observable(newValue) {
419
+ if (arguments.length > 0) {
420
+ _latestValue = newValue;
421
+ observable.notifySubscribers(_latestValue);
422
+ }
423
+ else // The caller only needs to be notified of changes if they did a "read" operation
424
+ ko.dependencyDetection.registerDependency(observable);
425
+
426
+ return _latestValue;
427
+ }
428
+ observable.__ko_proto__ = ko.observable;
429
+ observable.valueHasMutated = function () { observable.notifySubscribers(_latestValue); }
430
+
431
+ ko.subscribable.call(observable);
432
+ return observable;
433
+ }
434
+ ko.isObservable = function (instance) {
435
+ if ((instance === null) || (instance === undefined) || (instance.__ko_proto__ === undefined)) return false;
436
+ if (instance.__ko_proto__ === ko.observable) return true;
437
+ return ko.isObservable(instance.__ko_proto__); // Walk the prototype chain
438
+ }
439
+ ko.isWriteableObservable = function (instance) {
440
+ return (typeof instance == "function") && instance.__ko_proto__ === ko.observable;
441
+ }/// <reference path="observable.js" />
442
+
443
+ ko.observableArray = function (initialValues) {
444
+ var result = new ko.observable(initialValues);
445
+
446
+ ko.utils.arrayForEach(["pop", "push", "reverse", "shift", "sort", "splice", "unshift"], function (methodName) {
447
+ result[methodName] = function () {
448
+ var underlyingArray = result();
449
+ var methodCallResult = underlyingArray[methodName].apply(underlyingArray, arguments);
450
+ result.valueHasMutated();
451
+ return methodCallResult;
452
+ };
453
+ });
454
+
455
+ ko.utils.arrayForEach(["slice"], function (methodName) {
456
+ result[methodName] = function () {
457
+ var underlyingArray = result();
458
+ return underlyingArray[methodName].apply(underlyingArray, arguments);
459
+ };
460
+ });
461
+
462
+ result.remove = function (valueOrPredicate) {
463
+ var underlyingArray = result();
464
+ var remainingValues = [];
465
+ var removedValues = [];
466
+ var predicate = typeof valueOrPredicate == "function" ? valueOrPredicate : function (value) { return value === valueOrPredicate; };
467
+ for (var i = 0, j = underlyingArray.length; i < j; i++) {
468
+ var value = underlyingArray[i];
469
+ if (!predicate(value))
470
+ remainingValues.push(value);
471
+ else
472
+ removedValues.push(value);
473
+ }
474
+ result(remainingValues);
475
+ return removedValues;
476
+ };
477
+
478
+ result.removeAll = function (arrayOfValues) {
479
+ if (!arrayOfValues)
480
+ return [];
481
+ return result.remove(function (value) {
482
+ return ko.utils.arrayIndexOf(arrayOfValues, value) >= 0;
483
+ });
484
+ };
485
+
486
+ result.indexOf = function (item) {
487
+ var underlyingArray = result();
488
+ return ko.utils.arrayIndexOf(underlyingArray, item);
489
+ };
490
+
491
+ return result;
492
+ }/// <reference path="observable.js" />
493
+
494
+ ko.dependentObservable = function (evaluatorFunction, evaluatorFunctionTarget, options) {
495
+ if (typeof evaluatorFunction != "function")
496
+ throw "Pass a function that returns the value of the dependentObservable";
497
+
498
+ var _subscriptionsToDependencies = [];
499
+ function disposeAllSubscriptionsToDependencies() {
500
+ ko.utils.arrayForEach(_subscriptionsToDependencies, function (subscription) {
501
+ subscription.dispose();
502
+ });
503
+ _subscriptionsToDependencies = [];
504
+ }
505
+
506
+ function replaceSubscriptionsToDependencies(newDependencies) {
507
+ disposeAllSubscriptionsToDependencies();
508
+ ko.utils.arrayForEach(newDependencies, function (dependency) {
509
+ _subscriptionsToDependencies.push(dependency.subscribe(evaluate));
510
+ });
511
+ };
512
+
513
+ var _latestValue, _isFirstEvaluation = true;
514
+ function evaluate() {
515
+ if ((!_isFirstEvaluation) && options && typeof options.disposeWhen == "function") {
516
+ if (options.disposeWhen()) {
517
+ dependentObservable.dispose();
518
+ return;
519
+ }
520
+ }
521
+
522
+ try {
523
+ ko.dependencyDetection.begin();
524
+ _latestValue = evaluatorFunctionTarget ? evaluatorFunction.call(evaluatorFunctionTarget) : evaluatorFunction();
525
+ } catch (ex) {
526
+ throw ex;
527
+ } finally {
528
+ var distinctDependencies = ko.utils.arrayGetDistinctValues(ko.dependencyDetection.end());
529
+ replaceSubscriptionsToDependencies(distinctDependencies);
530
+ }
531
+
532
+ dependentObservable.notifySubscribers(_latestValue);
533
+ _isFirstEvaluation = false;
534
+ }
535
+
536
+ function dependentObservable() {
537
+ if (arguments.length > 0)
538
+ throw "Cannot write a value to a dependentObservable. Do not pass any parameters to it";
539
+
540
+ ko.dependencyDetection.registerDependency(dependentObservable);
541
+ return _latestValue;
542
+ }
543
+ dependentObservable.__ko_proto__ = ko.dependentObservable;
544
+ dependentObservable.getDependenciesCount = function () { return _subscriptionsToDependencies.length; }
545
+ dependentObservable.dispose = function () {
546
+ disposeAllSubscriptionsToDependencies();
547
+ };
548
+
549
+ ko.subscribable.call(dependentObservable);
550
+ evaluate();
551
+ return dependentObservable;
552
+ };
553
+ ko.dependentObservable.__ko_proto__ = ko.observable;/// <reference path="../utils.js" />
554
+
555
+ ko.jsonExpressionRewriting = (function () {
556
+ var restoreCapturedTokensRegex = /\[ko_token_(\d+)\]/g;
557
+ var javaScriptAssignmentTarget = /^[\_$a-z][\_$a-z]*(\[.*?\])*(\.[\_$a-z][\_$a-z]*(\[.*?\])*)*$/i;
558
+ var javaScriptReservedWords = ["true", "false"];
559
+
560
+ function restoreTokens(string, tokens) {
561
+ return string.replace(restoreCapturedTokensRegex, function (match, tokenIndex) {
562
+ return tokens[tokenIndex];
563
+ });
564
+ }
565
+
566
+ function isWriteableValue(expression) {
567
+ if (ko.utils.arrayIndexOf(javaScriptReservedWords, ko.utils.stringTrim(expression).toLowerCase()) >= 0)
568
+ return false;
569
+ return expression.match(javaScriptAssignmentTarget) !== null;
570
+ }
571
+
572
+ return {
573
+ parseJson: function (jsonString) {
574
+ jsonString = ko.utils.stringTrim(jsonString);
575
+ if (jsonString.length < 3)
576
+ return {};
577
+
578
+ // We're going to split on commas, so first extract any blocks that may contain commas other than those at the top level
579
+ var tokens = [];
580
+ var tokenStart = null, tokenEndChar;
581
+ for (var position = jsonString.charAt(0) == "{" ? 1 : 0; position < jsonString.length; position++) {
582
+ var c = jsonString.charAt(position);
583
+ if (tokenStart === null) {
584
+ switch (c) {
585
+ case '"':
586
+ case "'":
587
+ case "/":
588
+ tokenStart = position;
589
+ tokenEndChar = c;
590
+ break;
591
+ case "{":
592
+ tokenStart = position;
593
+ tokenEndChar = "}";
594
+ break;
595
+ case "[":
596
+ tokenStart = position;
597
+ tokenEndChar = "]";
598
+ break;
599
+ }
600
+ } else if (c == tokenEndChar) {
601
+ var token = jsonString.substring(tokenStart, position + 1);
602
+ tokens.push(token);
603
+ var replacement = "[ko_token_" + (tokens.length - 1) + "]";
604
+ jsonString = jsonString.substring(0, tokenStart) + replacement + jsonString.substring(position + 1);
605
+ position -= (token.length - replacement.length);
606
+ tokenStart = null;
607
+ }
608
+ }
609
+
610
+ // Now we can safely split on commas to get the key/value pairs
611
+ var result = {};
612
+ var keyValuePairs = jsonString.split(",");
613
+ for (var i = 0, j = keyValuePairs.length; i < j; i++) {
614
+ var pair = keyValuePairs[i];
615
+ var colonPos = pair.indexOf(":");
616
+ if ((colonPos > 0) && (colonPos < pair.length - 1)) {
617
+ var key = ko.utils.stringTrim(pair.substring(0, colonPos));
618
+ var value = ko.utils.stringTrim(pair.substring(colonPos + 1));
619
+ if (key.charAt(0) == "{")
620
+ key = key.substring(1);
621
+ if (value.charAt(value.length - 1) == "}")
622
+ value = value.substring(0, value.length - 1);
623
+ key = ko.utils.stringTrim(restoreTokens(key, tokens));
624
+ value = ko.utils.stringTrim(restoreTokens(value, tokens));
625
+ result[key] = value;
626
+ }
627
+ }
628
+ return result;
629
+ },
630
+
631
+ insertPropertyAccessorsIntoJson: function (jsonString) {
632
+ var parsed = ko.jsonExpressionRewriting.parseJson(jsonString);
633
+ var propertyAccessorTokens = [];
634
+ for (var key in parsed) {
635
+ var value = parsed[key];
636
+ if (isWriteableValue(value)) {
637
+ if (propertyAccessorTokens.length > 0)
638
+ propertyAccessorTokens.push(", ");
639
+ propertyAccessorTokens.push(key + " : function(__ko_value) { " + value + " = __ko_value; }");
640
+ }
641
+ }
642
+
643
+ if (propertyAccessorTokens.length > 0) {
644
+ var allPropertyAccessors = propertyAccessorTokens.join("");
645
+ jsonString = jsonString + ", '_ko_property_writers' : { " + allPropertyAccessors + " } ";
646
+ }
647
+
648
+ return jsonString;
649
+ }
650
+ };
651
+ })();/// <reference path="../subscribables/dependentObservable.js" />
652
+
653
+ (function () {
654
+ var bindingAttributeName = "data-bind";
655
+ ko.bindingHandlers = {};
656
+
657
+ function parseBindingAttribute(attributeText, viewModel) {
658
+ try {
659
+ var json = " { " + ko.jsonExpressionRewriting.insertPropertyAccessorsIntoJson(attributeText) + " } ";
660
+ return ko.utils.evalWithinScope(json, viewModel === null ? window : viewModel);
661
+ } catch (ex) {
662
+ throw new Error("Unable to parse binding attribute.\nMessage: " + ex + ";\nAttribute value: " + attributeText);
663
+ }
664
+ }
665
+
666
+ function invokeBindingHandler(handler, element, dataValue, allBindings, viewModel) {
667
+ handler(element, dataValue, allBindings, viewModel);
668
+ }
669
+
670
+ ko.applyBindingsToNode = function (node, bindings, viewModel) {
671
+ var isFirstEvaluation = true;
672
+ new ko.dependentObservable(
673
+ function () {
674
+ var evaluatedBindings = (typeof bindings == "function") ? bindings() : bindings;
675
+ var parsedBindings = evaluatedBindings || parseBindingAttribute(node.getAttribute(bindingAttributeName), viewModel);
676
+ for (var bindingKey in parsedBindings) {
677
+ if (ko.bindingHandlers[bindingKey]) {
678
+ if (isFirstEvaluation && typeof ko.bindingHandlers[bindingKey].init == "function")
679
+ invokeBindingHandler(ko.bindingHandlers[bindingKey].init, node, parsedBindings[bindingKey], parsedBindings, viewModel);
680
+ if (typeof ko.bindingHandlers[bindingKey].update == "function")
681
+ invokeBindingHandler(ko.bindingHandlers[bindingKey].update, node, parsedBindings[bindingKey], parsedBindings, viewModel);
682
+ }
683
+ }
684
+ },
685
+ null,
686
+ { disposeWhen: function () { return !ko.utils.domNodeIsAttachedToDocument(node); } }
687
+ );
688
+ isFirstEvaluation = false;
689
+ };
690
+
691
+ ko.applyBindings = function (rootNode, viewModel) {
692
+ var elemsWithBindingAttribute = ko.utils.getElementsHavingAttribute(rootNode, bindingAttributeName);
693
+ ko.utils.arrayForEach(elemsWithBindingAttribute, function (element) {
694
+ ko.applyBindingsToNode(element, null, viewModel);
695
+ });
696
+ };
697
+ })();/// <reference path="bindingAttributeSyntax.js" />
698
+
699
+ ko.bindingHandlers.click = {
700
+ init: function (element, value, allBindings, viewModel) {
701
+ ko.utils.registerEventHandler(element, "click", function (event) {
702
+ try { value.call(viewModel); }
703
+ finally {
704
+ if (event.preventDefault)
705
+ event.preventDefault();
706
+ else
707
+ event.returnValue = false;
708
+ }
709
+ });
710
+ }
711
+ };
712
+
713
+ ko.bindingHandlers.submit = {
714
+ init: function (element, value, allBindings, viewModel) {
715
+ if (typeof value != "function")
716
+ throw new Error("The value for a submit binding must be a function to invoke on submit");
717
+ ko.utils.registerEventHandler(element, "submit", function (event) {
718
+ try { value.call(viewModel); }
719
+ finally {
720
+ if (event.preventDefault)
721
+ event.preventDefault();
722
+ else
723
+ event.returnValue = false;
724
+ }
725
+ });
726
+ }
727
+ };
728
+
729
+ ko.bindingHandlers.visible = {
730
+ update: function (element, value) {
731
+ value = ko.utils.unwrapObservable(value);
732
+ var isCurrentlyVisible = !(element.style.display == "none");
733
+ if (value && !isCurrentlyVisible)
734
+ element.style.display = "";
735
+ else if ((!value) && isCurrentlyVisible)
736
+ element.style.display = "none";
737
+ }
738
+ }
739
+
740
+ ko.bindingHandlers.enable = {
741
+ update: function (element, value) {
742
+ value = ko.utils.unwrapObservable(value);
743
+ if (value && element.disabled)
744
+ element.removeAttribute("disabled");
745
+ else if ((!value) && (!element.disabled))
746
+ element.disabled = true;
747
+ }
748
+ };
749
+
750
+ ko.bindingHandlers.disable = { update: function (element, value) { ko.bindingHandlers.enable.update(element, !ko.utils.unwrapObservable(value)); } };
751
+
752
+ ko.bindingHandlers.value = {
753
+ init: function (element, value, allBindings) {
754
+ var eventName = allBindings.valueUpdate || "change";
755
+ if (ko.isWriteableObservable(value))
756
+ ko.utils.registerEventHandler(element, eventName, function () { value(this.value); });
757
+ else if (allBindings._ko_property_writers && allBindings._ko_property_writers.value)
758
+ ko.utils.registerEventHandler(element, eventName, function () { allBindings._ko_property_writers.value(this.value); });
759
+ },
760
+ update: function (element, value) {
761
+ var newValue = ko.utils.unwrapObservable(value);
762
+
763
+ if (newValue != element.value) {
764
+ var applyValueAction = function () { element.value = newValue; };
765
+ applyValueAction();
766
+
767
+ // Workaround for IE6 bug: It won't reliably apply values to SELECT nodes during the same execution thread
768
+ // right after you've changed the set of OPTION nodes on it. So for that node type, we'll schedule a second thread
769
+ // to apply the value as well.
770
+ var alsoApplyAsynchronously = element.tagName == "SELECT";
771
+ if (alsoApplyAsynchronously)
772
+ setTimeout(applyValueAction, 0);
773
+ }
774
+ }
775
+ };
776
+
777
+ ko.bindingHandlers.options = {
778
+ update: function (element, value, allBindings) {
779
+
780
+ if (element.tagName != "SELECT")
781
+ throw new Error("values binding applies only to SELECT elements");
782
+
783
+ var previousSelectedValues = ko.utils.arrayMap(ko.utils.arrayFilter(element.childNodes, function (node) {
784
+ return node.tagName && node.tagName == "OPTION" && node.selected;
785
+ }), function (node) {
786
+ return node.value || node.innerText || node.textContent;
787
+ });
788
+
789
+ value = ko.utils.unwrapObservable(value);
790
+ var selectedValue = element.value;
791
+ ko.utils.emptyDomNode(element);
792
+
793
+ if (value) {
794
+ if (typeof value.length != "number")
795
+ value = [value];
796
+ for (var i = 0, j = value.length; i < j; i++) {
797
+ var option = document.createElement("OPTION");
798
+ var optionValue = typeof allBindings.options_value == "string" ? value[i][allBindings.options_value] : value[i];
799
+ option.value = optionValue.toString();
800
+ option.innerHTML = (typeof allBindings.options_text == "string" ? value[i][allBindings.options_text] : optionValue).toString();
801
+ element.appendChild(option);
802
+ }
803
+
804
+ // IE6 doesn't like us to assign selection to OPTION nodes before they're added to the document.
805
+ // That's why we first added them without selection. Now it's time to set the selection.
806
+ var newOptions = element.getElementsByTagName("OPTION");
807
+ for (var i = 0, j = newOptions.length; i < j; i++) {
808
+ if (ko.utils.arrayIndexOf(previousSelectedValues, newOptions[i].value) >= 0)
809
+ ko.utils.setOptionNodeSelectionState(newOptions[i], true);
810
+ }
811
+ }
812
+ }
813
+ };
814
+
815
+ ko.bindingHandlers.selectedOptions = {
816
+ getSelectedValuesFromSelectNode: function (selectNode) {
817
+ var result = [];
818
+ var nodes = selectNode.childNodes;
819
+ for (var i = 0, j = nodes.length; i < j; i++) {
820
+ var node = nodes[i];
821
+ if ((node.tagName == "OPTION") && node.selected)
822
+ result.push(node.value);
823
+ }
824
+ return result;
825
+ },
826
+ init: function (element, value, allBindings) {
827
+
828
+ if (ko.isWriteableObservable(value))
829
+ ko.utils.registerEventHandler(element, "change", function () { value(ko.bindingHandlers.selectedOptions.getSelectedValuesFromSelectNode(this)); });
830
+ else if (allBindings._ko_property_writers && allBindings._ko_property_writers.value)
831
+ ko.utils.registerEventHandler(element, "change", function () { allBindings._ko_property_writers.value(ko.bindingHandlers.selectedOptions.getSelectedValuesFromSelectNode(this)); });
832
+ },
833
+ update: function (element, value) {
834
+ if (element.tagName != "SELECT")
835
+ throw new Error("values binding applies only to SELECT elements");
836
+
837
+ var newValue = ko.utils.unwrapObservable(value);
838
+ if (newValue && typeof newValue.length == "number") {
839
+ var nodes = element.childNodes;
840
+ for (var i = 0, j = nodes.length; i < j; i++) {
841
+ var node = nodes[i];
842
+ if (node.tagName == "OPTION")
843
+ ko.utils.setOptionNodeSelectionState(node, ko.utils.arrayIndexOf(newValue, node.value) >= 0);
844
+ }
845
+ }
846
+ }
847
+ };
848
+
849
+ ko.bindingHandlers.text = {
850
+ update: function (element, value) {
851
+ value = ko.utils.unwrapObservable(value);
852
+ typeof element.innerText == "string" ? element.innerText = value
853
+ : element.textContent = value;
854
+ }
855
+ };
856
+
857
+ ko.bindingHandlers.css = {
858
+ update: function (element, value) {
859
+ value = value || {};
860
+ for (var className in value) {
861
+ if (typeof className == "string") {
862
+ var shouldHaveClass = ko.utils.unwrapObservable(value[className]);
863
+ ko.utils.toggleDomNodeCssClass(element, className, shouldHaveClass);
864
+ }
865
+ }
866
+ }
867
+ };
868
+
869
+ ko.bindingHandlers.style = {
870
+ update: function (element, value) {
871
+ value = ko.utils.unwrapObservable(value || {});
872
+ for (var styleName in value) {
873
+ if (typeof styleName == "string") {
874
+ var styleValue = ko.utils.unwrapObservable(value[styleName]);
875
+ element.style[styleName] = styleValue || ""; // Empty string removes the value, whereas null/undefined have no effect
876
+ }
877
+ }
878
+ }
879
+ };
880
+
881
+ ko.bindingHandlers.uniqueName = {
882
+ init: function (element, value) {
883
+ if (value) {
884
+ element.name = "ko_unique_" + (++ko.bindingHandlers.uniqueName.currentIndex);
885
+
886
+ // Workaround IE 6 issue - http://www.matts411.com/post/setting_the_name_attribute_in_ie_dom/
887
+ if (/MSIE 6/i.test(navigator.userAgent))
888
+ element.mergeAttributes(document.createElement("<INPUT name='" + element.name + "'/>"), false);
889
+ }
890
+ }
891
+ };
892
+ ko.bindingHandlers.uniqueName.currentIndex = 0;
893
+
894
+ ko.bindingHandlers.checked = {
895
+ init: function (element, value, allBindings) {
896
+ if (ko.isWriteableObservable(value)) {
897
+ var updateHandler;
898
+ if (element.type == "checkbox")
899
+ updateHandler = function () { value(this.checked) };
900
+ else if (element.type == "radio")
901
+ updateHandler = function () { if (this.checked) value(this.value) };
902
+ if (updateHandler) {
903
+ ko.utils.registerEventHandler(element, "change", updateHandler);
904
+ ko.utils.registerEventHandler(element, "click", updateHandler);
905
+ }
906
+ } else if (allBindings._ko_property_writers && allBindings._ko_property_writers.checked) {
907
+ var updateHandler;
908
+ if (element.type == "checkbox")
909
+ updateHandler = function () { allBindings._ko_property_writers.checked(this.checked) };
910
+ else if (element.type == "radio")
911
+ updateHandler = function () { if (this.checked) allBindings._ko_property_writers.checked(this.value) };
912
+ if (updateHandler) {
913
+ ko.utils.registerEventHandler(element, "change", updateHandler);
914
+ ko.utils.registerEventHandler(element, "click", updateHandler);
915
+ }
916
+ }
917
+
918
+ // IE 6 won't allow radio buttons to be selected unless they have a name
919
+ if ((element.type == "radio") && !element.name)
920
+ ko.bindingHandlers.uniqueName.init(element, true);
921
+ },
922
+ update: function (element, value) {
923
+ value = ko.utils.unwrapObservable(value);
924
+ if (element.type == "checkbox")
925
+ element.checked = value;
926
+ else if (element.type == "radio")
927
+ element.checked = (element.value == value);
928
+ }
929
+ };/// <reference path="../utils.js" />
930
+
931
+ ko.templateEngine = function () {
932
+ this.renderTemplate = function (templateName, data, options) {
933
+ throw "Override renderTemplate in your ko.templateEngine subclass";
934
+ },
935
+ this.isTemplateRewritten = function (templateName) {
936
+ throw "Override isTemplateRewritten in your ko.templateEngine subclass";
937
+ },
938
+ this.rewriteTemplate = function (templateName, rewriterCallback) {
939
+ throw "Override rewriteTemplate in your ko.templateEngine subclass";
940
+ },
941
+ this.createJavaScriptEvaluatorBlock = function (script) {
942
+ throw "Override createJavaScriptEvaluatorBlock in your ko.templateEngine subclass";
943
+ }
944
+ };/// <reference path="templateEngine.js" />
945
+
946
+ ko.templateRewriting = (function () {
947
+ var memoizeBindingAttributeSyntaxRegex = /(<[a-z]+(\s+(?!data-bind=)[a-z0-9]+(=(\"[^\"]*\"|\'[^\']*\'))?)*\s+)data-bind=(["'])(.*?)\5/g;
948
+
949
+ return {
950
+ ensureTemplateIsRewritten: function (template, templateEngine) {
951
+ if (!templateEngine.isTemplateRewritten(template))
952
+ templateEngine.rewriteTemplate(template, function (htmlString) {
953
+ return ko.templateRewriting.memoizeBindingAttributeSyntax(htmlString, templateEngine);
954
+ });
955
+ },
956
+
957
+ memoizeBindingAttributeSyntax: function (htmlString, templateEngine) {
958
+ return htmlString.replace(memoizeBindingAttributeSyntaxRegex, function () {
959
+ var tagToRetain = arguments[1];
960
+ var dataBindAttributeValue = arguments[6];
961
+
962
+ dataBindAttributeValue = ko.jsonExpressionRewriting.insertPropertyAccessorsIntoJson(dataBindAttributeValue);
963
+
964
+ // For no obvious reason, Opera fails to evaluate dataBindAttributeValue unless it's wrapped in an additional anonymous function,
965
+ // even though Opera's built-in debugger can evaluate it anyway. No other browser requires this extra indirection.
966
+ var applyBindingsToNextSiblingScript = "ko.templateRewriting.applyMemoizedBindingsToNextSibling(function() { \
967
+ return (function() { return { " + dataBindAttributeValue + " } })() \
968
+ })";
969
+ return templateEngine.createJavaScriptEvaluatorBlock(applyBindingsToNextSiblingScript) + tagToRetain;
970
+ });
971
+ },
972
+
973
+ applyMemoizedBindingsToNextSibling: function (bindings) {
974
+ return ko.memoization.memoize(function (domNode) {
975
+ if (domNode.nextSibling)
976
+ ko.applyBindingsToNode(domNode.nextSibling, bindings, null);
977
+ });
978
+ }
979
+ }
980
+ })();/// <reference path="templating.js" />
981
+ /// <reference path="../subscribables/dependentObservable.js" />
982
+
983
+ (function () {
984
+ var _templateEngine;
985
+ ko.setTemplateEngine = function (templateEngine) {
986
+ if ((templateEngine != undefined) && !(templateEngine instanceof ko.templateEngine))
987
+ throw "templateEngine must inherit from ko.templateEngine";
988
+ _templateEngine = templateEngine;
989
+ }
990
+
991
+ function getFirstNodeFromPossibleArray(nodeOrNodeArray) {
992
+ return nodeOrNodeArray.nodeType ? nodeOrNodeArray
993
+ : nodeOrNodeArray.length > 0 ? nodeOrNodeArray[0]
994
+ : null;
995
+ }
996
+
997
+ function executeTemplate(targetNodeOrNodeArray, renderMode, template, data, options) {
998
+ var dataForTemplate = ko.utils.unwrapObservable(data);
999
+
1000
+ options = options || {};
1001
+ var templateEngineToUse = (options.templateEngine || _templateEngine);
1002
+ ko.templateRewriting.ensureTemplateIsRewritten(template, templateEngineToUse);
1003
+ var renderedNodesArray = templateEngineToUse.renderTemplate(template, dataForTemplate, options);
1004
+
1005
+ // Loosely check result is an array of DOM nodes
1006
+ if ((typeof renderedNodesArray.length != "number") || (renderedNodesArray.length > 0 && typeof renderedNodesArray[0].nodeType != "number"))
1007
+ throw "Template engine must return an array of DOM nodes";
1008
+
1009
+ if (renderedNodesArray)
1010
+ ko.utils.arrayForEach(renderedNodesArray, function (renderedNode) {
1011
+ ko.memoization.unmemoizeDomNodeAndDescendants(renderedNode);
1012
+ });
1013
+
1014
+ switch (renderMode) {
1015
+ case "replaceChildren": ko.utils.setDomNodeChildren(targetNodeOrNodeArray, renderedNodesArray); break;
1016
+ case "replaceNode": ko.utils.replaceDomNodes(targetNodeOrNodeArray, renderedNodesArray); break;
1017
+ case "ignoreTargetNode": break;
1018
+ default: throw new Error("Unknown renderMode: " + renderMode);
1019
+ }
1020
+
1021
+ return renderedNodesArray;
1022
+ }
1023
+
1024
+ ko.renderTemplate = function (template, data, options, targetNodeOrNodeArray, renderMode) {
1025
+ options = options || {};
1026
+ if ((options.templateEngine || _templateEngine) == undefined)
1027
+ throw "Set a template engine before calling renderTemplate";
1028
+ renderMode = renderMode || "replaceChildren";
1029
+
1030
+ if (targetNodeOrNodeArray) {
1031
+ var firstTargetNode = getFirstNodeFromPossibleArray(targetNodeOrNodeArray);
1032
+ var whenToDispose = function () { return (!firstTargetNode) || !ko.utils.domNodeIsAttachedToDocument(firstTargetNode); };
1033
+
1034
+ return new ko.dependentObservable( // So the DOM is automatically updated when any dependency changes
1035
+ function () {
1036
+ var renderedNodesArray = executeTemplate(targetNodeOrNodeArray, renderMode, template, data, options);
1037
+ if (renderMode == "replaceNode") {
1038
+ targetNodeOrNodeArray = renderedNodesArray;
1039
+ firstTargetNode = getFirstNodeFromPossibleArray(targetNodeOrNodeArray);
1040
+ }
1041
+ },
1042
+ null,
1043
+ { disposeWhen: whenToDispose }
1044
+ );
1045
+ } else {
1046
+ // We don't yet have a DOM node to evaluate, so use a memo and render the template later when there is a DOM node
1047
+ return ko.memoization.memoize(function (domNode) {
1048
+ ko.renderTemplate(template, data, options, domNode, "replaceNode");
1049
+ });
1050
+ }
1051
+ };
1052
+
1053
+ ko.renderTemplateForEach = function (template, arrayOrObservableArray, options, targetNode) {
1054
+ var whenToDispose = function () { return !ko.utils.domNodeIsAttachedToDocument(targetNode); };
1055
+
1056
+ new ko.dependentObservable(function () {
1057
+ var unwrappedArray = ko.utils.unwrapObservable(arrayOrObservableArray);
1058
+ if (typeof unwrappedArray.length == "undefined") // Coerce single value into array
1059
+ unwrappedArray = [unwrappedArray];
1060
+
1061
+ ko.utils.setDomNodeChildrenFromArrayMapping(targetNode, unwrappedArray, function (arrayValue) {
1062
+ return executeTemplate(null, "ignoreTargetNode", template, arrayValue, options);
1063
+ }, options);
1064
+ }, null, { disposeWhen: whenToDispose });
1065
+ };
1066
+
1067
+ ko.bindingHandlers.template = {
1068
+ update: function (element, bindingValue, allBindings, viewModel) {
1069
+ var templateName = typeof bindingValue == "string" ? bindingValue : bindingValue.name;
1070
+
1071
+ if (typeof bindingValue.foreach != "undefined") {
1072
+ // Render once for each data point
1073
+ ko.renderTemplateForEach(templateName, bindingValue.foreach || [], { afterAdd: bindingValue.afterAdd, beforeRemove: bindingValue.beforeRemove }, element);
1074
+ }
1075
+ else {
1076
+ // Render once for this single data point (or use the viewModel if no data was provided)
1077
+ var templateData = bindingValue.data;
1078
+ ko.renderTemplate(templateName, typeof templateData == "undefined" ? viewModel : templateData, null, element);
1079
+ }
1080
+ }
1081
+ };
1082
+ })();/// <reference path="../../utils.js" />
1083
+
1084
+ // Simple calculation based on Levenshtein distance.
1085
+ (function () {
1086
+
1087
+ function calculateEditDistanceMatrix(oldArray, newArray, maxAllowedDistance) {
1088
+ var distances = [];
1089
+ for (var i = 0; i <= newArray.length; i++)
1090
+ distances[i] = [];
1091
+
1092
+ // Top row - transform old array into empty array via deletions
1093
+ for (var i = 0, j = Math.min(oldArray.length, maxAllowedDistance); i <= j; i++)
1094
+ distances[0][i] = i;
1095
+
1096
+ // Left row - transform empty array into new array via additions
1097
+ for (var i = 1, j = Math.min(newArray.length, maxAllowedDistance); i <= j; i++) {
1098
+ distances[i][0] = i;
1099
+ }
1100
+
1101
+ // Fill out the body of the array
1102
+ var oldIndex, oldIndexMax = oldArray.length, newIndex, newIndexMax = newArray.length;
1103
+ var distanceViaAddition, distanceViaDeletion;
1104
+ for (oldIndex = 1; oldIndex <= oldIndexMax; oldIndex++) {
1105
+ var newIndexMinForRow = Math.max(1, oldIndex - maxAllowedDistance);
1106
+ var newIndexMaxForRow = Math.min(newIndexMax, oldIndex + maxAllowedDistance);
1107
+ for (newIndex = newIndexMinForRow; newIndex <= newIndexMaxForRow; newIndex++) {
1108
+ if (oldArray[oldIndex - 1] === newArray[newIndex - 1])
1109
+ distances[newIndex][oldIndex] = distances[newIndex - 1][oldIndex - 1];
1110
+ else {
1111
+ var northDistance = distances[newIndex - 1][oldIndex] === undefined ? Number.MAX_VALUE : distances[newIndex - 1][oldIndex] + 1;
1112
+ var westDistance = distances[newIndex][oldIndex - 1] === undefined ? Number.MAX_VALUE : distances[newIndex][oldIndex - 1] + 1;
1113
+ distances[newIndex][oldIndex] = Math.min(northDistance, westDistance);
1114
+ }
1115
+ }
1116
+ }
1117
+
1118
+ return distances;
1119
+ }
1120
+
1121
+ function findEditScriptFromEditDistanceMatrix(editDistanceMatrix, oldArray, newArray) {
1122
+ var oldIndex = oldArray.length;
1123
+ var newIndex = newArray.length;
1124
+ var editScript = [];
1125
+ var maxDistance = editDistanceMatrix[newIndex][oldIndex];
1126
+ if (maxDistance === undefined)
1127
+ return null; // maxAllowedDistance must be too small
1128
+ while ((oldIndex > 0) || (newIndex > 0)) {
1129
+ var me = editDistanceMatrix[newIndex][oldIndex];
1130
+ var distanceViaAdd = (newIndex > 0) ? editDistanceMatrix[newIndex - 1][oldIndex] : maxDistance + 1;
1131
+ var distanceViaDelete = (oldIndex > 0) ? editDistanceMatrix[newIndex][oldIndex - 1] : maxDistance + 1;
1132
+ var distanceViaRetain = (newIndex > 0) && (oldIndex > 0) ? editDistanceMatrix[newIndex - 1][oldIndex - 1] : maxDistance + 1;
1133
+ if ((distanceViaAdd === undefined) || (distanceViaAdd < me - 1)) distanceViaAdd = maxDistance + 1;
1134
+ if ((distanceViaDelete === undefined) || (distanceViaDelete < me - 1)) distanceViaDelete = maxDistance + 1;
1135
+ if (distanceViaRetain < me - 1) distanceViaRetain = maxDistance + 1;
1136
+
1137
+ if ((distanceViaAdd <= distanceViaDelete) && (distanceViaAdd < distanceViaRetain)) {
1138
+ editScript.push({ status: "added", value: newArray[newIndex - 1] });
1139
+ newIndex--;
1140
+ } else if ((distanceViaDelete < distanceViaAdd) && (distanceViaDelete < distanceViaRetain)) {
1141
+ editScript.push({ status: "deleted", value: oldArray[oldIndex - 1] });
1142
+ oldIndex--;
1143
+ } else {
1144
+ editScript.push({ status: "retained", value: oldArray[oldIndex - 1] });
1145
+ newIndex--;
1146
+ oldIndex--;
1147
+ }
1148
+ }
1149
+ return editScript.reverse();
1150
+ }
1151
+
1152
+ ko.utils.compareArrays = function (oldArray, newArray, maxEditsToConsider) {
1153
+ if (maxEditsToConsider === undefined) {
1154
+ return ko.utils.compareArrays(oldArray, newArray, 1) // First consider likely case where there is at most one edit (very fast)
1155
+ || ko.utils.compareArrays(oldArray, newArray, 10) // If that fails, account for a fair number of changes while still being fast
1156
+ || ko.utils.compareArrays(oldArray, newArray, Number.MAX_VALUE); // Ultimately give the right answer, even though it may take a long time
1157
+ } else {
1158
+ oldArray = oldArray || [];
1159
+ newArray = newArray || [];
1160
+ var editDistanceMatrix = calculateEditDistanceMatrix(oldArray, newArray, maxEditsToConsider);
1161
+ return findEditScriptFromEditDistanceMatrix(editDistanceMatrix, oldArray, newArray);
1162
+ }
1163
+ };
1164
+ })();/// <reference path="compareArrays.js" />
1165
+
1166
+ (function () {
1167
+ // Objective:
1168
+ // * Given an input array, a container DOM node, and a function from array elements to arrays of DOM nodes,
1169
+ // map the array elements to arrays of DOM nodes, concatenate together all these arrays, and use them to populate the container DOM node
1170
+ // * Next time we're given the same combination of things (with the array possibly having mutated), update the container DOM node
1171
+ // so that its children is again the concatenation of the mappings of the array elements, but don't re-map any array elements that we
1172
+ // previously mapped - retain those nodes, and just insert/delete other ones
1173
+
1174
+ ko.utils.setDomNodeChildrenFromArrayMapping = function (domNode, array, mapping, options) {
1175
+ // Compare the provided array against the previous one
1176
+ array = array || [];
1177
+ options = options || {};
1178
+ var isFirstExecution = ko.utils.domData.get(domNode, "setDomNodeChildrenFromArrayMapping_lastMappingResult") === undefined;
1179
+ var lastMappingResult = ko.utils.domData.get(domNode, "setDomNodeChildrenFromArrayMapping_lastMappingResult") || [];
1180
+ var lastArray = ko.utils.arrayMap(lastMappingResult, function (x) { return x.arrayEntry; });
1181
+ var editScript = ko.utils.compareArrays(lastArray, array);
1182
+
1183
+ // Build the new mapping result
1184
+ var newMappingResult = [];
1185
+ var lastMappingResultIndex = 0;
1186
+ var nodesToDelete = [];
1187
+ var nodesAdded = [];
1188
+ var insertAfterNode = null;
1189
+ for (var i = 0, j = editScript.length; i < j; i++) {
1190
+ switch (editScript[i].status) {
1191
+ case "retained":
1192
+ // Just keep the information - don't touch the nodes
1193
+ var dataToRetain = lastMappingResult[lastMappingResultIndex];
1194
+ newMappingResult.push(dataToRetain);
1195
+ if (dataToRetain.domNodes.length > 0)
1196
+ insertAfterNode = dataToRetain.domNodes[dataToRetain.domNodes.length - 1];
1197
+ lastMappingResultIndex++;
1198
+ break;
1199
+
1200
+ case "deleted":
1201
+ // Queue these nodes for later removal
1202
+ ko.utils.arrayForEach(lastMappingResult[lastMappingResultIndex].domNodes, function (node) {
1203
+ nodesToDelete.push(node);
1204
+ insertAfterNode = node;
1205
+ });
1206
+ lastMappingResultIndex++;
1207
+ break;
1208
+
1209
+ case "added":
1210
+ // Map this array value and insert the resulting nodes at the current insertion point
1211
+ var mappedNodes = mapping(editScript[i].value) || [];
1212
+ newMappingResult.push({ arrayEntry: editScript[i].value, domNodes: mappedNodes });
1213
+ for (var nodeIndex = 0, nodeIndexMax = mappedNodes.length; nodeIndex < nodeIndexMax; nodeIndex++) {
1214
+ var node = mappedNodes[nodeIndex];
1215
+ nodesAdded.push(node);
1216
+ if (insertAfterNode == null) {
1217
+ // Insert at beginning
1218
+ if (domNode.firstChild)
1219
+ domNode.insertBefore(node, domNode.firstChild);
1220
+ else
1221
+ domNode.appendChild(node);
1222
+ } else {
1223
+ // Insert after insertion point
1224
+ if (insertAfterNode.nextSibling)
1225
+ domNode.insertBefore(node, insertAfterNode.nextSibling);
1226
+ else
1227
+ domNode.appendChild(node);
1228
+ }
1229
+ insertAfterNode = node;
1230
+ }
1231
+ break;
1232
+ }
1233
+ }
1234
+
1235
+ ko.utils.arrayForEach(nodesToDelete, function (node) { ko.utils.domData.cleanNodeAndDescendants(node); });
1236
+
1237
+ var invokedBeforeRemoveCallback = false;
1238
+ if (!isFirstExecution) {
1239
+ if (options.afterAdd)
1240
+ options.afterAdd(nodesAdded);
1241
+ if (options.beforeRemove) {
1242
+ options.beforeRemove(nodesToDelete);
1243
+ invokedBeforeRemoveCallback = true;
1244
+ }
1245
+ }
1246
+ if (!invokedBeforeRemoveCallback)
1247
+ ko.utils.arrayForEach(nodesToDelete, function (node) {
1248
+ if (node.parentNode)
1249
+ node.parentNode.removeChild(node);
1250
+ });
1251
+
1252
+ // Store a copy of the array items we just considered so we can difference it next time
1253
+ ko.utils.domData.set(domNode, "setDomNodeChildrenFromArrayMapping_lastMappingResult", newMappingResult);
1254
+ }
1255
+ })();/// <reference path="../templating.js" />
1256
+
1257
+ ko.jqueryTmplTemplateEngine = function () {
1258
+ function getTemplateNode(template) {
1259
+ var templateNode = document.getElementById(template);
1260
+ if (templateNode == null)
1261
+ throw new Error("Cannot find template with ID=" + template);
1262
+ return templateNode;
1263
+ }
1264
+
1265
+ this.renderTemplate = function (template, data, options) {
1266
+ // jquery.tmpl doesn't like it if the template returns just text content or nothing - it only likes you to return DOM nodes.
1267
+ // To make things more flexible, we can wrap the whole template in a <script> node so that jquery.tmpl just processes it as
1268
+ // text and doesn't try to parse the output. Then, since jquery.tmpl has jQuery as a dependency anyway, we can use jQuery to
1269
+ // parse that text into a document fragment using jQuery.clean().
1270
+ var templateTextInWrapper = "<script type=\"text/html\">" + ko.utils.stringTrim(getTemplateNode(template).text) + "</script>";
1271
+ var renderedMarkupInWrapper = $.tmpl(templateTextInWrapper, data);
1272
+ return jQuery.clean([renderedMarkupInWrapper[0].text], document);
1273
+ },
1274
+
1275
+ this.isTemplateRewritten = function (template) {
1276
+ return getTemplateNode(template).isRewritten === true;
1277
+ },
1278
+
1279
+ this.rewriteTemplate = function (template, rewriterCallback) {
1280
+ var templateNode = getTemplateNode(template);
1281
+ var rewritten = rewriterCallback(templateNode.text)
1282
+ templateNode.text = rewritten;
1283
+ templateNode.isRewritten = true;
1284
+ },
1285
+
1286
+ this.createJavaScriptEvaluatorBlock = function (script) {
1287
+ return "{{= " + script + "}}";
1288
+ },
1289
+
1290
+ // Am considering making template registration a native part of the API (and storing added templates centrally), but for now it's specific to this template engine
1291
+ this.addTemplate = function (templateName, templateMarkup) {
1292
+ document.write("<script type='text/html' id='" + templateName + "'>" + templateMarkup + "</script>");
1293
+ }
1294
+ };
1295
+ ko.jqueryTmplTemplateEngine.prototype = new ko.templateEngine();
1296
+
1297
+ // Use this one by default
1298
+ ko.setTemplateEngine(new ko.jqueryTmplTemplateEngine());