diff options
| author | Misko Hevery | 2010-01-24 17:10:58 -0800 |
|---|---|---|
| committer | Misko Hevery | 2010-01-24 17:10:58 -0800 |
| commit | efad9ec5be8da442af5fb3dffc08510f7a71e10f (patch) | |
| tree | b6ffdda829b47b9058f0b2ccbd6ef3465ccfe0bc | |
| parent | c7719c24121b500f0bc2ac7c652d8ec0de418a37 (diff) | |
| download | angular.js-efad9ec5be8da442af5fb3dffc08510f7a71e10f.tar.bz2 | |
changes to make it closure compiler compatible
| -rw-r--r-- | angular-minified.js | 56 | ||||
| -rw-r--r-- | angular.js | 5 | ||||
| -rw-r--r-- | jsTestDriver.conf | 2 | ||||
| -rw-r--r-- | lib/underscore/underscore-min.js | 17 | ||||
| -rw-r--r-- | lib/underscore/underscore.js | 105 | ||||
| -rw-r--r-- | src/Angular.js | 20 | ||||
| -rw-r--r-- | src/Binder.js | 15 | ||||
| -rw-r--r-- | src/ControlBar.js | 2 | ||||
| -rw-r--r-- | src/DataStore.js | 104 | ||||
| -rw-r--r-- | src/Model.js | 12 | ||||
| -rw-r--r-- | src/Parser.js | 3 | ||||
| -rw-r--r-- | src/Scope.js | 12 | ||||
| -rw-r--r-- | src/Server.js | 4 | ||||
| -rw-r--r-- | test/BinderTest.js | 308 | ||||
| -rw-r--r-- | test/EntityDeclarationTest.js | 28 | ||||
| -rw-r--r-- | test/ParserTest.js | 3 | ||||
| -rw-r--r-- | test/ScenarioSpec.js | 2 |
17 files changed, 347 insertions, 351 deletions
diff --git a/angular-minified.js b/angular-minified.js index c9103560..64ce47d8 100644 --- a/angular-minified.js +++ b/angular-minified.js @@ -1,22 +1,22 @@ -function J(){return function(){}}function N(q){return function(){return q}} -(function(q,y){function n(){}function K(a,b,c){var d=q.console;switch(arguments.length){case 1:d.log(a);break;case 2:d.log(a,b);break;default:d.log(a,b,c);break}}function W(a,b,c){var d=q.console;switch(arguments.length){case 1:d.error(a);break;case 2:d.error(a,b);break;default:d.error(a,b,c);break}}function da(a,b){var c=y.createElement("div");c.className=a;for(var d=a="",e=0;e<b.length;e++){var f=b[e];a+=d+(typeof f=="string"?f:w(f));d=" "}c.appendChild(y.createTextNode(a));O.appendChild(c)}function ea(a){switch(a.nodeName){case "OPTION":case "PRE":case "TITLE":return true; +function J(){return function(){}}function M(q){return function(){return q}} +(function(q,y){function n(){}function N(a,b,c){var d=q.console;switch(arguments.length){case 1:d.log(a);break;case 2:d.log(a,b);break;default:d.log(a,b,c);break}}function W(a,b,c){var d=q.console;switch(arguments.length){case 1:d.error(a);break;case 2:d.error(a,b);break;default:d.error(a,b,c);break}}function da(a,b){var c=y.createElement("div");c.className=a;for(var d=a="",e=0;e<b.length;e++){var f=b[e];a+=d+(typeof f=="string"?f:w(f));d=" "}c.appendChild(y.createTextNode(a));O.appendChild(c)}function ea(a){switch(a.nodeName){case "OPTION":case "PRE":case "TITLE":return true; default:return false}}function fa(a,b){if(ea(a))if(X)a.innerText=b;else a.textContent=b;else a.innerHTML=b}function C(a){if(!a||!a.replace)return a;return a.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">")}function Ca(a){if(!a||!a.replace)return a;return a.replace(/</g,"<").replace(/>/g,">").replace(/\"/g,""")}function Da(a,b){if(!a)throw"Missing this";if(!_.isFunction(b))throw"Missing function";return function(){return b.apply(a,arguments)}}function ga(a){var b=y.createElement("div"); -b.appendChild(a);var c=b.innerHTML;b.removeChild(a);return c}function Y(a){var b=(""+a).toLowerCase();if(b=="f"||b=="0"||b=="false"||b=="no")a=false;return!!a}function Z(a,b){for(var c in a){var d=b[c],e=typeof d;if(e=="undefined")b[c]=P(w(a[c]));else e=="object"&&d.constructor!=array&&c.substring(0,1)!="$"&&Z(a[c],d)}}function ha(a){this.location=a;this.delay=25;this.setTimeout=function(b,c){q.setTimeout(b,c)};this.Wb=function(b){return b};this.I=a.href}function Ea(){K("Angular.configureJQueryPlugins()"); -var a=k.fn;a.scope=function(){for(var b=this;b&&b.get(0);){var c=b.data("scope");if(c)return c;b=b.parent()}return null};a.controller=function(){return this.data("controller")||Q.Rb}}function Fa(a){if(a.hd=="console"&&!O){O=y.createElement("div");O.id="ng-console";y.getElementsByTagName("body")[0].appendChild(O);K=function(){da("ng-console-info",arguments)};console.error=function(){da("ng-console-error",arguments)}}}function ia(a,b){var c={};o(b,function(d,e){c[e]=_(d).bind(a)});return c}function Ga(a, -b){var c=new ja(b.server,b.database),d=new x(a[0],c,b.location,b);c=new R(a.find("body"),b.oa);var e=b.fa=="$MEMORY"?new $(this.window):new ka(b.oa,k.getScript);e=new la(e,new S(k(a.body)),function(){d.d()});var f=new ma(e,c),g="/data/"+b.fa,h=new T(function(l,p){e.K("POST",g,l,p)},f,d.anchor);d.$a.push(function(){h.ga()});var i=new v({$anchor:d.anchor,$updateView:_(d.d).bind(d),$config:b,$console:q.console,$datastore:ia(h,{load:h.load,loadMany:h.ja,loadOrCreate:h.Ja,loadAll:h.Ia,save:h.save,remove:h.remove, -flush:h.ga,query:h.Ua,entity:h.C,entities:h.entities,documentCountsByUser:h.Fb,userDocumentIdsByEntity:h.yc,join:h.join}),$save:function(l){h.sc(i.p,l,d.anchor)},$window:q,$uid:function(){return""+(new Date).getTime()},$users:f},"ROOT");a.data("scope",i);d.C(i);d.compile();c.bind();(new A(a)).bind();var j=_(ia(i,{updateView:i.d,set:i.h,get:i.get,eval:i.eval})).extend({init:function(){b.location.listen(_(d.mc).bind(d));d.Ra();d.Lb();i.d();return j},element:a[0],config:b});return j}function G(a,b,c){var d= -_.last(b);o(c,function(e){d[e]=_[e]});m[a]=m[a]||{};o(b,function(e){U(m[a],e)})}function x(a,b,c,d){this.B=a;this.location=c;this.anchor={};this.Dc=b;this.zb=d||{};this.$a=[]}function R(a,b){this.document=a;this.aa=b;this.window=q;this.D=[]}function T(a,b,c){this.post=a;this.bb=b;this.z={M:[]};this.anchor=c;this.P=[]}function w(a,b){var c=[];aa(c,a,b?"\n ":null,_([]));return c.join("")}function P(a){try{var b=new D(a,true),c=b.Z();b.G();return c()}catch(d){W("fromJson error: ",a,d);throw d;}}function aa(a, -b,c,d){if(typeof b=="object"){if(d.include(b)){a.push("RECURSION");return}d.push(b)}var e=typeof b;if(b===null)a.push("null");else if(e==="function")return;else if(e==="boolean")a.push(""+b);else if(e==="number")isNaN(b)?a.push("null"):a.push(""+b);else if(e==="string")return a.push(m.String.quoteUnicode(b));else if(e==="object")if(b instanceof Array){a.push("[");var f=b.length;e=false;for(var g=0;g<f;g++){var h=b[g];e&&a.push(",");typeof h=="function"||typeof h=="undefined"?a.push("null"):aa(a,h, -c,d);e=true}a.push("]")}else if(b instanceof Date)a.push(m.String.quoteUnicode(m.Date.toString(b)));else{a.push("{");c&&a.push(c);e=false;g=c?c+" ":false;h=[];for(var i in b)i.indexOf("$$")!==0&&h.push(i);h.sort();for(i=0;i<h.length;i++){var j=h[i];try{f=b[j];if(typeof f!="function"){if(e){a.push(",");c&&a.push(c)}a.push(m.String.quote(j));a.push(":");aa(a,f,g,d);e=true}}catch(l){}}a.push("}")}typeof b=="object"&&d.pop()}function E(a,b){this.$$entity=a;this.O(b||{});this.N=a.title;this.fb()}function F(a, -b){this.text=a;this.Db=b?20:-1;this.i=[];this.index=0}function D(a,b){this.text=a;this.i=(new F(a,b)).parse();this.index=0}function v(a,b){this.cb=[];this.qa={};this.name=b;a=a||{};function c(){}c.prototype=a;this.p=new c;this.p.Jc=a;if(b=="ROOT")this.p.Kc=this.p}function ka(a,b){this.url=a;this.$b=0;this.getScript=b;this.zc="_"+(""+Math.random()).substr(2)+"_";this.ka=1800}function $(a){this.frame=a}function la(a,b,c){this.Eb=a;this.update=c;this.status=b}function ma(a,b){this.oa=a;this.da=b}function ja(a, -b){this.ac=0;this.aa=a;this.fa=b;this.za=q.zd?swfobject.za:function(){alert("ERROR: swfobject not loaded!")}}function L(a,b,c,d){this.view=a;this.Cd=c;this.Xa=b;this.Pc=d+"/_attachments";this.value=null;this.c=undefined}function Q(a){this.view=a}function na(a,b){this.view=a;this.exp=b;this.L=a.getAttribute("ng-validate");this.rc=typeof a.attributes["ng-required"]!="undefined";this.Ga=null;this.c=undefined;this.o=a.value;a.getAttribute("ng-widget")==="datepicker"&&k(a).gd()}function oa(a,b){this.view= -a;this.exp=b;this.c=undefined;this.o=a.checked?a.value:""}function pa(a,b){this.view=a;this.exp=b;this.c=undefined;this.o=a.value}function qa(a,b){this.view=a;this.exp=b;this.c=undefined;this.o=this.selected()}function ra(a,b){this.view=a;this.exp=b;this.c=this.ia=undefined;this.Fa=a.value;this.o=a.checked?a.value:null}function M(a,b){this.view=a;this.exp=x.X(b);this.u=false;this.tc={element:a}}function sa(a,b){this.view=a;this.tb=b}function ta(a,b){this.view=a;this.exp=b;this.u=false}function ua(a, -b){this.view=a;this.exp=b}function va(a,b){this.view=a;this.exp=b}function wa(a,b){this.view=a;this.exp=b}function xa(a,b){this.view=a;this.exp=b}function ya(a,b){this.view=a;this.exp=b}function za(a,b){this.view=a;this.exp=b}function Aa(a,b,c,d){this.view=a;this.template=c;this.prefix=d;this.children=[];a=b.match(/^\s*(.+)\s+in\s+(.*)\s*$/);if(!a)throw"Expected ng-repeat in form of 'item in collection' but got '"+b+"'.";b=a[1];this.V=a[2];a=b.match(/^([\$\w]+)|\(([\$\w]+)\s*,\s*([\$\w]+)\)$/);if(!a)throw"'item' in 'item in collection' should be identifier or (key, value) but get '"+ +b.appendChild(a);var c=b.innerHTML;b.removeChild(a);return c}function Y(a){var b=(""+a).toLowerCase();if(b=="f"||b=="0"||b=="false"||b=="no")a=false;return!!a}function Z(a,b){for(var c in a){var d=b[c],e=typeof d;if(e=="undefined")b[c]=P(w(a[c]));else e=="object"&&d.constructor!=array&&c.substring(0,1)!="$"&&Z(a[c],d)}}function ha(a){this.location=a;this.delay=25;this.setTimeout=function(b,c){q.setTimeout(b,c)};this.Wb=function(b){return b};this.I=a.href}function Ea(){var a=k.fn;a.scope=function(){for(var b= +this;b&&b.get(0);){var c=b.data("scope");if(c)return c;b=b.parent()}return null};a.controller=function(){return this.data("controller")||Q.Rb}}function Fa(a){if(a.hd=="console"&&!O){O=y.createElement("div");O.id="ng-console";y.getElementsByTagName("body")[0].appendChild(O);N=function(){da("ng-console-info",arguments)};console.error=function(){da("ng-console-error",arguments)}}}function ia(a,b){var c={};o(b,function(d,e){c[e]=_(d).bind(a)});return c}function Ga(a,b){var c=new ja(b.server,b.database), +d=new x(a[0],c,b.location,b);c=new R(a.find("body"),b.oa);var e=b.fa=="$MEMORY"?new $(this.window):new ka(b.oa,k.getScript);e=new la(e,new S(k(a.body)),function(){d.d()});var f=new ma(e,c),g="/data/"+b.fa,h=new T(function(l,p){e.K("POST",g,l,p)},f,d.anchor);d.$a.push(function(){h.ga()});var i=new v({$anchor:d.anchor,$updateView:_(d.d).bind(d),$config:b,$console:q.console,$datastore:ia(h,{load:h.load,loadMany:h.ja,loadOrCreate:h.Ja,loadAll:h.Ia,save:h.save,remove:h.remove,flush:h.ga,query:h.Ua,entity:h.C, +entities:h.entities,documentCountsByUser:h.Fb,userDocumentIdsByEntity:h.yc,join:h.join}),$save:function(l){h.sc(i.p,l,d.anchor)},$window:q,$uid:function(){return""+(new Date).getTime()},$users:f},"ROOT");a.data("scope",i);d.C(i);d.compile();c.bind();(new A(a)).bind();var j=_(ia(i,{updateView:i.d,set:i.h,get:i.get,eval:i.eval})).extend({init:function(){b.location.listen(_(d.mc).bind(d));d.Ra();d.Lb();d.d();return j},element:a[0],config:b});return j}function G(a,b,c){var d=_.last(b);o(c,function(e){d[e]= +_[e]});m[a]=m[a]||{};o(b,function(e){U(m[a],e)})}function x(a,b,c,d){this.B=a;this.location=c;this.anchor={};this.Dc=b;this.zb=d||{};this.$a=[]}function R(a,b){this.document=a;this.aa=b;this.window=q;this.D=[]}function T(a,b,c){this.post=a;this.bb=b;this.z={M:[]};this.anchor=c;this.P=[]}function w(a,b){var c=[];aa(c,a,b?"\n ":null,_([]));return c.join("")}function P(a){try{var b=new D(a,true),c=b.Z();b.G();return c()}catch(d){W("fromJson error: ",a,d);throw d;}}function aa(a,b,c,d){if(typeof b== +"object"){if(d.include(b)){a.push("RECURSION");return}d.push(b)}var e=typeof b;if(b===null)a.push("null");else if(e==="function")return;else if(e==="boolean")a.push(""+b);else if(e==="number")isNaN(b)?a.push("null"):a.push(""+b);else if(e==="string")return a.push(m.String.quoteUnicode(b));else if(e==="object")if(b instanceof Array){a.push("[");var f=b.length;e=false;for(var g=0;g<f;g++){var h=b[g];e&&a.push(",");typeof h=="function"||typeof h=="undefined"?a.push("null"):aa(a,h,c,d);e=true}a.push("]")}else if(b instanceof +Date)a.push(m.String.quoteUnicode(m.Date.toString(b)));else{a.push("{");c&&a.push(c);e=false;g=c?c+" ":false;h=[];for(var i in b)i.indexOf("$$")!==0&&h.push(i);h.sort();for(i=0;i<h.length;i++){var j=h[i];try{f=b[j];if(typeof f!="function"){if(e){a.push(",");c&&a.push(c)}a.push(m.String.quote(j));a.push(":");aa(a,f,g,d);e=true}}catch(l){}}a.push("}")}typeof b=="object"&&d.pop()}function E(a,b){this.$$entity=a;this.O(b||{});this.N=a.title;this.fb()}function F(a,b){this.text=a;this.Db=b?20:-1;this.i= +[];this.index=0}function D(a,b){this.text=a;this.i=(new F(a,b)).parse();this.index=0}function v(a,b){this.cb=[];this.qa={};this.name=b;a=a||{};function c(){}c.prototype=a;this.p=new c;this.p.Jc=a;if(b=="ROOT")this.p.Kc=this.p}function ka(a,b){this.url=a;this.$b=0;this.getScript=b;this.zc="_"+(""+Math.random()).substr(2)+"_";this.ka=1800}function $(a){this.frame=a}function la(a,b,c){this.Eb=a;this.update=c;this.status=b}function ma(a,b){this.oa=a;this.da=b}function ja(a,b){this.ac=0;this.aa=a;this.fa= +b;this.za=q.zd?swfobject.za:function(){alert("ERROR: swfobject not loaded!")}}function K(a,b,c,d){this.view=a;this.Cd=c;this.Xa=b;this.Pc=d+"/_attachments";this.value=null;this.c=undefined}function Q(a){this.view=a}function na(a,b){this.view=a;this.exp=b;this.L=a.getAttribute("ng-validate");this.rc=typeof a.attributes["ng-required"]!="undefined";this.Ga=null;this.c=undefined;this.o=a.value;a.getAttribute("ng-widget")==="datepicker"&&k(a).gd()}function oa(a,b){this.view=a;this.exp=b;this.c=undefined; +this.o=a.checked?a.value:""}function pa(a,b){this.view=a;this.exp=b;this.c=undefined;this.o=a.value}function qa(a,b){this.view=a;this.exp=b;this.c=undefined;this.o=this.selected()}function ra(a,b){this.view=a;this.exp=b;this.c=this.ia=undefined;this.Fa=a.value;this.o=a.checked?a.value:null}function L(a,b){this.view=a;this.exp=x.X(b);this.u=false;this.tc={element:a}}function sa(a,b){this.view=a;this.tb=b}function ta(a,b){this.view=a;this.exp=b;this.u=false}function ua(a,b){this.view=a;this.exp=b}function va(a, +b){this.view=a;this.exp=b}function wa(a,b){this.view=a;this.exp=b}function xa(a,b){this.view=a;this.exp=b}function ya(a,b){this.view=a;this.exp=b}function za(a,b){this.view=a;this.exp=b}function Aa(a,b,c,d){this.view=a;this.template=c;this.prefix=d;this.children=[];a=b.match(/^\s*(.+)\s+in\s+(.*)\s*$/);if(!a)throw"Expected ng-repeat in form of 'item in collection' but got '"+b+"'.";b=a[1];this.V=a[2];a=b.match(/^([\$\w]+)|\(([\$\w]+)\s*,\s*([\$\w]+)\)$/);if(!a)throw"'item' in 'item in collection' should be identifier or (key, value) but get '"+ b+"'.";this.Bc=a[3]||a[1];this.Vb=a[2]}function A(a){this.B=a}function S(a){this.Ka=a.append(S.hb).find("#ng-loading");this.$=0}var ba={s:"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_=",Gb:function(a){var b="",c,d,e,f,g,h,i=0;for(a=ba.ob(a);i<a.length;){c=a.charCodeAt(i++);d=a.charCodeAt(i++);e=a.charCodeAt(i++);f=c>>2;c=(c&3)<<4|d>>4;g=(d&15)<<2|e>>6;h=e&63;if(isNaN(d))g=h=64;else if(isNaN(e))h=64;b=b+this.s.charAt(f)+this.s.charAt(c)+this.s.charAt(g)+this.s.charAt(h)}return b}, jd:function(a){var b="",c,d,e,f,g,h=0;for(a=a.replace(/[^A-Za-z0-9\+\/\=]/g,"");h<a.length;){c=this.s.indexOf(a.charAt(h++));d=this.s.indexOf(a.charAt(h++));f=this.s.indexOf(a.charAt(h++));g=this.s.indexOf(a.charAt(h++));c=c<<2|d>>4;d=(d&15)<<4|f>>2;e=(f&3)<<6|g;b+=String.fromCharCode(c);if(f!=64)b+=String.fromCharCode(d);if(g!=64)b+=String.fromCharCode(e)}return b=ba.nb(b)},ob:function(a){a=a.replace(/\r\n/g,"\n");for(var b="",c=0;c<a.length;c++){var d=a.charCodeAt(c);if(d<128)b+=String.fromCharCode(d); else{if(d>127&&d<2048)b+=String.fromCharCode(d>>6|192);else{b+=String.fromCharCode(d>>12|224);b+=String.fromCharCode(d>>6&63|128)}b+=String.fromCharCode(d&63|128)}}return b},nb:function(a){for(var b="",c=0,d=c1=c2=0;c<a.length;){d=a.charCodeAt(c);if(d<128){b+=String.fromCharCode(d);c++}else if(d>191&&d<224){c2=a.charCodeAt(c+1);b+=String.fromCharCode((d&31)<<6|c2&63);c+=2}else{c2=a.charCodeAt(c+1);c3=a.charCodeAt(c+2);b+=String.fromCharCode((d&15)<<12|(c2&63)<<6|c3&63);c+=3}}return b}};if(typeof y.getAttribute== "undefined")y.getAttribute=J();if(typeof Node=="undefined")Node={ELEMENT_NODE:1,ATTRIBUTE_NODE:2,TEXT_NODE:3,CDATA_SECTION_NODE:4,ENTITY_REFERENCE_NODE:5,ENTITY_NODE:6,PROCESSING_INSTRUCTION_NODE:7,COMMENT_NODE:8,DOCUMENT_NODE:9,DOCUMENT_TYPE_NODE:10,DOCUMENT_FRAGMENT_NODE:11,NOTATION_NODE:12};q.console||(q.console={log:n,error:n});var O,o=_.each,U=_.extend,k=q.jQuery,X=k.browser.msie,m=q.angular||(q.angular={}),Ba=m.validator||(m.validator={}),r=m.filter||(m.filter={}),ca=m.callbacks||(m.callbacks= -{});m.alert||(m.alert=function(){K(arguments);q.alert.apply(q,arguments)});ha.prototype={watch:function(){var a=this;function b(){if(a.I!==a.location.href){var c=a.location.hash.match(/^#\$iframe_notify=(.*)$/);if(c){a.I.match(/#/)||(a.I+="#");a.location.href=a.I;c="_iframe_notify_"+c[1];var d=ca[c];delete ca[c];try{(d||n)()}catch(e){alert(e)}}else{a.Wb(a.location.href);a.I=a.location.href}}a.setTimeout(b,a.delay)}b();return this},h:function(a){var b=this.location.href;b.match(/#/)||(b+="#");if(b!= +{});m.alert||(m.alert=function(){N(arguments);q.alert.apply(q,arguments)});ha.prototype={watch:function(){var a=this;function b(){if(a.I!==a.location.href){var c=a.location.hash.match(/^#\$iframe_notify=(.*)$/);if(c){a.I.match(/#/)||(a.I+="#");a.location.href=a.I;c="_iframe_notify_"+c[1];var d=ca[c];delete ca[c];try{(d||n)()}catch(e){alert(e)}}else{a.Wb(a.location.href);a.I=a.location.href}}a.setTimeout(b,a.delay)}b();return this},h:function(a){var b=this.location.href;b.match(/#/)||(b+="#");if(b!= a)this.location.href=a;this.md=a},get:function(){return q.location.href}};m.startUrlWatcher=function(){return(new ha(q.location)).watch()};m.compile=function(a,b){b=_({server:"",location:{get:n,set:n,listen:n}}).extend(b||{});Fa(b);Ea();return Ga(k(a),b)};var H={typeOf:function(a){if(a===null)return"null";var b=typeof a;if(b=="object"){if(a instanceof Array)return"array";if(a instanceof Date)return"date";if(a.nodeType==1)return"element"}return b}},V={},Ha={includeIf:function(a,b,c){var d=_.indexOf(a, b);if(c)d==-1&&a.push(b);else a.splice(d,1);return a},sum:function(a,b){b=m.Function.compile(b);for(var c=0,d=0;d<a.length;d++){var e=1*b(a[d]);isNaN(e)||(c+=e)}return c},remove:function(a,b){var c=_.indexOf(a,b);c>=0&&a.splice(c,1);return b},find:function(a,b,c){if(b){var d=m.Function.compile(b);_.detect(a,function(e){if(d(e)){c=e;return true}});return c}},findById:function(a,b){return m.Lc.find(a,function(c){return c.w==b},null)},filter:function(a,b){var c=[];c.wb=function(j){for(var l=0;l<c.length;l++)if(!c[l](j))return false; return true};var d=v.J;function e(j,l){if(l.charAt(0)==="!")return!e(j,l.substr(1));switch(typeof j){case "boolean":case "number":case "string":return(""+j).toLowerCase().indexOf(l)>-1;case "object":for(var p in j)if(p.charAt(0)!=="$"&&e(j[p],l))return true;return false;case "array":for(p=0;p<j.length;p++)if(e(j[p],l))return true;return false;default:return false}}switch(typeof b){case "boolean":case "number":case "string":b={Fc:b};case "object":for(var f in b)f=="$"?function(){var j=(""+b[f]).toLowerCase(); @@ -27,22 +27,22 @@ b,c){var d=a[b];if(!d){d={};a[b]=d}Z(c,d);return a}},Ia={quote:function(a){retur (b=a.match(/^(\d\d\d\d)-(\d\d)-(\d\d)T(\d\d):(\d\d):(\d\d)Z$/))){a=new Date(0);a.setUTCFullYear(b[1],b[2]-1,b[3]);a.setUTCHours(b[4],b[5],b[6],0);return a}return a}},Ja={toString:function(a){function b(c){return c<10?"0"+c:c}return a.getUTCFullYear()+"-"+b(a.getUTCMonth()+1)+"-"+b(a.getUTCDate())+"T"+b(a.getUTCHours())+":"+b(a.getUTCMinutes())+":"+b(a.getUTCSeconds())+"Z"}},Ka={compile:function(a){if(_.isFunction(a))return a;else if(a){var b=new v;return function(c){b.p=c;return b.eval(a)}}else return function(c){return c}}}; G("Global",[H],["extend","clone","isEqual","isElement","isArray","isFunction","isUndefined"]);G("Collection",[H,V],["each","map","reduce","reduceRight","detect","select","reject","all","any","include","invoke","pluck","max","min","sortBy","sortedIndex","toArray","size"]);G("Array",[H,V,Ha],["first","last","compact","flatten","without","uniq","intersect","zip","indexOf","lastIndexOf"]);G("Object",[H,V,{}],["keys","values"]);G("String",[H,Ia],[]);G("Date",[H,Ja],[]);G("Function",[H,V,Ka],["bind","bindAll", "delay","defer","wrap","compose"]);x.X=function(a){for(var b=[],c=0,d;(d=a.indexOf("{{",c))>-1;){c<d&&b.push(a.substr(c,d-c));c=d;d=a.indexOf("}}",d);d=d<0?a.length:d+2;b.push(a.substr(c,d-c));c=d}c!=a.length&&b.push(a.substr(c,a.length-c));return b.length===0?[a]:b};x.Qb=function(a){a=x.X(a);return a.length>1||x.H(a[0])!==null};x.H=function(a){return(a=a.replace(/\n/gm," ").match(/^\{\{(.*)\}\}$/))?a[1]:null};x.prototype={nc:function(a){var b={};a.replace(/(?:^|&)([^&=]*)=?([^&]*)/g,function(c,d, -e){if(d)b[decodeURIComponent(d)]=decodeURIComponent(e)});return b},Ra:function(){var a=this,b=this.location.get()||"",c=b.indexOf("#");if(!(c<0)){b=this.nc(b.substring(c+1));o(a.anchor,function(d,e){delete a.anchor[e]});o(b,function(d,e){a.anchor[e]=d})}},mc:function(){this.Ra();this.d()},xc:function(){var a=this.location.get(),b=a.indexOf("#");if(b>-1)a=a.substring(0,b);a+="#";b="";for(var c in this.anchor){var d=this.anchor[c];if(typeof d==="undefined"||d===null)delete this.anchor[c];else{a+=b+ -encodeURIComponent(c);if(d!==true)a+="="+encodeURIComponent(d);b="&"}}this.location.h(a);return a},d:function(){(new Date).getTime();var a=k(this.B).scope();a.h("$invalidWidgets",[]);a.d();(new Date).getTime();this.xc();_.each(this.$a,function(b){b()})},R:function(a){var b=k(this.B),c=b.find(a);if(b.is(a))c=c.andSelf();return c},Lb:function(){this.R("[ng-init]").each(function(){var a=k(this),b=a.scope();try{b.eval(a.attr("ng-init"))}catch(c){alert("EVAL ERROR:\n"+a.attr("ng-init")+"\n"+w(c,true))}})}, +e){if(d)b[decodeURIComponent(d)]=decodeURIComponent(e)});return b},Ra:function(){var a=this,b=this.location.get()||"",c=b.indexOf("#");if(!(c<0)){b=this.nc(b.substring(c+1));o(a.anchor,function(d,e){delete a.anchor[e]});o(b,function(d,e){a.anchor[e]=d})}},mc:function(){this.Ra();this.d()},xc:function(){var a=this.location.get()||"",b=a.indexOf("#");if(b>-1)a=a.substring(0,b);a+="#";b="";for(var c in this.anchor){var d=this.anchor[c];if(typeof d==="undefined"||d===null)delete this.anchor[c];else{a+= +b+encodeURIComponent(c);if(d!==true)a+="="+encodeURIComponent(d);b="&"}}this.location.h(a);return a},d:function(){(new Date).getTime();var a=k(this.B).scope();a.h("$invalidWidgets",[]);a.d();(new Date).getTime();this.xc();_.each(this.$a,function(b){b()})},R:function(a){var b=k(this.B),c=b.find(a);if(b.is(a))c=c.andSelf();return c},Lb:function(){this.R("[ng-init]").each(function(){var a=k(this),b=a.scope();try{b.eval(a.attr("ng-init"))}catch(c){alert("EVAL ERROR:\n"+a.attr("ng-init")+"\n"+w(c,true))}})}, C:function(a){this.R("[ng-entity]").attr("ng-watch",function(){try{var b=k(this);return a.C(b.attr("ng-entity"))+(b.attr("ng-watch")||"")}catch(c){alert(c)}})},compile:function(){var a=k(this.B);if(this.zb.Qc){var b=this.R(":submit").not("[ng-action]");b.attr("ng-action","$save()");b.not(":disabled").not("ng-bind-attr").attr("ng-bind-attr",'{disabled:"{{$invalidWidgets}}"}')}this.Sa(this.B)(this.B,a.scope(),"");this.R("a[ng-action]").live("click",function(){var c=k(this),d=c.scope();try{d.eval(c.attr("ng-action")); -c.removeAttr("ng-error");c.removeClass("ng-exception")}catch(e){c.addClass("ng-exception");c.attr("ng-error",w(e,true))}d.get("$updateView")();return false})},wc:function(a,b,c){b=b.concat();var d=b.pop(),e=x.X(a.nodeValue);if(e.length>1||x.H(e[0])){var f=a.parentNode;if(ea(f)){f.setAttribute("ng-bind-template",a.nodeValue);c.push({path:b,b:function(l){return new M(l,l.getAttribute("ng-bind-template"))}})}else for(var g=0;g<e.length;g++){var h=e[g],i=x.H(h),j;if(i){j=y.createElement("span");k(j).attr("ng-bind", +c.removeAttr("ng-error");c.removeClass("ng-exception")}catch(e){c.addClass("ng-exception");c.attr("ng-error",w(e,true))}d.get("$updateView")();return false})},wc:function(a,b,c){b=b.concat();var d=b.pop(),e=x.X(a.nodeValue);if(e.length>1||x.H(e[0])){var f=a.parentNode;if(ea(f)){f.setAttribute("ng-bind-template",a.nodeValue);c.push({path:b,b:function(l){return new L(l,l.getAttribute("ng-bind-template"))}})}else for(var g=0;g<e.length;g++){var h=e[g],i=x.H(h),j;if(i){j=y.createElement("span");k(j).attr("ng-bind", i);g===0&&c.push({path:b.concat(d+g),b:this.Pa})}else if(X&&h.charAt(0)==" "){j=y.createElement("span");j.innerHTML=" "+h.substring(1)}else j=y.createTextNode(h);f.insertBefore(j,a)}f.removeChild(a)}},Sa:function(a){var b=[];this.Ta(a,[],b);return function(c,d,e){for(var f=b.length,g=0;g<f;g++){for(var h=b[g],i=c,j=h.path,l=0;l<j.length;l++)i=i.childNodes[j[l]];try{d.rb(h.b(i,d,e))}catch(p){alert(p)}}}},Ta:function(a,b,c){var d=a.nodeType;if(d==Node.TEXT_NODE)this.wc(a,b,c);else if(!(d!=Node.ELEMENT_NODE&& -d!=Node.DOCUMENT_NODE))if(a.getAttribute){d=a.getAttribute("ng-non-bindable");if(!(d||d==="")){if(d=a.attributes){var e=a.getAttribute("ng-bind-attr");a.removeAttribute("ng-bind-attr");e=e?P(e):{};for(var f=d.length,g=0;g<f;g++){var h=d[g],i=h.name;h=X&&i=="href"?decodeURI(a.getAttribute(i,2)):h.value;if(x.Qb(h))e[i]=h}d=w(e);d.length>2&&a.setAttribute("ng-bind-attr",d)}a.getAttribute||K(a);var j=a.getAttribute("ng-repeat");if(j){a.removeAttribute("ng-repeat");var l=this.Sa(a);d=y.createComment("ng-repeat: "+ +d!=Node.DOCUMENT_NODE))if(a.getAttribute){d=a.getAttribute("ng-non-bindable");if(!(d||d==="")){if(d=a.attributes){var e=a.getAttribute("ng-bind-attr");a.removeAttribute("ng-bind-attr");e=e?P(e):{};for(var f=d.length,g=0;g<f;g++){var h=d[g],i=h.name;h=X&&i=="href"?decodeURI(a.getAttribute(i,2)):h.value;if(x.Qb(h))e[i]=h}d=w(e);d.length>2&&a.setAttribute("ng-bind-attr",d)}a.getAttribute||N(a);var j=a.getAttribute("ng-repeat");if(j){a.removeAttribute("ng-repeat");var l=this.Sa(a);d=y.createComment("ng-repeat: "+ j);e=a.parentNode;e.insertBefore(d,a);e.removeChild(a);function p(s,t,z){var I=k(a).clone();I.css("display","");I.attr("ng-repeat-index",""+z);I.data("scope",s);l(I[0],s,t+z+":");return I}c.push({path:b,b:function(s,t,z){return new Aa(k(s),j,p,z)}})}else{a.getAttribute("ng-eval")&&c.push({path:b,b:this.fc});a.getAttribute("ng-bind")&&c.push({path:b,b:this.Pa});a.getAttribute("ng-bind-attr")&&c.push({path:b,b:this.bc});a.getAttribute("ng-hide")&&c.push({path:b,b:this.gc});a.getAttribute("ng-show")&& c.push({path:b,b:this.hc});a.getAttribute("ng-class")&&c.push({path:b,b:this.cc});a.getAttribute("ng-class-odd")&&c.push({path:b,b:this.ec});a.getAttribute("ng-class-even")&&c.push({path:b,b:this.dc});a.getAttribute("ng-style")&&c.push({path:b,b:this.ic});a.getAttribute("ng-watch")&&c.push({path:b,b:this.jc});d=a.nodeName;if(d=="INPUT"||d=="TEXTAREA"||d=="SELECT"||d=="BUTTON"){var B=this;c.push({path:b,b:function(s,t,z){s.name=z+s.name.split(":").pop();return B.Dc.Ab(k(s),t)}})}if(d=="OPTION")if(!k("<select/>").append(k(a).clone()).html().match(/<option(\s.*\s|\s)value\s*=\s*.*>.*<\/\s*option\s*>/gi))a.value= -a.text;d=a.childNodes;for(e=0;e<d.length;e++)this.Ta(d[e],b.concat(e),c)}}}},fc:function(a){return new ta(a,a.getAttribute("ng-eval"))},Pa:function(a){return new M(a,"{{"+a.getAttribute("ng-bind")+"}}")},bc:function(a){return new sa(a,P(a.getAttribute("ng-bind-attr")))},gc:function(a){return new ua(a,a.getAttribute("ng-hide"))},hc:function(a){return new va(a,a.getAttribute("ng-show"))},cc:function(a){return new wa(a,a.getAttribute("ng-class"))},dc:function(a){return new xa(a,a.getAttribute("ng-class-even"))}, +a.text;d=a.childNodes;for(e=0;e<d.length;e++)this.Ta(d[e],b.concat(e),c)}}}},fc:function(a){return new ta(a,a.getAttribute("ng-eval"))},Pa:function(a){return new L(a,"{{"+a.getAttribute("ng-bind")+"}}")},bc:function(a){return new sa(a,P(a.getAttribute("ng-bind-attr")))},gc:function(a){return new ua(a,a.getAttribute("ng-hide"))},hc:function(a){return new va(a,a.getAttribute("ng-show"))},cc:function(a){return new wa(a,a.getAttribute("ng-class"))},dc:function(a){return new xa(a,a.getAttribute("ng-class-even"))}, ec:function(a){return new ya(a,a.getAttribute("ng-class-odd"))},ic:function(a){return new za(a,a.getAttribute("ng-style"))},jc:function(a,b){b.watch(a.getAttribute("ng-watch"))}};R.Mc='<div><div class="ui-widget-overlay"></div><div id="ng-login" ng-non-bindable="true"><div class="ng-login-container"></div></div></div>';R.jb='<div ng-non-bindable="true" title="Permission Error:">Sorry, you do not have permission for this!</div>';R.prototype={bind:J(),Na:function(a){this.D.push(a);this.D.length==1&& this.Ba("/user_session/new.mini?return_url="+encodeURIComponent(this.ab()))},Xb:function(a){this.D.push(a);this.D.length==1&&this.Ba("/user_session/do_destroy.mini")},ab:function(){return this.window.location.href.split("#")[0]},Ba:function(a){var b=this,c=(new Date).getTime(),d=this.ab();d+="#$iframe_notify="+c;var e=k('<div style="overflow:hidden; padding:2px 0 0 0;"><iframe name="'+d+'" src="'+this.aa+a+'" width="500" height="330"/></div>');this.document.append(e);e.Aa({height:363,width:500,wd:false, Zb:true,title:'Authentication: <a href="http://www.getangular.com"><tt><angular/></tt></a>'});callbacks["_iframe_notify_"+c]=function(){e.Aa("destroy");e.remove();o(b.D,function(f){f()});b.D=[]}},Qa:function(){if(!this.Da){this.Da=k(R.jb);this.Da.Aa({Vc:true,height:70,Zb:true})}}};T.kb=U(J(),{all:function(){return[]},query:function(){return[]},load:function(){return{}},title:undefined});T.prototype={Q:function(a){if(!a instanceof E)throw"Parameter must be an instance of Entity! "+w(a);var b= a.N+"/"+a.w,c=this.z[b];if(c)E.ea(a,c);else c=this.z[b]=a;return c},load:function(a,b,c,d){if(b&&b!=="*"){var e=this;this.A(["GET",a.N+"/"+b],function(f){a.O(f);a.fb();f=a.Gc(a);e.Q(f);(c||n)(a)},d)}return a},ja:function(a,b,c){var d=this,e=[],f=0;o(b,function(g){e.push(d.load(a(),g,function(){f++;if(f==b.length)(c||n)(e)}))});return e},Ja:function(a,b,c){return this.load(a,b,c,function(d){if(d.ba==404){a.w=b;(c||n)(a)}else throw d;})},Ia:function(a,b){var c=this,d=[];d.ra=function(e){return e.N== a.title};this.z.M.push(d);this.A(["GET",a.title],function(e){for(var f=0;f<e.length;f++){var g=a();g.O(e[f]);d.push(c.Q(g))}(b||n)(d)});return d},save:function(a,b){var c=this,d={};a.gb(d);this.A(["POST","",d],function(e){a.O(e);var f=c.Q(a);_.each(c.z.M,function(g){g.ra(a)&&m.Array.includeIf(g,f,true)});if(a.sa)c.anchor[a.sa]=a.w;b&&b(a)})},remove:function(a,b){var c=this,d={};a.gb(d);this.A(["DELETE","",d],function(e){delete c.z[a.N+"/"+a.w];_.each(c.z.M,function(f){for(var g=0;g<f.length;g++)f[g].w== -a.w&&f.splice(g,1)});(b||n)(e)})},A:function(a,b,c){a.db=b;a.eb=c||function(d){throw d;};this.P.push(a)},ga:function(){function a(d,e){K("RESPONSE["+d+"]: ",e);if(e.ba==401)b.bb.Na(function(){b.post(c,a)});else if(e.ba)alert(w(e));else for(d=0;d<e.length;d++){var f=e[d],g=c[d],h=f.ba;if(h)h==403?b.bb.Qa():g.eb(f);else g.db(f)}}if(this.P.length!==0){var b=this,c=this.P;this.P=[];K("REQUEST:",c);this.post(c,a)}},sc:function(a,b){function c(){d--;d===0&&b&&b()}var d=1;for(var e in a){var f=a[e];if(f&& -f.ta==E.prototype.ta){d++;f.ta(c)}}c()},Ua:function(a,b,c,d){var e=this,f=[];f.ra=N(false);this.z.M.push(f);this.A(["GET",a.title+"/"+b+"="+c],function(g){for(var h=0;h<g.length;h++){var i=(new a).O(g[h]);f.push(e.Q(i))}d&&d(f)});return f},entities:function(a){var b=[],c=this;this.A(["GET","$entities"],function(d){for(var e in d)b.push(c.C(e));b.sort(function(f,g){return f.title>g.title?1:-1});a&&a(b)});return b},Fb:function(){var a={};this.post([["GET","$users"]],function(b,c){o(c[0],function(d, +a.w&&f.splice(g,1)});(b||n)(e)})},A:function(a,b,c){a.db=b;a.eb=c||function(d){throw d;};this.P.push(a)},ga:function(){function a(d,e){N("RESPONSE["+d+"]: ",e);if(e.ba==401)b.bb.Na(function(){b.post(c,a)});else if(e.ba)alert(w(e));else for(d=0;d<e.length;d++){var f=e[d],g=c[d],h=f.ba;if(h)h==403?b.bb.Qa():g.eb(f);else g.db(f)}}if(this.P.length!==0){var b=this,c=this.P;this.P=[];N("REQUEST:",c);this.post(c,a)}},sc:function(a,b){function c(){d--;d===0&&b&&b()}var d=1;for(var e in a){var f=a[e];if(f&& +f.ta==E.prototype.ta){d++;f.ta(c)}}c()},Ua:function(a,b,c,d){var e=this,f=[];f.ra=M(false);this.z.M.push(f);this.A(["GET",a.title+"/"+b+"="+c],function(g){for(var h=0;h<g.length;h++){var i=(new a).O(g[h]);f.push(e.Q(i))}d&&d(f)});return f},entities:function(a){var b=[],c=this;this.A(["GET","$entities"],function(d){for(var e in d)b.push(c.C(e));b.sort(function(f,g){return f.title>g.title?1:-1});a&&a(b)});return b},Fb:function(){var a={};this.post([["GET","$users"]],function(b,c){o(c[0],function(d, e){a[e]=d})});return a},yc:function(a){var b={};this.post([["GET","$users/"+a]],function(c,d){o(d[0],function(e,f){b[f]=e})});return b},C:function(a,b){if(!a)return T.kb;var c=this,d=U(function(e){return new E(d,e)},{title:a,$$factory:true,datastore:this,defaults:b||{},load:function(e,f){return c.load(d(),e,f)},loadMany:function(e,f){return c.ja(d,e,f)},loadOrCreate:function(e,f){return c.Ja(d(),e,f)},all:function(e){return c.Ia(d,e)},query:function(e,f,g){return c.Ua(d,e,f,g)},properties:function(e){c.A(["GET", a+"/$properties"],e)}});return d},join:function(a){function b(){throw"Joined entities can not be instantiated into a document.";}var c=_(a).Wc().map(function(d,e){return e}).sortBy(function(d){var e=[];do{if(_(e).include(d))throw"Infinite loop in join: "+e.join(" -> ");e.push(d);if(!a[d])throw _("Named entity '<%=name%>' is undefined.").template({name:d});d=a[d].W?a[d].W.substring(0,a[d].W.indexOf(".")):undefined}while(d);return e.length}).value();if(_(c).select(function(d){return a[d].W}).length!= c.length-1)throw"Exactly one entity needs to be primary.";b.query=function(d,e){var f=[],g=d?d.substring(0,d.indexOf(".")):undefined;if(g!=c[0])throw _("Named entity '<%=name%>' is not a primary entity.").template({name:g});var h=1;a[g].join.query(d.substring(d.indexOf(".")+1),e,function(i){var j=c[h++],l=a[j],p=l.W,B={};_(i).each(function(s){var t={};f.push(t);t[g]=s;s=v.J(t,p);B[s]=s});l.join.ja(_.toArray(B),function(s){var t={};_(s).each(function(z){t[z.w]=z});_(f).each(function(z){var I=v.J(z, @@ -55,14 +55,14 @@ b){return b?undefined:a},googleChartApi:U(function(a,b,c,d){b=b||{};a={xb:a,Xc:u return b.join("|")},collect:function(a,b){var c=[],d=0;o(a.uc||[],function(e){var f=[];e=e[b]||[];o(_.isArray(e)?e:[e],function(g){f.push(encodeURIComponent(g));d++});c.push(f.join("|"))});return d?c.join(","):null},encode:function(a,b,c){b=b||200;c=c||b;var d="http://chart.apis.google.com/chart?",e=[];a.bd=b+"x"+c;o(a,function(f,g){f&&e.push(g+"="+f)});e.sort();d+=e.join("&");return new r.g({url:d,html:'<img width="'+b+'" height="'+c+'" src="'+d+'"/>'})}}),qrcode:function(a,b,c){return u.encode({xb:"qr", ad:encodeURIComponent(a)},b,c)},chart:{td:function(a,b,c){return u("p",a,b,c)},ud:function(a,b,c){return u("p3",a,b,c)},vd:function(a,b,c){return u("pc",a,b,c)},Sc:function(a,b,c){return u("bhs",a,b,c)},Rc:function(a,b,c){return u("bhg",a,b,c)},Uc:function(a,b,c){return u("bvs",a,b,c)},Tc:function(a,b,c){return u("bvg",a,b,c)},qd:function(a,b,c){return u("lc",a,b,c)},yd:function(a,b,c){return u("ls",a,b,c)},xd:function(a,b,c){return u("s",a,b,c)}},html:function(a){return new r.g({html:a})},linky:function(a){if(!a)return a; for(var b=/(ftp|http|https|mailto):\/\/([^\(\)|\s]+)/,c,d=a,e=[];c=d.match(b);){c=c[0].replace(/[\.\;\,\(\)\{\}\<\>]$/,"");var f=d.indexOf(c);e.push(C(d.substr(0,f)));e.push('<a href="'+c+'">');e.push(c);e.push("</a>");d=d.substring(f+c.length)}e.push(C(d));return new r.g({text:a,html:e.join("")})}},function(a,b){r[b]=a});u=r.googleChartApi;array=[].constructor;m.toJson=w;m.fromJson=P;E.ea=function(a,b){if(!(a===b||!a||!b)){var c=function(e,f,g){return g.substring(0,2)!=="$$"&&typeof e[g]!=="function"&& -typeof f[g]!=="function"};for(var d in b)c(a,b,d)&&delete b[d];for(d in a)if(c(a,b,d))b[d]=a[d]}};E.prototype={$migrate:function(){Z(this.$$entity.kd,this);return this},$save:function(a){this.$$entity.Cb.save(this,a===true?undefined:a);a===true&&this.$$entity.Cb.ga();return this},$loadFrom:function(a){E.ea(a,this);return this},$saveTo:function(a){E.ea(this,a);return this}};F.ua={"null":N(null),"true":N(true),"false":N(false),"+":function(a,b,c){return(b||0)+(c||0)},"-":function(a,b,c){return(b||0)- +typeof f[g]!=="function"};for(var d in b)c(a,b,d)&&delete b[d];for(d in a)if(c(a,b,d))b[d]=a[d]}};E.prototype={$migrate:function(){Z(this.$$entity.kd,this);return this},$save:function(a){this.$$entity.Cb.save(this,a===true?undefined:a);a===true&&this.$$entity.Cb.ga();return this},$loadFrom:function(a){E.ea(a,this);return this},$saveTo:function(a){E.ea(this,a);return this}};F.ua={"null":M(null),"true":M(true),"false":M(false),"+":function(a,b,c){return(b||0)+(c||0)},"-":function(a,b,c){return(b||0)- (c||0)},"*":function(a,b,c){return b*c},"/":function(a,b,c){return b/c},"%":function(a,b,c){return b%c},"^":function(a,b,c){return b^c},"=":function(a,b,c){return a.scope.h(b,c)},"==":function(a,b,c){return b==c},"!=":function(a,b,c){return b!=c},"<":function(a,b,c){return b<c},">":function(a,b,c){return b>c},"<=":function(a,b,c){return b<=c},">=":function(a,b,c){return b>=c},"&&":function(a,b,c){return b&&c},"||":function(a,b,c){return b||c},"&":function(a,b,c){return b&c},"|":function(a,b,c){return c(a, b)},"!":function(a,b){return!b}};F.ib={n:"\n",f:"\u000c",r:"\r",t:"\t",v:"\u000b","'":"'",'"':'"'};F.prototype={F:function(){return this.index+1<this.text.length?this.text.charAt(this.index+1):false},parse:function(){for(var a=this.i,b=F.ua,c=true;this.index<this.text.length;){var d=this.text.charAt(this.index);if(d=='"'||d=="'"){this.qc(d);c=true}else if(d=="("||d=="["){a.push({index:this.index,text:d});this.index++}else if(d=="{"){c=this.F();if(c==":"||c=="("){a.push({index:this.index,text:d+c}); this.index++}else a.push({index:this.index,text:d});this.index++;c=true}else if(d==")"||d=="]"||d=="}"){a.push({index:this.index,text:d});this.index++;c=false}else if(d==":"||d=="."||d==","||d==";"){a.push({index:this.index,text:d});this.index++;c=true}else if(c&&d=="/"){this.pc();c=false}else if(this.ha(d)){this.oc();c=false}else if(this.U(d)){this.Va();c=false}else if(this.Tb(d))this.index++;else{c=d+this.F();var e=b[d],f=b[c];if(f){a.push({index:this.index,text:c,b:f});this.index+=2}else if(e){a.push({index:this.index, text:d,b:e});this.index+=1}else throw"Lexer Error: Unexpected next character ["+this.text.substring(this.index)+"] in expression '"+this.text+"' at column '"+(this.index+1)+"'.";c=true}}return a},ha:function(a){return"0"<=a&&a<="9"},Tb:function(a){return a==" "||a=="\r"||a=="\t"||a=="\n"||a=="\u000b"},U:function(a){return"a"<=a&&a<="z"||"A"<=a&&a<="Z"||"_"==a||a=="$"},oc:function(){for(var a="",b=this.index;this.index<this.text.length;){var c=this.text.charAt(this.index);if(c=="."||this.ha(c))a+= c;else break;this.index++}a=1*a;this.i.push({index:b,text:a,b:function(){return a}})},Va:function(){for(var a="",b=this.index;this.index<this.text.length;){var c=this.text.charAt(this.index);if(c=="."||this.U(c)||this.ha(c))a+=c;else break;this.index++}c=F.ua[a];if(!c){c=function(d){return d.scope.get(a)};c.T=a}this.i.push({index:b,text:a,b:c})},qc:function(a){var b=this.index,c=this.Db;this.index++;for(var d="",e=false;this.index<this.text.length;){var f=this.text.charAt(this.index);if(e){if(f== "u"){f=this.text.substring(this.index+1,this.index+5);this.index+=4;d+=String.fromCharCode(parseInt(f,16))}else{e=F.ib[f];d+=e?e:f}e=false}else if(f=="\\")e=true;else if(f==a){this.index++;this.i.push({index:b,text:d,b:function(){return d.length==c?m.String.toDate(d):d}});return}else d+=f;this.index++}throw"Lexer Error: Unterminated quote ["+this.text.substring(b)+"] starting at column '"+(b+1)+"' in expression '"+this.text+"'.";},pc:function(){var a=this.index;this.index++;for(var b="",c=false;this.index< -this.text.length;){var d=this.text.charAt(this.index);if(c){b+=d;c=false}else if(d==="\\"){b+=d;c=true}else if(d==="/"){this.index++;c="";if(this.U(this.text.charAt(this.index))){this.Va();c=this.i.pop().text}var e=new RegExp(b,c);this.i.push({index:a,text:b,od:c,b:function(){return e}});return}else b+=d;this.index++}throw"Lexer Error: Unterminated RegExp ["+this.text.substring(a)+"] starting at column '"+(a+1)+"' in expression '"+this.text+"'.";}};D.lb=N(0);D.prototype={error:function(a,b){throw"Token '"+ +this.text.length;){var d=this.text.charAt(this.index);if(c){b+=d;c=false}else if(d==="\\"){b+=d;c=true}else if(d==="/"){this.index++;c="";if(this.U(this.text.charAt(this.index))){this.Va();c=this.i.pop().text}var e=new RegExp(b,c);this.i.push({index:a,text:b,od:c,b:function(){return e}});return}else b+=d;this.index++}throw"Lexer Error: Unterminated RegExp ["+this.text.substring(a)+"] starting at column '"+(a+1)+"' in expression '"+this.text+"'.";}};D.lb=M(0);D.prototype={error:function(a,b){throw"Token '"+ b.text+"' is "+a+" at column='"+(b.index+1)+"' of expression '"+this.text+"' starting at '"+this.text.substring(b.index)+"'.";},Y:function(){if(this.i.length===0)throw"Unexpected end of expression: "+this.text;return this.i[0]},F:function(a,b,c,d){var e=this.i;if(e.length>0){e=e[0];var f=e.text;if(f==a||f==b||f==c||f==d||!a&&!b&&!c&&!d)return e}return false},a:function(a,b,c,d){if(a=this.F(a,b,c,d)){this.i.shift();return this.fd=a}return false},j:function(a){if(!this.a(a)){var b=this.F();throw"Expecting '"+ a+"' at column '"+(b.index+1)+"' in '"+this.text+"' got '"+this.text.substring(b.index)+"'.";}},mb:function(a,b){return function(c){return a(c,b(c))}},q:function(a,b,c){return function(d){return b(d,a(d),c(d))}},Ea:function(){return this.i.length>0},G:function(){if(this.i.length!==0)throw"Did not understand '"+this.text.substring(this.i[0].index)+"' while evaluating '"+this.text+"'.";},pa:function(){for(var a=[];;){this.i.length>0&&!this.F("}",")",";","]")&&a.push(this.Ca());if(!this.a(";"))return function(b){for(var c, d=0;d<a.length;d++){var e=a[d];if(e)c=e(b)}return c}}},Ca:function(){for(var a=this.m(),b;;)if(b=this.a("|"))a=this.q(a,b.b,this.filter());else return a},filter:function(){return this.wa(m.filter)},L:function(){return this.wa(m.validator)},wa:function(a){for(var b=this.Pb(a),c=[];;)if(this.a(":"))c.push(this.m());else{var d=function(e,f){f=[f];for(var g=0;g<c.length;g++)f.push(c[g](e));return b.apply(e,f)};return function(){return d}}},m:function(){return this.vc()},vc:function(){if(this.a("throw")){var a= @@ -82,14 +82,14 @@ b,c,function(){e.status.Hb();try{d.apply(this,arguments)}catch(f){alert(w(f))}e. b+"."},number:function(a,b,c){var d=1*a;if(d==a){if(typeof b!="undefined"&&d<b)return"Value can not be less than "+b+".";if(typeof b!="undefined"&&d>c)return"Value can not be greater than "+c+".";return null}else return"Value is not a number."},integer:function(a,b,c){b=Ba.number(a,b,c);if(b===null&&a!=Math.round(a))return"Value is not a whole number.";return b},date:function(a){if(a.match(/^\d\d?\/\d\d?\/\d\d\d\d$/))return null;return"Value is not a date. (Expecting format: 12/31/2009)."},ssn:function(a){if(a.match(/^\d\d\d-\d\d-\d\d\d\d$/))return null; return"SSN needs to be in 999-99-9999 format."},email:function(a){if(a.match(/^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,4}$/))return null;return"Email needs to be in username@host.com format."},phone:function(a){if(a.match(/^1\(\d\d\d\)\d\d\d-\d\d\d\d$/))return null;if(a.match(/^\+\d{2,3} (\(\d{1,5}\))?[\d ]+\d$/))return null;return"Phone number needs to be in 1(987)654-3210 format in North America or +999 (123) 45678 906 internationaly."},url:function(a){if(a.match(/^(ftp|http|https):\/\/(\w+:{0,1}\w*@)?(\S+)(:[0-9]+)?(\/|\/([\w#!:.?+=&%@!\-\/]))?$/))return null; return"URL needs to be in http://server[:port]/path format."},json:function(a){try{P(a);return null}catch(b){return b.toString()}}},function(a,b){Ba[b]=a});ja.prototype={Ab:function(a,b){var c,d=a.attr("type").toLowerCase(),e=a.attr("name");if(e)e=e.split(":").pop();var f="change",g=true;if(d=="button"||d=="submit"||d=="reset"||d=="image"){c=new La(a[0],e);f="click";g=false}else if(d=="text"||d=="textarea"||d=="hidden"||d=="password"){c=new na(a[0],e);f="keyup change"}else if(d=="checkbox"){c=new oa(a[0], -e);f="click"}else if(d=="radio"){c=new ra(a[0],e);f="click"}else if(d=="select-one")c=new pa(a[0],e);else if(d=="select-multiple")c=new qa(a[0],e);else if(d=="file")c=this.Bb(a,e);else throw"Unknown type: "+d;a.data("controller",c);var h=b.get("$updateView");k(c.view,":input").bind(f,function(){if(c.e(b)){var i=k(c.view).attr("ng-action")||"";b.k(c,i)&&h(b)}return g});return c},Bb:function(a){var b="__uploadWidget_"+this.ac++,c=L.template(b);a.after(c);b=this.za({data:this.aa+"/admin/ServerAPI.swf", -width:"95",height:"20",align:"top",Ed:"transparent"},{pd:"uploadWidgetId="+b,Oc:"always"},b);a.remove();a=new L(c,a[0].name,b,this.aa+"/data/"+this.fa);k(b).data("controller",a);return a}};L.dispatchEvent=function(a,b,c){a=y.getElementById(a);a=k(a).data("controller");L.prototype["_on_"+b].apply(a,c)};L.template=function(a){return k('<span class="ng-upload-widget"><input type="checkbox" ng-non-bindable="true"/><object id="'+a+'" /><a></a><span/></span>')};L.prototype={e:function(a){var b=this.view.find("input").attr("checked")? -this.value:null;if(this.c===b)return false;else{a.h(this.Xa,b);return true}},d:function(a){if((a=a.get(this.Xa))&&this.value!==a){this.value=a;this.view.find("a").attr("href",this.value.url).text(this.value.text);this.view.find("span").text(m.filter.bytes(this.value.size))}this.view.find("input").attr("checked",!!a)}};Q.prototype={e:N(true),d:n};Q.Rb=new Q;var La=Q;na.prototype={e:function(a){var b=this.view.value;if(this.c===b)return false;else{a.l(this.exp,b);this.c=b;return true}},d:function(a){var b= +e);f="click"}else if(d=="radio"){c=new ra(a[0],e);f="click"}else if(d=="select-one")c=new pa(a[0],e);else if(d=="select-multiple")c=new qa(a[0],e);else if(d=="file")c=this.Bb(a,e);else throw"Unknown type: "+d;a.data("controller",c);var h=b.get("$updateView");k(c.view,":input").bind(f,function(){if(c.e(b)){var i=k(c.view).attr("ng-action")||"";b.k(c,i)&&h(b)}return g});return c},Bb:function(a){var b="__uploadWidget_"+this.ac++,c=K.template(b);a.after(c);b=this.za({data:this.aa+"/admin/ServerAPI.swf", +width:"95",height:"20",align:"top",Ed:"transparent"},{pd:"uploadWidgetId="+b,Oc:"always"},b);a.remove();a=new K(c,a[0].name,b,this.aa+"/data/"+this.fa);k(b).data("controller",a);return a}};K.dispatchEvent=function(a,b,c){a=y.getElementById(a);a=k(a).data("controller");K.prototype["_on_"+b].apply(a,c)};K.template=function(a){return k('<span class="ng-upload-widget"><input type="checkbox" ng-non-bindable="true"/><object id="'+a+'" /><a></a><span/></span>')};K.prototype={e:function(a){var b=this.view.find("input").attr("checked")? +this.value:null;if(this.c===b)return false;else{a.h(this.Xa,b);return true}},d:function(a){if((a=a.get(this.Xa))&&this.value!==a){this.value=a;this.view.find("a").attr("href",this.value.url).text(this.value.text);this.view.find("span").text(m.filter.bytes(this.value.size))}this.view.find("input").attr("checked",!!a)}};Q.prototype={e:M(true),d:n};Q.Rb=new Q;var La=Q;na.prototype={e:function(a){var b=this.view.value;if(this.c===b)return false;else{a.l(this.exp,b);this.c=b;return true}},d:function(a){var b= this.view,c=a.get(this.exp);if(typeof c==="undefined"){c=this.o;a.l(this.exp,c)}c=c?c:"";if(this.c!=c)this.c=b.value=c;var d=false;b.removeAttribute("ng-error");if(this.rc)d=!(c&&c.length>0);var e=d?"Required Value":null;if(!d&&this.L&&c){e=a.Ac(this.L,c);d=!!e}if(this.Ga!==e){this.Ga=d;if(e!==null){b.setAttribute("ng-error",e);a.Yb(this)}k(b).toggleClass("ng-validation-error",d)}}};oa.prototype={e:function(a){var b=this.view;b=b.checked?b.value:"";if(this.c===b)return false;else{a.l(this.exp,b); this.c=b;return true}},d:function(a){var b=this.view,c=a.eval(this.exp);if(typeof c==="undefined"){c=this.o;a.l(this.exp,c)}b.checked=b.value==""+c}};pa.prototype={e:function(a){if(this.view.selectedIndex<0)a.l(this.exp,null);else{var b=this.view.value;if(this.c===b)return false;else{a.l(this.exp,b);this.c=b;return true}}},d:function(a){var b=this.view,c=a.get(this.exp);if(typeof c==="undefined"){c=this.o;a.l(this.exp,c)}if(c!==this.c){b.value=c?c:"";this.c=c}}};qa.prototype={selected:function(){for(var a= [],b=this.view.options,c=0;c<b.length;c++){var d=b[c];d.selected&&a.push(d.value)}return a},e:function(a){var b=this.selected();if(this.c===b)return false;else{a.l(this.exp,b);this.c=b;return true}},d:function(a){var b=this.view,c=a.get(this.exp);if(typeof c==="undefined"){c=this.o;a.l(this.exp,c)}if(c!==this.c){a=b.options;for(b=0;b<a.length;b++){var d=a[b];d.selected=_.include(c,d.value)}this.c=c}}};ra.prototype={e:function(a){var b=this.view;if(this.ia)return false;else{b.checked=true;this.c=a.l(this.exp, -this.Fa);return this.ia=true}},d:function(a){var b=this.view,c=a.get(this.exp);if(this.o&&typeof c==="undefined"){c=this.o;a.l(this.exp,c)}if(this.c!=c){this.ia=b.checked=this.Fa==""+c;this.c=c}}};M.Ya=function(a){switch(typeof a){case "string":case "boolean":case "number":return C(a);case "function":return M.Ya(a());case "object":if(a&&a.tagName&&a.nodeName&&a.ownerDocument&&a.removeAttribute)return ga(a);else if(a instanceof m.filter.g){switch(typeof a.html){case "string":case "number":return a.html; -case "function":return a.html();case "object":if(a.html&&a.html.tagName&&a.html.nodeName&&a.html.ownerDocument&&a.html.removeAttribute)return ga(a.html);default:break}switch(typeof a.text){case "string":case "number":return C(a.text);case "function":return C(a.text());default:break}}if(a===null)return"";return C(w(a,true));default:return""}};M.prototype={e:n,d:function(a){for(var b=[],c=this.exp,d=c.length,e=0;e<d;e++){var f=c[e],g=x.H(f);if(g){a.k(this,g,this.tc,function(h){b.push(M.Ya(h))},function(h, +this.Fa);return this.ia=true}},d:function(a){var b=this.view,c=a.get(this.exp);if(this.o&&typeof c==="undefined"){c=this.o;a.l(this.exp,c)}if(this.c!=c){this.ia=b.checked=this.Fa==""+c;this.c=c}}};L.Ya=function(a){switch(typeof a){case "string":case "boolean":case "number":return C(a);case "function":return L.Ya(a());case "object":if(a&&a.tagName&&a.nodeName&&a.ownerDocument&&a.removeAttribute)return ga(a);else if(a instanceof m.filter.g){switch(typeof a.html){case "string":case "number":return a.html; +case "function":return a.html();case "object":if(a.html&&a.html.tagName&&a.html.nodeName&&a.html.ownerDocument&&a.html.removeAttribute)return ga(a.html);default:break}switch(typeof a.text){case "string":case "number":return C(a.text);case "function":return C(a.text());default:break}}if(a===null)return"";return C(w(a,true));default:return""}};L.prototype={e:n,d:function(a){for(var b=[],c=this.exp,d=c.length,e=0;e<d;e++){var f=c[e],g=x.H(f);if(g){a.k(this,g,this.tc,function(h){b.push(L.Ya(h))},function(h, i){fa(this.view,i)});if(this.u)return}else b.push(C(f))}fa(this.view,b.join(""))}};sa.prototype={e:n,d:function(a){var b=k(this.view),c=this.tb;if(this.u){this.u=false;b.removeClass("ng-exception").removeAttr("ng-error")}var d=b.is("img");for(var e in c){for(var f=x.X(c[e]),g=[],h=0;h<f.length;h++){var i=x.H(f[h]);if(i)try{var j=a.eval(i,{element:b[0],attrName:e});if(j&&(j.constructor!==array||j.length!==0))g.push(j)}catch(l){this.u=true;W("BindAttrUpdater",l);i=w(l,true);g.push("["+i+"]");b.addClass("ng-exception").attr("ng-error", i)}else g.push(f[h])}f=g.length?g.join(""):null;if(d&&e=="src"&&!f)f=a.get("config.server")+"/images/blank.gif";b.attr(e,f)}}};ta.prototype={e:n,d:function(a){a.k(this,this.exp)}};ua.prototype={e:n,d:function(a){a.k(this,this.exp,{},function(b){var c=k(this.view);Y(b)?c.hide():c.show()})}};va.prototype={e:n,d:function(a){a.k(this,this.exp,{},function(b){var c=k(this.view);Y(b)?c.show():c.hide()})}};wa.prototype={e:n,d:function(a){a.k(this,this.exp,{},function(b){if(b!==null&&b!==undefined)this.view.className= b})}};xa.prototype={e:n,d:function(a){a.k(this,this.exp,{},function(b){var c=a.get("$index");k(this.view).toggleClass(b,c%2===1)})}};ya.prototype={e:n,d:function(a){a.k(this,this.exp,{},function(b){var c=a.get("$index");k(this.view).toggleClass(b,c%2===0)})}};za.prototype={e:n,d:function(a){a.k(this,this.exp,{},function(b){k(this.view).attr("style","").css(b)})}};Aa.prototype={e:n,d:function(a){a.k(this,this.V,{},function(b){var c=this;if(!b){b=[];a.Sb(this.V)&&a.h(this.V,b)}var d=b.length,e=this.children.length, @@ -396,7 +396,6 @@ UrlWatcher.prototype = { ///////////////////////////////////////////////// function configureJQueryPlugins() { - log('Angular.configureJQueryPlugins()'); var fn = jQuery['fn']; fn['scope'] = function() { var element = this; @@ -499,7 +498,7 @@ function wireAngular(element, config) { config['location']['listen'](_(binder.onUrlChange).bind(binder)); binder.parseAnchor(); binder.executeInit(); - scope.updateView(); + binder.updateView(); return self; }, 'element':element[0], @@ -917,7 +916,7 @@ Binder.prototype = { }, updateAnchor: function() { - var url = this.location.get(); + var url = this.location.get() || ""; var anchorIndex = url.indexOf('#'); if (anchorIndex > -1) url = url.substring(0, anchorIndex); diff --git a/jsTestDriver.conf b/jsTestDriver.conf index 28958ee4..6c2cf0bb 100644 --- a/jsTestDriver.conf +++ b/jsTestDriver.conf @@ -4,7 +4,7 @@ load: - lib/jasmine/jasmine-0.10.0.js - lib/jasmine-jstd-adapter/JasmineAdapter.js - lib/webtoolkit/webtoolkit.base64.js - - lib/jquery/jquery-1.3.2.js + - lib/jquery/jquery-1.4.0.js - lib/jquery/jquery-ui-1.7.1.custom.min.js - lib/underscore/underscore.js - src/Angular.js diff --git a/lib/underscore/underscore-min.js b/lib/underscore/underscore-min.js new file mode 100644 index 00000000..53145b71 --- /dev/null +++ b/lib/underscore/underscore-min.js @@ -0,0 +1,17 @@ +(function(){var j=this,n=j._,i=function(a){this._wrapped=a},m=typeof StopIteration!=="undefined"?StopIteration:"__break__",b=j._=function(a){return new i(a)};if(typeof exports!=="undefined")exports._=b;var k=Array.prototype.slice,o=Array.prototype.unshift,p=Object.prototype.toString,q=Object.prototype.hasOwnProperty,r=Object.prototype.propertyIsEnumerable;b.VERSION="0.5.7";b.each=function(a,c,d){try{if(a.forEach)a.forEach(c,d);else if(b.isArray(a)||b.isArguments(a))for(var e=0,f=a.length;e<f;e++)c.call(d, +a[e],e,a);else{var g=b.keys(a);f=g.length;for(e=0;e<f;e++)c.call(d,a[g[e]],g[e],a)}}catch(h){if(h!=m)throw h;}return a};b.map=function(a,c,d){if(a&&b.isFunction(a.map))return a.map(c,d);var e=[];b.each(a,function(f,g,h){e.push(c.call(d,f,g,h))});return e};b.reduce=function(a,c,d,e){if(a&&b.isFunction(a.reduce))return a.reduce(b.bind(d,e),c);b.each(a,function(f,g,h){c=d.call(e,c,f,g,h)});return c};b.reduceRight=function(a,c,d,e){if(a&&b.isFunction(a.reduceRight))return a.reduceRight(b.bind(d,e),c); +var f=b.clone(b.toArray(a)).reverse();b.each(f,function(g,h){c=d.call(e,c,g,h,a)});return c};b.detect=function(a,c,d){var e;b.each(a,function(f,g,h){if(c.call(d,f,g,h)){e=f;b.breakLoop()}});return e};b.select=function(a,c,d){if(a&&b.isFunction(a.filter))return a.filter(c,d);var e=[];b.each(a,function(f,g,h){c.call(d,f,g,h)&&e.push(f)});return e};b.reject=function(a,c,d){var e=[];b.each(a,function(f,g,h){!c.call(d,f,g,h)&&e.push(f)});return e};b.all=function(a,c,d){c=c||b.identity;if(a&&b.isFunction(a.every))return a.every(c, +d);var e=true;b.each(a,function(f,g,h){(e=e&&c.call(d,f,g,h))||b.breakLoop()});return e};b.any=function(a,c,d){c=c||b.identity;if(a&&b.isFunction(a.some))return a.some(c,d);var e=false;b.each(a,function(f,g,h){if(e=c.call(d,f,g,h))b.breakLoop()});return e};b.include=function(a,c){if(b.isArray(a))return b.indexOf(a,c)!=-1;var d=false;b.each(a,function(e){if(d=e===c)b.breakLoop()});return d};b.invoke=function(a,c){var d=b.rest(arguments,2);return b.map(a,function(e){return(c?e[c]:e).apply(e,d)})};b.pluck= +function(a,c){return b.map(a,function(d){return d[c]})};b.max=function(a,c,d){if(!c&&b.isArray(a))return Math.max.apply(Math,a);var e={computed:-Infinity};b.each(a,function(f,g,h){g=c?c.call(d,f,g,h):f;g>=e.computed&&(e={value:f,computed:g})});return e.value};b.min=function(a,c,d){if(!c&&b.isArray(a))return Math.min.apply(Math,a);var e={computed:Infinity};b.each(a,function(f,g,h){g=c?c.call(d,f,g,h):f;g<e.computed&&(e={value:f,computed:g})});return e.value};b.sortBy=function(a,c,d){return b.pluck(b.map(a, +function(e,f,g){return{value:e,criteria:c.call(d,e,f,g)}}).sort(function(e,f){e=e.criteria;f=f.criteria;return e<f?-1:e>f?1:0}),"value")};b.sortedIndex=function(a,c,d){d=d||b.identity;for(var e=0,f=a.length;e<f;){var g=e+f>>1;d(a[g])<d(c)?(e=g+1):(f=g)}return e};b.toArray=function(a){if(!a)return[];if(a.toArray)return a.toArray();if(b.isArray(a))return a;if(b.isArguments(a))return k.call(a);return b.values(a)};b.size=function(a){return b.toArray(a).length};b.first=function(a,c,d){return c&&!d?k.call(a, +0,c):a[0]};b.rest=function(a,c,d){return k.call(a,b.isUndefined(c)||d?1:c)};b.last=function(a){return a[a.length-1]};b.compact=function(a){return b.select(a,function(c){return!!c})};b.flatten=function(a){return b.reduce(a,[],function(c,d){if(b.isArray(d))return c.concat(b.flatten(d));c.push(d);return c})};b.without=function(a){var c=b.rest(arguments);return b.select(a,function(d){return!b.include(c,d)})};b.uniq=function(a,c){return b.reduce(a,[],function(d,e,f){if(0==f||(c===true?b.last(d)!=e:!b.include(d, +e)))d.push(e);return d})};b.intersect=function(a){var c=b.rest(arguments);return b.select(b.uniq(a),function(d){return b.all(c,function(e){return b.indexOf(e,d)>=0})})};b.zip=function(){for(var a=b.toArray(arguments),c=b.max(b.pluck(a,"length")),d=new Array(c),e=0;e<c;e++)d[e]=b.pluck(a,String(e));return d};b.indexOf=function(a,c){if(a.indexOf)return a.indexOf(c);for(var d=0,e=a.length;d<e;d++)if(a[d]===c)return d;return-1};b.lastIndexOf=function(a,c){if(a.lastIndexOf)return a.lastIndexOf(c);for(var d= +a.length;d--;)if(a[d]===c)return d;return-1};b.range=function(a,c,d){var e=b.toArray(arguments),f=e.length<=1;a=f?0:e[0];c=f?e[0]:e[1];d=e[2]||1;e=Math.ceil((c-a)/d);if(e<=0)return[];e=new Array(e);f=a;for(var g=0;;f+=d){if((d>0?f-c:c-f)>=0)return e;e[g++]=f}};b.bind=function(a,c){var d=b.rest(arguments,2);return function(){return a.apply(c||j,d.concat(b.toArray(arguments)))}};b.bindAll=function(a){var c=b.rest(arguments);if(c.length==0)c=b.functions(a);b.each(c,function(d){a[d]=b.bind(a[d],a)}); +return a};b.delay=function(a,c){var d=b.rest(arguments,2);return setTimeout(function(){return a.apply(a,d)},c)};b.defer=function(a){return b.delay.apply(b,[a,1].concat(b.rest(arguments)))};b.wrap=function(a,c){return function(){var d=[a].concat(b.toArray(arguments));return c.apply(c,d)}};b.compose=function(){var a=b.toArray(arguments);return function(){for(var c=b.toArray(arguments),d=a.length-1;d>=0;d--)c=[a[d].apply(this,c)];return c[0]}};b.keys=function(a){if(b.isArray(a))return b.range(0,a.length); +var c=[];for(var d in a)q.call(a,d)&&c.push(d);return c};b.values=function(a){return b.map(a,b.identity)};b.functions=function(a){return b.select(b.keys(a),function(c){return b.isFunction(a[c])}).sort()};b.extend=function(a,c){for(var d in c)a[d]=c[d];return a};b.clone=function(a){if(b.isArray(a))return a.slice(0);return b.extend({},a)};b.tap=function(a,c){c(a);return a};b.isEqual=function(a,c){if(a===c)return true;var d=typeof a;if(d!=typeof c)return false;if(a==c)return true;if(!a&&c||a&&!c)return false; +if(a.isEqual)return a.isEqual(c);if(b.isDate(a)&&b.isDate(c))return a.getTime()===c.getTime();if(b.isNaN(a)&&b.isNaN(c))return true;if(b.isRegExp(a)&&b.isRegExp(c))return a.source===c.source&&a.global===c.global&&a.ignoreCase===c.ignoreCase&&a.multiline===c.multiline;if(d!=="object")return false;if(a.length&&a.length!==c.length)return false;d=b.keys(a);var e=b.keys(c);if(d.length!=e.length)return false;for(var f in a)if(!b.isEqual(a[f],c[f]))return false;return true};b.isEmpty=function(a){return b.keys(a).length== +0};b.isElement=function(a){return!!(a&&a.nodeType==1)};b.isArray=function(a){return!!(a&&a.concat&&a.unshift)};b.isArguments=function(a){return a&&b.isNumber(a.length)&&!a.concat&&!a.substr&&!a.apply&&!r.call(a,"length")};b.isFunction=function(a){return!!(a&&a.constructor&&a.call&&a.apply)};b.isString=function(a){return!!(a===""||a&&a.charCodeAt&&a.substr)};b.isNumber=function(a){return a===+a||p.call(a)==="[object Number]"};b.isDate=function(a){return!!(a&&a.getTimezoneOffset&&a.setUTCFullYear)}; +b.isRegExp=function(a){return!!(a&&a.test&&a.exec&&(a.ignoreCase||a.ignoreCase===false))};b.isNaN=function(a){return b.isNumber(a)&&isNaN(a)};b.isNull=function(a){return a===null};b.isUndefined=function(a){return typeof a=="undefined"};b.noConflict=function(){j._=n;return this};b.identity=function(a){return a};b.breakLoop=function(){throw m;};var s=0;b.uniqueId=function(a){var c=s++;return a?a+c:c};b.templateSettings={start:"<%",end:"%>",interpolate:/<%=(.+?)%>/g};b.template=function(a,c){var d=b.templateSettings; +a=new Function("obj","var p=[],print=function(){p.push.apply(p,arguments);};with(obj){p.push('"+a.replace(/[\r\t\n]/g," ").replace(new RegExp("'(?=[^"+d.end[0]+"]*"+d.end+")","g"),"\t").split("'").join("\\'").split("\t").join("'").replace(d.interpolate,"',$1,'").split(d.start).join("');").split(d.end).join("p.push('")+"');}return p.join('');");return c?a(c):a};b.forEach=b.each;b.foldl=b.inject=b.reduce;b.foldr=b.reduceRight;b.filter=b.select;b.every=b.all;b.some=b.any;b.head=b.first;b.tail=b.rest; +b.methods=b.functions;var l=function(a,c){return c?b(a).chain():a};b.each(b.functions(b),function(a){var c=b[a];i.prototype[a]=function(){var d=b.toArray(arguments);o.call(d,this._wrapped);return l(c.apply(b,d),this._chain)}});b.each(["pop","push","reverse","shift","sort","splice","unshift"],function(a){var c=Array.prototype[a];i.prototype[a]=function(){c.apply(this._wrapped,arguments);return l(this._wrapped,this._chain)}});b.each(["concat","join","slice"],function(a){var c=Array.prototype[a];i.prototype[a]= +function(){return l(c.apply(this._wrapped,arguments),this._chain)}});i.prototype.chain=function(){this._chain=true;return this};i.prototype.value=function(){return this._wrapped}})(); diff --git a/lib/underscore/underscore.js b/lib/underscore/underscore.js index 047f01c5..7006910e 100644 --- a/lib/underscore/underscore.js +++ b/lib/underscore/underscore.js @@ -1,14 +1,14 @@ // Underscore.js -// (c) 2009 Jeremy Ashkenas, DocumentCloud Inc. +// (c) 2010 Jeremy Ashkenas, DocumentCloud Inc. // Underscore is freely distributable under the terms of the MIT license. // Portions of Underscore are inspired by or borrowed from Prototype.js, // Oliver Steele's Functional, and John Resig's Micro-Templating. // For all details and documentation: -// http://documentcloud.github.com/underscore/ +// http://documentcloud.github.com/underscore (function() { - /*------------------------- Baseline setup ---------------------------------*/ + // ------------------------- Baseline setup --------------------------------- // Establish the root object, "window" in the browser, or "global" on the server. var root = this; @@ -38,9 +38,9 @@ propertyIsEnumerable = Object.prototype.propertyIsEnumerable; // Current version. - _.VERSION = '0.5.1'; + _.VERSION = '0.5.7'; - /*------------------------ Collection Functions: ---------------------------*/ + // ------------------------ Collection Functions: --------------------------- // The cornerstone, an each implementation. // Handles objects implementing forEach, arrays, and raw objects. @@ -226,7 +226,7 @@ if (iterable.toArray) return iterable.toArray(); if (_.isArray(iterable)) return iterable; if (_.isArguments(iterable)) return slice.call(iterable); - return _.map(iterable, function(val){ return val; }); + return _.values(iterable); }; // Return the number of elements in an object. @@ -234,7 +234,7 @@ return _.toArray(obj).length; }; - /*-------------------------- Array Functions: ------------------------------*/ + // -------------------------- Array Functions: ------------------------------ // Get the first element of an array. Passing "n" will return the first N // values in the array. Aliased as "head". The "guard" check allows it to work @@ -340,7 +340,7 @@ } }; - /* ----------------------- Function Functions: -----------------------------*/ + // ----------------------- Function Functions: ------------------------------ // Create a function bound to a given object (assigning 'this', and arguments, // optionally). Binding with arguments is also known as 'curry'. @@ -396,7 +396,7 @@ }; }; - /* ------------------------- Object Functions: ---------------------------- */ + // ------------------------- Object Functions: ------------------------------ // Retrieve the names of an object's properties. _.keys = function(obj) { @@ -428,6 +428,13 @@ return _.extend({}, obj); }; + // Invokes interceptor with the obj, and then returns obj. + // The primary purpose of this method is to "tap into" a method chain, in order to perform operations on intermediate results within the chain. + _.tap = function(obj, interceptor) { + interceptor(obj); + return obj; + }; + // Perform a deep comparison to check if two objects are equal. _.isEqual = function(a, b) { // Check object identity. @@ -474,9 +481,39 @@ return !!(obj && obj.nodeType == 1); }; + // Is a given value an array? + _.isArray = function(obj) { + return !!(obj && obj.concat && obj.unshift); + }; + // Is a given variable an arguments object? _.isArguments = function(obj) { - return obj && _.isNumber(obj.length) && !_.isArray(obj) && !propertyIsEnumerable.call(obj, 'length'); + return obj && _.isNumber(obj.length) && !obj.concat && !obj.substr && !obj.apply && !propertyIsEnumerable.call(obj, 'length'); + }; + + // Is a given value a function? + _.isFunction = function(obj) { + return !!(obj && obj.constructor && obj.call && obj.apply); + }; + + // Is a given value a string? + _.isString = function(obj) { + return !!(obj === '' || (obj && obj.charCodeAt && obj.substr)); + }; + + // Is a given value a number? + _.isNumber = function(obj) { + return (obj === +obj) || (toString.call(obj) === '[object Number]'); + }; + + // Is a given value a date? + _.isDate = function(obj) { + return !!(obj && obj.getTimezoneOffset && obj.setUTCFullYear); + }; + + // Is the given value a regular expression? + _.isRegExp = function(obj) { + return !!(obj && obj.test && obj.exec && (obj.ignoreCase || obj.ignoreCase === false)); }; // Is the given value NaN -- this one is interesting. NaN != NaN, and @@ -495,17 +532,7 @@ return typeof obj == 'undefined'; }; - // Define the isArray, isDate, isFunction, isNumber, isRegExp, and isString - // functions based on their toString identifiers. - var types = ['Array', 'Date', 'Function', 'Number', 'RegExp', 'String']; - for (var i=0, l=types.length; i<l; i++) { - (function() { - var identifier = '[object ' + types[i] + ']'; - _['is' + types[i]] = function(obj) { return toString.call(obj) == identifier; }; - })(); - } - - /* -------------------------- Utility Functions: -------------------------- */ + // -------------------------- Utility Functions: ---------------------------- // Run Underscore.js in noConflict mode, returning the '_' variable to its // previous owner. Returns a reference to the Underscore object. @@ -532,25 +559,34 @@ return prefix ? prefix + id : id; }; + // By default, Underscore uses ERB-style template delimiters, change the + // following template settings to use alternative delimiters. + _.templateSettings = { + start : '<%', + end : '%>', + interpolate : /<%=(.+?)%>/g + }; + // JavaScript templating a-la ERB, pilfered from John Resig's // "Secrets of the JavaScript Ninja", page 83. + // Single-quote fix from Rick Strahl's version. _.template = function(str, data) { + var c = _.templateSettings; var fn = new Function('obj', 'var p=[],print=function(){p.push.apply(p,arguments);};' + 'with(obj){p.push(\'' + - str - .replace(/[\r\t\n]/g, " ") - .split("<%").join("\t") - .replace(/((^|%>)[^\t]*)'/g, "$1\r") - .replace(/\t=(.*?)%>/g, "',$1,'") - .split("\t").join("');") - .split("%>").join("p.push('") - .split("\r").join("\\'") - + "');}return p.join('');"); + str.replace(/[\r\t\n]/g, " ") + .replace(new RegExp("'(?=[^"+c.end[0]+"]*"+c.end+")","g"),"\t") + .split("'").join("\\'") + .split("\t").join("'") + .replace(c.interpolate, "',$1,'") + .split(c.start).join("');") + .split(c.end).join("p.push('") + + "');}return p.join('');"); return data ? fn(data) : fn; }; - /*------------------------------- Aliases ----------------------------------*/ + // ------------------------------- Aliases ---------------------------------- _.forEach = _.each; _.foldl = _.inject = _.reduce; @@ -562,7 +598,7 @@ _.tail = _.rest; _.methods = _.functions; - /*------------------------ Setup the OOP Wrapper: --------------------------*/ + // ------------------------ Setup the OOP Wrapper: -------------------------- // Helper function to continue chaining intermediate results. var result = function(obj, chain) { @@ -573,8 +609,9 @@ _.each(_.functions(_), function(name) { var method = _[name]; wrapper.prototype[name] = function() { - unshift.call(arguments, this._wrapped); - return result(method.apply(_, arguments), this._chain); + var args = _.toArray(arguments); + unshift.call(args, this._wrapped); + return result(method.apply(_, args), this._chain); }; }); diff --git a/src/Angular.js b/src/Angular.js index d3eef9d9..cadef4d0 100644 --- a/src/Angular.js +++ b/src/Angular.js @@ -20,11 +20,9 @@ if (typeof Node == 'undefined') { function noop() {} if (!window['console']) window['console']={'log':noop, 'error':noop}; -var consoleNode, +var consoleNode, jQuery, msie, foreach = _.each, extend = _.extend, - jQuery = window['jQuery'], - msie = jQuery['browser']['msie'], angular = window['angular'] || (window['angular'] = {}), angularValidator = angular['validator'] || (angular['validator'] = {}), angularFilter = angular['filter'] || (angular['filter'] = {}), @@ -212,7 +210,6 @@ UrlWatcher.prototype = { self.setTimeout(pull, self.delay); }; pull(); - return this; }, set: function(url) { @@ -271,19 +268,20 @@ function exposeMethods(obj, methods){ function wireAngular(element, config) { var widgetFactory = new WidgetFactory(config['server'], config['database']); - var binder = new Binder(element[0], widgetFactory, config['location'], config); + var binder = new Binder(element[0], widgetFactory, datastore, config['location'], config); var controlBar = new ControlBar(element.find('body'), config.server); var onUpdate = function(){binder.updateView();}; - var server = config.database=="$MEMORY" ? + var server = config['database'] =="$MEMORY" ? new FrameServer(this.window) : - new Server(config.server, jQuery.getScript); + new Server(config['server'], jQuery['getScript']); server = new VisualServer(server, new Status(jQuery(element.body)), onUpdate); var users = new Users(server, controlBar); - var databasePath = '/data/' + config.database; + var databasePath = '/data/' + config['database']; var post = function(request, callback){ server.request("POST", databasePath, request, callback); }; var datastore = new DataStore(post, users, binder.anchor); + binder.datastore = datastore; binder.updateListeners.push(function(){datastore.flush();}); var scope = new Scope({ '$anchor' : binder.anchor, @@ -343,10 +341,14 @@ function wireAngular(element, config) { } angular['startUrlWatcher'] = function(){ - return new UrlWatcher(window['location']).watch(); + var watcher = new UrlWatcher(window['location']); + watcher.watch(); + return exposeMethods(watcher, {'listen':watcher.listen, 'set':watcher.set, 'get':watcher.get}); }; angular['compile'] = function(element, config) { + jQuery = window['jQuery']; + msie = jQuery['browser']['msie']; config = _({ 'server': "", 'location': {'get':noop, 'set':noop, 'listen':noop} diff --git a/src/Binder.js b/src/Binder.js index 48a4f611..e516ec32 100644 --- a/src/Binder.js +++ b/src/Binder.js @@ -1,6 +1,7 @@ -function Binder(doc, widgetFactory, location, config) { +function Binder(doc, widgetFactory, datastore, location, config) { this.doc = doc; this.location = location; + this.datastore = datastore; this.anchor = {}; this.widgetFactory = widgetFactory; this.config = config || {}; @@ -49,7 +50,7 @@ Binder.prototype = { }, parseAnchor: function() { - var self = this, url = this.location.get() || ""; + var self = this, url = this.location['get']() || ""; var anchorIndex = url.indexOf('#'); if (anchorIndex < 0) return; @@ -70,7 +71,7 @@ Binder.prototype = { }, updateAnchor: function() { - var url = this.location.get() || ""; + var url = this.location['get']() || ""; var anchorIndex = url.indexOf('#'); if (anchorIndex > -1) url = url.substring(0, anchorIndex); @@ -87,7 +88,7 @@ Binder.prototype = { sep = '&'; } } - this.location.set(url); + this.location['set'](url); return url; }, @@ -123,12 +124,14 @@ Binder.prototype = { }, entity: function (scope) { + var self = this; this.docFindWithSelf("[ng-entity]").attr("ng-watch", function() { try { var jNode = jQuery(this); - var decl = scope.entity(jNode.attr("ng-entity")); + var decl = scope.entity(jNode.attr("ng-entity"), self.datastore); return decl + (jNode.attr('ng-watch') || ""); } catch (e) { + log(e); alert(e); } }); @@ -136,7 +139,7 @@ Binder.prototype = { compile: function() { var jNode = jQuery(this.doc); - if (this.config.autoSubmit) { + if (this.config['autoSubmit']) { var submits = this.docFindWithSelf(":submit").not("[ng-action]"); submits.attr("ng-action", "$save()"); submits.not(":disabled").not("ng-bind-attr").attr("ng-bind-attr", '{disabled:"{{$invalidWidgets}}"}'); diff --git a/src/ControlBar.js b/src/ControlBar.js index 53c87199..a50b8854 100644 --- a/src/ControlBar.js +++ b/src/ControlBar.js @@ -55,7 +55,7 @@ ControlBar.prototype = { resizable: false, modal:true, title: 'Authentication: <a href="http://www.getangular.com"><tt><angular/></tt></a>' }); - callbacks["_iframe_notify_" + id] = function() { + angularCallbacks["_iframe_notify_" + id] = function() { loginView.dialog("destroy"); loginView.remove(); foreach(self.callbacks, function(callback){ diff --git a/src/DataStore.js b/src/DataStore.js index 7952096f..789b8f71 100644 --- a/src/DataStore.js +++ b/src/DataStore.js @@ -1,7 +1,8 @@ function DataStore(post, users, anchor) { this.post = post; this.users = users; - this._cache = {$collections:[]}; + this._cache_collections = []; + this._cache = {'$collections':this._cache_collections}; this.anchor = anchor; this.bulkRequest = []; }; @@ -15,10 +16,10 @@ DataStore.NullEntity = extend(function(){}, { DataStore.prototype = { cache: function(document) { - if (! document instanceof Model) { + if (! document.datastore === this) { throw "Parameter must be an instance of Entity! " + toJson(document); } - var key = document.$entity + '/' + document.$id; + var key = document['$entity'] + '/' + document['$id']; var cachedDocument = this._cache[key]; if (cachedDocument) { Model.copyDirectFields(document, cachedDocument); @@ -32,10 +33,10 @@ DataStore.prototype = { load: function(instance, id, callback, failure) { if (id && id !== '*') { var self = this; - this._jsonRequest(["GET", instance.$entity + "/" + id], function(response) { - instance.$loadFrom(response); - instance.$migrate(); - var clone = instance.$$entity(instance); + this._jsonRequest(["GET", instance['$entity'] + "/" + id], function(response) { + instance['$loadFrom'](response); + instance['$migrate'](); + var clone = instance['$$entity'](instance); self.cache(clone); (callback||noop)(instance); }, failure); @@ -61,8 +62,8 @@ DataStore.prototype = { loadOrCreate: function(instance, id, callback) { var self=this; return this.load(instance, id, callback, function(response){ - if (response.$status_code == 404) { - instance.$id = id; + if (response['$status_code'] == 404) { + instance['$id'] = id; (callback||noop)(instance); } else { throw response; @@ -73,15 +74,15 @@ DataStore.prototype = { loadAll: function(entity, callback) { var self = this; var list = []; - list.$$accept = function(doc){ - return doc.$entity == entity.title; + list['$$accept'] = function(doc){ + return doc['$entity'] == entity['title']; }; - this._cache.$collections.push(list); - this._jsonRequest(["GET", entity.title], function(response) { + this._cache_collections.push(list); + this._jsonRequest(["GET", entity['title']], function(response) { var rows = response; for ( var i = 0; i < rows.length; i++) { var document = entity(); - document.$loadFrom(rows[i]); + document['$loadFrom'](rows[i]); list.push(self.cache(document)); } (callback||noop)(list); @@ -92,17 +93,17 @@ DataStore.prototype = { save: function(document, callback) { var self = this; var data = {}; - document.$saveTo(data); + document['$saveTo'](data); this._jsonRequest(["POST", "", data], function(response) { - document.$loadFrom(response); + document['$loadFrom'](response); var cachedDoc = self.cache(document); - _.each(self._cache.$collections, function(collection){ - if (collection.$$accept(document)) { - angular['Array']['includeIf'](collection, cachedDoc, true); + _.each(self._cache_collections, function(collection){ + if (collection['$$accept'](document)) { + angularArray['includeIf'](collection, cachedDoc, true); } }); - if (document.$$anchor) { - self.anchor[document.$$anchor] = document.$id; + if (document['$$anchor']) { + self.anchor[document['$$anchor']] = document['$id']; } if (callback) callback(document); @@ -112,13 +113,13 @@ DataStore.prototype = { remove: function(document, callback) { var self = this; var data = {}; - document.$saveTo(data); + document['$saveTo'](data); this._jsonRequest(["DELETE", "", data], function(response) { - delete self._cache[document.$entity + '/' + document.$id]; - _.each(self._cache.$collections, function(collection){ + delete self._cache[document['$entity'] + '/' + document['$id']]; + _.each(self._cache_collections, function(collection){ for ( var i = 0; i < collection.length; i++) { var item = collection[i]; - if (item.$id == document.$id) { + if (item['$id'] == document['$id']) { collection.splice(i, 1); } } @@ -128,8 +129,8 @@ DataStore.prototype = { }, _jsonRequest: function(request, callback, failure) { - request.$$callback = callback; - request.$$failure = failure||function(response){ + request['$$callback'] = callback; + request['$$failure'] = failure||function(response){ throw response; }; this.bulkRequest.push(request); @@ -143,25 +144,25 @@ DataStore.prototype = { log('REQUEST:', bulkRequest); function callback(code, bulkResponse){ log('RESPONSE[' + code + ']: ', bulkResponse); - if(bulkResponse.$status_code == 401) { - self.users.login(function(){ + if(bulkResponse['$status_code'] == 401) { + self.users['login'](function(){ self.post(bulkRequest, callback); }); - } else if(bulkResponse.$status_code) { + } else if(bulkResponse['$status_code']) { alert(toJson(bulkResponse)); } else { for ( var i = 0; i < bulkResponse.length; i++) { var response = bulkResponse[i]; var request = bulkRequest[i]; - var responseCode = response.$status_code; + var responseCode = response['$status_code']; if(responseCode) { if(responseCode == 403) { - self.users.notAuthorized(); + self.users['notAuthorized'](); } else { - request.$$failure(response); + request['$$failure'](response); } } else { - request.$$callback(response); + request['$$callback'](response); } } } @@ -178,9 +179,9 @@ DataStore.prototype = { } for(var key in scope) { var item = scope[key]; - if (item && item.$save == Model.prototype.$save) { + if (item && item['$save'] == Model.prototype['$save']) { saveCounter++; - item.$save(onSaveDone); + item['$save'](onSaveDone); } } onSaveDone(); @@ -189,19 +190,18 @@ DataStore.prototype = { query: function(type, query, arg, callback){ var self = this; var queryList = []; - queryList.$$accept = function(doc){ + queryList['$$accept'] = function(doc){ return false; }; - this._cache.$collections.push(queryList); - var request = type.title + '/' + query + '=' + arg; + this._cache_collections.push(queryList); + var request = type['title'] + '/' + query + '=' + arg; this._jsonRequest(["GET", request], function(response){ var list = response; - for(var i = 0; i < list.length; i++) { - var document = new type().$loadFrom(list[i]); + foreach(list, function(item){ + var document = type()['$loadFrom'](item); queryList.push(self.cache(document)); - } - if (callback) - callback(queryList); + }); + (callback||noop)(queryList); }); return queryList; }, @@ -210,11 +210,11 @@ DataStore.prototype = { var entities = []; var self = this; this._jsonRequest(["GET", "$entities"], function(response) { - for (var entityName in response) { + foreach(response, function(value, entityName){ entities.push(self.entity(entityName)); - } + }); entities.sort(function(a,b){return a.title > b.title ? 1 : -1;}); - if (callback) callback(entities); + (callback||noop)(entities); }); return entities; }, @@ -223,9 +223,7 @@ DataStore.prototype = { var counts = {}; var self = this; self.post([["GET", "$users"]], function(code, response){ - foreach(response[0], function(value, key){ - counts[key] = value; - }); + extend(counts, response[0]); }); return counts; }, @@ -234,9 +232,7 @@ DataStore.prototype = { var ids = {}; var self = this; self.post([["GET", "$users/" + user]], function(code, response){ - foreach(response[0], function(value, key){ - ids[key] = value; - }); + extend(ids, response[0]); }); return ids; }, @@ -252,7 +248,7 @@ DataStore.prototype = { // entity.name does not work as name seems to be reserved for functions 'title': name, '$$factory': true, - 'datastore': this, + datastore: this, //private, obfuscate 'defaults': defaults || {}, 'load': function(id, callback){ return self.load(entity(), id, callback); diff --git a/src/Model.js b/src/Model.js index 4a3a1806..b09efd0e 100644 --- a/src/Model.js +++ b/src/Model.js @@ -3,9 +3,9 @@ function Model(entity, initial) { this['$$entity'] = entity; - this.$loadFrom(initial||{}); - this.$entity = entity['title']; - this.$migrate(); + this['$loadFrom'](initial||{}); + this['$entity'] = entity['title']; + this['$migrate'](); }; Model.copyDirectFields = function(src, dst) { @@ -25,9 +25,9 @@ Model.copyDirectFields = function(src, dst) { } }; -Model.prototype = { +extend(Model.prototype, { '$migrate': function() { - merge(this['$$entity'].defaults, this); + merge(this['$$entity']['defaults'], this); return this; }, @@ -62,4 +62,4 @@ Model.prototype = { Model.copyDirectFields(this, other); return this; } -};
\ No newline at end of file +});
\ No newline at end of file diff --git a/src/Parser.js b/src/Parser.js index 840f5541..d33ae3db 100644 --- a/src/Parser.js +++ b/src/Parser.js @@ -691,8 +691,7 @@ Parser.prototype = { defaults = this.primary()(null); } return function(self) { - var datastore = self.scope.get('$datastore'); - var Entity = datastore.entity(entity, defaults); + var Entity = self.datastore.entity(entity, defaults); self.scope.set(entity, Entity); if (instance) { var document = Entity(); diff --git a/src/Scope.js b/src/Scope.js index dcc50007..3b1f3930 100644 --- a/src/Scope.js +++ b/src/Scope.js @@ -6,9 +6,9 @@ function Scope(initialState, name) { var State = function(){}; State.prototype = initialState; this.state = new State(); - this.state.$parent = initialState; + this.state['$parent'] = initialState; if (name == "ROOT") { - this.state.$root = this.state; + this.state['$root'] = this.state; } }; @@ -37,7 +37,7 @@ Scope.getter = function(instance, path) { } } } - if (typeof instance === 'function' && !instance.$$factory) { + if (typeof instance === 'function' && !instance['$$factory']) { return bind(lastInstance, instance); } return instance; @@ -69,10 +69,12 @@ Scope.prototype = { }, get: function(path) { +// log('SCOPE.get', path, Scope.getter(this.state, path)); return Scope.getter(this.state, path); }, set: function(path, value) { +// log('SCOPE.set', path, value); var element = path.split('.'); var instance = this.state; for ( var i = 0; element.length > 1; i++) { @@ -145,9 +147,9 @@ Scope.prototype = { return expression(self)(self, value); }, - entity: function(entityDeclaration) { + entity: function(entityDeclaration, datastore) { var expression = new Parser(entityDeclaration).entityDeclaration(); - return expression({scope:this}); + return expression({scope:this, datastore:datastore}); }, markInvalid: function(widget) { diff --git a/src/Server.js b/src/Server.js index f351e84c..2932c09b 100644 --- a/src/Server.js +++ b/src/Server.js @@ -14,10 +14,10 @@ Server.prototype = { request: function(method, url, request, callback) { var requestId = this.uuid + (this.nextId++); angularCallbacks[requestId] = function(response) { - delete angular[requestId]; + delete angularCallbacks[requestId]; callback(200, response); }; - var payload = {u:url, m:method, p:request}; + var payload = {'u':url, 'm':method, 'p':request}; payload = this.base64url(toJson(payload)); var totalPockets = Math.ceil(payload.length / this.maxSize); var baseUrl = this.url + "/$/" + requestId + "/" + totalPockets + "/"; diff --git a/test/BinderTest.js b/test/BinderTest.js index 56ada614..6ef46fae 100644 --- a/test/BinderTest.js +++ b/test/BinderTest.js @@ -5,14 +5,13 @@ function compile(content, initialScope, config) { config = config || {autoSubmit:true}; var scope = new Scope(initialScope, "ROOT"); h.data('scope', scope); - var binder = new Binder(h[0], new WidgetFactory(), new MockLocation(), config); var datastore = new DataStore(); - scope.set("$datastore", datastore); + var binder = new Binder(h[0], new WidgetFactory(), datastore, new MockLocation(), config); scope.set("$updateView", _(binder.updateView).bind(binder)); scope.set("$anchor", binder.anchor); binder.entity(scope); binder.compile(); - return {node:h, binder:binder, scope:scope}; + return {node:h, binder:binder, scope:scope, datastore:datastore}; } function compileToHtml(content) { @@ -117,34 +116,23 @@ BinderTest.prototype.testChangingTextfieldUpdatesModel = function(){ }; BinderTest.prototype.testChangingTextareaUpdatesModel = function(){ - var form = html('<textarea name="model.note">abc</textarea>'); - var scope = new Scope({model:{}}); - form.data('scope', scope); - var binder = new Binder(form.get(0), new WidgetFactory(), new MockLocation()); - binder.compile(); - binder.updateView(); - assertEquals(scope.get('model').note, 'abc'); + var c = compile('<textarea name="model.note">abc</textarea>'); + c.binder.updateView(); + assertEquals(c.scope.get('model').note, 'abc'); }; BinderTest.prototype.testChangingRadioUpdatesModel = function(){ - var form = html('<input type="radio" name="model.price" value="A" checked>' + + var c = compile('<input type="radio" name="model.price" value="A" checked>' + '<input type="radio" name="model.price" value="B">'); - var scope = new Scope({model:{}}); - form.data('scope', scope); - var binder = new Binder(form.get(0), new WidgetFactory(), new MockLocation()); - binder.compile(); - binder.updateView(); - assertEquals(scope.get('model').price, 'A'); + c.binder.updateView(); + assertEquals(c.scope.get('model').price, 'A'); }; BinderTest.prototype.testChangingCheckboxUpdatesModel = function(){ - var form = html('<input type="checkbox" name="model.price" value="A" checked>'); - var scope = new Scope({model:{}}); - form.data('scope', scope); - var binder = new Binder(form.get(0), new WidgetFactory(), new MockLocation()); - binder.compile(); - binder.updateView(); - assertEquals('A', scope.get('model').price); + var form = compile('<input type="checkbox" name="model.price" value="A" checked>'); + form.scope.set('model', {}); + form.binder.updateView(); + assertEquals('A', form.scope.get('model').price); }; BinderTest.prototype.testBindUpdate = function() { @@ -154,37 +142,28 @@ BinderTest.prototype.testBindUpdate = function() { }; BinderTest.prototype.testChangingSelectNonSelectedUpdatesModel = function(){ - var form = html('<select name="model.price"><option value="A">A</option><option value="B">B</option></select>'); - var scope = new Scope({model:{}}); - form.data('scope', scope); - var binder = new Binder(form.get(0), new WidgetFactory(), new MockLocation()); - binder.compile(); - binder.updateView(); - assertEquals('A', scope.get('model').price); + var form = compile('<select name="model.price"><option value="A">A</option><option value="B">B</option></select>'); + form.scope.set('model', {}); + form.binder.updateView(); + assertEquals('A', form.scope.get('model').price); }; BinderTest.prototype.testChangingMultiselectUpdatesModel = function(){ - var form = html('<select name="Invoice.options" multiple="multiple">' + + var form = compile('<select name="Invoice.options" multiple="multiple">' + '<option value="A" selected>Gift wrap</option>' + '<option value="B" selected>Extra padding</option>' + '<option value="C">Expedite</option>' + '</select>'); - var scope = new Scope({Invoice:{}}); - form.data('scope', scope); - var binder = new Binder(form.get(0), new WidgetFactory(), new MockLocation()); - binder.compile(); - binder.updateView(); - assertJsonEquals(["A", "B"], scope.get('Invoice').options); + form.scope.set("Invoice", {}); + form.binder.updateView(); + assertJsonEquals(["A", "B"], form.scope.get('Invoice').options); }; BinderTest.prototype.testChangingSelectSelectedUpdatesModel = function(){ - var form = html('<select name="model.price"><option>A</option><option selected value="b">B</option></select>'); - var scope = new Scope({model:{}}); - form.data('scope', scope); - var binder = new Binder(form.get(0), new WidgetFactory(), new MockLocation()); - binder.compile(); - binder.updateView(); - assertEquals(scope.get('model').price, 'b'); + var form = compile('<select name="model.price"><option>A</option><option selected value="b">B</option></select>'); + form.scope.set('model', {}); + form.binder.updateView(); + assertEquals(form.scope.get('model').price, 'b'); }; BinderTest.prototype.testExecuteInitialization = function() { @@ -207,13 +186,11 @@ BinderTest.prototype.testExecuteInitializationStatements = function() { }; BinderTest.prototype.testApplyTextBindings = function(){ - var form = html('<div ng-bind="model.a">x</div>'); - var scope = new Scope({model:{a:123}}); - form.data('scope', scope); - var binder = new Binder(form.get(0), null, new MockLocation()); - binder.compile(); - binder.updateView(); - assertEquals('123', form.text()); + var form = compile('<div ng-bind="model.a">x</div>'); + form.scope.set('model', {a:123}); + form.binder.compile(); + form.binder.updateView(); + assertEquals('123', form.node.text()); }; BinderTest.prototype.testReplaceBindingInTextWithSpan = function() { @@ -285,10 +262,9 @@ BinderTest.prototype.testExistingAttrbindingIsAppended = function() { }; BinderTest.prototype.testAttributesAreEvaluated = function(){ - var form = html('<a ng-bind-attr=\'{"a":"a", "b":"a+b={{a+b}}"}\'></a>'); - form.data('scope', new Scope({a:1, b:2})); - var binder = new Binder(form.get(0), null, new MockLocation()); - binder.compile(); + var c = compile('<a ng-bind-attr=\'{"a":"a", "b":"a+b={{a+b}}"}\'></a>'); + var binder = c.binder, form = c.node; + c.scope.eval('a=1;b=2'); binder.updateView(); var a = form.find("a"); assertEquals(a.attr('a'), 'a'); @@ -296,16 +272,16 @@ BinderTest.prototype.testAttributesAreEvaluated = function(){ }; BinderTest.prototype.testInputsAreUpdated = function(){ - var form = - html('<input type="tEXt" name="A.text"/>' + - '<textarea name="A.textarea"/>' + - '<input name="A.radio" type="rADio" value="r"/>' + - '<input name="A.radioOff" type="rADio" value="r"/>' + - '<input name="A.checkbox" type="checkbox" value="c" />' + - '<input name="A.checkboxOff" type="checkbox" value="c" />' + - '<select name="A.select"><option>a</option><option value="S">b</option></select>'); - var binder = new Binder(form.get(0), new WidgetFactory(), new MockLocation()); - form.data('scope', new Scope({A:{text:"t1", textarea:"t2", radio:"r", checkbox:"c", select:"S"}})); + var a = + compile('<input type="tEXt" name="A.text"/>' + + '<textarea name="A.textarea"></textarea>' + + '<input name="A.radio" type="rADio" value="r"/>' + + '<input name="A.radioOff" type="rADio" value="r"/>' + + '<input name="A.checkbox" type="checkbox" value="c" />' + + '<input name="A.checkboxOff" type="checkbox" value="c" />' + + '<select name="A.select"><option>a</option><option value="S">b</option></select>'); + var binder = a.binder, form = a.node; + a.scope.set('A', {text:"t1", textarea:"t2", radio:"r", checkbox:"c", select:"S"}); binder.compile(); binder.updateView(); assertEquals(form.find("input[type=text]").attr('value'), 't1'); @@ -348,8 +324,8 @@ BinderTest.prototype.testButtonElementActionExecutesInScope = function(){ }; BinderTest.prototype.testParseEmptyAnchor = function(){ - var location = new MockLocation(); - var binder = new Binder(null, null, location); + var binder = compile("<div/>").binder; + var location = binder.location; var anchor = binder.anchor; location.url = "a#x=1"; binder.parseAnchor(); @@ -362,8 +338,8 @@ BinderTest.prototype.testParseEmptyAnchor = function(){ }; BinderTest.prototype.testParseAnchor = function(){ - var location = new MockLocation(); - var binder = new Binder(null, null, location); + var binder = compile("<div/>").binder; + var location = binder.location; location.url = "a#x=1"; binder.parseAnchor(); assertEquals(binder.anchor.x, "1"); @@ -376,7 +352,7 @@ BinderTest.prototype.testParseAnchor = function(){ }; BinderTest.prototype.testWriteAnchor = function(){ - var binder = new Binder(null, null, new MockLocation()); + var binder = compile("<div/>").binder; binder.location.set('a'); binder.anchor.a = 'b'; binder.anchor.c = ' '; @@ -386,22 +362,20 @@ BinderTest.prototype.testWriteAnchor = function(){ }; BinderTest.prototype.testWriteAnchorAsPartOfTheUpdateView = function(){ - var binder = new Binder(html("<div/>")[0], null, new MockLocation()); + var binder = compile("<div/>").binder; binder.location.set('a'); - $(binder.doc).data('scope', new Scope()); binder.anchor.a = 'b'; binder.updateView(); assertEquals(binder.location.get(), "a#a=b"); }; BinderTest.prototype.testRepeaterUpdateBindings = function(){ - var form = html('<ul><LI ng-repeat="item in model.items" ng-bind="item.a"/></ul>'); - var binder = new Binder(form.get(0), null, new MockLocation()); + var a = compile('<ul><LI ng-repeat="item in model.items" ng-bind="item.a"/></ul>'); + var form = a.node; var items = [{a:"A"}, {a:"B"}]; - form.data('scope', new Scope({model:{items:items}})); - binder.compile(); + a.scope.set('model', {items:items}); - binder.updateView(); + a.binder.updateView(); assertEquals('<ul>' + '<#comment></#comment>' + '<li ng-bind="item.a" ng-repeat-index="0">A</li>' + @@ -409,7 +383,7 @@ BinderTest.prototype.testRepeaterUpdateBindings = function(){ '</ul>', form.sortedHtml()); items.unshift({a:'C'}); - binder.updateView(); + a.binder.updateView(); assertEquals('<ul>' + '<#comment></#comment>' + '<li ng-bind="item.a" ng-repeat-index="0">C</li>' + @@ -418,7 +392,7 @@ BinderTest.prototype.testRepeaterUpdateBindings = function(){ '</ul>', form.sortedHtml()); items.shift(); - binder.updateView(); + a.binder.updateView(); assertEquals('<ul>' + '<#comment></#comment>' + '<li ng-bind="item.a" ng-repeat-index="0">A</li>' + @@ -427,15 +401,13 @@ BinderTest.prototype.testRepeaterUpdateBindings = function(){ }; BinderTest.prototype.testRepeaterContentDoesNotBind = function(){ - var form = html('<ul><LI ng-repeat="item in model.items"><span ng-bind="item.a"/></li></ul>'); - form.data('scope', new Scope({model:{items:[{a:"A"}]}})); - var binder = new Binder(form.get(0), null, new MockLocation()); - binder.compile(); - binder.updateView(); + var a = compile('<ul><LI ng-repeat="item in model.items"><span ng-bind="item.a"/></li></ul>'); + a.scope.set('model', {items:[{a:"A"}]}); + a.binder.updateView(); assertEquals('<ul>' + '<#comment></#comment>' + '<li ng-repeat-index="0"><span ng-bind="item.a">A</span></li>' + - '</ul>', form.sortedHtml()); + '</ul>', a.node.sortedHtml()); }; BinderTest.prototype.testShouldBindActionsOnRepeaterClone = function(){ @@ -524,64 +496,55 @@ BinderTest.prototype.testRepeaterAdd = function(){ }; BinderTest.prototype.testIfTextBindingThrowsErrorDecorateTheSpan = function(){ - var doc = $('<div>{{error.throw()}}</div>'); - var scope = new Scope(); - doc.data('scope', scope); - var binder = new Binder(doc[0], new WidgetFactory(), new MockLocation()); - binder.compile(); + var a = compile('<div>{{error.throw()}}</div>'); + var doc = a.node.find('div'); - scope.set('error.throw', function(){throw "ErrorMsg1";}); - binder.updateView(); + a.scope.set('error.throw', function(){throw "ErrorMsg1";}); + a.binder.updateView(); var span = doc.find('span'); assertTrue(span.hasClass('ng-exception')); assertEquals('ErrorMsg1', fromJson(span.text())); assertEquals('"ErrorMsg1"', span.attr('ng-error')); - scope.set('error.throw', function(){throw "MyError";}); - binder.updateView(); + a.scope.set('error.throw', function(){throw "MyError";}); + a.binder.updateView(); span = doc.find('span'); assertTrue(span.hasClass('ng-exception')); assertTrue(span.text(), span.text().match('MyError') !== null); assertEquals('"MyError"', span.attr('ng-error')); - scope.set('error.throw', function(){return "ok";}); - binder.updateView(); + a.scope.set('error.throw', function(){return "ok";}); + a.binder.updateView(); assertFalse(span.hasClass('ng-exception')); assertEquals('ok', span.text()); assertEquals(null, span.attr('ng-error')); }; BinderTest.prototype.testIfAttrBindingThrowsErrorDecorateTheSpan = function(){ - var doc = $('<div attr="before {{error.throw()}} after"/>'); - var scope = new Scope(); - doc.data('scope', scope); - var binder = new Binder(doc[0], new WidgetFactory(), new MockLocation()); - binder.compile(); + var a = compile('<div attr="before {{error.throw()}} after"></div>'); + var doc = a.node.find("div"); - scope.set('error.throw', function(){throw "ErrorMsg";}); - binder.updateView(); + a.scope.set('error.throw', function(){throw "ErrorMsg";}); + a.binder.updateView(); assertTrue('ng-exception', doc.hasClass('ng-exception')); assertEquals('before ["ErrorMsg"] after', doc.attr('attr')); assertEquals('"ErrorMsg"', doc.attr('ng-error')); - scope.set('error.throw', function(){ return 'X';}); - binder.updateView(); + a.scope.set('error.throw', function(){ return 'X';}); + a.binder.updateView(); assertFalse('!ng-exception', doc.hasClass('ng-exception')); assertEquals('before X after', doc.attr('attr')); assertEquals(null, doc.attr('ng-error')); + }; BinderTest.prototype.testNestedRepeater = function() { - var doc = html('<div ng-repeat="m in model" name="{{m.name}}">' + + var a = compile('<div ng-repeat="m in model" name="{{m.name}}">' + '<ul name="{{i}}" ng-repeat="i in m.item"></ul>' + '</div>'); - var scope = new Scope(); - doc.data('scope', scope); - var binder = new Binder(doc[0], new WidgetFactory(), new MockLocation()); - binder.compile(); - scope.set('model', [{name:'a', item:['a1', 'a2']}, {name:'b', item:['b1', 'b2']}]); - binder.updateView(); + a.scope.set('model', [{name:'a', item:['a1', 'a2']}, {name:'b', item:['b1', 'b2']}]); + a.binder.updateView(); assertEquals( //'<#comment></#comment>'+ @@ -594,88 +557,71 @@ BinderTest.prototype.testNestedRepeater = function() { '<#comment></#comment>'+ '<ul name="b1" ng-bind-attr="{"name":"{{i}}"}" ng-repeat-index="0"></ul>'+ '<ul name="b2" ng-bind-attr="{"name":"{{i}}"}" ng-repeat-index="1"></ul>'+ - '</div>', doc.sortedHtml()); + '</div>', a.node.sortedHtml()); }; BinderTest.prototype.testRadioButtonGetsPrefixed = function () { - var doc = html('<input ng-repeat="m in model" type="radio" name="m.a" value="on"/>'); - var scope = new Scope(); - doc.data('scope', scope); - var binder = new Binder(doc[0], new WidgetFactory(), new MockLocation()); - binder.compile(); - - scope.set('model', ['a1', 'a2']); - binder.updateView(); + var a = compile('<input ng-repeat="m in model" type="radio" name="m.a" value="on"/>'); + a.scope.set('model', ['a1', 'a2']); + a.binder.updateView(); assertEquals( //'<#comment></#comment>'+ '<input name="0:m.a" ng-repeat-index="0" type="radio" value="on"></input>'+ '<input name="1:m.a" ng-repeat-index="1" type="radio" value="on"></input>', - doc.sortedHtml()); + a.node.sortedHtml()); }; BinderTest.prototype.testHideBindingExpression = function() { - var doc = html('<div ng-hide="hidden == 3"/>'); - var scope = new Scope(); - doc.data('scope', scope); - var binder = new Binder(doc[0], new WidgetFactory(), new MockLocation()); - binder.compile(); + var a = compile('<div ng-hide="hidden == 3"/>'); - scope.set('hidden', 3); - binder.updateView(); + a.scope.set('hidden', 3); + a.binder.updateView(); - assertHidden(doc.children()); + assertHidden(a.node.children()); - scope.set('hidden', 2); - binder.updateView(); + a.scope.set('hidden', 2); + a.binder.updateView(); - assertVisible(doc.children()); + assertVisible(a.node.children()); }; BinderTest.prototype.testHideBinding = function() { - var doc = html('<div ng-hide="hidden"/>'); - var scope = new Scope(); - doc.data('scope', scope); - var binder = new Binder(doc[0], new WidgetFactory(), new MockLocation()); - binder.compile(); + var c = compile('<div ng-hide="hidden"/>'); - scope.set('hidden', 'true'); - binder.updateView(); + c.scope.set('hidden', 'true'); + c.binder.updateView(); - assertHidden(doc.children()); + assertHidden(c.node.children()); - scope.set('hidden', 'false'); - binder.updateView(); + c.scope.set('hidden', 'false'); + c.binder.updateView(); - assertVisible(doc.children()); + assertVisible(c.node.children()); - scope.set('hidden', ''); - binder.updateView(); + c.scope.set('hidden', ''); + c.binder.updateView(); - assertVisible(doc.children()); + assertVisible(c.node.children()); }; BinderTest.prototype.testShowBinding = function() { - var doc = html('<div ng-show="show"/>'); - var scope = new Scope(); - doc.data('scope', scope); - var binder = new Binder(doc[0], new WidgetFactory(), new MockLocation()); - binder.compile(); + var c = compile('<div ng-show="show"/>'); - scope.set('show', 'true'); - binder.updateView(); + c.scope.set('show', 'true'); + c.binder.updateView(); - assertVisible(doc.children()); + assertVisible(c.node.children()); - scope.set('show', 'false'); - binder.updateView(); + c.scope.set('show', 'false'); + c.binder.updateView(); - assertHidden(doc.children()); + assertHidden(c.node.children()); - scope.set('show', ''); - binder.updateView(); + c.scope.set('show', ''); + c.binder.updateView(); - assertHidden(doc.children()); + assertHidden(c.node.children()); }; BinderTest.prototype.testBindClassUndefined = function() { @@ -688,22 +634,18 @@ BinderTest.prototype.testBindClassUndefined = function() { }; BinderTest.prototype.testBindClass = function() { - var doc = html('<div ng-class="class"/>'); - var scope = new Scope(); - doc.data('scope', scope); - var binder = new Binder(doc[0], new WidgetFactory(), new MockLocation()); - binder.compile(); + var c = compile('<div ng-class="class"/>'); - scope.set('class', 'testClass'); - binder.updateView(); + c.scope.set('class', 'testClass'); + c.binder.updateView(); - assertEquals(doc.sortedHtml(), + assertEquals(c.node.sortedHtml(), '<div class="testClass" ng-class="class"></div>'); - scope.set('class', ['a', 'b']); - binder.updateView(); + c.scope.set('class', ['a', 'b']); + c.binder.updateView(); - assertEquals(doc.sortedHtml(), + assertEquals(c.node.sortedHtml(), '<div class="a,b" ng-class="class"></div>'); }; @@ -717,21 +659,17 @@ BinderTest.prototype.testBindClassEvenOdd = function() { }; BinderTest.prototype.testBindStyle = function() { - var doc = html('<div ng-style="style"/>'); - var scope = new Scope(); - doc.data('scope', scope); - var binder = new Binder(doc[0], new WidgetFactory(), new MockLocation()); - binder.compile(); + var c = compile('<div ng-style="style"/>'); - scope.eval('style={color:"red"}'); - binder.updateView(); + c.scope.eval('style={color:"red"}'); + c.binder.updateView(); - assertEquals("red", doc.find('div').css('color')); + assertEquals("red", c.node.find('div').css('color')); - scope.eval('style={}'); - binder.updateView(); + c.scope.eval('style={}'); + c.binder.updateView(); - assertEquals(doc.sortedHtml(), '<div ng-style="style"></div>'); + assertEquals(c.node.sortedHtml(), '<div ng-style="style"></div>'); }; BinderTest.prototype.testActionOnAHrefThrowsError = function(){ @@ -919,7 +857,7 @@ BinderTest.prototype.testParseQueryString = function(){ BinderTest.prototype.testSetBinderAnchorTriggersListeners = function(){ expectAsserts(2); var doc = html("<div/>")[0]; - var binder = new Binder(doc, null, new MockLocation()); + var binder = new Binder(doc, null, null, new MockLocation()); var scope = new Scope({$binder:binder, $anchor:binder.anchor}); jQuery(doc).data('scope', scope); diff --git a/test/EntityDeclarationTest.js b/test/EntityDeclarationTest.js index d64dd775..28986ea8 100644 --- a/test/EntityDeclarationTest.js +++ b/test/EntityDeclarationTest.js @@ -2,31 +2,34 @@ EntityDeclarationTest = TestCase('EntityDeclarationTest'); EntityDeclarationTest.prototype.testEntityTypeOnly = function(){ expectAsserts(2); - var scope = new Scope({$datastore:{entity:function(name){ + var datastore = {entity:function(name){ assertEquals("Person", name); - }}}); - var init = scope.entity("Person"); + }}; + var scope = new Scope(); + var init = scope.entity("Person", datastore); assertEquals("", init); }; EntityDeclarationTest.prototype.testWithDefaults = function(){ expectAsserts(4); - var scope = new Scope({$datastore:{entity:function(name, init){ + var datastore = {entity:function(name, init){ assertEquals("Person", name); assertEquals("=a:", init.a); assertEquals(0, init.b.length); - }}}); - var init = scope.entity('Person:{a:"=a:", b:[]}'); + }}; + var scope = new Scope(); + var init = scope.entity('Person:{a:"=a:", b:[]}', datastore); assertEquals("", init); }; EntityDeclarationTest.prototype.testWithName = function(){ expectAsserts(2); - var scope = new Scope({$datastore:{entity:function(name, init){ + var datastore = {entity:function(name, init){ assertEquals("Person", name); return function (){ return {}; }; - }}}); - var init = scope.entity('friend=Person'); + }}; + var scope = new Scope(); + var init = scope.entity('friend=Person', datastore); assertEquals("$anchor.friend:{friend=Person.load($anchor.friend);friend.$$anchor=\"friend\";};", init); }; @@ -34,12 +37,13 @@ EntityDeclarationTest.prototype.testMultipleEntities = function(){ expectAsserts(3); var expect = ['Person', 'Book']; var i=0; - var scope = new Scope({$datastore:{entity:function(name, init){ + var datastore = {entity:function(name, init){ assertEquals(expect[i], name); i++; return function (){ return {}; }; - }}}); - var init = scope.entity('friend=Person;book=Book;'); + }}; + var scope = new Scope(); + var init = scope.entity('friend=Person;book=Book;', datastore); assertEquals("$anchor.friend:{friend=Person.load($anchor.friend);friend.$$anchor=\"friend\";};" + "$anchor.book:{book=Book.load($anchor.book);book.$$anchor=\"book\";};", init); diff --git a/test/ParserTest.js b/test/ParserTest.js index fbd9f508..2fcbc7fe 100644 --- a/test/ParserTest.js +++ b/test/ParserTest.js @@ -451,8 +451,7 @@ ParserTest.prototype.testItShouldHaveDefaultArugument = function(){ ParserTest.prototype.testReturnFunctionsAreNotBound = function(){ var scope = new Scope(); - scope.set("$datastore", new DataStore()); - scope.entity("Group"); + scope.entity("Group", new DataStore()); var Group = scope.get("Group"); assertEquals("eval Group", "function", typeof scope.eval("Group")); assertEquals("direct Group", "function", typeof Group); diff --git a/test/ScenarioSpec.js b/test/ScenarioSpec.js index c3c29f02..2ca1de2f 100644 --- a/test/ScenarioSpec.js +++ b/test/ScenarioSpec.js @@ -29,7 +29,7 @@ describe("ScenarioSpec: Scope", function(){ }); it("should have config", function(){ - expect(angular.compile('', {a:'b'}).config.a).toEqual('b'); + expect(angular.compile('<div></div>', {a:'b'}).config.a).toEqual('b'); }); it("should have $ objects", function(){ |
